Compare commits
212 Commits
76ffff363a
...
screen-dev
| Author | SHA1 | Date | |
|---|---|---|---|
| 84f454ea8a | |||
| ac1d1ae154 | |||
| 825243e741 | |||
| 0389ed85f3 | |||
| aef94f406a | |||
| 95d69fb7b1 | |||
| 684002ffc8 | |||
| 098dfa05f8 | |||
| d6c9310e50 | |||
| 142de3102b | |||
| 9b5806a2c0 | |||
| 2b6697fa5a | |||
| 3bb859b693 | |||
| 5b3701afd0 | |||
| f531075853 | |||
| 8cb6fbee3e | |||
| f454b02c99 | |||
| bfe72cf2c3 | |||
| fb90d81bb3 | |||
| 823c0949d0 | |||
| c1c411e48a | |||
| 43153a791d | |||
| 11111d035b | |||
| ab9bb1e85d | |||
| 4079c40e5d | |||
| 4ebd5f0988 | |||
| a0095b4054 | |||
| 84bc29410a | |||
| f3fda19c64 | |||
| 9a8247f833 | |||
| c4c79aaa64 | |||
| 0966813c25 | |||
| dd4fa36597 | |||
| 9b14d96e24 | |||
| ac54ce999e | |||
| f49efb5edd | |||
| 97f9b3ff0e | |||
| 674a0c6c33 | |||
| 7f3d02b8fb | |||
| cd8871d45a | |||
| 11d44de513 | |||
| 78eb81549b | |||
| 65f0e92296 | |||
| 9a585e97db | |||
| 7fb6d1aa47 | |||
| 1378947a9e | |||
| 0b2e7d9b86 | |||
| 87ffaca398 | |||
| 06ef1c3d1d | |||
| bc5f2b4470 | |||
| f24241533b | |||
| 87cd27b798 | |||
| 3fd6f812b9 | |||
| 1772c7e0e5 | |||
| eb5abec9ff | |||
| 834bd04d45 | |||
| da0d3d12ef | |||
| 1280b7196c | |||
| 567ddf85a5 | |||
| 3766b2c0fa | |||
| 695fcd0f8f | |||
| 11269efa2d | |||
| 4b8380a6a9 | |||
| 5c150b0d26 | |||
| 96e4f7874f | |||
| bf833fc763 | |||
| f4e6821484 | |||
| fb0eda4565 | |||
| fef1704cbd | |||
| 679f8f2a07 | |||
| 376b50c3b5 | |||
| 7d51c37cad | |||
| ad95debdac | |||
| cceca2af4f | |||
| 887af476ba | |||
| 28a6e525d8 | |||
| 66e2a3daab | |||
| d3558f5ee4 | |||
| 4005b921e6 | |||
| 7d2d49b7e2 | |||
| cc4d6ab347 | |||
| 7497c1d1b9 | |||
| a1fdc958db | |||
| 9dcf2a6c12 | |||
| fb4f9d4abc | |||
| 651a78bceb | |||
| a4ae820e98 | |||
| 466d3a14b6 | |||
| b421d11bc2 | |||
| 408ba489ca | |||
| b5956822ab | |||
| 6600a5db7a | |||
| 506cf28c96 | |||
| 5f7a1c0f4b | |||
| 1f49a3af20 | |||
| a0ea6041cc | |||
| 0e7b54291f | |||
| cbc7a341c9 | |||
| 85cfd204ae | |||
| 2cb4dbcd84 | |||
| 6ad3ef9d7c | |||
| 36b1e19120 | |||
| 902e9a0a03 | |||
| 7f560cd140 | |||
| e3224d37a1 | |||
| 52b6083baa | |||
| 98e2c4c3be | |||
| 4c31eeb837 | |||
| b61a202267 | |||
| c51baa166b | |||
| f005448705 | |||
| ba4df32176 | |||
| ae1c2a5d6c | |||
| f16b92582c | |||
| cc3164a423 | |||
| 2742f874ce | |||
| e7ea8c8f44 | |||
| c502688737 | |||
| 243724c9a6 | |||
| 8808b25682 | |||
| f5fc1d64ec | |||
| a0790b100a | |||
| c3d64e4d04 | |||
| 89cc734595 | |||
| 587094e85e | |||
| 0299d32a52 | |||
| 15196f8d71 | |||
| 8b20c89cb2 | |||
| ba8b86d523 | |||
| 2cd60ea105 | |||
| 10033348d6 | |||
| 9a9198b168 | |||
| 9ad720823a | |||
| 763338cc2a | |||
| d203ca541a | |||
| 9db3b4f9f7 | |||
| 7a13a73758 | |||
| 7b88d754ee | |||
| 87d683273a | |||
| f71119885a | |||
| 000c8fec25 | |||
| 9406b0eb98 | |||
| fd9caf8da6 | |||
| 658fa5042c | |||
| 62eb0e7e7d | |||
| e9c8b10d29 | |||
| c837caa78a | |||
| 5ee8a6d17f | |||
| ffa76c5a7a | |||
| c0bed77a5d | |||
| d0a31f9ee8 | |||
| be1fb382ff | |||
| 3308887e4c | |||
| bcfeb04fd3 | |||
| 21bbaa5c30 | |||
| 8fc9f975e1 | |||
| 893c690e7d | |||
| ee6628a19b | |||
| 111079eb48 | |||
| b84bb3fd89 | |||
| b22795134d | |||
| be4d99fb94 | |||
| 2509077842 | |||
| 28cf2d1946 | |||
| 0336e67ac5 | |||
| b8827248cb | |||
| b3b4d9c0dc | |||
| cc190e42f8 | |||
| ec59f226b3 | |||
| 6523e061bd | |||
| 59d2a09644 | |||
| 21a8871e3c | |||
| bf92b8010b | |||
| d06feb2078 | |||
| 4d58c9883c | |||
| ec35538afd | |||
| 328f893da9 | |||
| c53bc4dc45 | |||
| cacd939dd6 | |||
| b59b564544 | |||
| 0861c3e15f | |||
| edab894447 | |||
| 99b019ebc9 | |||
| 9b78635fd8 | |||
| ab9a13264c | |||
| 46490aebee | |||
| b8779bee61 | |||
| c296e63df4 | |||
| 3fa574d18b | |||
| ca7e9a60b2 | |||
| d763eb2cd8 | |||
| 7aafcf2113 | |||
| 62fff8c9f4 | |||
| 3a6c668476 | |||
| 71cd3cd76c | |||
| 86cbf64a9d | |||
| f64b5d30cb | |||
| e42f1204ee | |||
| 5f4fcdf754 | |||
| b3598f1ba8 | |||
| 37d2d9bde5 | |||
| d0d4c25377 | |||
| 13310948c3 | |||
| 1b19a91d74 | |||
| 89711b6a07 | |||
| 6ad00c60fe | |||
| 5f055ce5c9 | |||
| e8333c6552 | |||
| d68d48ddee | |||
| 6cec2849ba | |||
| 7145afd5a0 | |||
| 4d9e8e5373 |
@ -1,11 +1,15 @@
|
||||
# 页面标题
|
||||
VUE_APP_TITLE = EMS管理系统
|
||||
VUE_APP_TITLE = 上动新能源-EMS管理系统
|
||||
|
||||
# 路由懒加载
|
||||
VUE_CLI_BABEL_TRANSPILE_MODULES = true
|
||||
|
||||
# 开发环境配置
|
||||
ENV = 'development'
|
||||
NODE_ENV = 'development'
|
||||
|
||||
# EMS管理系统/开发环境
|
||||
VUE_APP_BASE_API = '/dev-api'
|
||||
|
||||
# 路由懒加载
|
||||
VUE_CLI_BABEL_TRANSPILE_MODULES = true
|
||||
# EMS管理系统/开发环境 图片拼接地址
|
||||
VUE_APP_IMG_URL = '/dev-api'
|
||||
|
||||
|
||||
@ -1,8 +1,12 @@
|
||||
# 页面标题
|
||||
VUE_APP_TITLE = EMS管理系统
|
||||
VUE_APP_TITLE = 上动新能源-EMS管理系统
|
||||
|
||||
# 生产环境配置
|
||||
ENV = 'production'
|
||||
NODE_ENV = 'production'
|
||||
|
||||
# EMS管理系统/生产环境
|
||||
VUE_APP_BASE_API = '/dev-api'
|
||||
VUE_APP_BASE_API= 'http://1.15.120.242:8089'
|
||||
|
||||
# EMS管理系统/生产环境 图片拼接地址
|
||||
VUE_APP_IMG_URL = 'http://1.15.120.242:8089'
|
||||
|
||||
|
||||
14
.env.staging
@ -1,12 +1,12 @@
|
||||
# 页面标题
|
||||
VUE_APP_TITLE = EMS管理系统
|
||||
|
||||
BABEL_ENV = production
|
||||
|
||||
NODE_ENV = production
|
||||
VUE_APP_TITLE = 上动新能源-EMS管理系统
|
||||
|
||||
# 测试环境配置
|
||||
ENV = 'staging'
|
||||
NODE_ENV = 'staging'
|
||||
|
||||
# EMS管理系统/测试环境
|
||||
VUE_APP_BASE_API = '/stage-api'
|
||||
VUE_APP_BASE_API= 'http://110.40.171.179:8089'
|
||||
|
||||
# EMS管理系统/测试环境 图片拼接地址
|
||||
VUE_APP_IMG_URL = 'http://110.40.171.179:8089'
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
<meta name="renderer" content="webkit">
|
||||
<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>
|
||||
<!--[if lt IE 11]><script>window.location.href='/html/ie.html';</script><![endif]-->
|
||||
<style>
|
||||
|
||||
BIN
public/logo-icon.png
Normal file
|
After Width: | Height: | Size: 31 KiB |
@ -2,8 +2,383 @@ import request from '@/utils/request'
|
||||
|
||||
//获取单个站点的信息
|
||||
export function getDzjkHomeView(siteId) {
|
||||
return request({
|
||||
url: `/ems/siteMonitor/homeView?siteId=${siteId}`,
|
||||
method: 'get'
|
||||
})
|
||||
return request({
|
||||
url: `/ems/siteMonitor/homeView?siteId=${siteId}`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
//站点首页 冲放曲线
|
||||
export function getSevenChargeData({siteId, startDate, endDate}) {
|
||||
return request({
|
||||
url: `/ems/siteMap/getSevenChargeData?siteId=${siteId}&startDate=${startDate}&endDate=${endDate}`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 获取站点包含的设备种类 用来判断单站监控设备监控的菜单栏展示
|
||||
export function getSiteAllDeviceCategory(siteId) {
|
||||
return request({
|
||||
url: `/ems/siteConfig/getSiteAllDeviceCategory?siteId=${siteId}`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
//EMS
|
||||
export function getEmsDataList(siteId) {
|
||||
return request({
|
||||
url: `/ems/siteMonitor/getEmsDataList?siteId=${siteId}`,
|
||||
method: 'get',
|
||||
})
|
||||
}
|
||||
|
||||
//获取pcs、实时运行头部的设备信息
|
||||
export function getRunningHeadInfo(siteId) {
|
||||
return request({
|
||||
url: `/ems/siteMonitor/runningHeadInfo?siteId=${siteId}`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
//获取pcs列表
|
||||
export function getPcsDetailInfo(siteId) {
|
||||
return request({
|
||||
url: `/ems/siteMonitor/getPcsDetailInfo?siteId=${siteId}`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
//获取BMS总览数据
|
||||
export function getBMSOverView(siteId) {
|
||||
return request({
|
||||
url: `/ems/siteMonitor/getBMSOverView?siteId=${siteId}`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
//获取BMS电池簇总览数据
|
||||
export function getBMSBatteryCluster(siteId) {
|
||||
return request({
|
||||
url: `/ems/siteMonitor/getBMSBatteryCluster?siteId=${siteId}`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
//获取单体电池 电池堆列表数据
|
||||
export function getStackNameList(siteId) {
|
||||
return request({
|
||||
url: `/ems/siteMonitor/getStackNameList?siteId=${siteId}`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
//获取单体电池 电池簇列表数据
|
||||
export function getClusterNameList({stackDeviceId, siteId}) {
|
||||
return request({
|
||||
url: `/ems/siteMonitor/getClusterNameList?stackDeviceId=${stackDeviceId}&siteId=${siteId}`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
//单体电池表格数据
|
||||
export function getClusterDataInfoList({siteId, stackDeviceId, clusterDeviceId, batteryId, pageSize, pageNum}) {
|
||||
return request({
|
||||
url: `/ems/siteMonitor/getClusterDataInfoList?clusterDeviceId=${clusterDeviceId}&siteId=${siteId}&stackDeviceId=${stackDeviceId}&batteryId=${batteryId}&pageSize=${pageSize}&pageNum=${pageNum}`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 单体电池图表
|
||||
//http://localhost:8089/ems/siteMonitor/getSingleBatteryData?clusterDeviceId=BMSC01&siteId=021_FXX_01&deviceId=001&startDate=2025-07-11&endDate=2025-07-18
|
||||
export function getSingleBatteryData({siteId, deviceId, clusterDeviceId, startDate, endDate}) {
|
||||
return request({
|
||||
url: `/ems/siteMonitor/getSingleBatteryData?siteId=${siteId}&deviceId=${deviceId}&startDate=${startDate}&endDate=${endDate}&clusterDeviceId=${clusterDeviceId}`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
//获取液冷列表数据
|
||||
export function getCoolingDataList(siteId) {
|
||||
return request({
|
||||
url: `/ems/siteMonitor/getCoolingDataList?siteId=${siteId}`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
//获取动环数据
|
||||
export function getDhDataList(siteId) {
|
||||
return request({
|
||||
url: `/ems/siteMonitor/getDhDataList?siteId=${siteId}`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
//获取消防数据
|
||||
export function getXfDataList(siteId) {
|
||||
return request({
|
||||
url: `/ems/siteMonitor/getXfDataList?siteId=${siteId}`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
//获取电表数据
|
||||
export function getAmmeterDataList(siteId) {
|
||||
return request({
|
||||
url: `/ems/siteMonitor/getAmmeterDataList?siteId=${siteId}`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 故障告警
|
||||
export function getAlarmDetailList({
|
||||
status,
|
||||
siteId,
|
||||
deviceId,
|
||||
alarmLevel,
|
||||
alarmStartTime,
|
||||
alarmEndTime,
|
||||
pageSize,
|
||||
pageNum
|
||||
}) {
|
||||
return request({
|
||||
url: `/ems/siteAlarm/getAlarmDetailList?siteId=${siteId}&status=${status}&deviceId=${deviceId}&alarmLevel=${alarmLevel}&alarmStartTime=${alarmStartTime}&alarmEndTime=${alarmEndTime}&pageSize=${pageSize}&pageNum=${pageNum}`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 告警生成工单
|
||||
export function createTicketNo(data) {
|
||||
return request({
|
||||
url: `/ems/siteAlarm/createTicketNo`,
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 概率统计
|
||||
//获取概率统计 电量指标接口
|
||||
export function getElectricData({siteId, startDate, endDate}) {
|
||||
return request({
|
||||
url: `/ems/statsReport/getElectricData?siteId=${siteId}&startDate=${startDate}&endDate=${endDate}`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
//获取pcs列表
|
||||
export function getPcsNameList(siteId) {
|
||||
return request({
|
||||
url: `/ems/siteMonitor/getPcsNameList?siteId=${siteId}`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
//pcs曲线
|
||||
export function getPCSData({siteId, startTime, endTime, dataType}) {
|
||||
return request({
|
||||
url: `/ems/statsReport/getPCSData?siteId=${siteId}&startDate=${startTime}&endDate=${endTime}&dataType=${dataType}`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
//电池堆曲线
|
||||
export function getStackData({siteId, startTime, endTime, dataType}) {
|
||||
return request({
|
||||
url: `/ems/statsReport/getStackData?siteId=${siteId}&startDate=${startTime}&endDate=${endTime}&dataType=${dataType}`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
//电池温度
|
||||
export function getClusterData({siteId, stackId, clusterId, dateTime, pageNum, pageSize}) {
|
||||
return request({
|
||||
url: `/ems/statsReport/getClusterData?siteId=${siteId}&stackId=${stackId}&clusterId=${clusterId}&dateTime=${dateTime}&pageNum=${pageNum}&pageSize=${pageSize}`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// 实时运行
|
||||
//储能
|
||||
export function storagePower(siteId, startTime, endTime) {
|
||||
return request({
|
||||
url: `/ems/siteMonitor/runningGraph/storagePower?siteId=${siteId}&startDate=${startTime}&endDate=${endTime}`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
//poc温度
|
||||
export function pcsMaxTemp(siteId, startTime, endTime) {
|
||||
return request({
|
||||
url: `/ems/siteMonitor/runningGraph/pcsMaxTemp?siteId=${siteId}&startDate=${startTime}&endDate=${endTime}`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 电池平均soc
|
||||
export function batteryAveSoc(siteId, startTime, endTime) {
|
||||
return request({
|
||||
url: `/ems/siteMonitor/runningGraph/batteryAveSoc?siteId=${siteId}&startDate=${startTime}&endDate=${endTime}`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 电池平均温度
|
||||
export function batteryAveTemp(siteId, startTime, endTime) {
|
||||
return request({
|
||||
url: `/ems/siteMonitor/runningGraph/batteryAveTemp?siteId=${siteId}&startDate=${startTime}&endDate=${endTime}`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 功率曲线
|
||||
export function getPowerData({siteId, startDate, endDate}) {
|
||||
return request({
|
||||
url: `/ems/statsReport/getPowerData?siteId=${siteId}&startDate=${startDate}&endDate=${endDate}`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
//电表列表
|
||||
export function getLoadNameList(siteId) {
|
||||
return request({
|
||||
url: `/ems/statsReport/getLoadNameList?siteId=${siteId}`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 电表报表
|
||||
export function getAmmeterData({siteId, startTime, endTime, pageSize, pageNum}) {
|
||||
return request({
|
||||
url: `/ems/statsReport/getAmmeterData?siteId=${siteId}&startTime=${startTime}&endTime=${endTime}&pageSize=${pageSize}&pageNum=${pageNum}`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 电价报表
|
||||
export function getAmmeterRevenueData(data) {
|
||||
return request({
|
||||
url: `/ems/statsReport/getAmmeterRevenueData`,
|
||||
method: 'get',
|
||||
params: data
|
||||
})
|
||||
}
|
||||
|
||||
//策略列表
|
||||
export function strategyRunningList(siteId) {
|
||||
return request({
|
||||
url: `/system/strategyRunning/list?siteId=${siteId}`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
//停止策略
|
||||
export function stopStrategyRunning(id) {
|
||||
return request({
|
||||
url: `/system/strategyRunning/stop?id=${id}`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 获取所有主策略
|
||||
export function getMainStrategyList() {
|
||||
return request({
|
||||
url: `/system/strategyRunning/getMainStrategyList`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
//获取所有辅助策略
|
||||
export function getAuxStrategyList() {
|
||||
return request({
|
||||
url: `/system/strategyRunning/getAuxStrategyList`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
//配置策略
|
||||
export function configStrategy(data) {
|
||||
return request({
|
||||
url: `/system/strategyRunning/configStrategy`,
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
//http://localhost:8089/strategy/temp/getTempNameList?strategyId=1&siteId=021_FXX_01
|
||||
//获取策略下的所有模板列表
|
||||
export function getTempNameList({siteId, strategyId}) {
|
||||
return request({
|
||||
url: `/strategy/temp/getTempNameList?siteId=${siteId}&strategyId=${strategyId}`,
|
||||
method: 'get',
|
||||
})
|
||||
}
|
||||
|
||||
//获取模板详情
|
||||
///strategy/temp/list?templateId=1
|
||||
export function getStrategyTempDetail(templateId) {
|
||||
return request({
|
||||
url: `/strategy/temp/list?templateId=${templateId}`,
|
||||
method: 'get',
|
||||
})
|
||||
}
|
||||
|
||||
//新增模板
|
||||
export function addStrategyTemp(data) {
|
||||
return request({
|
||||
url: `/strategy/temp`,
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export function editStrategyTemp(data) {
|
||||
return request({
|
||||
url: `/strategy/temp`,
|
||||
method: 'put',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
//http://localhost:8089/strategy/temp/{id}
|
||||
export function deleteStrategyTemp(id) {
|
||||
return request({
|
||||
url: `/strategy/temp/` + id,
|
||||
method: 'delete',
|
||||
})
|
||||
}
|
||||
|
||||
//http://localhost:8089/strategy/timeConfig/list?strategyId=1&siteId=021_FXX_01
|
||||
export function timeConfigList({siteId, strategyId}) {
|
||||
return request({
|
||||
url: `/strategy/timeConfig/list?siteId=${siteId}&strategyId=${strategyId}`,
|
||||
method: 'get',
|
||||
})
|
||||
}
|
||||
|
||||
//保存时间配置
|
||||
// http://localhost:8089/strategy/timeConfig
|
||||
export function setTimeConfigList(data) {
|
||||
return request({
|
||||
url: `/strategy/timeConfig`,
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 策略曲线图
|
||||
//http://localhost:8089/strategy/curve/curveList?strategyId=1&siteId=021_FXX_01
|
||||
export function curveList({siteId, strategyId}) {
|
||||
return request({
|
||||
url: `/strategy/curve/curveList?siteId=${siteId}&strategyId=${strategyId}`,
|
||||
method: 'get',
|
||||
})
|
||||
}
|
||||
|
||||
//单站监控 首页 当日功率曲线
|
||||
export function getPointData({siteId, startDate, endDate}) {
|
||||
return request({
|
||||
url: `/ems/siteMonitor/getPointData?siteId=${siteId}&startDate=${startDate}&endDate=${endDate}`,
|
||||
method: 'get',
|
||||
})
|
||||
}
|
||||
|
||||
@ -6,3 +6,10 @@ export function getSiteTotalInfo() {
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
// 图表
|
||||
export function dataList() {
|
||||
return request({
|
||||
url: '/ems/homePage/dataList',
|
||||
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',
|
||||
})
|
||||
}
|
||||
|
||||
32
src/api/ems/search.js
Normal file
@ -0,0 +1,32 @@
|
||||
import request from '@/utils/request'
|
||||
// 获取设备列表
|
||||
export function getAllDeviceCategory() {
|
||||
return request({
|
||||
url: '/ems/generalQuery/getAllDeviceCategory',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
// 点位列表
|
||||
export function pointFuzzyQuery(data) {
|
||||
return request({
|
||||
url: '/ems/generalQuery/pointFuzzyQuery',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
// 图表
|
||||
export function getPointValueList(data) {
|
||||
return request({
|
||||
url: '/ems/generalQuery/getPointValueList',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 图表
|
||||
export function getAllBatteryIdsBySites(data) {
|
||||
return request({
|
||||
url: `/ems/generalQuery/getAllBatteryIdsBySites/${data}`,
|
||||
method: 'get',
|
||||
})
|
||||
}
|
||||
203
src/api/ems/site.js
Normal file
@ -0,0 +1,203 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 站点列表
|
||||
export function getSiteInfoList({siteName, startTime, endTime, pageSize, pageNum}) {
|
||||
return request({
|
||||
url: `/ems/siteConfig/getSiteInfoList?siteName=${siteName}&startTime=${startTime}&endTime=${endTime}&pageSize=${pageSize}&pageNum=${pageNum}`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 设备列表
|
||||
export function getDeviceInfoList(data) {
|
||||
return request({
|
||||
url: `/ems/siteConfig/getDeviceInfoList`,
|
||||
method: 'get',
|
||||
params: data
|
||||
})
|
||||
}
|
||||
|
||||
// 设备详情
|
||||
export function getDeviceDetailInfo(id) {
|
||||
return request({
|
||||
url: `/ems/siteConfig/getDeviceDetailInfo?id=${id}`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 获取所有设备类别
|
||||
export function getDeviceCategory() {
|
||||
return request({
|
||||
url: `/ems/siteConfig/getDeviceCategory`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 新增设备
|
||||
export function addDevice(data) {
|
||||
return request({
|
||||
url: `/ems/siteConfig/addDevice`,
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 编辑设备
|
||||
export function updateDevice(data) {
|
||||
return request({
|
||||
url: `/ems/siteConfig/updateDevice`,
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除设备
|
||||
export function deleteService(id) {
|
||||
return request({
|
||||
url: `/ems/siteConfig/deleteService/` + id,
|
||||
method: 'delete',
|
||||
})
|
||||
}
|
||||
|
||||
//pcs开、关机
|
||||
export function updateDeviceStatus(data) {
|
||||
return request({
|
||||
url: `/ems/siteConfig/updateDeviceStatus`,
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 获取上级设备id列表
|
||||
export function getParentDeviceId({siteId, deviceCategory}) {
|
||||
return request({
|
||||
url: `/ems/siteConfig/getParentDeviceId?siteId=${siteId}&deviceCategory=${deviceCategory}`,
|
||||
method: 'get',
|
||||
})
|
||||
}
|
||||
|
||||
//获取所有设备
|
||||
export function getDeviceList(siteId) {
|
||||
return request({
|
||||
url: `/ems/siteConfig/getDeviceList?siteId=${siteId}`,
|
||||
method: 'get',
|
||||
})
|
||||
}
|
||||
|
||||
//获取设备点位table
|
||||
export function getDevicePointList(data) {
|
||||
return request({
|
||||
url: `/ems/siteConfig/getDevicePointList`,
|
||||
method: 'get',
|
||||
params: data
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
//获取设备类型下面的所有设备列表
|
||||
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',
|
||||
})
|
||||
}
|
||||
|
||||
// 点位导出
|
||||
export function exportPointList(data) {
|
||||
return request({
|
||||
url: `/ems/pointMatch/export`,
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 点位导入
|
||||
export function importPointList(data) {
|
||||
return request({
|
||||
url: `/ems/pointMatch/importData`,
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
//mqtt
|
||||
export function getMqttList({pageSize, pageNum, mqttTopic, topicName, siteId}) {
|
||||
return request({
|
||||
url: `/ems/mqttConfig/list?pageSize=${pageSize}&pageNum=${pageNum}&mqttTopic=${mqttTopic}&topicName=${topicName}&siteId=${siteId}`,
|
||||
method: 'get',
|
||||
})
|
||||
}
|
||||
|
||||
export function getMqttDetail(id) {
|
||||
return request({
|
||||
url: `/ems/mqttConfig/${id}`,
|
||||
method: 'get',
|
||||
})
|
||||
}
|
||||
|
||||
export function addMqtt(data) {
|
||||
return request({
|
||||
url: `/ems/mqttConfig`,
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export function editMqtt(data) {
|
||||
return request({
|
||||
url: `/ems/mqttConfig`,
|
||||
method: 'put',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export function deleteMqtt(id) {
|
||||
return request({
|
||||
url: `/ems/mqttConfig/${id}`,
|
||||
method: 'delete',
|
||||
})
|
||||
}
|
||||
52
src/api/ems/ticket.js
Normal file
@ -0,0 +1,52 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 查询工单主列表
|
||||
export function listTicket({pageNum, pageSize}) {
|
||||
return request({
|
||||
url: `/ticket/list?pageNum=${pageNum}&pageSize=${pageSize}`,
|
||||
method: 'get',
|
||||
})
|
||||
}
|
||||
|
||||
// 查询工单主详细
|
||||
export function getTicket(id) {
|
||||
return request({
|
||||
url: '/ticket/' + id,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 新增工单主
|
||||
export function addTicket(data) {
|
||||
return request({
|
||||
url: '/ticket',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 修改工单主
|
||||
export function updateTicket(data) {
|
||||
return request({
|
||||
url: '/ticket',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除工单主
|
||||
export function delTicket(data) {
|
||||
return request({
|
||||
url: `/ticket/drop`,
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
//查询所有的用户列表
|
||||
export function getAllUser() {
|
||||
return request({
|
||||
url: `/system/user/getAllUser`,
|
||||
method: 'get',
|
||||
})
|
||||
}
|
||||
BIN
src/assets/images/ems/bigData.png
Normal file
|
After Width: | Height: | Size: 11 MiB |
BIN
src/assets/images/ems/bms.png
Normal file
|
After Width: | Height: | Size: 314 KiB |
BIN
src/assets/images/ems/cloud.jpeg
Normal file
|
After Width: | Height: | Size: 49 KiB |
BIN
src/assets/images/ems/computer.png
Normal file
|
After Width: | Height: | Size: 177 KiB |
BIN
src/assets/images/ems/db.png
Normal file
|
After Width: | Height: | Size: 377 KiB |
BIN
src/assets/images/ems/login-background.png
Normal file
|
After Width: | Height: | Size: 706 KiB |
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 |
BIN
src/assets/images/ems/logo-small.png
Normal file
|
After Width: | Height: | Size: 65 KiB |
BIN
src/assets/images/ems/logo.png
Normal file
|
After Width: | Height: | Size: 83 KiB |
BIN
src/assets/images/ems/lq.png
Normal file
|
After Width: | Height: | Size: 182 KiB |
BIN
src/assets/images/ems/pcs.png
Normal file
|
After Width: | Height: | Size: 88 KiB |
|
Before Width: | Height: | Size: 509 KiB |
@ -4,101 +4,249 @@
|
||||
|
||||
//右侧内容区域
|
||||
//父元素
|
||||
.ems-dashboard-editor-container{
|
||||
.ems-dashboard-editor-container {
|
||||
background-color: #F1F5FC;
|
||||
padding: 24px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
//除去顶部信息(如搜索栏、站点基本信息等)外的 白色背景内容区域
|
||||
.ems-content-container{
|
||||
.ems-content-container {
|
||||
background-color: #ffffff;
|
||||
margin-top: 24px;
|
||||
}
|
||||
|
||||
//需要设置内padding的白色背景区域
|
||||
.ems-content-container-padding{
|
||||
.ems-content-container-padding {
|
||||
padding: 24px;
|
||||
}
|
||||
|
||||
//card通用样式 标题、body
|
||||
.common-card-container{
|
||||
.el-card__header{
|
||||
padding:14px;
|
||||
border-bottom: none;
|
||||
.common-card-container {
|
||||
.el-card__header {
|
||||
padding: 14px;
|
||||
border-bottom: none;
|
||||
font-size: 12px;
|
||||
background: #F1F5FB;
|
||||
position: relative;
|
||||
|
||||
.card-title {
|
||||
font-weight: 500;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.el-button--text {
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
.common-card-container-body-no-padding {
|
||||
.el-card__body {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.common-card-container-no-title-bg {
|
||||
.el-card__header {
|
||||
background-color: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
//单站监控 设备监控card公共样式
|
||||
.sbjk-card-container {
|
||||
.el-card__header {
|
||||
background-color: transparent;
|
||||
padding: 5px 14px;
|
||||
color: #ffffff;
|
||||
position: relative;
|
||||
border-radius: 5px 5px 0 0;
|
||||
|
||||
.large-title {
|
||||
font-size: 18px;
|
||||
font-weight: 500;
|
||||
line-height: 40px;
|
||||
padding: 0 50px 0 11px;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.info {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
color: #ffffff;
|
||||
font-size: 12px;
|
||||
background: #F1F5FB ;
|
||||
.card-title{
|
||||
font-weight: 500;
|
||||
color:#333333;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.el-button--text {
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
.alarm {
|
||||
position: absolute;
|
||||
right: 25px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
|
||||
.alarm-icon {
|
||||
font-size: 22px;
|
||||
color: #fff;
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
}
|
||||
.large-title{
|
||||
font-size: 20px;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
|
||||
//红色背景颜色标题
|
||||
&.warning-card-container {
|
||||
.el-card__header {
|
||||
background-color: #b64040; //#fc6b69;
|
||||
}
|
||||
|
||||
.work-status {
|
||||
color: #b64040 !important;;
|
||||
}
|
||||
}
|
||||
|
||||
//绿色背景颜色标题
|
||||
&.running-card-container {
|
||||
.el-card__header {
|
||||
background-color: #40b6a5; //#05aea3;
|
||||
}
|
||||
|
||||
.work-status {
|
||||
color: #40b6a5 !important;
|
||||
}
|
||||
}
|
||||
|
||||
//灰色背景颜色标题
|
||||
&.timing-card-container {
|
||||
.el-card__header {
|
||||
background-color: #666666;
|
||||
}
|
||||
|
||||
.work-status {
|
||||
color: #666666 !important;;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* card标题里的时间选择器 */
|
||||
.time-range-card {
|
||||
&.common-card-container .el-card__header {
|
||||
padding-top: 0;
|
||||
padding-bottom: 0;
|
||||
|
||||
.time-range-header {
|
||||
height: 40px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
.card-title {
|
||||
line-height: 40px;
|
||||
}
|
||||
.el-button--text{
|
||||
color: #666666;
|
||||
}
|
||||
}
|
||||
}
|
||||
.common-card-container-body-no-padding{
|
||||
.el-card__body{
|
||||
padding:0;
|
||||
}
|
||||
}
|
||||
.common-card-container-no-title-bg {
|
||||
.el-card__header{
|
||||
background-color: transparent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//描述样式 PCS、BMS总览、BMS电池簇页面公共样式
|
||||
.descriptions-main{
|
||||
padding:24px;
|
||||
.descriptions-main {
|
||||
padding: 24px;
|
||||
position: relative;
|
||||
&.descriptions-main-bg-color{
|
||||
background-color:#f1f5fc ;
|
||||
.el-descriptions__body{
|
||||
background-color:#f1f5fc ;
|
||||
|
||||
&.descriptions-main-bg-color {
|
||||
background-color: #f1f5fc;
|
||||
|
||||
.el-descriptions__body {
|
||||
background-color: #f1f5fc;
|
||||
}
|
||||
}
|
||||
.el-descriptions-item__cell[colspan='1']{
|
||||
width:25%
|
||||
|
||||
.el-descriptions-item__cell[colspan='1'] {
|
||||
width: 25%
|
||||
}
|
||||
.el-descriptions__body .el-descriptions__table{
|
||||
.descriptions-direction{
|
||||
|
||||
.el-descriptions__body .el-descriptions__table {
|
||||
.descriptions-direction {
|
||||
line-height: 19px;
|
||||
color: #666666;
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
}
|
||||
.descriptions-label{
|
||||
|
||||
.descriptions-label {
|
||||
line-height: 14px;
|
||||
color: #666666;
|
||||
font-size: 12px;
|
||||
}
|
||||
.danger{
|
||||
color:#FC6B69;
|
||||
|
||||
.danger {
|
||||
color: #FC6B69;
|
||||
}
|
||||
.save{
|
||||
color:#09ADA3;
|
||||
|
||||
.save {
|
||||
color: #09ADA3;
|
||||
}
|
||||
.keep{
|
||||
color:#3C81FF;
|
||||
|
||||
.keep {
|
||||
color: #3C81FF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//电表、液冷公共样式
|
||||
.device-info-row {
|
||||
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
||||
border-left: 1px solid #eee;
|
||||
border-top: 1px solid #eee;
|
||||
|
||||
.device-info-col {
|
||||
padding: 10px 0;
|
||||
text-align: center;
|
||||
font-size: 12px;
|
||||
color: #666666;
|
||||
line-height: 14px;
|
||||
border-bottom: 1px solid #eee;
|
||||
border-right: 1px solid #eee;
|
||||
|
||||
.left {
|
||||
}
|
||||
|
||||
.right {
|
||||
display: block;
|
||||
font-weight: 500;
|
||||
font-size: 16px;
|
||||
line-height: 18px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//公共表格样式
|
||||
.common-table.el-table{
|
||||
color:#333333;
|
||||
.el-table {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.common-table.el-table {
|
||||
color: #333333;
|
||||
|
||||
.el-table__header-wrapper th, .el-table__fixed-header-wrapper th {
|
||||
background: #f1f5fc;
|
||||
border-bottom: none;
|
||||
|
||||
.table-head {
|
||||
color: #515a6e;
|
||||
}
|
||||
}
|
||||
.warning-status{
|
||||
color:#FC6B69;
|
||||
|
||||
.warning-status {
|
||||
color: #FC6B69;
|
||||
|
||||
&.circle::before {
|
||||
content: "";
|
||||
display: inline-block;
|
||||
@ -110,3 +258,77 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//二、三级菜单栏样式
|
||||
.ems-second-menu {
|
||||
width: fit-content;
|
||||
|
||||
.el-menu-item {
|
||||
line-height: 40px;
|
||||
height: 40px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
&.el-menu--horizontal > .el-menu-item.is-active, &.el-menu--horizontal > .el-menu-item {
|
||||
border-bottom: none !important;
|
||||
}
|
||||
|
||||
.el-menu-item.is-active {
|
||||
background: #0366c1 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.ems-third-menu-container {
|
||||
position: relative;
|
||||
padding-left: 140px;
|
||||
background-color: #ffffff;
|
||||
|
||||
.ems-third-menu {
|
||||
border-right: none;
|
||||
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
||||
height: fit-content;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
|
||||
.el-menu-item {
|
||||
line-height: 45px;
|
||||
height: 45px;
|
||||
padding: 0 !important;
|
||||
width: 125px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.el-menu-item:hover {
|
||||
background: #67b1ff !important;
|
||||
color: #ffffff !important;
|
||||
}
|
||||
|
||||
.el-menu-item.is-active {
|
||||
background: #409eff !important;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//按钮栏 选中样式
|
||||
.ems-btns-group {
|
||||
.activeBtn {
|
||||
background-color: #0366c1;
|
||||
border-color: #0366c1;
|
||||
color: #ffffff;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
//搜索栏样式
|
||||
.select-container.el-form--inline .el-form-item {
|
||||
margin-right: 15px;
|
||||
}
|
||||
|
||||
//红色背景颜色按钮
|
||||
.alarm-btn, .alarm-btn:hover, .alarm-btn:focus {
|
||||
background-color: #FC6B69;
|
||||
border-color: #FC6B69;
|
||||
}
|
||||
|
||||
49
src/components/BigDataPopup/index.vue
Normal file
@ -0,0 +1,49 @@
|
||||
<template>
|
||||
<el-dialog :fullscreen="true" :append-to-body="true" :visible.sync="show" :show-close="false" top="0"
|
||||
custom-class="big-data-dialog">
|
||||
<img src="@/assets/images/ems/bigData.png" alt="">
|
||||
<div class="close-btn" @click="show=false">
|
||||
<i class="el-icon-close"></i>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
<style lang="scss" scoped>
|
||||
.close-btn {
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
top: 10px;
|
||||
font-size: 23px;
|
||||
line-height: 20px;
|
||||
color: rgba(176, 228, 255, 0.7);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
img {
|
||||
height: 100vh;
|
||||
width: 100vw;
|
||||
display: block;
|
||||
margin: 0;
|
||||
}
|
||||
</style>
|
||||
<style lang="scss">
|
||||
.big-data-dialog {
|
||||
.el-dialog__header {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.el-dialog__body {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
show: false
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
150
src/components/Ems/DateRangeSelect/index.vue
Normal file
@ -0,0 +1,150 @@
|
||||
<template>
|
||||
<div class="time-range">
|
||||
<el-date-picker
|
||||
v-model="dateRange"
|
||||
:class="miniTimePicker ? 'mini-date-picker' : ''"
|
||||
type="daterange"
|
||||
range-separator="至"
|
||||
start-placeholder="开始时间"
|
||||
value-format="yyyy-MM-dd"
|
||||
:clearable="false"
|
||||
:picker-options="pickerOptions"
|
||||
end-placeholder="结束时间">
|
||||
</el-date-picker>
|
||||
<template v-if="!showIcon">
|
||||
<el-button size="mini" style="margin-left: 10px;" :loading="loading" @click="reset">重置</el-button>
|
||||
<el-button type="primary" size="mini" :loading="loading" @click="search">搜索</el-button>
|
||||
<el-button type="primary" size="mini" :loading="loading" @click="timeLine('before')">上一时段</el-button>
|
||||
<el-button type="primary" size="mini" :loading="loading" @click="timeLine('next')" :disabled="disabledNextBtn">
|
||||
下一时段
|
||||
</el-button>
|
||||
</template>
|
||||
<template v-else>
|
||||
<el-button class="btn-icon" icon="el-icon-refresh-right" circle size="mini" style="margin-left: 8px;"
|
||||
:loading="loading"
|
||||
@click="reset"></el-button>
|
||||
<el-button class="btn-icon" type="primary" size="mini" icon="el-icon-search" circle :loading="loading"
|
||||
@click="search"></el-button>
|
||||
<el-button class="btn-icon" type="primary" size="mini" icon="el-icon-d-arrow-left" circle :loading="loading"
|
||||
@click="timeLine('before')"></el-button>
|
||||
<el-button class="btn-icon" type="primary" size="mini" icon="el-icon-d-arrow-right" circle :loading="loading"
|
||||
@click="timeLine('next')"
|
||||
:disabled="disabledNextBtn"></el-button>
|
||||
</template>
|
||||
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {formatDate} from '@/filters/ems'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
showIcon: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false
|
||||
},
|
||||
miniTimePicker: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
disabledNextBtn() {
|
||||
return new Date(this.dateRange[1]) >= new Date(this.defaultDateRange[1])
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
dateRange: [],
|
||||
defaultDateRange: [],
|
||||
pickerOptions: {
|
||||
disabledDate(time) {
|
||||
return time.getTime() > Date.now();
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
init(today = false) {
|
||||
const now = new Date(), formatNow = formatDate(now);
|
||||
const weekAgo = formatDate(today ? new Date(now.getTime()) : new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000))
|
||||
this.dateRange = [weekAgo, formatNow];
|
||||
this.defaultDateRange = [weekAgo, formatNow];
|
||||
this.$emit('updateDate', this.dateRange)
|
||||
},
|
||||
showBtnLoading(status) {
|
||||
this.loading = status
|
||||
},
|
||||
resetDate() {
|
||||
this.dateRange = this.defaultDateRange
|
||||
},
|
||||
//重置 设置时间范围为初始化时间段
|
||||
reset() {
|
||||
this.resetDate()
|
||||
this.$emit('reset')
|
||||
this.$emit('updateDate', this.dateRange)
|
||||
},
|
||||
// 搜索
|
||||
search() {
|
||||
this.$emit('updateDate', this.dateRange)
|
||||
},
|
||||
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 毫秒数
|
||||
const baseDis = 24 * 60 * 60 * 1000
|
||||
const calcDis = nowDis === 0 ? baseDis : nowDis
|
||||
let start = type === 'before' ? nowStartTimes - calcDis : nowStartTimes + calcDis
|
||||
if (start > maxTime) start = maxTime
|
||||
let end = type === 'before' ? nowEndTimes - calcDis : nowEndTimes + calcDis
|
||||
if (end > maxTime) end = maxTime
|
||||
this.dateRange = [formatDate(start), formatDate(end)]
|
||||
this.$emit('updateDate', this.dateRange)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.time-range {
|
||||
display: flex;
|
||||
|
||||
::v-deep {
|
||||
|
||||
.el-range-editor--medium .el-range__icon, .el-range-editor--medium .el-range__close-icon {
|
||||
line-height: 22px;
|
||||
}
|
||||
|
||||
.el-range-editor--medium.el-input__inner {
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
.el-range-editor--medium .el-range-separator {
|
||||
line-height: 22px;
|
||||
}
|
||||
|
||||
.el-button--mini {
|
||||
padding: 3px 10px;
|
||||
}
|
||||
|
||||
// 展示icon的小组件
|
||||
.btn-icon.el-button--mini {
|
||||
padding: 3px 8px;
|
||||
margin-left: 6px;
|
||||
}
|
||||
|
||||
//小宽度时间选择框
|
||||
.mini-date-picker {
|
||||
width: 250px !important;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
@ -2,7 +2,7 @@
|
||||
<template>
|
||||
<el-card shadow="always" class="single-square-box" :style="{background: 'linear-gradient(180deg, '+data.bgColor+' 0%,rgba(255,255,255,0) 100%)'}">
|
||||
<div class="single-square-box-title">{{ data.title }}</div>
|
||||
<div class="single-square-box-value">{{ data.value }}</div>
|
||||
<div class="single-square-box-value">{{ data.value | formatNumber }}</div>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
@ -24,7 +24,7 @@
|
||||
font-weight: 500;
|
||||
}
|
||||
::v-deep .el-card__body{
|
||||
padding: 12px 16px;
|
||||
padding: 12px 10px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
<el-row type="flex" >
|
||||
<el-card shadow="hover" class="card common-card-container-body-no-padding" v-for="(item,index) in data" :key="index+'zdInfo'" :style="{borderBottomColor:item.color}">
|
||||
<div class="info">{{ item.title }}</div>
|
||||
<div class="num">{{item.num}}</div>
|
||||
<div class="num">{{item.num | formatNumber}}</div>
|
||||
</el-card>
|
||||
</el-row>
|
||||
</template>
|
||||
@ -23,22 +23,22 @@ export default {
|
||||
title:'装机功率(MW)',
|
||||
num:'',
|
||||
color:'#3C81FF',
|
||||
attr:'installedPower'
|
||||
attr:'installPower'
|
||||
|
||||
},{
|
||||
title:'装机容量(MW)',
|
||||
num:'',
|
||||
color:'#5AC7C0',
|
||||
attr:'installedCap'
|
||||
attr:'installCapacity'
|
||||
|
||||
},{
|
||||
title:'总充电量(MWh)',
|
||||
title:'总充电量(KWh)',
|
||||
num:'',
|
||||
color:'#A696FF',
|
||||
attr:'totalChargedCap'
|
||||
|
||||
},{
|
||||
title:'总放电量(MWh)',
|
||||
title:'总放电量(KWh)',
|
||||
num:'',
|
||||
color:'#A696FF',
|
||||
attr:'totalDischargedCap'
|
||||
@ -49,14 +49,14 @@ export default {
|
||||
methods: {
|
||||
setData(res = {}){
|
||||
this.data.forEach((item)=>{
|
||||
item.num =(res[item.attr] || res[item.attr] === 0) ? res[item.attr] : '—'
|
||||
item.num =res[item.attr]
|
||||
})
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
getSiteTotalInfo().then(response => {
|
||||
console.log('单个站点基本信息返回数据',response)
|
||||
this.setData(response.data || {})
|
||||
this.setData(response?.data || {})
|
||||
}).catch(()=>{
|
||||
this.setData({})
|
||||
})
|
||||
@ -65,11 +65,13 @@ export default {
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.card{
|
||||
width: 150px;
|
||||
min-width: 150px;
|
||||
height: 96px;
|
||||
margin-right: 27px;
|
||||
border-bottom: 4px solid transparent;
|
||||
text-align: center;
|
||||
box-sizing: border-box;
|
||||
padding:0 10px;
|
||||
.info{
|
||||
color: #666666;
|
||||
line-height: 14px;
|
||||
|
||||
@ -3,13 +3,13 @@
|
||||
<div class="zd-select-container">
|
||||
<el-form :inline="true">
|
||||
<el-form-item label="站点选择">
|
||||
<el-select v-model="id" placeholder="请选择换电站名称" :loading="loading" loading-text="正在加载数据" @change="change">
|
||||
<el-option :label="item.siteName" :value="item.id" v-for="(item,index) in siteList" :key="index+'zdxeSelect'"></el-option>
|
||||
<el-select v-model="id" placeholder="请选择换电站名称" :loading="loading" loading-text="正在加载数据" @change="onSubmit">
|
||||
<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>
|
||||
<el-button type="warning" @click="onSubmit">搜索</el-button>
|
||||
</el-form-item>
|
||||
<!-- <el-form-item>-->
|
||||
<!-- <el-button type="primary" :loading="searchLoading" @click="onSubmit">搜索</el-button>-->
|
||||
<!-- </el-form-item>-->
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
@ -28,7 +28,7 @@ import {mapGetters} from "vuex"
|
||||
required:false
|
||||
},
|
||||
defaultSiteId:{//默认展示的站点ID
|
||||
type:String|Number,
|
||||
type:String,
|
||||
default:'',
|
||||
required:false
|
||||
}
|
||||
@ -37,6 +37,7 @@ import {mapGetters} from "vuex"
|
||||
return {
|
||||
id:'',
|
||||
loading:false,
|
||||
searchLoading:false,
|
||||
siteList:[],
|
||||
}
|
||||
},
|
||||
@ -47,15 +48,12 @@ import {mapGetters} from "vuex"
|
||||
onSubmit(){
|
||||
this.$emit('submitSite',this.id)
|
||||
},
|
||||
change(id){
|
||||
this.$emit('changeSite',id)
|
||||
},
|
||||
setDefaultSite(){
|
||||
const defaultSite = parseInt(this.defaultSiteId)
|
||||
if(defaultSite && this.siteList.find(item=>item.id === defaultSite)){
|
||||
const defaultSite = this.defaultSiteId
|
||||
if(defaultSite && this.siteList.find(item=>item.siteId === defaultSite)){
|
||||
this.id = defaultSite
|
||||
}else if(!defaultSite && this.siteList.length>0){
|
||||
this.id = this.siteList[0].id
|
||||
this.id = this.siteList[0].siteId
|
||||
}
|
||||
this.$emit('submitSite',this.id)
|
||||
},
|
||||
@ -64,11 +62,12 @@ import {mapGetters} from "vuex"
|
||||
this.siteList = response.data || []
|
||||
console.log("获取站点列表返回数据",response,this.siteList)
|
||||
this.setDefaultSite()
|
||||
}).finally(() => {this.loading=false})
|
||||
}).finally(() => {this.loading=false;this.searchLoading=false})
|
||||
}
|
||||
},
|
||||
mounted(){
|
||||
this.loading=true
|
||||
this.searchLoading=true
|
||||
this.$nextTick(()=>{
|
||||
if(this.getListByStore){
|
||||
if(this.zdList.length === 0){
|
||||
@ -79,6 +78,7 @@ import {mapGetters} from "vuex"
|
||||
}else{
|
||||
this.siteList = this.zdList
|
||||
this.loading=false
|
||||
this.searchLoading=false
|
||||
console.log("从store中获取站点列表数据",this.zdList,this.siteList)
|
||||
this.setDefaultSite()
|
||||
}
|
||||
|
||||
@ -196,7 +196,9 @@ export default {
|
||||
// 上传成功回调
|
||||
handleUploadSuccess(res, file) {
|
||||
if (res.code === 200) {
|
||||
this.uploadList.push({ name: res.fileName, url: res.fileName })
|
||||
this.uploadList.push({ name: res.fileName, url: res.url })
|
||||
// todo
|
||||
// this.uploadList.push({ name: res.fileName, url: res.fileName })
|
||||
this.uploadedSuccessfully()
|
||||
} else {
|
||||
this.number--
|
||||
@ -256,7 +258,7 @@ export default {
|
||||
|
||||
::v-deep .el-upload-list--picture-card.is-disabled + .el-upload--picture-card {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
// 去掉动画效果
|
||||
::v-deep .el-list-enter-active,
|
||||
|
||||
24
src/filters/ems.js
Normal file
@ -0,0 +1,24 @@
|
||||
|
||||
export const formatNumber = (val) => {
|
||||
if(val || [0,'0'].includes(val)) {
|
||||
return val
|
||||
}else {return '-'}
|
||||
}
|
||||
|
||||
|
||||
export const formatDate = (val,toSeconds = false,onlyTime=false) => {
|
||||
if(!val) return ''
|
||||
const date = new Date(val)
|
||||
const month = date.getMonth() + 1,day = date.getDate()
|
||||
const hours = date.getHours(),minuets=date.getMinutes(),seconds = date.getSeconds();
|
||||
const front = `${date.getFullYear()}-${month<10?'0'+month : month}-${day<10 ? '0'+day : day}`
|
||||
const back = `${hours<10 ? '0'+hours : hours}:${minuets<10 ? '0'+minuets : minuets}:${seconds<10 ? '0'+seconds : seconds}`
|
||||
if(onlyTime) return back
|
||||
if(!toSeconds){
|
||||
return front
|
||||
} else{
|
||||
return front +' '+back
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -1,19 +1,24 @@
|
||||
<template>
|
||||
<div class="navbar">
|
||||
<hamburger id="hamburger-container" :is-active="sidebar.opened" class="hamburger-container" @toggleClick="toggleSideBar" />
|
||||
<hamburger id="hamburger-container" :is-active="sidebar.opened" class="hamburger-container"
|
||||
@toggleClick="toggleSideBar"/>
|
||||
|
||||
<breadcrumb v-if="!topNav" id="breadcrumb-container" class="breadcrumb-container" />
|
||||
<top-nav v-if="topNav" id="topmenu-container" class="topmenu-container" />
|
||||
<breadcrumb v-if="!topNav" id="breadcrumb-container" class="breadcrumb-container"/>
|
||||
<top-nav v-if="topNav" id="topmenu-container" class="topmenu-container"/>
|
||||
|
||||
<div class="right-menu">
|
||||
<template v-if="device!=='mobile'">
|
||||
<search id="header-search" class="right-menu-item" />
|
||||
<div class="big-data-container">
|
||||
<i class="el-icon-s-marketing big-data-icon" @click.stop="showBigDataImg"></i>
|
||||
</div>
|
||||
|
||||
<search id="header-search" class="right-menu-item"/>
|
||||
|
||||
|
||||
<screenfull id="screenfull" class="right-menu-item hover-effect" />
|
||||
<screenfull id="screenfull" class="right-menu-item hover-effect"/>
|
||||
|
||||
<el-tooltip content="布局大小" effect="dark" placement="bottom">
|
||||
<size-select id="size-select" class="right-menu-item hover-effect" />
|
||||
<size-select id="size-select" class="right-menu-item hover-effect"/>
|
||||
</el-tooltip>
|
||||
|
||||
</template>
|
||||
@ -32,16 +37,15 @@
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
|
||||
<div class="right-menu-item hover-effect setting" @click="setLayout" v-if="setting">
|
||||
<svg-icon icon-class="more-up" />
|
||||
<svg-icon icon-class="more-up"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters } from 'vuex'
|
||||
import {mapGetters} from 'vuex'
|
||||
import Breadcrumb from '@/components/Breadcrumb'
|
||||
import TopNav from '@/components/TopNav'
|
||||
import Hamburger from '@/components/Hamburger'
|
||||
@ -78,6 +82,12 @@ export default {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
showBigDataImg() {
|
||||
const routeUrl = this.$router.resolve({
|
||||
path: '/screen'
|
||||
})
|
||||
window.open(routeUrl.href, '_blank')
|
||||
},
|
||||
toggleSideBar() {
|
||||
this.$store.dispatch('app/toggleSideBar')
|
||||
},
|
||||
@ -93,7 +103,8 @@ export default {
|
||||
this.$store.dispatch('LogOut').then(() => {
|
||||
location.href = '/index'
|
||||
})
|
||||
}).catch(() => {})
|
||||
}).catch(() => {
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -105,7 +116,7 @@ export default {
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
background: #fff;
|
||||
box-shadow: 0 1px 4px rgba(0,21,41,.08);
|
||||
box-shadow: 0 1px 4px rgba(0, 21, 41, .08);
|
||||
|
||||
.hamburger-container {
|
||||
line-height: 46px;
|
||||
@ -113,7 +124,7 @@ export default {
|
||||
float: left;
|
||||
cursor: pointer;
|
||||
transition: background .3s;
|
||||
-webkit-tap-highlight-color:transparent;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
|
||||
&:hover {
|
||||
background: rgba(0, 0, 0, .025)
|
||||
@ -139,6 +150,17 @@ export default {
|
||||
height: 100%;
|
||||
line-height: 50px;
|
||||
|
||||
.big-data-container {
|
||||
display: inline-block;
|
||||
padding: 0 8px;
|
||||
height: 100%;
|
||||
font-size: 24px;
|
||||
color: #5a5e66;
|
||||
vertical-align: text-bottom;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
}
|
||||
@ -168,6 +190,7 @@ export default {
|
||||
.avatar-wrapper {
|
||||
margin-top: 10px;
|
||||
position: relative;
|
||||
padding-right: 10px;
|
||||
|
||||
.user-avatar {
|
||||
cursor: pointer;
|
||||
@ -176,7 +199,7 @@ export default {
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.user-nickname{
|
||||
.user-nickname {
|
||||
position: relative;
|
||||
bottom: 10px;
|
||||
font-size: 14px;
|
||||
|
||||
@ -1,45 +1,60 @@
|
||||
<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">
|
||||
<router-link v-if="collapse" key="collapse" class="sidebar-logo-link" to="/">
|
||||
<img v-if="logo" :src="logo" class="sidebar-logo" />
|
||||
<h1 v-else class="sidebar-title" :style="{ color: sideTheme === 'theme-dark' ? variables.logoTitleColor : variables.logoLightTitleColor }">{{ title }} </h1>
|
||||
<router-link
|
||||
v-if="collapse"
|
||||
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 v-else key="expand" class="sidebar-logo-link" to="/">
|
||||
<img v-if="logo" :src="logo" class="sidebar-logo" />
|
||||
<h1 class="sidebar-title" :style="{ color: sideTheme === 'theme-dark' ? variables.logoTitleColor : variables.logoLightTitleColor }">{{ title }} </h1>
|
||||
<img :src="logo" class="sidebar-logo" />
|
||||
<!-- <h1 class="sidebar-title" :style="{ color: sideTheme === 'theme-dark' ? variables.logoTitleColor : variables.logoLightTitleColor }">{{ title }} </h1>-->
|
||||
</router-link>
|
||||
</transition>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<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 logoSmall from "@/assets/images/ems/logo-small.png";
|
||||
export default {
|
||||
name: 'SidebarLogo',
|
||||
name: "SidebarLogo",
|
||||
props: {
|
||||
collapse: {
|
||||
type: Boolean,
|
||||
required: true
|
||||
}
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
variables() {
|
||||
return variables
|
||||
return variables;
|
||||
},
|
||||
sideTheme() {
|
||||
return this.$store.state.settings.sideTheme
|
||||
}
|
||||
return this.$store.state.settings.sideTheme;
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
title: process.env.VUE_APP_TITLE,
|
||||
logo: logoImg
|
||||
}
|
||||
}
|
||||
}
|
||||
logo: logo,
|
||||
logoSmall: logoSmall,
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@ -66,10 +81,10 @@ export default {
|
||||
width: 100%;
|
||||
|
||||
& .sidebar-logo {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
vertical-align: middle;
|
||||
margin-right: 12px;
|
||||
//margin-right: 12px;
|
||||
}
|
||||
|
||||
& .sidebar-title {
|
||||
|
||||
@ -55,3 +55,12 @@ export default {
|
||||
}
|
||||
}
|
||||
</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>
|
||||
@ -36,6 +36,8 @@ import DictTag from '@/components/DictTag'
|
||||
// 字典数据组件
|
||||
import DictData from '@/components/DictData'
|
||||
|
||||
import {formatNumber} from '@/filters/ems'
|
||||
|
||||
// 全局方法挂载
|
||||
Vue.prototype.getDicts = getDicts
|
||||
Vue.prototype.getConfigKey = getConfigKey
|
||||
@ -74,7 +76,7 @@ Vue.use(Element, {
|
||||
})
|
||||
|
||||
Vue.config.productionTip = false
|
||||
|
||||
Vue.filter('formatNumber', formatNumber)
|
||||
new Vue({
|
||||
el: '#app',
|
||||
router,
|
||||
|
||||
25
src/mixins/ems/getQuerySiteId.js
Normal file
@ -0,0 +1,25 @@
|
||||
// 用于单站监控二级菜单页面获取路由中的站点ID
|
||||
const getQuerySiteId= {
|
||||
data: function () {
|
||||
return {
|
||||
siteId:''
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
'$route.query':{
|
||||
handler (newQuery,oldQuery) {
|
||||
// 参数变化处理
|
||||
this.$nextTick(() => {
|
||||
const {siteId} =newQuery
|
||||
if(siteId){
|
||||
this.siteId = siteId
|
||||
siteId && this.init(newQuery.siteId)
|
||||
console.log('mixin=>getQuerySiteId=>页面参数siteId发生了变化,this.siteId=',this.siteId)
|
||||
}
|
||||
})
|
||||
},
|
||||
immediate: true,
|
||||
}
|
||||
},
|
||||
}
|
||||
export default getQuerySiteId
|
||||
24
src/mixins/ems/intervalUpdate.js
Normal file
@ -0,0 +1,24 @@
|
||||
// 定时刷新
|
||||
const intervalUpdate= {
|
||||
data: function () {
|
||||
return {
|
||||
intervalUpdateTimer:null
|
||||
}
|
||||
},
|
||||
beforeDestroy() {
|
||||
console.log('销毁之前 清空定时器')
|
||||
if( this.intervalUpdateTimer) {
|
||||
window.clearInterval(this.intervalUpdateTimer)
|
||||
this.intervalUpdateTimer = null
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
updateInterval: function (cn,time=60000) {
|
||||
window.clearInterval(this.intervalUpdateTimer)
|
||||
this.intervalUpdateTimer = null
|
||||
this.intervalUpdateTimer = window.setInterval(cn,time)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
export default intervalUpdate
|
||||
@ -1,124 +1,304 @@
|
||||
import Layout from "@/layout/index.vue";
|
||||
|
||||
//todo delete 删除动态路由页面的定义 接口会传递进来
|
||||
// const ems = [
|
||||
// {
|
||||
// path: '',
|
||||
// component: Layout,
|
||||
// redirect: 'noRedirect',
|
||||
// children: [
|
||||
// {
|
||||
// path: 'zddt',
|
||||
// component: () => import('@/views/ems/zddt/index'),
|
||||
// name: 'zddt',
|
||||
// meta: { title: '站点地图', icon: 'guide' }
|
||||
// }
|
||||
// ]
|
||||
// }
|
||||
// ]
|
||||
// export default ems
|
||||
|
||||
//单站监控
|
||||
// todo 本地设置了 hidden:true,不会显示在侧边栏,需要在系统管理、菜单管理中手动添加菜单后才会展示在侧边栏
|
||||
export const dzjk=[
|
||||
{
|
||||
path: '/dzjk',
|
||||
component: Layout,
|
||||
redirect: '/dzjk/home',
|
||||
meta: { title: '单站监控', icon: 'dashboard',},
|
||||
alwaysShow: false,
|
||||
name:'Dzjk',
|
||||
hidden:true,
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
component: () => import('@/views/ems/dzjk/index'),
|
||||
name: 'Dzjk',
|
||||
export const dzjk = [
|
||||
{
|
||||
path: '/dzjk',
|
||||
component: Layout,
|
||||
redirect: '/dzjk/home',
|
||||
meta: {title: '单站监控', icon: 'dashboard',},
|
||||
alwaysShow: false,
|
||||
name: 'Dzjk',
|
||||
hidden: true,
|
||||
children: [
|
||||
{
|
||||
path: '/dzjk/home',
|
||||
component: () => import('@/views/ems/dzjk/home/index.vue'),
|
||||
name: 'DjzkHome',
|
||||
meta: { title: '首页',breadcrumb: false,activeMenu: '/dzjk',activeSecondMenuName:'DjzkHome' }
|
||||
},
|
||||
{
|
||||
path: '/dzjk/sbjk',
|
||||
component: () => import('@/views/ems/dzjk/sbjk/index.vue'),
|
||||
name: 'DjzkSbjk',
|
||||
meta: { title: '设备监控',breadcrumb: false,activeMenu: '/dzjk'},
|
||||
redirect: '/dzjk/sbjk/ssyx',
|
||||
children: [
|
||||
{
|
||||
path: 'ssyx',
|
||||
component: () => import('@/views/ems/dzjk/sbjk/ssyx/index.vue'),
|
||||
name: 'DjzkSbjkSsyx',
|
||||
meta: { title: '实时运行',breadcrumb: false,activeMenu: '/dzjk',activeSecondMenuName:'DjzkSbjk'},
|
||||
},
|
||||
{
|
||||
path: 'pcs',
|
||||
component: () => import('@/views/ems/dzjk/sbjk/pcs/index.vue'),
|
||||
name: 'DjzkSbjkPcs',
|
||||
meta: { title: 'Pcs',breadcrumb: false,activeMenu: '/dzjk',activeSecondMenuName:'DjzkSbjk'},
|
||||
},
|
||||
{
|
||||
path: 'bmszl',
|
||||
component: () => import('@/views/ems/dzjk/sbjk/bmszl/index.vue'),
|
||||
name: 'DjzkSbjkBmszl',
|
||||
meta: { title: 'BMS总览',breadcrumb: false,activeMenu: '/dzjk',activeSecondMenuName:'DjzkSbjk'},
|
||||
},
|
||||
{
|
||||
path: 'bmsdcc',
|
||||
component: () => import('@/views/ems/dzjk/sbjk/bmsdcc/index.vue'),
|
||||
name: 'DjzkSbjkBmsdcc',
|
||||
meta: { title: 'BMS电池簇',breadcrumb: false,activeMenu: '/dzjk',activeSecondMenuName:'DjzkSbjk'},
|
||||
},
|
||||
{
|
||||
path: 'dtdc',
|
||||
component: () => import('@/views/ems/dzjk/sbjk/dtdc/index.vue'),
|
||||
name: 'DjzkSbjkDtdc',
|
||||
meta: { title: '单体电池',breadcrumb: false,activeMenu: '/dzjk',activeSecondMenuName:'DjzkSbjk'},
|
||||
},
|
||||
{
|
||||
path: 'db',
|
||||
component: () => import('@/views/ems/dzjk/sbjk/db/index.vue'),
|
||||
name: 'DjzkSbjkDb',
|
||||
meta: { title: '电表',breadcrumb: false,activeMenu: '/dzjk',activeSecondMenuName:'DjzkSbjk'},
|
||||
},
|
||||
{
|
||||
path: 'yl',
|
||||
component: () => import('@/views/ems/dzjk/sbjk/yl/index.vue'),
|
||||
name: 'DjzkSbjkYl',
|
||||
meta: { title: '液冷',breadcrumb: false,activeMenu: '/dzjk',activeSecondMenuName:'DjzkSbjk'},
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '/dzjk/gzgj',
|
||||
component: () => import('@/views/ems/dzjk/gzgj/index.vue'),
|
||||
name: 'DjzkGzgj',
|
||||
meta: { title: '故障告警',breadcrumb: false,activeMenu: '/dzjk',activeSecondMenuName:'DjzkGzgj' }
|
||||
},
|
||||
{
|
||||
path: '/dzjk/tjbb',
|
||||
component: () => import('@/views/ems/dzjk/tjbb/index.vue'),
|
||||
name: 'DjzkTjbb',
|
||||
meta: {title: '统计报表', breadcrumb: false, activeMenu: '/dzjk'},
|
||||
redirect: '/dzjk/tjbb/gltj',
|
||||
children: [
|
||||
{
|
||||
path: 'gltj',
|
||||
component: () => import('@/views/ems/dzjk/tjbb/gltj/index.vue'),
|
||||
name: 'DjzkTjbbGltj',
|
||||
meta: { title: '概率统计',breadcrumb: false,activeMenu: '/dzjk',activeSecondMenuName:'DjzkTjbb'},
|
||||
}
|
||||
]
|
||||
}
|
||||
{
|
||||
path: '',
|
||||
component: () => import('@/views/ems/dzjk/index'),
|
||||
name: 'Dzjk',
|
||||
redirect: '/dzjk/home',
|
||||
hidden: true,
|
||||
children: [
|
||||
{
|
||||
path: '/dzjk/home',
|
||||
component: () => import('@/views/ems/dzjk/home/index.vue'),
|
||||
name: 'DzjkHome',
|
||||
meta: {
|
||||
title: '站点首页',
|
||||
breadcrumb: false,
|
||||
activeMenu: '/dzjk',
|
||||
activeSecondMenuName: 'DzjkHome'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/dzjk/zxlt',
|
||||
component: () => import('@/views/ems/dzjk/zxlt/index.vue'),
|
||||
name: 'DzjkZxlt',
|
||||
meta: {
|
||||
title: '主线路图',
|
||||
breadcrumb: false,
|
||||
activeMenu: '/dzjk',
|
||||
activeSecondMenuName: 'DzjkZxlt'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/dzjk/sbjk',
|
||||
component: () => import('@/views/ems/dzjk/sbjk/index.vue'),
|
||||
name: 'DzjkSbjk',
|
||||
meta: {title: '设备监控', breadcrumb: false, activeMenu: '/dzjk'},
|
||||
redirect: '/dzjk/sbjk/ssyx',
|
||||
children: [
|
||||
{
|
||||
path: 'ssyx',
|
||||
component: () => import('@/views/ems/dzjk/sbjk/ssyx/index.vue'),
|
||||
name: 'DzjkSbjkSsyx',
|
||||
meta: {
|
||||
title: '实时运行',
|
||||
breadcrumb: false,
|
||||
activeMenu: '/dzjk',
|
||||
activeSecondMenuName: 'DzjkSbjk',
|
||||
deviceCategory: 'SSYX'
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'ems',
|
||||
component: () => import('@/views/ems/dzjk/sbjk/ems/index.vue'),
|
||||
name: 'DzjkSbjkEms',
|
||||
meta: {
|
||||
title: 'EMS',
|
||||
breadcrumb: false,
|
||||
activeMenu: '/dzjk',
|
||||
activeSecondMenuName: 'DzjkSbjk',
|
||||
deviceCategory: 'EMS'
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'pcs',
|
||||
component: () => import('@/views/ems/dzjk/sbjk/pcs/index.vue'),
|
||||
name: 'DzjkSbjkPcs',
|
||||
meta: {
|
||||
title: 'PCS',
|
||||
breadcrumb: false,
|
||||
activeMenu: '/dzjk',
|
||||
activeSecondMenuName: 'DzjkSbjk',
|
||||
deviceCategory: 'PCS'
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'bmszl',
|
||||
component: () => import('@/views/ems/dzjk/sbjk/bmszl/index.vue'),
|
||||
name: 'DzjkSbjkBmszl',
|
||||
meta: {
|
||||
title: 'BMS总览',
|
||||
breadcrumb: false,
|
||||
activeMenu: '/dzjk',
|
||||
activeSecondMenuName: 'DzjkSbjk',
|
||||
deviceCategory: 'STACK'
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'bmsdcc',
|
||||
component: () => import('@/views/ems/dzjk/sbjk/bmsdcc/index.vue'),
|
||||
name: 'DzjkSbjkBmsdcc',
|
||||
meta: {
|
||||
title: 'BMS电池簇',
|
||||
breadcrumb: false,
|
||||
activeMenu: '/dzjk',
|
||||
activeSecondMenuName: 'DzjkSbjk',
|
||||
deviceCategory: 'CLUSTER'
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'dtdc',
|
||||
component: () => import('@/views/ems/dzjk/sbjk/dtdc/index.vue'),
|
||||
name: 'DzjkSbjkDtdc',
|
||||
meta: {
|
||||
title: 'BMS单体电池',
|
||||
breadcrumb: false,
|
||||
activeMenu: '/dzjk',
|
||||
activeSecondMenuName: 'DzjkSbjk',
|
||||
deviceCategory: 'BATTERY'
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'db',
|
||||
component: () => import('@/views/ems/dzjk/sbjk/db/index.vue'),
|
||||
name: 'DzjkSbjkDb',
|
||||
meta: {
|
||||
title: '电表',
|
||||
breadcrumb: false,
|
||||
activeMenu: '/dzjk',
|
||||
activeSecondMenuName: 'DzjkSbjk',
|
||||
deviceCategory: 'AMMETER'
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'yl',
|
||||
component: () => import('@/views/ems/dzjk/sbjk/yl/index.vue'),
|
||||
name: 'DzjkSbjkYl',
|
||||
meta: {
|
||||
title: '冷却',
|
||||
breadcrumb: false,
|
||||
activeMenu: '/dzjk',
|
||||
activeSecondMenuName: 'DzjkSbjk',
|
||||
deviceCategory: 'COOLING'
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'dh',
|
||||
component: () => import('@/views/ems/dzjk/sbjk/dh/index.vue'),
|
||||
name: 'DzjkSbjkDh',
|
||||
meta: {
|
||||
title: '动环',
|
||||
breadcrumb: false,
|
||||
activeMenu: '/dzjk',
|
||||
activeSecondMenuName: 'DzjkSbjk',
|
||||
deviceCategory: 'DH'
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'xf',
|
||||
component: () => import('@/views/ems/dzjk/sbjk/xf/index.vue'),
|
||||
name: 'DzjkSbjkXf',
|
||||
meta: {
|
||||
title: '消防',
|
||||
breadcrumb: false,
|
||||
activeMenu: '/dzjk',
|
||||
activeSecondMenuName: 'DzjkSbjk',
|
||||
deviceCategory: 'XF'
|
||||
},
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '/dzjk/gzgj',
|
||||
component: () => import('@/views/ems/dzjk/gzgj/index.vue'),
|
||||
name: 'DzjkGzgj',
|
||||
meta: {
|
||||
title: '故障告警',
|
||||
breadcrumb: false,
|
||||
activeMenu: '/dzjk',
|
||||
activeSecondMenuName: 'DzjkGzgj'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/dzjk/tjbb',
|
||||
component: () => import('@/views/ems/dzjk/tjbb/index.vue'),
|
||||
name: 'DzjkTjbb',
|
||||
meta: {title: '统计报表', breadcrumb: false, activeMenu: '/dzjk'},
|
||||
redirect: '/dzjk/tjbb/gltj',
|
||||
children: [
|
||||
{
|
||||
path: 'gltj',
|
||||
component: () => import('@/views/ems/dzjk/tjbb/gltj/index.vue'),
|
||||
name: 'DzjkTjbbGltj',
|
||||
meta: {
|
||||
title: '运行统计',
|
||||
breadcrumb: false,
|
||||
activeMenu: '/dzjk',
|
||||
activeSecondMenuName: 'DzjkTjbb'
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'glqx',
|
||||
component: () => import('@/views/ems/dzjk/tjbb/glqx/index.vue'),
|
||||
name: 'DzjkTjbbGlqx',
|
||||
meta: {
|
||||
title: '功率曲线',
|
||||
breadcrumb: false,
|
||||
activeMenu: '/dzjk',
|
||||
activeSecondMenuName: 'DzjkTjbb'
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'pcsqx',
|
||||
component: () => import('@/views/ems/dzjk/tjbb/pcsqx/index.vue'),
|
||||
name: 'DzjkTjbbPcsqx',
|
||||
meta: {
|
||||
title: 'PCS曲线',
|
||||
breadcrumb: false,
|
||||
activeMenu: '/dzjk',
|
||||
activeSecondMenuName: 'DzjkTjbb'
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'dcdqx',
|
||||
component: () => import('@/views/ems/dzjk/tjbb/dcdqx/index.vue'),
|
||||
name: 'DzjkTjbbDcdqx',
|
||||
meta: {
|
||||
title: '电池堆曲线',
|
||||
breadcrumb: false,
|
||||
activeMenu: '/dzjk',
|
||||
activeSecondMenuName: 'DzjkTjbb'
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'dcwd',
|
||||
component: () => import('@/views/ems/dzjk/tjbb/dcwd/index.vue'),
|
||||
name: 'DzjkTjbbDcwd',
|
||||
meta: {
|
||||
title: '电池温度',
|
||||
breadcrumb: false,
|
||||
activeMenu: '/dzjk',
|
||||
activeSecondMenuName: 'DzjkTjbb'
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'dbbb',
|
||||
component: () => import('@/views/ems/dzjk/tjbb/dbbb/index.vue'),
|
||||
name: 'DzjkTjbbDbbb',
|
||||
meta: {
|
||||
title: '电表报表',
|
||||
breadcrumb: false,
|
||||
activeMenu: '/dzjk',
|
||||
activeSecondMenuName: 'DzjkTjbb'
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'sybb',
|
||||
component: () => import('@/views/ems/dzjk/tjbb/sybb/index.vue'),
|
||||
name: 'DzjkTjbbSybb',
|
||||
meta: {
|
||||
title: '收益报表',
|
||||
breadcrumb: false,
|
||||
activeMenu: '/dzjk',
|
||||
activeSecondMenuName: 'DzjkTjbb'
|
||||
},
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '/dzjk/clpz',
|
||||
component: () => import('@/views/ems/dzjk/clpz/index.vue'),
|
||||
name: 'DzjkClpz',
|
||||
meta: {title: '策略配置', breadcrumb: false, activeMenu: '/dzjk'},
|
||||
redirect: '/dzjk/clpz/clyx',
|
||||
children: [
|
||||
{
|
||||
path: 'clyx',
|
||||
component: () => import('@/views/ems/dzjk/clpz/clyx/index.vue'),
|
||||
name: 'DzjkClpzClyx',
|
||||
meta: {
|
||||
title: '策略运行',
|
||||
breadcrumb: false,
|
||||
activeMenu: '/dzjk',
|
||||
activeSecondMenuName: 'DzjkClpz'
|
||||
},
|
||||
},
|
||||
// {
|
||||
// path: 'xftg',
|
||||
// component: () => import('@/views/ems/dzjk/clpz/xftg/index.vue'),
|
||||
// hidden:true,
|
||||
// breadcrumb: false,
|
||||
// name: 'DzjkClpzXftg',
|
||||
// meta: { title: '削峰填谷',breadcrumb: false,activeMenu: '/dzjk',activeSecondMenuName:'DzjkClpz'},
|
||||
// }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
|
||||
@ -1,7 +1,5 @@
|
||||
import Vue from 'vue'
|
||||
import Router from 'vue-router'
|
||||
// todo delete
|
||||
import ems from './ems'//EMS管理系统routers引用
|
||||
import {dzjk} from '@/router/ems'
|
||||
|
||||
Vue.use(Router)
|
||||
@ -54,6 +52,11 @@ export const constantRoutes = [
|
||||
component: () => import('@/views/register'),
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
path: '/screen',
|
||||
component: () => import('@/views/screen/index'),
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
path: '/404',
|
||||
component: () => import('@/views/error/404'),
|
||||
@ -92,7 +95,6 @@ export const constantRoutes = [
|
||||
]
|
||||
},
|
||||
// EMS管理系统routers
|
||||
// ...ems
|
||||
...dzjk
|
||||
]
|
||||
|
||||
|
||||
@ -7,12 +7,12 @@ module.exports = {
|
||||
/**
|
||||
* 侧边栏主题 深色主题theme-dark,浅色主题theme-light
|
||||
*/
|
||||
sideTheme: 'theme-dark',
|
||||
sideTheme: 'theme-light',
|
||||
|
||||
/**
|
||||
* 系统布局配置
|
||||
*/
|
||||
showSettings: true,
|
||||
showSettings: false,
|
||||
|
||||
/**
|
||||
* 是否显示顶部导航
|
||||
@ -52,5 +52,5 @@ module.exports = {
|
||||
/**
|
||||
* 底部版权文本内容
|
||||
*/
|
||||
footerContent: 'Copyright © 2018-2025 xzzn. All Rights Reserved.'
|
||||
footerContent: 'Copyright © 2025 上动新能源 版权所有'
|
||||
}
|
||||
|
||||
@ -1,12 +1,72 @@
|
||||
import {getAlarmDetailList, getSiteAllDeviceCategory} from '@/api/ems/dzjk'
|
||||
|
||||
const ems = {
|
||||
state: {
|
||||
zdList:[]
|
||||
},
|
||||
mutations: {
|
||||
SET_ZD_LIST(state, list) {
|
||||
state.zdList = list || []
|
||||
state: {
|
||||
dzjkAlarmLighting: false,//单站监控 告警统计红点标志
|
||||
zdList: [],
|
||||
zdDeviceCategoryOptions: {},//站点各个站点包含的设备种类 {021_DDS_01:["BATTERY","CLUSTER","STACK", "DH", "AMMETER", "PCS", "XF"],021_DDS_02:[]...}
|
||||
CLUSTERWorkStatusOptions: {'0': '静置', '1': '充电', '2': '放电', '3': '待机', '5': '运行', '9': "故障"},//电池簇工作状态
|
||||
PCSWorkStatusOptions: {'0': '运行', '1': '停机', '2': '故障', '3': '待机', '4': '充电', '5': '放电'},//PCS工作状态
|
||||
STACKWorkStatusOptions: {
|
||||
"0": "静置",
|
||||
"1": "充电",
|
||||
"2": "放电",
|
||||
"3": "浮充",
|
||||
'4': '待机',
|
||||
'5': '运行',
|
||||
'9': "故障"
|
||||
},//STACKBMS总览工作状态
|
||||
deviceStatusOptions: {'0': '离线', '1': '在线'},//设备状态
|
||||
gridStatusOptions: {'0': '并网', '1': '未并网'},//并网状态
|
||||
controlModeOptions: {'0': '远程', '1': '本地'},//控制模式
|
||||
warnOptions: {0: '正常', 1: '中断', 2: '不在线', 3: '异常'},//告警状态
|
||||
communicationStatusOptions: {'0': '正常', '1': '通讯中断', '2': '异常'},//通讯状态
|
||||
workModeOptions: {'0': '正常', '1': '停止'},//工作模式
|
||||
alarmLevelOptions: {'A': '提示', 'B': '一般', 'C': '严重', 'D': '紧急'},//告警等级
|
||||
alarmStatusOptions: {'0': '待处理', '1': '已处理', '2': '处理中'},//告警状态
|
||||
deviceTypeOptions: {'TCP': 'TCP', 'RTU': 'RTU'},//设备类型
|
||||
ticketStatusOptions: {1: '待处理', 2: '处理中', 3: '已处理'},//工单处理状态
|
||||
strategyStatusOptions: {'0': '未启用', '1': '已运行', '2': '已暂停', '3': '禁用', '4': '删除'},//策略状态
|
||||
chargeStatusOptions: {'1': '充电', '2': '待机', '3': '放电'},//冲放状态
|
||||
comparisonOperatorOptions: {'>': '>', '<': '<', '=': '=', '>=': '>=', '<=': '<='},
|
||||
relationWithPoint: {'||': '||', '&&': '&&'}
|
||||
},
|
||||
mutations: {
|
||||
SET_ZD_LIST(state, 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: {
|
||||
//查询站点的所有待处理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})
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
export default ems
|
||||
|
||||
@ -33,7 +33,13 @@ const permission = {
|
||||
GenerateRoutes({ commit }) {
|
||||
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 rdata = JSON.parse(JSON.stringify(res.data))
|
||||
const sidebarRoutes = filterAsyncRouter(sdata)
|
||||
@ -41,6 +47,10 @@ const permission = {
|
||||
const asyncRoutes = filterDynamicRoutes(dynamicRoutes)
|
||||
rewriteRoutes.push({ path: '*', redirect: '/404', hidden: true })
|
||||
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_SIDEBAR_ROUTERS', constantRoutes.concat(sidebarRoutes))
|
||||
commit('SET_DEFAULT_ROUTES', sidebarRoutes)
|
||||
@ -111,7 +121,7 @@ export function filterDynamicRoutes(routes) {
|
||||
}
|
||||
|
||||
export const loadView = (view) => {
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
if (process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'staging') {
|
||||
return (resolve) => require([`@/views/${view}`], resolve)
|
||||
} else {
|
||||
// 使用 import 实现生产环境的路由懒加载
|
||||
|
||||
@ -65,7 +65,7 @@ const user = {
|
||||
const user = res.user
|
||||
let avatar = user.avatar || ""
|
||||
if (!isHttp(avatar)) {
|
||||
avatar = (isEmpty(avatar)) ? defAva : process.env.VUE_APP_BASE_API + avatar
|
||||
avatar = (isEmpty(avatar)) ? defAva : process.env.VUE_APP_IMG_URL + avatar
|
||||
}
|
||||
if (res.roles && res.roles.length > 0) { // 验证返回的roles是否是一个非空数组
|
||||
commit('SET_ROLES', res.roles)
|
||||
|
||||
@ -17,7 +17,7 @@ const service = axios.create({
|
||||
// axios中请求配置有baseURL选项,表示请求URL公共部分
|
||||
baseURL: process.env.VUE_APP_BASE_API,
|
||||
// 超时
|
||||
timeout: 10000
|
||||
timeout: 60000
|
||||
})
|
||||
|
||||
// request拦截器
|
||||
|
||||
@ -11,7 +11,7 @@ export function isPathMatch(pattern, path) {
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断value字符串是否为空
|
||||
* 判断value字符串是否为空
|
||||
* @param {string} value
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
@ -23,7 +23,7 @@ export function isEmpty(value) {
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断url是否是http或https
|
||||
* 判断url是否是http或https
|
||||
* @param {string} url
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
@ -112,3 +112,13 @@ export function isArray(arg) {
|
||||
}
|
||||
return Array.isArray(arg)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string}
|
||||
* @returns {Boolean}
|
||||
* 只能输入中文、英文、数字、特殊字符!@#$%^&*-,./
|
||||
*/
|
||||
export function validText(text) {
|
||||
const reg = /^[a-zA-Z0-9\u4e00-\u9fa5!@#$%^&*-,.]+$/
|
||||
return reg.test(text)
|
||||
}
|
||||
|
||||
119
src/views/ems/dzjk/clpz/ClContainer.vue
Normal file
@ -0,0 +1,119 @@
|
||||
<template>
|
||||
<el-container class="clyx-container">
|
||||
<el-header class="clyx-header">
|
||||
<div class="clyx-title">策略状态:<span class="clyx-status save">{{strategyStatusOptions[info.status]}}</span></div>
|
||||
<div class="clyx-btns">
|
||||
<el-button v-if="!hideSettingBtn" size="small" @click="$emit('showSetting')">配置</el-button>
|
||||
<el-button v-if="info.status === '1'" type="warning" class="alarm-btn" size="small" @click='close'>停止策略</el-button>
|
||||
</div>
|
||||
</el-header>
|
||||
<el-main class="clyx-main">
|
||||
<slot name="default"></slot>
|
||||
</el-main>
|
||||
</el-container>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {mapState} from "vuex";
|
||||
import {stopStrategyRunning} from '@/api/ems/dzjk'
|
||||
export default {
|
||||
name:'DzjkClpzClContainer',
|
||||
props:{
|
||||
hideSettingBtn:{
|
||||
type:Boolean,
|
||||
default:false
|
||||
},
|
||||
info:{
|
||||
type:Object,
|
||||
default:()=>{return {}},
|
||||
}
|
||||
},
|
||||
computed:{
|
||||
...mapState({
|
||||
strategyStatusOptions: state => state.ems.strategyStatusOptions,
|
||||
})
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
loading:true
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
close(){
|
||||
this.$confirm('确认要停止策略吗?', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
showClose:false,
|
||||
closeOnClickModal:false,
|
||||
type: 'warning',
|
||||
beforeClose: (action, instance, done) => {
|
||||
if (action === 'confirm') {
|
||||
instance.confirmButtonLoading = true;
|
||||
this.loading = true
|
||||
stopStrategyRunning(this.info.id).then(response => {
|
||||
response.code === 200 && done();
|
||||
}).finally(() => {
|
||||
this.loading = false
|
||||
instance.confirmButtonLoading = false;
|
||||
})
|
||||
} else {
|
||||
done();
|
||||
}
|
||||
}
|
||||
}).then(() => {
|
||||
//只有在故障复位成功的情况下会走到这里
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: '停止策略成功!'
|
||||
});
|
||||
this.$emit('update')
|
||||
}).catch(() => {
|
||||
//取消复位
|
||||
});
|
||||
}
|
||||
},
|
||||
mounted(){
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.clyx-container{
|
||||
border:1px solid #eee;
|
||||
.clyx-header{
|
||||
background: #F1F5FB;
|
||||
display: flex;
|
||||
position: relative;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
padding: 0;
|
||||
height: 60px;
|
||||
border-radius: 6px 6px 0 0;
|
||||
.clyx-title{
|
||||
color: #333333;
|
||||
line-height: 20px;
|
||||
padding: 0 50px 0 25px;
|
||||
.clyx-status{
|
||||
font-weight: 500;
|
||||
font-size: 16px;
|
||||
&.danger{
|
||||
color:#FC6B69;
|
||||
}
|
||||
&.save{
|
||||
color:#09ADA3;
|
||||
}
|
||||
&.keep{
|
||||
color:#3C81FF;
|
||||
}
|
||||
}
|
||||
}
|
||||
.clyx-btns{
|
||||
position: absolute;
|
||||
right: 25px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
107
src/views/ems/dzjk/clpz/Setting.vue
Normal file
@ -0,0 +1,107 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
title="主从策略配置"
|
||||
custom-class="ems-dialog"
|
||||
:visible.sync="dialogFormVisible"
|
||||
width="420px"
|
||||
destroy-on-close
|
||||
lock-scroll
|
||||
append-to-body
|
||||
:close-on-click-modal="false"
|
||||
:close-on-press-escape="false"
|
||||
@close="cancel"
|
||||
>
|
||||
<el-form ref="form" :model="form" :rules='rule' label-width="100px" v-loading="loading > 0">
|
||||
<el-form-item label="主策略" prop="mainStrategyId">
|
||||
<el-select v-model="form.mainStrategyId" placeholder="请选择">
|
||||
<el-option :label="item.strategyName" :value="item.id" v-for="(item,index) in mainStrategyList" :key="index+'mainStrategyList'"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="辅助策略" prop="auxStrategyId">
|
||||
<el-select v-model="form.auxStrategyId" placeholder="请选择" clearable>
|
||||
<el-option :label="item.strategyName" :value="item.id" v-for="(item,index) in auxStrategyList" :key="index+'auxStrategyList'"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
<el-button type="primary" :loading="loading > 0" @click="sure">确 定</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {getMainStrategyList, getAuxStrategyList, configStrategy} from '@/api/ems/dzjk'
|
||||
export default {
|
||||
inject:['$home'],
|
||||
data(){
|
||||
return {
|
||||
info:{},
|
||||
loading:0,
|
||||
dialogFormVisible:false,
|
||||
mainStrategyList:[],
|
||||
auxStrategyList:[],
|
||||
form:{
|
||||
mainStrategyId:'',
|
||||
auxStrategyId:''
|
||||
},
|
||||
rule:{
|
||||
mainStrategyId:[
|
||||
{ required: true, message: '请选择主策略', trigger: ['blur','change'] },
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
showSettingDialog(item){
|
||||
console.log('打开弹窗',item)
|
||||
this.dialogFormVisible = true
|
||||
this.info = item || {}
|
||||
const {auxStrategyId = '',mainStrategyId = ''} = item
|
||||
this.form.auxStrategyId=auxStrategyId
|
||||
this.form.mainStrategyId=mainStrategyId
|
||||
this.init()
|
||||
},
|
||||
init(){
|
||||
this.loading+=2
|
||||
this.mainStrategyList=[]
|
||||
this.auxStrategyList=[]
|
||||
getMainStrategyList().then(response => {
|
||||
this.mainStrategyList=response?.data || []
|
||||
}).finally(()=>{this.loading-=1})
|
||||
getAuxStrategyList().then(response => {
|
||||
this.auxStrategyList=response?.data || []
|
||||
}).finally(()=>{this.loading-=1})
|
||||
},
|
||||
cancel(){
|
||||
this.$refs.form.resetFields()
|
||||
this.form={
|
||||
mainStrategyId:'',
|
||||
auxStrategyId:''
|
||||
}
|
||||
this.dialogFormVisible = false;
|
||||
},
|
||||
sure(){
|
||||
this.$refs['form'].validate(valid => {
|
||||
if (!valid) return
|
||||
console.log('this.$home',this.$home)
|
||||
this.loading +=1
|
||||
const {mainStrategyId='', auxStrategyId=''} = this.form
|
||||
configStrategy({mainStrategyId,auxiliaryStrategyId:auxStrategyId,siteId:this.$home.siteId,id:this.info?.id || ''}).then(response => {
|
||||
if(response?.code === 200){
|
||||
this.$home.init()
|
||||
this.cancel()
|
||||
}
|
||||
}).finally(()=>{
|
||||
this.loading -=1
|
||||
})
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
</style>
|
||||
129
src/views/ems/dzjk/clpz/clyx/index.vue
Normal file
@ -0,0 +1,129 @@
|
||||
|
||||
<template>
|
||||
<div v-loading="loading">
|
||||
<template v-if="!showTemp">
|
||||
<el-button v-if="!showTemp" type="primary" plain @click="settingStrategy" style="margin-bottom: 20px;">新增策略</el-button>
|
||||
<cl-container v-for="(item,index) in list" :key="index+'clContainer'" :info="item" :hide-setting-btn="showTemp" class="contain" @update="init" @showSetting="settingStrategy(item)">
|
||||
<template v-slot:default>
|
||||
<div class="cl-items cl-items-main" @click="toDetail(item.mainStrategyId,item.mainStrategyName)">
|
||||
<div class="cl-header">主策略</div>
|
||||
<div class="cl-content" >
|
||||
<div class="cl-name">{{item.mainStrategyName}}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cl-items" v-show="item.auxStrategyName" @click="toDetail(item.auxStrategyId,item.auxStrategyName)">
|
||||
<div class="cl-header">辅助策略</div>
|
||||
<div class="cl-content">
|
||||
<div class="cl-name">{{item.auxStrategyName}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</cl-container>
|
||||
<div v-if="list.length === 0">
|
||||
<el-empty :image-size="200" ></el-empty>
|
||||
</div>
|
||||
</template>
|
||||
<xftg ref="xftgTemp" v-else/>
|
||||
<setting ref="setting"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<script>
|
||||
import Setting from './../Setting.vue'
|
||||
import ClContainer from './../ClContainer.vue'
|
||||
import getQuerySiteId from '@/mixins/ems/getQuerySiteId'
|
||||
import Xftg from './../xftg/index.vue'
|
||||
import {strategyRunningList} from '@/api/ems/dzjk'
|
||||
export default {
|
||||
name:'DzjkClpzClyx',
|
||||
components:{ClContainer,Setting,Xftg},
|
||||
mixins: [getQuerySiteId],
|
||||
data() {
|
||||
return {
|
||||
showTemp:false,
|
||||
updateStrategyId:'',
|
||||
updateStrategyName:'',
|
||||
loading:false,
|
||||
list:[],
|
||||
}
|
||||
},
|
||||
provide(){
|
||||
return {$home:this}
|
||||
},
|
||||
methods:{
|
||||
settingStrategy(item=''){
|
||||
this.$refs.setting.showSettingDialog(item)
|
||||
},
|
||||
init(){
|
||||
this.loading = true
|
||||
this.list = []
|
||||
strategyRunningList(this.siteId).then(response => {
|
||||
this.list =JSON.parse(JSON.stringify(response?.data || {}))
|
||||
}).finally(() => {this.loading=false})
|
||||
this.$nextTick(() => {
|
||||
// 每次切换站点 展示策略运行 清空策略配置的数据
|
||||
this.$refs['xftgTemp'] && this.$refs['xftgTemp'].changeSiteId()
|
||||
this.showTemp=false
|
||||
this.updateStrategyId=''
|
||||
this.updateStrategyName=''
|
||||
})
|
||||
},
|
||||
toDetail(id,name){
|
||||
this.updateStrategyId=id
|
||||
this.updateStrategyName = name
|
||||
this.showTemp = true
|
||||
this.$nextTick(() => {
|
||||
this.$refs['xftgTemp'].init()
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.contain{
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.clyx-main{
|
||||
padding:0 12px 0 12px;
|
||||
.cl-items{
|
||||
cursor: pointer;
|
||||
width: 228px;
|
||||
height: 156px;
|
||||
display: inline-block;
|
||||
margin:24px 12px 0 12px;
|
||||
font-size:14px;
|
||||
color:#333333;
|
||||
border: 1px solid #eeeeee;
|
||||
.cl-header{
|
||||
background: #FFE5AC;
|
||||
text-align: center;
|
||||
font-size:16px;
|
||||
line-height: 40px;
|
||||
height: 40px;
|
||||
width: 100%;
|
||||
}
|
||||
.cl-content{
|
||||
background-color: #ffffff;
|
||||
position: relative;
|
||||
height: 114px;
|
||||
width: 100%;
|
||||
.cl-name{
|
||||
position: absolute;
|
||||
top:50%;
|
||||
left:50%;
|
||||
transform: translate(-50%,-50%);
|
||||
}
|
||||
}
|
||||
&.cl-items-main{
|
||||
.cl-header{
|
||||
background: #FFBE29;
|
||||
}
|
||||
.cl-content{
|
||||
background-color: #FFF2CB;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
53
src/views/ems/dzjk/clpz/index.vue
Normal file
@ -0,0 +1,53 @@
|
||||
<template>
|
||||
<div class="ems-dashboard-editor-container ems-third-menu-container">
|
||||
<el-menu
|
||||
class="ems-third-menu"
|
||||
:default-active="$route.name"
|
||||
background-color="#ffffff"
|
||||
text-color="#666666"
|
||||
active-text-color="#ffffff"
|
||||
>
|
||||
<el-menu-item :index="item.name" v-for="(item,index) in childrenRoute" :key="index+'clpzChildrenRoute'">
|
||||
<router-link style="height: 100%;width: 100%;display: block;" :to="{path:item.path,query:$route.query}">
|
||||
{{item.meta.title}}
|
||||
</router-link>
|
||||
</el-menu-item>
|
||||
</el-menu>
|
||||
|
||||
<div class="ems-content-container ems-content-container-padding clpz-ems-content-container">
|
||||
<keep-alive>
|
||||
<router-view></router-view>
|
||||
</keep-alive>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { dzjk } from '@/router/ems'
|
||||
const childrenRoute = dzjk[0].children[0].children.find(item=> item.name==='DzjkClpz').children.filter(item=>!item?.hidden)//获取到统计报表下面的字路由
|
||||
console.log('设备监控子路由',childrenRoute)
|
||||
export default {
|
||||
name:'DzjkClpz',
|
||||
data(){
|
||||
return {
|
||||
childrenRoute,
|
||||
activeMenu:''
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
console.log('当前统计报表页面路由',this.$route)
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.clpz-ems-content-container{
|
||||
margin-top:0;
|
||||
padding-top:0;
|
||||
padding-right: 0;
|
||||
flex: 1;
|
||||
}
|
||||
</style>
|
||||
|
||||
325
src/views/ems/dzjk/clpz/xftg/AddTemplate.vue
Normal file
@ -0,0 +1,325 @@
|
||||
<template>
|
||||
<el-dialog :visible.sync="dialogTableVisible" class="ems-dialog add-template-dialog"
|
||||
:title="mode === 'add'?'新增模板':`编辑模板` ">
|
||||
<el-form ref="addTempForm" :model="formData" :rules="rules" size="medium" label-width="100px">
|
||||
<el-form-item label="模板名称" prop="templateName">
|
||||
<el-input v-model="formData.templateName" placeholder="请输入" clearable :style="{width: '100%'}">
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="soc限制" prop="sdcLimit" required>
|
||||
<el-switch :active-value="1" :inactive-value="0" v-model="formData.sdcLimit"></el-switch>
|
||||
</el-form-item>
|
||||
<!-- <template v-if="formData.sdcLimit === 1">-->
|
||||
<el-form-item label="soc下限" prop="sdcDown">
|
||||
<el-input v-model="formData.sdcDown" placeholder="请输入" clearable :style="{width: '100%'}"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="soc上限" prop="sdcUp">
|
||||
<el-input v-model="formData.sdcUp" placeholder="请输入" clearable :style="{width: '100%'}"></el-input>
|
||||
</el-form-item>
|
||||
<!-- </template>-->
|
||||
</el-form>
|
||||
<el-button type="primary" size="mini" @click="addTime">新增</el-button>
|
||||
<!-- 新增时间段表单-->
|
||||
<el-collapse-transition>
|
||||
<el-card v-show="showAddTime" shadow="always" class="common-card-container" style="margin-top:25px;">
|
||||
<el-form class="add-time-form transition-box" ref="addTimeForm" :model="formInline" :rules="formInlineRule"
|
||||
label-width="100px" style="margin-top:25px">
|
||||
<!-- <el-form-item label="开始时间" prop="startTime">-->
|
||||
<!-- <el-time-select-->
|
||||
<!-- placeholder="开始时间"-->
|
||||
<!-- v-model="formInline.startTime"-->
|
||||
<!-- :picker-options="{-->
|
||||
<!-- start: '00:00',-->
|
||||
<!-- step: '00:01',-->
|
||||
<!-- end: '23:00',-->
|
||||
<!-- }">-->
|
||||
<!-- </el-time-select>-->
|
||||
<!-- </el-form-item>-->
|
||||
<!-- <el-form-item label="结束时间" prop="endTime">-->
|
||||
<!-- <el-time-select-->
|
||||
<!-- placeholder="结束时间"-->
|
||||
<!-- v-model="formInline.endTime"-->
|
||||
<!-- :picker-options="{-->
|
||||
<!-- start: '00:00',-->
|
||||
<!-- step: '00:01',-->
|
||||
<!-- end: '23:00',-->
|
||||
<!-- minTime: formInline.startTime-->
|
||||
<!-- }">-->
|
||||
<!-- </el-time-select>-->
|
||||
<!-- </el-form-item>-->
|
||||
<el-form-item label="时间范围" prop="timeRange">
|
||||
<el-time-picker
|
||||
is-range
|
||||
v-model="formInline.timeRange"
|
||||
range-separator="至"
|
||||
start-placeholder="开始时间"
|
||||
end-placeholder="结束时间"
|
||||
placeholder="选择时间范围"
|
||||
format="HH:mm"
|
||||
value-format="HH:mm"
|
||||
:style="{width: '100%'}">
|
||||
</el-time-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="冲放功率" prop="chargeDischargePower">
|
||||
<el-input v-model="formInline.chargeDischargePower" placeholder="请输入"
|
||||
:style="{width: '100%'}"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="充电状态" prop="chargeStatus">
|
||||
<el-select v-model="formInline.chargeStatus" placeholder="请选择" :style="{width: '100%'}">
|
||||
<el-option v-for="(value,key) in chargeStatusOptions" :key="key+'chargeStatusOptions'" :label="value"
|
||||
:value="key"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" size="mini" @click="saveTime">保存</el-button>
|
||||
<el-button size="mini" @click="cancelAddTime">取消</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
</el-collapse-transition>
|
||||
<el-table
|
||||
:data="tableData"
|
||||
border
|
||||
style="width: 100%;margin-top:25px">
|
||||
<el-table-column
|
||||
prop="startTime"
|
||||
label="开始时间">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="endTime"
|
||||
label="结束时间">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="chargeDischargePower"
|
||||
label="充放功率(kW)">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="chargeStatus"
|
||||
label="充电状态">
|
||||
<template slot-scope="scope">
|
||||
{{ chargeStatusOptions[scope.row.chargeStatus] }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
fixed="right"
|
||||
label="操作"
|
||||
width="120">
|
||||
<template slot-scope="scope">
|
||||
<el-button
|
||||
@click.native.prevent="deleteRow(scope.$index, tableData)"
|
||||
type="warning"
|
||||
size="mini">
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<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 {addStrategyTemp, editStrategyTemp, getStrategyTempDetail} from '@/api/ems/dzjk'
|
||||
|
||||
export default {
|
||||
inject: ['$home'],
|
||||
data() {
|
||||
const now = new Date()
|
||||
const year = now.getFullYear(), month = now.getMonth(), day = now.getDate()
|
||||
const range = [new Date(year, month, day, 0), new Date(year, month, day, 23)]
|
||||
return {
|
||||
mode: '',
|
||||
editTempId: '',
|
||||
dialogTableVisible: false,
|
||||
secondRange: range,
|
||||
formData: {
|
||||
templateName: '',
|
||||
sdcLimit: false,
|
||||
sdcDown: '',
|
||||
sdcUp: '',
|
||||
},
|
||||
rules: {
|
||||
templateName: [{
|
||||
required: true,
|
||||
message: '请输入',
|
||||
trigger: 'blur'
|
||||
}],
|
||||
sdcDown: [
|
||||
{required: true, message: '请输入', trigger: 'blur'},
|
||||
{pattern: /^(0|[1-9]\d*)(\.\d+)?$/, message: '请输入合法数字或小数'}
|
||||
],
|
||||
sdcUp: [
|
||||
{required: true, message: '请输入', trigger: 'blur'},
|
||||
{pattern: /^(0|[1-9]\d*)(\.\d+)?$/, message: '请输入合法数字或小数'}
|
||||
],
|
||||
},
|
||||
showAddTime: false,
|
||||
formInline: {
|
||||
timeRange: range,
|
||||
chargeDischargePower: '',
|
||||
chargeStatus: ''
|
||||
},
|
||||
formInlineRule: {
|
||||
timeRange: [{
|
||||
required: true,
|
||||
message: '请选择时间范围',
|
||||
trigger: 'change'
|
||||
}],
|
||||
chargeDischargePower: [{
|
||||
required: true,
|
||||
message: '请输入冲放功率',
|
||||
trigger: 'blur'
|
||||
},
|
||||
{pattern: /^-?\d*\.?\d*$/, message: '请输入合法数字或小数'}
|
||||
],
|
||||
chargeStatus: [{
|
||||
required: true,
|
||||
message: '请选择充放状态',
|
||||
trigger: ['blur', 'change']
|
||||
}
|
||||
]
|
||||
},
|
||||
tableData: [],
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
chargeStatusOptions: state => state?.ems?.chargeStatusOptions || {},
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
changeSiteId() {
|
||||
this.dialogTableVisible = false
|
||||
this.mode = ''
|
||||
this.editTempId = ''
|
||||
this.formData = {
|
||||
templateName: '',
|
||||
sdcLimit: false,
|
||||
sdcDown: '',
|
||||
sdcUp: '',
|
||||
}
|
||||
this.formInline = {
|
||||
timeRange: this.secondRange, chargeDischargePower: '', chargeStatus: ''
|
||||
}//startTime: '', endTime: '',
|
||||
this.showAddTime = false
|
||||
this.tableData = []
|
||||
},
|
||||
show({mode = 'add', editTempId = ''}) {
|
||||
this.$nextTick(() => {
|
||||
this.dialogTableVisible = true
|
||||
this.mode = mode
|
||||
this.editTempId = editTempId
|
||||
if (mode === 'edit' && editTempId) {
|
||||
getStrategyTempDetail(this.editTempId).then(response => {
|
||||
const data = JSON.parse(JSON.stringify(response?.data || []));
|
||||
if (data.length > 0) {
|
||||
const {templateName, sdcLimit, sdcDown, sdcUp} = JSON.parse(JSON.stringify(data[0]));
|
||||
this.formData.templateName = templateName
|
||||
this.formData.sdcLimit = sdcLimit
|
||||
this.formData.sdcDown = sdcDown
|
||||
this.formData.sdcUp = sdcUp
|
||||
}
|
||||
if (data.length === 1) {
|
||||
const {startTime, endTime} = data;
|
||||
if (!startTime || !endTime) {
|
||||
this.tableData = []
|
||||
} else {
|
||||
this.tableData = data
|
||||
}
|
||||
} else {
|
||||
this.tableData = data
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
addTime() {
|
||||
this.showAddTime = true
|
||||
},
|
||||
cancelAddTime() {
|
||||
this.$refs.addTimeForm.resetFields()
|
||||
this.showAddTime = false
|
||||
this.formInline = {timeRange: this.secondRange, chargeDischargePower: '', chargeStatus: ''}//startTime: '', endTime: '',
|
||||
},
|
||||
saveTime() {
|
||||
//表单校验,校验成功,添加到tableData里
|
||||
this.$refs.addTimeForm.validate(valid => {
|
||||
if (!valid) return
|
||||
const {timeRange: [startTime, endTime], chargeDischargePower, chargeStatus} = this.formInline
|
||||
|
||||
this.tableData.push({startTime, endTime, chargeDischargePower, chargeStatus})
|
||||
this.$nextTick(() => {
|
||||
this.cancelAddTime()
|
||||
})
|
||||
})
|
||||
},
|
||||
deleteRow(index) {
|
||||
this.tableData.splice(index, 1)
|
||||
},
|
||||
saveDialog() {
|
||||
this.$refs.addTempForm.validate(valid => {
|
||||
if (!valid) return
|
||||
const {templateName, sdcLimit, sdcDown, sdcUp} = this.formData
|
||||
const {siteId, updateStrategyId} = this.$home
|
||||
const {tableData} = this
|
||||
if (this.mode === 'edit') {
|
||||
editStrategyTemp({
|
||||
siteId,
|
||||
strategyId: updateStrategyId,
|
||||
templateId: this.editTempId,
|
||||
templateName,
|
||||
sdcLimit,
|
||||
sdcDown,
|
||||
sdcUp,
|
||||
timeConfigList: tableData
|
||||
}).then(response => {
|
||||
if (response?.code === 200) {
|
||||
this.closeDialog()
|
||||
this.$emit('update')
|
||||
this.$emit('updateTimeSetting')
|
||||
}
|
||||
})
|
||||
} else {
|
||||
addStrategyTemp({
|
||||
siteId,
|
||||
strategyId: updateStrategyId,
|
||||
templateName,
|
||||
sdcLimit,
|
||||
sdcDown,
|
||||
sdcUp,
|
||||
timeConfigList: tableData
|
||||
}).then(response => {
|
||||
if (response?.code === 200) {
|
||||
this.closeDialog()
|
||||
this.$emit('update')
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
closeDialog() {
|
||||
// 清空所有数据
|
||||
this.$refs.addTempForm.resetFields()
|
||||
this.formData = {
|
||||
templateName: '',
|
||||
sdcLimit: 0,
|
||||
sdcDown: '',
|
||||
sdcUp: '',
|
||||
}
|
||||
this.tableData = []
|
||||
this.cancelAddTime()
|
||||
this.dialogTableVisible = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.add-template-dialog {
|
||||
max-height: 90vh;
|
||||
overflow-y: auto;
|
||||
}
|
||||
</style>
|
||||
117
src/views/ems/dzjk/clpz/xftg/TempPowerChart.vue
Normal file
@ -0,0 +1,117 @@
|
||||
|
||||
<template>
|
||||
<el-card shadow="always" class="common-card-container common-card-container-body-no-padding" style="margin-top:25px;">
|
||||
<div slot="header">
|
||||
<span class="card-title">策略模板曲线展示</span>
|
||||
</div>
|
||||
<div style="height: 360px" id="tempChart"/>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
<script>
|
||||
import * as echarts from 'echarts'
|
||||
import resize from '@/mixins/ems/resize'
|
||||
import {curveList} from '@/api/ems/dzjk'
|
||||
export default {
|
||||
inject:['$home'],
|
||||
mixins: [resize],
|
||||
data() {
|
||||
return {
|
||||
chart: null
|
||||
}
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.destoryChart()
|
||||
},
|
||||
methods: {
|
||||
destoryChart(){
|
||||
if (!this.chart) {
|
||||
return
|
||||
}
|
||||
this.chart.dispose()
|
||||
this.chart = null
|
||||
},
|
||||
changeSiteId(){
|
||||
this.destoryChart()
|
||||
},
|
||||
init(){
|
||||
if(!this.chart){
|
||||
this.chart = echarts.init(document.getElementById('tempChart'))
|
||||
}
|
||||
const strategyId = this.$home.updateStrategyId
|
||||
const siteId=this.$home.siteId
|
||||
curveList({strategyId,siteId}).then(response => {
|
||||
this.setOption(response?.data || [])
|
||||
})
|
||||
},
|
||||
setOption(data) {
|
||||
if(!this.chart) return
|
||||
let obj = {}
|
||||
for(var i=0;i<=23;i++){
|
||||
obj[i] = {
|
||||
title:i<=9?`0${i}:00` : `${i}:00`
|
||||
}
|
||||
}
|
||||
const nowMonth = new Date().getMonth()+1;
|
||||
const localMonth = data.find(item=>item.month === nowMonth)?.powerList || []
|
||||
localMonth.forEach(item => {
|
||||
const startHours = parseInt(item.startTime.split(':')[0], 10)
|
||||
const endHours =parseInt(item.endTime.split(':')[0], 10)
|
||||
for(let i=startHours;i<=endHours;i++){
|
||||
obj[i].value = item.powerData
|
||||
}
|
||||
})
|
||||
let source = [['时间','冲放功率']]
|
||||
Object.values(obj).forEach(item => {
|
||||
const {title,value} = item
|
||||
source.push([title,value])
|
||||
})
|
||||
this.chart.setOption({
|
||||
color:['#FFBD00','#3C81FF'],
|
||||
grid: {
|
||||
containLabel: true
|
||||
},
|
||||
legend: {
|
||||
left: 'center',
|
||||
bottom: '15',
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: { // 坐标轴指示器,坐标轴触发有效
|
||||
type: 'shadow' // 默认为直线,可选为:'line' | 'shadow'
|
||||
}
|
||||
},
|
||||
textStyle:{
|
||||
color:"#333333",
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
axisLine: {
|
||||
lineStyle:{
|
||||
color: '#333333',
|
||||
}
|
||||
}
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
axisLine: {
|
||||
lineStyle:{
|
||||
color: '#333333',
|
||||
}
|
||||
}
|
||||
},
|
||||
dataset: {
|
||||
source
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name:'冲放功率',
|
||||
type: 'line',
|
||||
}]
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
196
src/views/ems/dzjk/clpz/xftg/TempTable.vue
Normal file
@ -0,0 +1,196 @@
|
||||
|
||||
<template>
|
||||
<el-card shadow="always" class="common-card-container">
|
||||
<div slot="header">
|
||||
<span class="card-title">新增模板</span>
|
||||
<div style="float: right; padding: 3px 0">
|
||||
<el-button type="text" size="mini" @click="back">返回策略运行</el-button>
|
||||
<el-button type="primary" size="mini" @click="addTemp">新增</el-button>
|
||||
<template v-if="tempList.length>0">
|
||||
<el-button type="warning" size="mini" @click="editTemp">编辑</el-button>
|
||||
<el-button type="primary" class="alarm-btn" size="mini" @click="deleteTemp">删除</el-button>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<template v-if="tempList.length>0">
|
||||
<el-button-group class="ems-btns-group">
|
||||
<el-button v-for="(item,index) in tempList" :key="index+'tempList'" :class="{'activeBtn' : activeBtn === item.templateId}" size="small" @click="changeTemp(item.templateId)">{{item.templateName}}</el-button>
|
||||
</el-button-group>
|
||||
<el-table
|
||||
:data="tableData"
|
||||
:span-method="tableSpanFilter"
|
||||
border
|
||||
style="width: 100%;margin-top:25px;">
|
||||
<!-- todo 如果要在span-method中使用column.property 在表格中必须定义prop="xxx"属性-->
|
||||
<el-table-column
|
||||
prop="templateName"
|
||||
label="模板名称"
|
||||
width="180">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="sdcLimit"
|
||||
label="SOC限制">
|
||||
<template slot-scope="scope">
|
||||
<el-switch disabled :active-value="1" :inactive-value="0" v-model="scope.row.sdcLimit"></el-switch>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="sdcDown"
|
||||
label="SOC下限">
|
||||
<template slot-scope="scope">
|
||||
{{scope.row.sdcDown ? scope.row. sdcDown + '%' : '-'}}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="sdcUp"
|
||||
label="SOC上限">
|
||||
<template slot-scope="scope">
|
||||
{{scope.row.sdcUp ? scope.row.sdcUp + '%' : '-'}}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="startTime"
|
||||
label="开始时间">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="endTime"
|
||||
label="结束时间">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="chargeDischargePower"
|
||||
label="充放功率(kW)">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="chargeStatus"
|
||||
label="充电状态">
|
||||
<template slot-scope="scope">
|
||||
{{chargeStatusOptions[scope.row.chargeStatus]}}
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
</el-table>
|
||||
</template>
|
||||
<template v-else>
|
||||
<el-empty :image-size="150"></el-empty>
|
||||
</template>
|
||||
</div>
|
||||
<add-template ref="addTemplate" :mode="handlerType" :editTempId="activeBtn" @update="init" @updateTimeSetting="$emit('updateTimeSetting')"/>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {mapState} from 'vuex'
|
||||
import AddTemplate from "./AddTemplate.vue";
|
||||
import {getTempNameList, getStrategyTempDetail, deleteStrategyTemp} from '@/api/ems/dzjk'
|
||||
export default {
|
||||
components: {AddTemplate},
|
||||
inject:['$home'],
|
||||
data() {
|
||||
return {
|
||||
handlerType:'',
|
||||
activeBtn:'',
|
||||
tempList:[],
|
||||
tableData:[],
|
||||
mixinPrototype:['templateName','sdcLimit','sdcDown','sdcUp']
|
||||
}
|
||||
},
|
||||
computed:{
|
||||
...mapState({
|
||||
chargeStatusOptions: state => state?.ems?.chargeStatusOptions || {},
|
||||
}),
|
||||
activeTempData(){
|
||||
return this.tempList.find(item=>item.templateId === this.activeBtn) || {}
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
back(){
|
||||
this.$home.init()
|
||||
},
|
||||
changeSiteId(){
|
||||
this.tempList=[]
|
||||
this.tableData=[]
|
||||
this.handlerType=''
|
||||
this.activeBtn=''
|
||||
this.$refs.addTemplate && this.$refs.addTemplate.changeSiteId()
|
||||
},
|
||||
addTemp(){
|
||||
this.$refs.addTemplate.show({mode:'add',editTempId:''})
|
||||
},
|
||||
editTemp(){
|
||||
this.$refs.addTemplate.show({mode:'edit',editTempId:this.activeBtn})
|
||||
},
|
||||
init(){
|
||||
getTempNameList({strategyId:this.$home.updateStrategyId,siteId:this.$home.siteId}).then(response => {
|
||||
const data = response?.data || [];
|
||||
this.tempList =data
|
||||
if(data.length ===0 && this.activeBtn){
|
||||
this.activeBtn=''
|
||||
}else if(!this.activeBtn && data.length>0){
|
||||
this.activeBtn =data[0].templateId
|
||||
}else if(this.activeBtn && data.length>0 && !data.find(item=>item.templateId === this.activeBtn)){
|
||||
this.activeBtn =data[0].templateId
|
||||
}
|
||||
this.activeBtn && getStrategyTempDetail(this.activeBtn).then(response => {
|
||||
this.tableData=response?.data || [];
|
||||
})
|
||||
})
|
||||
},
|
||||
deleteTemp(){
|
||||
this.$confirm(`确认要删除${this.activeTempData.templateName}吗?`, {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
showClose:false,
|
||||
closeOnClickModal:false,
|
||||
type: 'warning',
|
||||
beforeClose: (action, instance, done) => {
|
||||
if (action === 'confirm') {
|
||||
instance.confirmButtonLoading = true;
|
||||
deleteStrategyTemp(this.activeBtn).then(response => {
|
||||
if(response?.code === 200){
|
||||
//删除成功
|
||||
done();
|
||||
}
|
||||
}).finally(() => {
|
||||
instance.confirmButtonLoading = false;
|
||||
})
|
||||
} else {
|
||||
done();
|
||||
}
|
||||
}
|
||||
}).then(() => {
|
||||
//只有删除成功的情况下会走到这里
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: '删除成功!'
|
||||
});
|
||||
this.init()
|
||||
this.$emit('updateTimeSetting')
|
||||
}).catch(() => {
|
||||
//取消
|
||||
});
|
||||
},
|
||||
changeTemp(id=''){
|
||||
//切换模板 更新数据
|
||||
if(id !== this.activeBtn){
|
||||
this.activeBtn=id;
|
||||
this.init()
|
||||
}
|
||||
},
|
||||
tableSpanFilter({ row, column, rowIndex, columnIndex }){
|
||||
if(!this.mixinPrototype.includes(column.property)) return { rowspan: 1,colspan: 1 }
|
||||
if(rowIndex===0){
|
||||
return {
|
||||
rowspan: this.tableData.length,
|
||||
colspan: 1
|
||||
};
|
||||
}else{
|
||||
return {
|
||||
rowspan: 0,
|
||||
colspan: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
149
src/views/ems/dzjk/clpz/xftg/TimeSetting.vue
Normal file
@ -0,0 +1,149 @@
|
||||
|
||||
<template>
|
||||
<el-card shadow="always" class="common-card-container" style="margin-top:25px;">
|
||||
<div slot="header">
|
||||
<span class="card-title">策略配置:{{$home.updateStrategyName}}</span>
|
||||
<div style="float: right; padding: 3px 0">
|
||||
<el-button type="warning" size="mini" @click="changeEditStatus">{{edit?'保存':'编辑'}}</el-button>
|
||||
<el-button type="default" size="mini" @click="cancelChange" v-show="edit === true">取消</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div style="padding:0 6px 12px 6px;">
|
||||
<div class="cl-items" v-for="(item,index) in tableData" :key="index+'lclf'">
|
||||
<div class="cl-header">{{item.month}}月</div>
|
||||
<div class="cl-content">
|
||||
<div class="cl-name" v-if="!edit">
|
||||
{{item.templateName || '-'}}
|
||||
</div>
|
||||
<template v-else>
|
||||
<el-select v-model="tableData[index].templateId" :disabled="!edit" class="temp-select" placeholder="请选择" clearable size="mini">
|
||||
<el-option
|
||||
v-for="(item,index) in tempList"
|
||||
:key="index+'sjpz'"
|
||||
:label="item.templateName"
|
||||
:value="item.templateId">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</el-card>
|
||||
</template>
|
||||
<script>
|
||||
import {timeConfigList, getTempNameList,setTimeConfigList} from '@/api/ems/dzjk'
|
||||
export default {
|
||||
inject:['$home'],
|
||||
data() {
|
||||
return {
|
||||
edit:false,
|
||||
loading:false,
|
||||
tableData:[],
|
||||
tempList:[]
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
changeSiteId(){
|
||||
this.tableData=[]
|
||||
this.tempList=[]
|
||||
this.edit = false
|
||||
},
|
||||
init(){
|
||||
this.getTimeConfigList()
|
||||
},
|
||||
getTempList(){
|
||||
const strategyId = this.$home.updateStrategyId
|
||||
const siteId=this.$home.siteId
|
||||
getTempNameList({strategyId,siteId}).then(response => {
|
||||
this.tempList =response?.data || [];
|
||||
})
|
||||
},
|
||||
getTimeConfigList(){
|
||||
const strategyId = this.$home.updateStrategyId
|
||||
const siteId=this.$home.siteId
|
||||
return timeConfigList({strategyId,siteId}).then(response => {
|
||||
const data = JSON.parse(JSON.stringify(response?.data || []))
|
||||
if(data.length === 0){
|
||||
for(var i=1;i<=12;i++){
|
||||
data.push({
|
||||
month:i,
|
||||
strategyId,
|
||||
siteId,
|
||||
templateId:'',
|
||||
templateName:''
|
||||
})
|
||||
}
|
||||
}
|
||||
this.tableData=data
|
||||
})
|
||||
},
|
||||
cancelChange(){
|
||||
this.edit =false
|
||||
this.getTimeConfigList()
|
||||
},
|
||||
changeEditStatus(){
|
||||
//当前状态是编辑状态
|
||||
if(this.edit){
|
||||
console.log('this.tableData',this.tableData)
|
||||
const strategyId = this.$home.updateStrategyId
|
||||
const siteId=this.$home.siteId
|
||||
this.tableData.forEach(item=>{
|
||||
item.siteId=siteId
|
||||
item.strategyId=strategyId
|
||||
item.templateName = (this.tempList.find(temp=>temp.templateId===item.templateId) || {}).templateName || ''
|
||||
})
|
||||
setTimeConfigList(this.tableData).then(response => {
|
||||
if(response?.code === 200){
|
||||
//更改成功 调用接口更新数据
|
||||
this.getTimeConfigList()
|
||||
this.edit=false;
|
||||
}
|
||||
})
|
||||
}else{
|
||||
this.edit=true;
|
||||
this.getTempList()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.cl-items{
|
||||
width: 144px;
|
||||
height: 90px;
|
||||
line-height: 16px;
|
||||
display: inline-block;
|
||||
margin:12px 6px 0 6px;
|
||||
font-size:14px;
|
||||
color:#333333;
|
||||
border: 1px solid #eeeeee;
|
||||
.cl-header{
|
||||
background: #FFE5AC;
|
||||
text-align: center;
|
||||
font-size:16px;
|
||||
line-height: 30px;
|
||||
height: 30px;
|
||||
width: 100%;
|
||||
}
|
||||
.cl-content{
|
||||
background-color: #ffffff;
|
||||
position: relative;
|
||||
height: 58px;
|
||||
width: 100%;
|
||||
.cl-name{
|
||||
position: absolute;
|
||||
top:50%;
|
||||
left:50%;
|
||||
transform: translate(-50%,-50%);
|
||||
}
|
||||
.temp-select{
|
||||
width: 90%;
|
||||
position: absolute;
|
||||
top:50%;
|
||||
left:50%;
|
||||
transform: translate(-50%,-50%);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
66
src/views/ems/dzjk/clpz/xftg/index.vue
Normal file
@ -0,0 +1,66 @@
|
||||
|
||||
<template>
|
||||
<!-- <cl-container :hideSettingBtn="true">-->
|
||||
<!-- <template v-slot:default>-->
|
||||
<div>
|
||||
<temp-table ref="tempTable" @updateTimeSetting="updateTimeSetting"/>
|
||||
<time-setting ref="timeSetting"/>
|
||||
<temp-power-chart ref="tomePowerChart"/>
|
||||
</div>
|
||||
<!-- </template>-->
|
||||
<!-- </cl-container>-->
|
||||
</template>
|
||||
|
||||
|
||||
<script>
|
||||
import ClContainer from './../ClContainer.vue'
|
||||
import TempTable from "./TempTable.vue";
|
||||
import TimeSetting from "./TimeSetting.vue";
|
||||
import TempPowerChart from "./TempPowerChart.vue";
|
||||
export default {
|
||||
name:'DzjkClpzXftg',
|
||||
components:{ClContainer,TempTable,TimeSetting,TempPowerChart},
|
||||
data() {
|
||||
return {
|
||||
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
init(){
|
||||
this.$nextTick(() => {
|
||||
this.$refs.tempTable.init()
|
||||
this.$refs.timeSetting.init()
|
||||
this.$refs.tomePowerChart.init()
|
||||
})
|
||||
},
|
||||
changeSiteId(){
|
||||
this.$nextTick(() => {
|
||||
this.$refs.tempTable.changeSiteId()
|
||||
this.$refs.timeSetting.changeSiteId()
|
||||
this.$refs.tomePowerChart.changeSiteId()
|
||||
})
|
||||
},
|
||||
updateTimeSetting(){
|
||||
this.$refs.timeSetting.init()
|
||||
this.$refs.tomePowerChart.init()
|
||||
}
|
||||
},
|
||||
mounted(){
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
::v-deep{
|
||||
.common-card-container .el-card__header{
|
||||
padding:5px 20px;
|
||||
height:44px;
|
||||
.card-title{
|
||||
line-height: 34px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
@ -1,44 +1,42 @@
|
||||
|
||||
<template>
|
||||
<el-card shadow="always" class="common-card-container common-card-container-no-title-bg">
|
||||
<el-card v-loading="loading" gshadow="always" class="common-card-container common-card-container-no-title-bg">
|
||||
<!-- 搜索栏-->
|
||||
<div class="select-container">
|
||||
<el-form :inline="true">
|
||||
<el-form-item label="设备类型">
|
||||
<el-select v-model="search.sblx" placeholder="请选择" :loading="loading" loading-text="正在加载数据">
|
||||
<el-option :label="item.name" :value="item.id" v-for="(item,index) in sblxOptions" :key="index+'sblxOptions'"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="告警等级">
|
||||
<el-select v-model="search.gjdj" placeholder="请选择" :loading="loading" loading-text="正在加载数据">
|
||||
<el-option :label="item.name" :value="item.id" v-for="(item,index) in gjdjOptions" :key="index+'gjdjOptions'"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="时间选择">
|
||||
<el-date-picker
|
||||
v-model="dateRange"
|
||||
type="datetimerange"
|
||||
range-separator="至"
|
||||
start-placeholder="开始时间"
|
||||
:picker-options="pickerOptions"
|
||||
:default-value="defaultDateRange"
|
||||
end-placeholder="结束时间">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="warning" @click="onSearch" native-type="button">搜索</el-button>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button @click="onReset" native-type="button">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<el-form :inline="true" class="select-container">
|
||||
<el-form-item label="设备清单">
|
||||
<el-select v-model="search.deviceId" clearable placeholder="请选择" :loading="loading" loading-text="正在加载数据">
|
||||
<el-option :label="item.deviceName" :value="item.deviceId" v-for="(item,key) in deviceOptions" :key="key+'deviceIdOptions'"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="告警等级">
|
||||
<el-select v-model="search.alarmLevel" clearable placeholder="请选择" :loading="loading" loading-text="正在加载数据">
|
||||
<el-option :label="value" :value="key" v-for="(value,key) in $store.state.ems.alarmLevelOptions" :key="key+'alarmLevelOptions'"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="时间选择">
|
||||
<el-date-picker
|
||||
v-model="dateRange"
|
||||
type="daterange"
|
||||
range-separator="至"
|
||||
start-placeholder="开始时间"
|
||||
:picker-options="pickerOptions"
|
||||
:default-value="defaultDateRange"
|
||||
end-placeholder="结束时间">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="onSearch" native-type="button">搜索</el-button>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button @click="onReset" native-type="button">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div style="margin:30px 0;">
|
||||
<!-- 二个选择按钮-->
|
||||
<el-row style="">
|
||||
<el-col :xs="24" :sm="24" :lg="24">
|
||||
<el-button-group>
|
||||
<el-button v-for="(item,index) in btnList" :key="index+'dtdcBtns'" type="warning" :class="{'activeBtn' : activeBtn === item.id}" @click="changeDataType(item.id)">{{item.name}}</el-button>
|
||||
<el-button-group class="ems-btns-group">
|
||||
<el-button v-for="(item,index) in btnList" :key="index+'dtdcBtns'" :class="{'activeBtn' : activeBtn === item.id}" @click="changeDataType(item.id)">{{item.name}}</el-button>
|
||||
</el-button-group>
|
||||
</el-col>
|
||||
</el-row>
|
||||
@ -50,122 +48,182 @@
|
||||
max-height="500"
|
||||
style="width: 100%;margin-top:25px;">
|
||||
<el-table-column
|
||||
prop="name"
|
||||
width="200"
|
||||
prop="deviceName"
|
||||
label="设备名称">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="告警等级"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{scope.row.gjdj}}</span>
|
||||
<span>{{$store.state.ems.alarmLevelOptions[scope.row.alarmLevel]}}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="alarmContent"
|
||||
show-overflow-tooltip
|
||||
label="告警内容">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="alarmStartTime"
|
||||
label="告警发生时间">
|
||||
<template slot-scope="scope">
|
||||
<span>{{scope.row.gjnr}}</span>
|
||||
<span>{{formatDate(scope.row.alarmStartTime,true)}}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="startTime"
|
||||
label="告警发生时间">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="finishTime"
|
||||
prop="alarmEndTime"
|
||||
label="告警结束时间">
|
||||
<template slot-scope="scope">
|
||||
<span>{{formatDate(scope.row.alarmEndTime,true)}}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="状态">
|
||||
<template slot-scope="scope">
|
||||
<span :class="scope.row.status === 2 ? 'warning-status' : ''">{{scope.row.status === 2 ? '告警中' :'已结束'}}</span>
|
||||
<span :class="['0','2'].includes(scope.row.status) ? 'warning-status' : ''">{{$store.state.ems.alarmStatusOptions[scope.row.status]}}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="工单"
|
||||
fixed="right"
|
||||
width="250"
|
||||
>
|
||||
<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="primary" size="mini" v-else @click="createTicket(scope.row.id)">生成工单</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>
|
||||
</div>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
|
||||
<script>
|
||||
import {getAlarmDetailList,createTicketNo} from'@/api/ems/dzjk'
|
||||
import {getDeviceList} from'@/api/ems/site'
|
||||
import getQuerySiteId from "@/mixins/ems/getQuerySiteId";
|
||||
import { formatDate } from '@/filters/ems'
|
||||
export default {
|
||||
name:'DzjkGzgj',
|
||||
mixins:[getQuerySiteId],
|
||||
data() {
|
||||
return {
|
||||
loading:false,
|
||||
btnList:[
|
||||
{name:'今日告警',id:'today'},
|
||||
{name:'历史告警',id:'yesterday'},
|
||||
{name:'未处理告警',id:'today'},
|
||||
{name:'历史告警',id:'history'},
|
||||
],
|
||||
deviceOptions:[],//设备列表
|
||||
pickerOptions:{
|
||||
disabledDate(time) {
|
||||
return time.getTime() > Date.now();
|
||||
},
|
||||
},
|
||||
defaultDateRange:[],//默认展示的时间
|
||||
dateRange:[],
|
||||
dateRange:[],//alarmStartTime,alarmEndTime
|
||||
activeBtn:'today',
|
||||
loading:false,
|
||||
search:{sblx:'',gjdj:''},
|
||||
sblxOptions:[
|
||||
{name:'类型一',id:1},
|
||||
{name:'类型二',id:2},
|
||||
{name:'类型三',id:3},
|
||||
],
|
||||
gjdjOptions:[
|
||||
{name:'严重',id:1},
|
||||
{name:'普通',id:2},
|
||||
],
|
||||
tableData:[
|
||||
{name:'告警一',gjdj:'等级一',gjnr:'设备一温度过高',startTime:'2025/06/20 18:09:40',finishTime:'2025/06/20 20:07:01',status:1},
|
||||
{name:'告警二',gjdj:'等级一',gjnr:'设备二温度过高',startTime:'2025/06/20 18:09:40',finishTime:'2025/06/20 20:07:01',status:2},
|
||||
{name:'告警三',gjdj:'等级一',gjnr:'设备一温度过高',startTime:'2025/06/20 18:09:40',finishTime:'2025/06/20 20:07:01',status:1},
|
||||
{name:'告警四',gjdj:'等级一',gjnr:'设备二温度过高',startTime:'2025/06/20 18:09:40',finishTime:'2025/06/20 20:07:01',status:2}
|
||||
]
|
||||
search:{deviceId:'',alarmLevel:''},
|
||||
// 表格、分页
|
||||
tableData:[],
|
||||
pageSize:10,//分页栏当前每个数据总数
|
||||
pageNum:1,//分页栏当前页数
|
||||
totalSize:0,//table表格数据总数
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
formatDate,
|
||||
toTicket(){
|
||||
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) {
|
||||
const date1 = new Date(day1),date2 = new Date(day2)
|
||||
return date1.getFullYear() === date2.getFullYear() &&
|
||||
date1.getMonth() === date2.getMonth() &&
|
||||
date1.getDate() === date2.getDate();
|
||||
},
|
||||
// 分页
|
||||
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.search.dcd=''
|
||||
this.search.dcc=''
|
||||
this.search={deviceId:'',alarmLevel:''}
|
||||
this.dateRange=[]
|
||||
this.pageNum =1//每次搜索从1开始搜索
|
||||
this.getData()
|
||||
},
|
||||
// 获取数据
|
||||
getData(){
|
||||
this.loading=false
|
||||
},
|
||||
// 切换今日、历史告警
|
||||
changeDataType(id){
|
||||
if(id !== this.activeBtn){
|
||||
console.log('点击了不同的菜单,更新数据')
|
||||
this.activeBtn=id;
|
||||
this.getData()
|
||||
}
|
||||
},
|
||||
|
||||
// 获取数据
|
||||
getData(){
|
||||
this.$store.dispatch('getSiteAlarmNum',this.siteId)
|
||||
this.loading=true
|
||||
const {deviceId,alarmLevel} = this.search
|
||||
const {siteId,pageNum,pageSize,activeBtn} =this
|
||||
const [alarmStartTime='',alarmEndTime='']=(this.dateRange || [])
|
||||
let status = activeBtn === 'today' ? '0' : '1,2'
|
||||
getAlarmDetailList({status,deviceId,alarmLevel,siteId,pageSize,pageNum,alarmStartTime:formatDate(alarmStartTime),alarmEndTime:formatDate(alarmEndTime)}).then(response => {
|
||||
this.tableData=response?.rows || [];
|
||||
this.totalSize = response?.total || 0
|
||||
}).finally(() => {this.loading=false})
|
||||
},
|
||||
getDeviceOptions(){
|
||||
getDeviceList(this.siteId).then(response => {
|
||||
this.deviceOptions = JSON.parse(JSON.stringify(response?.data || []))
|
||||
})
|
||||
},
|
||||
init(){
|
||||
this.getDeviceOptions()
|
||||
this.onReset()
|
||||
},
|
||||
},
|
||||
mounted(){
|
||||
this.getData()
|
||||
const now = new Date();
|
||||
const lastMonth = new Date(now.getFullYear(), now.getMonth() - 1, 1);
|
||||
this.defaultDateRange = [lastMonth, now];
|
||||
// this.dateRange = [lastMonth, now];
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.select-container{
|
||||
.el-form--inline .el-form-item{
|
||||
margin-right: 20px;
|
||||
}
|
||||
}
|
||||
.activeBtn{
|
||||
background-color: #FFF2CB;
|
||||
border-color: #FFF2CB;
|
||||
color: #666666;
|
||||
font-weight: 600;
|
||||
}
|
||||
</style>
|
||||
|
||||
127
src/views/ems/dzjk/home/ActiveChart.vue
Normal file
@ -0,0 +1,127 @@
|
||||
<template>
|
||||
<el-card shadow="always" class="common-card-container common-card-container-body-no-padding time-range-card">
|
||||
<div slot="header" class="time-range-header">
|
||||
<span class="card-title">当日功率曲线</span>
|
||||
<date-range-select ref="dateRangeSelect" :showIcon="true" :mini-time-picker="true" @updateDate="updateDate"/>
|
||||
</div>
|
||||
<div style="height: 310px" id="activeChart"></div>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as echarts from 'echarts'
|
||||
import resize from '@/mixins/ems/resize'
|
||||
import DateRangeSelect from '@/components/Ems/DateRangeSelect/index.vue'
|
||||
import {getPointData} from '@/api/ems/dzjk'
|
||||
import intervalUpdate from "@/mixins/ems/intervalUpdate";
|
||||
|
||||
export default {
|
||||
mixins: [resize, intervalUpdate],
|
||||
components: {DateRangeSelect},
|
||||
data() {
|
||||
return {
|
||||
chart: null,
|
||||
timeRange: [],
|
||||
siteId: '',
|
||||
isInit: true
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.$nextTick(() => {
|
||||
this.initChart()
|
||||
})
|
||||
},
|
||||
beforeDestroy() {
|
||||
if (!this.chart) {
|
||||
return
|
||||
}
|
||||
this.chart.dispose()
|
||||
this.chart = null
|
||||
},
|
||||
methods: {
|
||||
// 更新时间范围 重置图表
|
||||
updateDate(data) {
|
||||
this.timeRange = data
|
||||
!this.isInit && this.getGVQXData()
|
||||
this.isInit = false
|
||||
},
|
||||
getGVQXData() {
|
||||
this.showLoading()
|
||||
const {siteId, timeRange} = this
|
||||
getPointData({siteId, startDate: timeRange[0], endDate: timeRange[1]}).then(response => {
|
||||
this.setOption(response?.data || [])
|
||||
}).finally(() => this.hideLoading())
|
||||
},
|
||||
init(siteId) {
|
||||
//初始化 清空数据
|
||||
this.siteId = siteId
|
||||
this.isInit = true
|
||||
this.timeRange = []
|
||||
this.$refs.dateRangeSelect.init(true)
|
||||
this.getGVQXData()
|
||||
this.updateInterval(this.getGVQXData)
|
||||
},
|
||||
initChart() {
|
||||
this.chart = echarts.init(document.querySelector('#activeChart'))
|
||||
},
|
||||
showLoading() {
|
||||
this.chart && this.chart.showLoading()
|
||||
},
|
||||
hideLoading() {
|
||||
this.chart && this.chart.hideLoading()
|
||||
},
|
||||
setOption(data) {
|
||||
const source = [['日期', '电网功率', '负载功率', '储能功率', '光伏功率', 'soc平均值', 'soh平均值', '电池平均温度平均值']]
|
||||
console.log('source.slice(1)', source[0].slice(1))
|
||||
this.chart && data.forEach((item) => {
|
||||
source.push([item.statisDate, item.gridPower, item.loadPower, item.storagePower, item.pvPower, item.avgSoc, item.avgSoh, item.avgTemp])
|
||||
})
|
||||
this.chart.setOption({
|
||||
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',
|
||||
},
|
||||
{
|
||||
type: 'value',
|
||||
},
|
||||
],
|
||||
dataset: {source},
|
||||
series: source[0].slice(1).map((item, index) => {
|
||||
return {
|
||||
type: 'line',//index === 5 ? 'bar' : 'line',
|
||||
showSymbol: false,
|
||||
symbolSize: 2,
|
||||
smooth: true,
|
||||
areaStyle: {
|
||||
opacity: 0.5,
|
||||
},
|
||||
yAxisIndex: index <= 4 ? 0 : 1
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
86
src/views/ems/dzjk/home/AlarmTable.vue
Normal file
@ -0,0 +1,86 @@
|
||||
<template>
|
||||
<!-- <el-card shadow="always" class="common-card-container common-card-container-body-no-padding">
|
||||
<div slot="header">
|
||||
<span class="card-title">当前报警</span>
|
||||
</div>
|
||||
<div class="ssgj-container">
|
||||
<el-table
|
||||
class="common-table"
|
||||
:data="tableData"
|
||||
height="100%"
|
||||
stripe
|
||||
style="width: 100%">
|
||||
<el-table-column
|
||||
prop="deviceName"
|
||||
label="名称">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="状态"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span :class="{'circle warning-status' : scope.row.status !== 0}">{{ $store.state.ems.warnOptions[scope.row.status]}}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
class-name="alarm-content"
|
||||
prop="alarmContent"
|
||||
show-overflow-tooltip
|
||||
label="告警内容">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="工单"
|
||||
fixed="right"
|
||||
show-overflow-tooltip
|
||||
>
|
||||
<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="primary" size="mini" v-else @click="toTicket">生成工单</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</el-card> -->
|
||||
<el-alert type="error" :closable="false">
|
||||
<template>
|
||||
<div style="cursor: pointer" @click="toAlarm">设备告警</div>
|
||||
</template>
|
||||
</el-alert>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
tableData: {
|
||||
require: true,
|
||||
type: Array,
|
||||
default: () => {
|
||||
return [];
|
||||
},
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {};
|
||||
},
|
||||
methods: {
|
||||
toAlarm() {
|
||||
this.$router.push({ path: "/dzjk/gzgj", query: this.$route.query });
|
||||
},
|
||||
toTicket() {
|
||||
this.$router.push({ path: "/ticket" });
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
//实时告警
|
||||
.ssgj-container {
|
||||
padding: 20px;
|
||||
height: 250px;
|
||||
box-sizing: border-box;
|
||||
::v-deep {
|
||||
.el-table .el-table__header-wrapper th,
|
||||
.el-table .el-table__fixed-header-wrapper th {
|
||||
background: #fff2cb;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
82
src/views/ems/dzjk/home/ClInfo.vue
Normal file
@ -0,0 +1,82 @@
|
||||
<template>
|
||||
<el-card
|
||||
shadow="always"
|
||||
class="common-card-container common-card-container-body-no-padding"
|
||||
>
|
||||
<div slot="header">
|
||||
<span class="card-title">策略信息</span>
|
||||
</div>
|
||||
<!-- <el-empty :image-size="100" ></el-empty> -->
|
||||
<div
|
||||
style="
|
||||
box-sizing: border-box;
|
||||
height: 250px;
|
||||
padding: 20px 15px;
|
||||
overflow-y: auto;
|
||||
"
|
||||
>
|
||||
<el-descriptions class="home-normal-info" :column="2">
|
||||
<el-descriptions-item size="mini" label="模板名称">{{
|
||||
info.mainStrategyName || "-"
|
||||
}}</el-descriptions-item>
|
||||
<el-descriptions-item size="mini" label="SOC限制">{{
|
||||
mainInfo.sdcLimit === 1 ? "开" : mainInfo.sdcLimit === 0 ? "关" : "-"
|
||||
}}</el-descriptions-item>
|
||||
<el-descriptions-item size="mini" label="SOC下限(%)">{{
|
||||
formatNumber(mainInfo.sdcDown)
|
||||
}}</el-descriptions-item>
|
||||
<el-descriptions-item size="mini" label="SOC上限(%)">{{
|
||||
formatNumber(mainInfo.sdcUp)
|
||||
}}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
<el-table
|
||||
:data="info.siteMonitorDataVo || []"
|
||||
border
|
||||
size="mini"
|
||||
style="width: 100%; margin-top: 15px"
|
||||
>
|
||||
<el-table-column prop="startTime" label="开始时间"> </el-table-column>
|
||||
<el-table-column prop="endTime" label="结束时间"> </el-table-column>
|
||||
<el-table-column prop="chargeDischargePower" label="充放功率(kW)">
|
||||
</el-table-column>
|
||||
<el-table-column prop="chargeStatus" label="充电状态">
|
||||
<template slot-scope="scope">
|
||||
{{ chargeStatusOptions[scope.row.chargeStatus] }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</el-card>
|
||||
</template>
|
||||
<script>
|
||||
import { mapState } from "vuex";
|
||||
import { formatNumber } from "@/filters/ems";
|
||||
export default {
|
||||
props: {
|
||||
info: {
|
||||
require: true,
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {};
|
||||
},
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
chargeStatusOptions: (state) => state?.ems?.chargeStatusOptions || {},
|
||||
}),
|
||||
mainInfo() {
|
||||
return this.info?.siteMonitorDataVo?.length > 0
|
||||
? this.info.siteMonitorDataVo[0]
|
||||
: {};
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {};
|
||||
},
|
||||
methods: {
|
||||
formatNumber,
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped></style>
|
||||
@ -1,147 +0,0 @@
|
||||
|
||||
<template>
|
||||
<el-row style="background:#fff;margin-top:30px;">
|
||||
<el-col :xs="24" :sm="24" :lg="24">
|
||||
<el-card shadow="always" class="common-card-container common-card-container-body-no-padding">
|
||||
<div slot="header">
|
||||
<span class="card-title">能量流转</span>
|
||||
</div>
|
||||
<div style="height: 310px" id="nllzChart"></div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as echarts from 'echarts'
|
||||
import resize from '@/mixins/ems/resize'
|
||||
|
||||
export default {
|
||||
mixins: [resize],
|
||||
data() {
|
||||
return {
|
||||
chart: null
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.$nextTick(() => {
|
||||
this.initChart()
|
||||
})
|
||||
},
|
||||
beforeDestroy() {
|
||||
if (!this.chart) {
|
||||
return
|
||||
}
|
||||
this.chart.dispose()
|
||||
this.chart = null
|
||||
},
|
||||
methods: {
|
||||
initChart(data) {
|
||||
this.chart = echarts.init(document.querySelector('#nllzChart'))
|
||||
},
|
||||
setOption(data) {
|
||||
const {siteMonitorDataVo=[],gridNrtPower,loadNrtPower,energyStorageNrtPower,energyStorageAvailElec} = data
|
||||
const source = [['日期','充电量','放电量']]
|
||||
siteMonitorDataVo.forEach(item=>{
|
||||
source.push([item.ammeterDate, item.chargedCap,item.disChargedCap])
|
||||
})
|
||||
const filterValue=(num)=>{return num || num === 0 ? num : '-'}
|
||||
this.chart.setOption({
|
||||
title: [
|
||||
// 右上角
|
||||
{
|
||||
text: `电网 实时功率:${filterValue(gridNrtPower)} kW`,
|
||||
top: 10,
|
||||
right: 10,
|
||||
textStyle:{
|
||||
fontSize:12,
|
||||
color:'#666666'
|
||||
}
|
||||
},
|
||||
// 右下角
|
||||
{
|
||||
text: `负载 实时功率:${filterValue(loadNrtPower)} kW`,
|
||||
bottom: 10,
|
||||
right: 10,
|
||||
textStyle:{
|
||||
fontSize:12,
|
||||
color:'#666666'
|
||||
}
|
||||
},
|
||||
// 左下角第一行
|
||||
{
|
||||
text: '储能',
|
||||
bottom: 40,
|
||||
left: 10,
|
||||
textStyle:{
|
||||
fontSize:12,
|
||||
color:'#666666'
|
||||
}
|
||||
},
|
||||
// 左下角第二行
|
||||
{
|
||||
text: `实时功率:${filterValue(energyStorageNrtPower)} kW`,
|
||||
bottom: 26,
|
||||
left: 10,
|
||||
textStyle:{
|
||||
fontSize:12,
|
||||
color:'#666666'
|
||||
}
|
||||
},
|
||||
// 左下角第三行
|
||||
{
|
||||
text: `可用电量:${filterValue(energyStorageAvailElec)} kWh`,
|
||||
bottom: 10,
|
||||
left: 10,
|
||||
textStyle:{
|
||||
fontSize:12,
|
||||
color:'#666666'
|
||||
}
|
||||
}
|
||||
],
|
||||
grid:{
|
||||
left:200
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: { // 坐标轴指示器,坐标轴触发有效
|
||||
type: 'shadow' // 默认为直线,可选为:'line' | 'shadow'
|
||||
}
|
||||
},
|
||||
textStyle:{
|
||||
color:"#333333",
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
axisLine: {
|
||||
lineStyle:{
|
||||
color: '#333333',
|
||||
}
|
||||
}
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
axisLine: {
|
||||
lineStyle:{
|
||||
color: '#333333',
|
||||
}
|
||||
}
|
||||
},
|
||||
dataset:{
|
||||
source
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name:'充电量',
|
||||
type: 'line',
|
||||
},{
|
||||
name:'放电量',
|
||||
type: 'line',
|
||||
}]
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
120
src/views/ems/dzjk/home/WeekChart.vue
Normal file
@ -0,0 +1,120 @@
|
||||
<template>
|
||||
<el-card shadow="always" class="common-card-container common-card-container-body-no-padding time-range-card">
|
||||
<div slot="header" class="time-range-header">
|
||||
<span class="card-title">一周充放曲线</span>
|
||||
<date-range-select ref="dateRangeSelect" :showIcon="true" :mini-time-picker="true" @updateDate="updateDate"/>
|
||||
</div>
|
||||
<div style="height: 310px" id="weekChart"></div>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as echarts from 'echarts'
|
||||
import resize from '@/mixins/ems/resize'
|
||||
import DateRangeSelect from '@/components/Ems/DateRangeSelect/index.vue'
|
||||
import {getSevenChargeData} from '@/api/ems/dzjk'
|
||||
|
||||
export default {
|
||||
mixins: [resize],
|
||||
components: {DateRangeSelect},
|
||||
data() {
|
||||
return {
|
||||
chart: null,
|
||||
timeRange: [],
|
||||
siteId: '',
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.$nextTick(() => {
|
||||
this.initChart()
|
||||
})
|
||||
},
|
||||
beforeDestroy() {
|
||||
if (!this.chart) {
|
||||
return
|
||||
}
|
||||
this.chart.dispose()
|
||||
this.chart = null
|
||||
},
|
||||
methods: {
|
||||
// 更新时间范围 重置图表
|
||||
updateDate(data) {
|
||||
this.timeRange = data
|
||||
this.getWeekKData()
|
||||
},
|
||||
getWeekKData() {
|
||||
this.showLoading()
|
||||
const {siteId, timeRange} = this
|
||||
getSevenChargeData({siteId, startDate: timeRange[0], endDate: timeRange[1]}).then(response => {
|
||||
this.setOption(response?.data || [])
|
||||
}).finally(() => this.hideLoading())
|
||||
},
|
||||
init(siteId) {
|
||||
//初始化 清空数据
|
||||
this.siteId = siteId
|
||||
this.timeRange = []
|
||||
this.deviceId = ''
|
||||
this.$refs.dateRangeSelect.init()
|
||||
},
|
||||
initChart() {
|
||||
this.chart = echarts.init(document.querySelector('#weekChart'))
|
||||
},
|
||||
showLoading() {
|
||||
this.chart && this.chart.showLoading()
|
||||
},
|
||||
hideLoading() {
|
||||
this.chart && this.chart.hideLoading()
|
||||
},
|
||||
setOption(data, unit) {
|
||||
const source = [['日期', '充电量', '放电量']]
|
||||
data.forEach(item => {
|
||||
source.push([item.ammeterDate, item.chargedCap, item.disChargedCap])
|
||||
})
|
||||
this.chart && this.chart.setOption({
|
||||
color: ['#4472c4', '#70ad47'],//所有充放电颜色保持统一
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: { // 坐标轴指示器,坐标轴触发有效
|
||||
type: 'shadow' // 默认为直线,可选为:'line' | 'shadow'
|
||||
}
|
||||
},
|
||||
grid: {
|
||||
containLabel: true
|
||||
},
|
||||
legend: {
|
||||
left: 'center',
|
||||
bottom: '15',
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
name: unit,
|
||||
nameLocation: 'center'
|
||||
},
|
||||
yAxis: [{
|
||||
type: 'value',
|
||||
name: '充电量/放电量kWh',
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: '#333333',
|
||||
},
|
||||
onZero: false
|
||||
}
|
||||
}],
|
||||
dataset: {
|
||||
source
|
||||
},
|
||||
series: [
|
||||
{
|
||||
yAxisIndex: 0,
|
||||
type: 'bar',
|
||||
},
|
||||
{
|
||||
yAxisIndex: 0,
|
||||
type: 'bar',
|
||||
},
|
||||
]
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@ -1,143 +1,339 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-row :gutter="32" style="background:#fff;">
|
||||
<el-col :xs="24" :sm="24" :lg="10">
|
||||
<el-card shadow="always" class="common-card-container common-card-container-body-no-padding">
|
||||
<div v-loading="loading">
|
||||
<el-row style="background: #fff" class="row-container" :gutter="15">
|
||||
<el-col :xs="24" :sm="24" :lg="5">
|
||||
<!-- 站点信息-->
|
||||
<el-card
|
||||
shadow="always"
|
||||
class="common-card-container common-card-container-body-no-padding"
|
||||
>
|
||||
<div slot="header">
|
||||
<span class="card-title">数据概览</span>
|
||||
<span class="card-title">站点信息</span>
|
||||
<div class="alarm-msg" v-if="tableData.length > 0" @click="toAlarm">
|
||||
<i class="el-icon-message-solid"></i> 设备告警
|
||||
</div>
|
||||
</div>
|
||||
<div style="height: 310px" >
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12" v-for="(item,index) in sjglData" :key="index+'sjglData'" class="sjgl-data">
|
||||
<div class="sjgl-title">{{item.title}}</div>
|
||||
<div class="sjgl-value">{{item.value}}</div>
|
||||
<div
|
||||
style="box-sizing: border-box; height: 218px; padding: 20px 15px"
|
||||
>
|
||||
<!-- 地址、运行时间-->
|
||||
<div class="site-info site-info-address">
|
||||
<div class="title">
|
||||
<i class="el-icon-location"></i>
|
||||
</div>
|
||||
<div class="value">{{ info.siteAddress }}</div>
|
||||
</div>
|
||||
<div class="site-info">
|
||||
<div class="title">
|
||||
<i class="el-icon-date"></i>
|
||||
</div>
|
||||
<div class="value">{{ info.runningTime || '-' }}</div>
|
||||
</div>
|
||||
<!-- 装机功率、容量 -->
|
||||
<el-row :gutter="10" style="margin-top:20px;">
|
||||
<el-col
|
||||
:span="12"
|
||||
class="sjgl-col power-col"
|
||||
>
|
||||
<div class="sjgl-wrapper">
|
||||
<div class="sjgl-title">装机功率(MW)</div>
|
||||
<div class="sjgl-value">
|
||||
{{ info.installPower | formatNumber }}
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col
|
||||
:span="12"
|
||||
class="sjgl-col power-col"
|
||||
>
|
||||
<div class="sjgl-wrapper">
|
||||
<div class="sjgl-title">装机容量(MW)</div>
|
||||
<div class="sjgl-value">
|
||||
{{ info.installCapacity | formatNumber }}
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="24" :lg="14">
|
||||
<el-card shadow="always" class="common-card-container common-card-container-body-no-padding">
|
||||
<!-- 总累计运行数据-->
|
||||
<el-col :xs="24" :sm="24" :lg="19">
|
||||
<el-card
|
||||
shadow="always"
|
||||
class="common-card-container common-card-container-body-no-padding"
|
||||
>
|
||||
<div slot="header">
|
||||
<span class="card-title">实时告警</span>
|
||||
<!-- <el-button style="float: right; padding: 3px 0" type="text" size="small">通讯状态:<span style="color:red">超时</span></el-button>-->
|
||||
<span class="card-title">总累计运行数据</span>
|
||||
<div class="total-count">
|
||||
<span class="title">总收入</span>
|
||||
<span class="value">{{ runningInfo.totalRevenue | formatNumber }}</span>
|
||||
<span class="unit">元</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ssgj-container">
|
||||
<el-table
|
||||
class="common-table"
|
||||
:data="tableData"
|
||||
height="100%"
|
||||
stripe
|
||||
style="width: 100%">
|
||||
<el-table-column
|
||||
prop="deviceName"
|
||||
label="名称">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="状态"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span class="warning-status circle">{{ scope.row.status === 0 ? '中断':'todo不是0是什么告警'}}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
class-name="alarm-content"
|
||||
prop="alarmContent"
|
||||
label="告警内容">
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div
|
||||
style="box-sizing: border-box; height: 218px; padding: 20px 15px"
|
||||
>
|
||||
<el-row :gutter="10">
|
||||
<el-col
|
||||
:span="6"
|
||||
v-for="(item, index) in sjglData"
|
||||
:key="index + 'sjglData'"
|
||||
class="sjgl-col"
|
||||
>
|
||||
<div class="sjgl-wrapper">
|
||||
<div class="sjgl-title">{{ item.title }}</div>
|
||||
<div class="sjgl-value" :style="{color:item.color}">
|
||||
{{ runningInfo[item.attr] | formatNumber }}
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="24" :lg="12">
|
||||
<week-chart ref="weekChart"/>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="24" :lg="12">
|
||||
<active-chart ref="activeChart"/>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<nllz-chart ref="nllzChart"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {getDzjkHomeView} from '@/api/ems/dzjk'
|
||||
import NllzChart from "./NllzChart.vue";
|
||||
import {getSingleSiteBaseInfo} from "@/api/ems/zddt";
|
||||
import {getDzjkHomeView} from "@/api/ems/dzjk";
|
||||
import WeekChart from "./WeekChart.vue";
|
||||
import ActiveChart from "./ActiveChart.vue";
|
||||
import AlarmTable from "./AlarmTable.vue";
|
||||
import ClInfo from "./ClInfo.vue";
|
||||
import getQuerySiteId from "@/mixins/ems/getQuerySiteId";
|
||||
import intervalUpdate from "@/mixins/ems/intervalUpdate";
|
||||
|
||||
export default {
|
||||
components: {NllzChart},
|
||||
watch: {
|
||||
'$route.query':{
|
||||
handler (newQuery,oldQuery) {
|
||||
// 参数变化处理
|
||||
console.log('单站监控=>首页=>页面地址发生变化',newQuery,oldQuery)
|
||||
this.$nextTick(() => {
|
||||
const {siteId} =newQuery
|
||||
siteId && this.getData(newQuery.siteId)
|
||||
})
|
||||
},
|
||||
immediate: true,
|
||||
}
|
||||
},
|
||||
name: "DzjkSbjkHome",
|
||||
components: {WeekChart, ActiveChart, AlarmTable, ClInfo},
|
||||
mixins: [getQuerySiteId, intervalUpdate],
|
||||
data() {
|
||||
return {
|
||||
sjglData:[{
|
||||
title:'今日充电量(MWh)',
|
||||
value:'',
|
||||
attr:'dayChargedCap'
|
||||
},{
|
||||
title:'今日放电量(MWh)',
|
||||
value:'',
|
||||
attr:'dayDisChargedCap'
|
||||
},{
|
||||
title:'总充电量(MWh)',
|
||||
value:'',
|
||||
attr:'totalChargedCap'
|
||||
},{
|
||||
title:'总放电量(MWh)',
|
||||
value:'',
|
||||
attr:'totalDischargedCap'
|
||||
}],
|
||||
// todo 表格里的不同状态可能需要显示不同颜色 确定表格内容
|
||||
tableData:[]
|
||||
}
|
||||
loading: false,
|
||||
sjglData: [
|
||||
{
|
||||
title: "今日充电量(kWh)",
|
||||
attr: "dayChargedCap",
|
||||
color: '#4472c4'
|
||||
},
|
||||
{
|
||||
title: "今日放电量(kWh)",
|
||||
attr: "dayDisChargedCap",
|
||||
color: '#70ad47'
|
||||
},
|
||||
{
|
||||
title: "总充电量(kWh)",
|
||||
attr: "totalChargedCap",
|
||||
color: '#4472c4'
|
||||
},
|
||||
{
|
||||
title: "今日实时收入(元)",
|
||||
attr: "dayRevenue",
|
||||
color: '#f67438'
|
||||
},
|
||||
{
|
||||
title: "昨日充电量(kWh)",
|
||||
attr: "yesterdayChargedCap",
|
||||
color: '#4472c4'
|
||||
},
|
||||
{
|
||||
title: "昨日放电量(kWh)",
|
||||
attr: "yesterdayDisChargedCap",
|
||||
color: '#70ad47'
|
||||
},
|
||||
{
|
||||
title: "总放电量(kWh)",
|
||||
attr: "totalDischargedCap",
|
||||
color: '#70ad47'
|
||||
},
|
||||
{
|
||||
title: "昨日实时收入(元)",
|
||||
attr: "yesterdayRevenue",
|
||||
color: '#f67438'
|
||||
},
|
||||
],
|
||||
info: {}, //基本信息
|
||||
runningInfo: {}, //总累计运行数据+报警表格
|
||||
};
|
||||
},
|
||||
methods:{
|
||||
getData(siteId){
|
||||
getDzjkHomeView(siteId).then(response => {
|
||||
const data = response.data || {}
|
||||
this.sjglData.forEach(item=>{
|
||||
item.value = (data[item.attr] || data[item.attr] === 0) ? data[item.attr] : '-'
|
||||
})
|
||||
this.tableData = data?.siteMonitorHomeAlarmVo || []
|
||||
this.$refs.nllzChart.setOption(data)
|
||||
})
|
||||
}
|
||||
computed: {
|
||||
tableData() {
|
||||
return this.runningInfo?.siteMonitorHomeAlarmVo || [];
|
||||
},
|
||||
},
|
||||
}
|
||||
methods: {
|
||||
toAlarm() {
|
||||
this.$router.push({path: "/dzjk/gzgj", query: this.$route.query});
|
||||
},
|
||||
getBaseInfo() {
|
||||
return getSingleSiteBaseInfo(this.siteId).then((response) => {
|
||||
this.info = response?.data || {};
|
||||
});
|
||||
},
|
||||
getRunningInfo() {
|
||||
return getDzjkHomeView(this.siteId).then((response) => {
|
||||
this.runningInfo = response?.data || {};
|
||||
});
|
||||
},
|
||||
init() {
|
||||
this.loading = true;
|
||||
// 功率曲线
|
||||
this.$refs.activeChart.init(this.siteId);
|
||||
// 一周冲放曲线
|
||||
this.$refs.weekChart.init(this.siteId);
|
||||
// 静态信息 this.getBaseInfo()
|
||||
// 总累计运行数据+故障告警 this.getRunningInfo()
|
||||
Promise.all([this.getBaseInfo(), this.getRunningInfo()]).finally(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
// 一分钟循环一次总累计运行数据
|
||||
this.updateInterval(this.getRunningInfo);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
//数据概览
|
||||
.sjgl-data{
|
||||
text-align: center;
|
||||
margin-top:20px;
|
||||
.sjgl-title{
|
||||
color: #666666;
|
||||
line-height: 14px;
|
||||
padding-top: 18px;
|
||||
}
|
||||
.sjgl-value{
|
||||
color: rgba(51,51,51,1);
|
||||
font-size: 26px;
|
||||
line-height: 26px;
|
||||
font-weight: 500;
|
||||
margin-top: 14px;
|
||||
}
|
||||
//设备告警
|
||||
.alarm-msg {
|
||||
background: #ff4949;
|
||||
padding: 2px 5px;
|
||||
font-size: 10px;
|
||||
font-weight: bolder;
|
||||
border-radius: 3px;
|
||||
line-height: 20px;
|
||||
cursor: pointer;
|
||||
color: #fff;
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
|
||||
//基本信息-地址 运行️时间
|
||||
.site-info {
|
||||
display: flex;
|
||||
font-size: 12px;
|
||||
line-height: 20px;
|
||||
margin-bottom: 10px;
|
||||
align-items: center;
|
||||
|
||||
&.site-info-address {
|
||||
height: 40px;
|
||||
}
|
||||
//实时告警
|
||||
.ssgj-container{
|
||||
padding:20px;
|
||||
height: 310px;
|
||||
box-sizing: border-box;
|
||||
::v-deep{
|
||||
.el-table .el-table__header-wrapper th, .el-table .el-table__fixed-header-wrapper th{
|
||||
background:#FFF2CB ;
|
||||
|
||||
.title {
|
||||
color: #1791ff;
|
||||
font-size: 18px;
|
||||
line-height: 20px;
|
||||
margin-right: 7px;
|
||||
}
|
||||
|
||||
.value {
|
||||
color: #000;
|
||||
font-size: 12px;
|
||||
max-height: 40px;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
//总收入
|
||||
.total-count {
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
font-size: 12px;
|
||||
font-weight: bolder;
|
||||
color: #333;
|
||||
line-height: 14px;
|
||||
|
||||
.unit {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.value {
|
||||
font-size: 22px;
|
||||
font-weight: bolder;
|
||||
color: #ed2f1d;
|
||||
font-style: italic;
|
||||
padding: 0 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.row-container {
|
||||
& > .el-col {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
//数据概览
|
||||
.sjgl-col {
|
||||
.sjgl-wrapper {
|
||||
text-align: left;
|
||||
padding: 15px 20px;
|
||||
background-color: #f2f7fb;
|
||||
}
|
||||
|
||||
&.power-col {
|
||||
.sjgl-wrapper {
|
||||
padding: 10px;
|
||||
|
||||
.sjgl-value {
|
||||
color: #c44444;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:nth-child(4),
|
||||
&:nth-child(2),
|
||||
&:nth-child(3),
|
||||
&:nth-child(4) {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.sjgl-title {
|
||||
color: #717171;
|
||||
line-height: 14px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.sjgl-value {
|
||||
color: rgba(51, 51, 51, 1);
|
||||
font-size: 22px;
|
||||
line-height: 26px;
|
||||
font-weight: bolder;
|
||||
font-style: italic;
|
||||
margin-top: 14px;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss">
|
||||
.home-normal-info {
|
||||
font-size: 12px;
|
||||
|
||||
.el-descriptions-item__container {
|
||||
.el-descriptions-item__label {
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
.el-descriptions-item__content {
|
||||
color: #333333;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -3,14 +3,20 @@
|
||||
<template>
|
||||
<div class="ems-dashboard-editor-container">
|
||||
<zd-select :get-list-by-store="true" :default-site-id="$route.query.siteId" @submitSite="submitSite"/>
|
||||
<!-- 这里是单站监控的二级菜单栏 需要循环拿到数据 显示在页面上-->
|
||||
<div class="router-container">
|
||||
<div class="route-link" :class="{'active':item.name === $route.meta.activeSecondMenuName}" v-for="(item,index) in childrenRoute" :key="index+'dzjkChildrenRoute'">
|
||||
<router-link style="height: 100%;width: 100%;display: block" :to="{path:item.path,query:$route.query}">
|
||||
{{item.meta.title}}
|
||||
<el-menu
|
||||
class="ems-second-menu"
|
||||
:default-active="$route.meta.activeSecondMenuName"
|
||||
background-color="#1890ff"
|
||||
text-color="#ffffff"
|
||||
active-text-color="#ffffff"
|
||||
mode="horizontal"
|
||||
>
|
||||
<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}">
|
||||
{{item.meta.title}}
|
||||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
</el-menu-item>
|
||||
</el-menu>
|
||||
<div class="ems-content-container ems-content-container-padding dzjk-ems-content-container">
|
||||
<keep-alive>
|
||||
<router-view></router-view>
|
||||
@ -24,6 +30,7 @@ import { dzjk } from '@/router/ems'
|
||||
const childrenRoute = dzjk[0].children[0].children//获取到单站监控下面的字路由
|
||||
console.log('childrenRoute',childrenRoute)
|
||||
import ZdSelect from '@/components/Ems/ZdSelect/index.vue'
|
||||
import {mapState} from "vuex";
|
||||
export default {
|
||||
components:{ZdSelect},
|
||||
data(){
|
||||
@ -32,14 +39,21 @@ export default {
|
||||
activeMenu:''
|
||||
}
|
||||
},
|
||||
computed:{
|
||||
...mapState({
|
||||
dzjkAlarmLighting:state=>state.ems.dzjkAlarmLighting
|
||||
})
|
||||
},
|
||||
methods:{
|
||||
submitSite(id){
|
||||
if(id != this.$route.query.siteId){
|
||||
console.log('单站监控选择了其他的站点id=',id,'并更新页面地址参数')
|
||||
if(id !== this.$route.query.siteId){
|
||||
// console.log('单站监控选择了其他的站点id=',id,'并更新页面地址参数')
|
||||
this.$router.push({query:{...this.$route.query,siteId:id}})
|
||||
}else{
|
||||
console.log('单站监控选择了相同的其他的站点id=',id,'页面地址不发生改变')
|
||||
// console.log('单站监控选择了相同的其他的站点id=',id,'页面地址不发生改变')
|
||||
}
|
||||
//获取告警列表数据
|
||||
this.$store.dispatch('getSiteAlarmNum',id)
|
||||
}
|
||||
},
|
||||
beforeRouteLeave(to,from, next){
|
||||
@ -48,32 +62,27 @@ export default {
|
||||
this.$store.commit('SET_ZD_LIST',[])
|
||||
next()
|
||||
},
|
||||
mounted() {
|
||||
console.log('单站监控一级页面路由',this.$route)
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.router-container{
|
||||
display: flex;
|
||||
.route-link{
|
||||
width: 104px;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
background-color: #FFBE29 ;
|
||||
color: #666666;
|
||||
font-size: 14px;
|
||||
text-align: center;
|
||||
}
|
||||
.route-link.active{
|
||||
background-color: #ffffff;
|
||||
color: #333333;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
.dzjk-ems-content-container{
|
||||
margin-top:0;
|
||||
min-height: 60vh;
|
||||
}
|
||||
.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>
|
||||
|
||||
420
src/views/ems/dzjk/sbjk/PointChart.vue
Normal file
@ -0,0 +1,420 @@
|
||||
<!--电位展示图表-->
|
||||
<template>
|
||||
<el-dialog
|
||||
:visible.sync="show"
|
||||
:title="pointName"
|
||||
:close-on-click-modal="false"
|
||||
show-close
|
||||
destroy-on-close
|
||||
lock-scroll
|
||||
append-to-body
|
||||
width="1000px"
|
||||
class="ems-dialog"
|
||||
:before-close="handleClosed"
|
||||
>
|
||||
<el-card
|
||||
shadow="always"
|
||||
class="common-card-container common-card-container-body-no-padding time-range-card"
|
||||
>
|
||||
<div slot="header" class="time-range-header">
|
||||
<el-radio-group class="card-title" v-model="dataUnit">
|
||||
<el-radio :label="1">分钟</el-radio>
|
||||
<el-radio :label="2">小时</el-radio>
|
||||
<el-radio :label="3">天</el-radio>
|
||||
</el-radio-group>
|
||||
<date-time-select
|
||||
ref="dateTimeSelect"
|
||||
:data-unit="dataUnit"
|
||||
@initDate="(e) => (dataRange = e || [])"
|
||||
@updateDate="updateDate"
|
||||
/>
|
||||
</div>
|
||||
<div style="height: 350px" id="searchChart"></div>
|
||||
</el-card>
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script>
|
||||
import * as echarts from "echarts";
|
||||
import resize from "@/mixins/ems/resize";
|
||||
import DateTimeSelect from "@/views/ems/search/DateTimeSelect.vue";
|
||||
import {getPointValueList} from "@/api/ems/search";
|
||||
import DateRangeSelect from "@/components/Ems/DateRangeSelect/index.vue";
|
||||
|
||||
export default {
|
||||
components: {DateRangeSelect, DateTimeSelect},
|
||||
mixins: [resize],
|
||||
props: {
|
||||
siteId: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
isDtdc() {
|
||||
return this.deviceCategory === "BATTERY";
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
show(val) {
|
||||
if (!val) {
|
||||
this.pointName = "";
|
||||
this.deviceCategory = "";
|
||||
this.deviceId = "";
|
||||
this.dataUnit = 1;
|
||||
this.child = "";
|
||||
if (!this.chart) {
|
||||
return;
|
||||
}
|
||||
this.hideLoading();
|
||||
this.chart.dispose();
|
||||
this.chart = null;
|
||||
}
|
||||
},
|
||||
dataUnit: {
|
||||
handler(newVal, oldVal) {
|
||||
if (!this.show) return;
|
||||
console.log("wacth到了dataUnit的变化", newVal, oldVal);
|
||||
this.$nextTick(() => {
|
||||
this.$refs.dateTimeSelect.init();
|
||||
this.getDate();
|
||||
});
|
||||
},
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
show: false,
|
||||
chart: null,
|
||||
dataUnit: 1,
|
||||
dataRange: [],
|
||||
child: "", //单体电池需要数据
|
||||
pointName: "",
|
||||
deviceCategory: "",
|
||||
deviceId: "",
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
showChart({pointName, deviceCategory, deviceId, child = ""}) {
|
||||
//初始化数据
|
||||
this.pointName = pointName;
|
||||
this.deviceCategory = deviceCategory;
|
||||
this.deviceId = deviceId;
|
||||
child && (this.child = child);
|
||||
this.show = true;
|
||||
this.$nextTick(() => {
|
||||
this.$refs.dateTimeSelect.init();
|
||||
this.initChart();
|
||||
this.getDate();
|
||||
});
|
||||
},
|
||||
initChart() {
|
||||
this.chart = echarts.init(document.querySelector("#searchChart"));
|
||||
},
|
||||
showLoading() {
|
||||
this.chart && this.chart.showLoading();
|
||||
},
|
||||
hideLoading() {
|
||||
this.chart && this.chart.hideLoading();
|
||||
},
|
||||
getDate() {
|
||||
this.showLoading();
|
||||
const {
|
||||
siteId,
|
||||
dataUnit,
|
||||
dataRange: [start = "", end = ""],
|
||||
child,
|
||||
deviceId,
|
||||
deviceCategory,
|
||||
pointName,
|
||||
} = this;
|
||||
let siteDeviceMap = {};
|
||||
child && (siteDeviceMap[siteId] = child);
|
||||
let startDate, endDate;
|
||||
if (start && dataUnit === 3) {
|
||||
// startDate= start + `${dataUnit === 2 ? ':00' : ' 00:00:00'}`
|
||||
startDate = start + " 00:00:00";
|
||||
} else {
|
||||
startDate = start;
|
||||
}
|
||||
if (end && dataUnit === 3) {
|
||||
// endDate= end + `${dataUnit === 2 ? ':00' : ' 00:00:00'}`
|
||||
endDate = end + " 00:00:00";
|
||||
} else {
|
||||
endDate = end;
|
||||
}
|
||||
|
||||
getPointValueList({
|
||||
siteIds: [siteId],
|
||||
deviceId,
|
||||
dataUnit,
|
||||
deviceCategory,
|
||||
pointName,
|
||||
startDate,
|
||||
endDate,
|
||||
siteDeviceMap,
|
||||
})
|
||||
.then((response) => {
|
||||
this.setOption(response?.data || []);
|
||||
})
|
||||
.finally(() => {
|
||||
this.hideLoading();
|
||||
});
|
||||
},
|
||||
setOption(data) {
|
||||
if (!this.chart) return;
|
||||
this.chart.clear();
|
||||
console.log("返回的数据", data);
|
||||
if (!data || data.length <= 0) {
|
||||
this.$message.warning("暂无数据");
|
||||
}
|
||||
console.log('展示的图表类型chartType', data[0].chartType)
|
||||
|
||||
if (data[0].chartType === 2) {
|
||||
// 箱型图
|
||||
this.setBoxOption(data)
|
||||
} else {
|
||||
//折线图
|
||||
this.setLineOption(data)
|
||||
}
|
||||
},
|
||||
setLineOption(data) {
|
||||
let dataset = [];
|
||||
data.forEach((item, index) => {
|
||||
item.deviceList.forEach((inner) => {
|
||||
dataset.push({
|
||||
name: `${
|
||||
this.isDtdc
|
||||
? `${inner.parentDeviceId ? inner.parentDeviceId + "-" : ""}${inner.deviceId}`
|
||||
: `${inner.deviceId}`
|
||||
}`,
|
||||
type: "line",
|
||||
markPoint: {
|
||||
symbolSize: 30,
|
||||
emphasis: {
|
||||
disabled: false//打开 鼠标高亮
|
||||
},
|
||||
data: [//最大值、最小值
|
||||
{
|
||||
// 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);
|
||||
});
|
||||
});
|
||||
});
|
||||
console.log("折线图图表数据", dataset);
|
||||
this.chart.setOption({
|
||||
legend: {
|
||||
// left: 'center',
|
||||
// top: '10',
|
||||
},
|
||||
grid: {
|
||||
containLabel: true,
|
||||
},
|
||||
tooltip: {
|
||||
trigger: "axis",
|
||||
axisPointer: {
|
||||
type: 'cross',
|
||||
},
|
||||
// axisPointer: {
|
||||
// // 坐标轴指示器,坐标轴触发有效
|
||||
// type: "shadow", // 默认为直线,可选为:'line' | 'shadow'
|
||||
// },
|
||||
},
|
||||
textStyle: {
|
||||
color: "#333333",
|
||||
},
|
||||
xAxis: {type: "category", data: dataset?.[0]?.xdata || []},
|
||||
yAxis: {
|
||||
type: "value",
|
||||
},
|
||||
dataZoom: [
|
||||
{
|
||||
type: "inside",
|
||||
start: 0,
|
||||
end: 100,
|
||||
},
|
||||
{
|
||||
start: 0,
|
||||
end: 100,
|
||||
},
|
||||
],
|
||||
series: dataset,
|
||||
});
|
||||
},
|
||||
setBoxOption(data) {
|
||||
let dataset = [];
|
||||
data.forEach((item, index) => {
|
||||
item.deviceList.forEach((inner) => {
|
||||
dataset.push({
|
||||
name: `${
|
||||
this.isDtdc
|
||||
? `${inner.parentDeviceId ? inner.parentDeviceId + "-" : ""}${inner.deviceId}`
|
||||
: `${inner.deviceId}`
|
||||
}`,
|
||||
type: "boxplot",
|
||||
// markPoint: {
|
||||
// symbolSize: 30,
|
||||
// emphasis: {
|
||||
// disabled: false//打开 鼠标高亮
|
||||
// },
|
||||
// data: [//最大值、最小值
|
||||
// {
|
||||
// // 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) => {
|
||||
const {valueDate, min, q1, median, q3, max} = value
|
||||
// const mid = (max - min) / 2, minLine = min + Math.abs(median / 2),
|
||||
// maxLine = max - Math.abs(median / 2)
|
||||
dataset[length - 1].xdata.push(valueDate);
|
||||
dataset[length - 1].data.push([min, q1, median, q3, max]);
|
||||
});
|
||||
});
|
||||
});
|
||||
console.log("箱型图图表数据", dataset);
|
||||
this.chart.setOption({
|
||||
legend: {
|
||||
// left: 'center',
|
||||
// top: '10',
|
||||
},
|
||||
grid: {
|
||||
containLabel: true,
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'item',
|
||||
formatter: function (params) {
|
||||
let data = params.data;
|
||||
let result = params.marker + params.name + ' ' + params.seriesName + '<br/>';
|
||||
result += '最小值: ' + data[1] + '<br/>';
|
||||
result += '平均值: ' + data[3] + '<br/>';
|
||||
result += '最大值: ' + data[5];
|
||||
return result;
|
||||
}
|
||||
// trigger: "axis",
|
||||
// axisPointer: {
|
||||
// type: 'cross',
|
||||
// },
|
||||
// axisPointer: {
|
||||
// // 坐标轴指示器,坐标轴触发有效
|
||||
// type: "shadow", // 默认为直线,可选为:'line' | 'shadow'
|
||||
// },
|
||||
},
|
||||
textStyle: {
|
||||
color: "#333333",
|
||||
},
|
||||
xAxis: {type: "category", data: dataset?.[0]?.xdata || []},
|
||||
yAxis: {
|
||||
type: "value",
|
||||
},
|
||||
dataZoom: [
|
||||
{
|
||||
type: "inside",
|
||||
start: 0,
|
||||
end: 100,
|
||||
},
|
||||
{
|
||||
start: 0,
|
||||
end: 100,
|
||||
},
|
||||
],
|
||||
series: dataset,
|
||||
});
|
||||
},
|
||||
|
||||
updateDate(val) {
|
||||
this.dataRange = val || [];
|
||||
this.getDate();
|
||||
},
|
||||
handleClosed(done) {
|
||||
if (!this.chart) {
|
||||
return done();
|
||||
}
|
||||
this.chart.dispose();
|
||||
this.chart = null;
|
||||
done();
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
::v-deep {
|
||||
.card-title .el-radio {
|
||||
line-height: 40px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -2,8 +2,8 @@
|
||||
<template>
|
||||
<!-- 6个方块-->
|
||||
<el-row :gutter="10">
|
||||
<el-col :xs="12" :sm="8" :lg="4" class="single-square-box-container" v-for="(item,index) in singleZdSqaure" :key="index+'singleSquareBox'">
|
||||
<single-square-box :data="item"></single-square-box>
|
||||
<el-col :xs="12" :sm="8" :lg="4" style="margin-bottom: 10px;" class="single-square-box-container" v-for="(item,index) in singleZdSqaure" :key="index+'singleSquareBox'">
|
||||
<single-square-box :data="{...item,value:formatNumber(data[item.attr])}" ></single-square-box>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</template>
|
||||
@ -11,36 +11,50 @@
|
||||
|
||||
<script>
|
||||
import SingleSquareBox from "@/components/Ems/SingleSquareBox/index.vue";
|
||||
|
||||
import {formatNumber} from '@/filters/ems'
|
||||
export default {
|
||||
components:{SingleSquareBox},
|
||||
props:{
|
||||
data:{
|
||||
type:Object,
|
||||
required:false,
|
||||
default:()=>{return {}}
|
||||
},
|
||||
},
|
||||
methods:{formatNumber},
|
||||
data() {
|
||||
return {
|
||||
// 单个电站 四个方块数据
|
||||
singleZdSqaure:[{
|
||||
title:'实时有功功率(kW)',
|
||||
value:'22.74',
|
||||
bgColor:'#FFF2CB'
|
||||
value:'',
|
||||
bgColor:'#FFF2CB',
|
||||
attr:'totalActivePower'
|
||||
},{
|
||||
title:'实时无功功率(kVar)',
|
||||
value:'22.74',
|
||||
bgColor:'#CBD6FF'
|
||||
value:'',
|
||||
bgColor:'#CBD6FF',
|
||||
attr:'totalReactivePower'
|
||||
},{
|
||||
title:'电池催SOC',
|
||||
value:'22.74',
|
||||
bgColor:'#DCCBFF'
|
||||
title:'电池堆SOC',
|
||||
value:'',
|
||||
bgColor:'#DCCBFF',
|
||||
attr:'soc'
|
||||
},{
|
||||
title:'电池堆SOH',
|
||||
value:'22.74',
|
||||
bgColor:'#FFD4CB'
|
||||
value:'',
|
||||
bgColor:'#FFD4CB',
|
||||
attr:'soh'
|
||||
},{
|
||||
title:'今日充电量(kWh)',
|
||||
value:'22.74',
|
||||
bgColor:'#FFD6F8'
|
||||
value:'',
|
||||
bgColor:'#FFD6F8',
|
||||
attr:'dayChargedCap'
|
||||
},{
|
||||
title:'今日放电量(kWh)',
|
||||
value:'22.74',
|
||||
bgColor:'#E1FFCA'
|
||||
value:'',
|
||||
bgColor:'#E1FFCA',
|
||||
attr:'dayDisChargedCap'
|
||||
}]
|
||||
}
|
||||
},
|
||||
@ -50,5 +64,10 @@ export default {
|
||||
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
@media only screen and (min-width: 1200px) {
|
||||
.single-square-box-container {
|
||||
min-width: 16.6666666667%;
|
||||
width: fit-content;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -1,146 +1,235 @@
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<el-card shadow="always" class="common-card-container common-card-container-body-no-padding common-card-container-no-title-bg">
|
||||
<div slot="header">
|
||||
<span class="large-title">1#电池簇</span>
|
||||
</div>
|
||||
<div v-loading="loading">
|
||||
<div v-for="(baseInfo,index) in baseInfoList" :key="index+'bmsdccContainer'" style="margin-bottom:25px;">
|
||||
<el-card shadow="always"
|
||||
class="sbjk-card-container common-card-container-body-no-padding common-card-container-no-title-bg"
|
||||
:class="handleCardClass(baseInfo)">
|
||||
<div slot="header">
|
||||
<span
|
||||
class="large-title">{{
|
||||
baseInfo.parentDeviceName ? `${baseInfo.parentDeviceName} -> ` : ''
|
||||
}}{{ baseInfo.deviceName }}</span>
|
||||
<div class="info">
|
||||
<div>数据更新时间:{{ baseInfo.dataUpdateTime || '-' }}</div>
|
||||
</div>
|
||||
<div class="alarm">
|
||||
<el-button type="primary" round size="small" style="margin-right:20px;"
|
||||
@click="pointDetail(baseInfo,'point')">详细
|
||||
</el-button>
|
||||
<el-badge :hidden="!baseInfo.alarmNum" :value="baseInfo.alarmNum || 0" class="item">
|
||||
<i
|
||||
class="el-icon-message-solid alarm-icon"
|
||||
@click="pointDetail(baseInfo,'alarmPoint')"
|
||||
></i>
|
||||
</el-badge>
|
||||
</div>
|
||||
</div>
|
||||
<div class="descriptions-main">
|
||||
<el-descriptions direction="vertical" :column="3" :colon="false">
|
||||
<el-descriptions-item labelClassName="descriptions-label" contentClassName="descriptions-direction keep" :span="1" label="工作状态" >放电</el-descriptions-item>
|
||||
<el-descriptions-item labelClassName="descriptions-label" contentClassName="descriptions-direction" :span="1" label="与PCS通信">正常</el-descriptions-item>
|
||||
<el-descriptions-item labelClassName="descriptions-label" contentClassName="descriptions-direction" :span="1" label="与EMS通信">正常</el-descriptions-item>
|
||||
<el-descriptions-item
|
||||
contentClassName="descriptions-direction work-status"
|
||||
:span="1" label="工作状态">
|
||||
{{ CLUSTERWorkStatusOptions[baseInfo.workStatus] }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item contentClassName="descriptions-direction"
|
||||
:span="1" label="与PCS通信">
|
||||
{{ $store.state.ems.communicationStatusOptions[baseInfo.pcsCommunicationStatus] }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item contentClassName="descriptions-direction"
|
||||
:span="1" label="与EMS通信">
|
||||
{{ $store.state.ems.communicationStatusOptions[baseInfo.emsCommunicationStatus] }}
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</div>
|
||||
<div class="descriptions-main descriptions-main-bg-color">
|
||||
<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">{{item.value}} <span v-if="item.unit" v-html="item.unit"></span></el-descriptions-item>
|
||||
<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)">
|
||||
{{ baseInfo[item.attr] | formatNumber }} <span v-if="item.unit" v-html="item.unit"></span>
|
||||
</span>
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
<!-- 进度-->
|
||||
<div class="process-container">
|
||||
<div class="process-line-bg">
|
||||
<div class="process-line"></div>
|
||||
<div class="process-line" :style="{height:baseInfo.currentSoc+'%'}"></div>
|
||||
</div>
|
||||
<div class="process pointer" @click="showChart( '当前SOC',baseInfo.deviceId)">当前SOC :
|
||||
{{ baseInfo.currentSoc }}%
|
||||
</div>
|
||||
<div class="process">当前SOC : 25%</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
<el-table
|
||||
class="common-table"
|
||||
:data="tableData"
|
||||
stripe
|
||||
max-height="500"
|
||||
style="width: 100%;margin-top:25px;">
|
||||
<el-table-column
|
||||
prop="name"
|
||||
width="190"
|
||||
label="簇号">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="簇电压"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{scope.row.voltage}} V</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="簇电流">
|
||||
<template slot-scope="scope">
|
||||
<span>{{scope.row.electric}} A</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="簇SOC">
|
||||
<template slot-scope="scope">
|
||||
<span>{{scope.row.soc}} %</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="maxVoltage"
|
||||
label="单体最高电压">
|
||||
<template slot-scope="scope">
|
||||
<span>{{scope.row.maxVoltage}} V</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="minVoltage"
|
||||
label="单体最低电压">
|
||||
<template slot-scope="scope">
|
||||
<span>{{scope.row.minVoltage}} V</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="单体最高温度">
|
||||
<template slot-scope="scope">
|
||||
<span>{{scope.row.maxTemperature}} ℃</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="minTemperature"
|
||||
label="单体最低温度">
|
||||
<template slot-scope="scope">
|
||||
<span>{{scope.row.minTemperature}} ℃</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
</el-table>
|
||||
<el-table
|
||||
class="common-table"
|
||||
:data="baseInfo.batteryDataList"
|
||||
stripe
|
||||
style="width: 100%;margin-top:25px;">
|
||||
<el-table-column
|
||||
prop="dataName"
|
||||
label="名称">
|
||||
<template slot-scope="scope">
|
||||
<span v-html="scope.row.dataName+'('+unitObj[scope.row.dataName]+')'"></span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="avgData"
|
||||
label="单体平均值"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span class="pointer"
|
||||
@click="showChart( tablePointNameMap[scope.row.dataName+scope.column.label],baseInfo.deviceId)">{{
|
||||
scope.row.avgData
|
||||
}}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="minData"
|
||||
label="单体最小值">
|
||||
<template slot-scope="scope">
|
||||
<span class="pointer"
|
||||
@click="showChart( tablePointNameMap[scope.row.dataName+scope.column.label],baseInfo.deviceId)">{{
|
||||
scope.row.minData
|
||||
}}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="minDataID"
|
||||
label="单体最小值ID">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="maxData"
|
||||
label="单体最大值">
|
||||
<template slot-scope="scope">
|
||||
<span class="pointer "
|
||||
@click="showChart( tablePointNameMap[scope.row.dataName+scope.column.label],baseInfo.deviceId)">{{
|
||||
scope.row.maxData
|
||||
}}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="maxDataID"
|
||||
label="单体最大值ID">
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-card>
|
||||
</div>
|
||||
<el-empty v-show="baseInfoList.length<=0" :image-size="200"></el-empty>
|
||||
<point-chart ref="pointChart" :site-id="siteId"/>
|
||||
<point-table ref="pointTable"/>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import pointChart from "./../PointChart.vue";
|
||||
import PointTable from "@/views/ems/site/sblb/PointTable.vue";
|
||||
import {getBMSBatteryCluster} from '@/api/ems/dzjk'
|
||||
import getQuerySiteId from "@/mixins/ems/getQuerySiteId";
|
||||
import intervalUpdate from "@/mixins/ems/intervalUpdate";
|
||||
import {mapState} from "vuex";
|
||||
|
||||
export default {
|
||||
components:{},
|
||||
name: 'DzjkSbjkBmsdcc',
|
||||
mixins: [getQuerySiteId, intervalUpdate],
|
||||
components: {PointTable, pointChart},
|
||||
computed: {
|
||||
...mapState({
|
||||
CLUSTERWorkStatusOptions: state => state?.ems?.CLUSTERWorkStatusOptions || {},
|
||||
})
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
infoData:[
|
||||
{label:'簇电压',value:'742',attr:'',unit:'V'},
|
||||
{label:'可充电量',value:'100',attr:'',unit:'kWh'},
|
||||
{label:'累计充电量',value:'100',attr:'',unit:'kWh'},
|
||||
{label:'簇电流',value:'12.7',attr:'',unit:'A'},
|
||||
{label:'可放电量',value:'300',attr:'',unit:'kWh'},
|
||||
{label:'累计放电量',value:'300',attr:'',unit:'kWh'},
|
||||
{label:'SOH',value:'98',attr:'',unit:'%'},
|
||||
{label:'平均温度',value:'11',attr:'',unit:'℃'},
|
||||
{label:'绝缘电阻',value:'2000',attr:'',unit:'Ω'},
|
||||
loading: false,
|
||||
unitObj: {
|
||||
'电压': 'V',
|
||||
'温度': '℃',
|
||||
'SOC': '%'
|
||||
},
|
||||
tablePointNameMap: {
|
||||
'电压单体最小值': '最低单体电压',
|
||||
'电压单体平均值': '电压平均值',
|
||||
'电压单体最大值': '最高单体电压',
|
||||
'温度单体最小值': '最低单体温度',
|
||||
'温度单体平均值': '平均单体温度',
|
||||
'温度单体最大值': '最高单体温度',
|
||||
'SOC单体最小值': '最低单体SOC',
|
||||
'SOC单体平均值': '当前SOC',
|
||||
'SOC单体最大值': '最高单体SOC',
|
||||
},
|
||||
baseInfoList: [],
|
||||
infoData: [
|
||||
{label: '簇电压', attr: 'clusterVoltage', unit: 'V', pointName: '簇电压'},
|
||||
{label: '可充电量', attr: 'chargeableCapacity', unit: 'kWh', pointName: '可充电量'},
|
||||
{label: '累计充电量', attr: 'totalChargedCapacity', unit: 'kWh', pointName: '累计充电量'},
|
||||
{label: '簇电流', attr: 'clusterCurrent', unit: 'A', pointName: '簇电流'},
|
||||
{label: '可放电量', attr: 'dischargeableCapacity', unit: 'kWh', pointName: '可放电量'},
|
||||
{label: '累计放电量', attr: 'totalDischargedCapacity', unit: 'kWh', pointName: '累计放电量'},
|
||||
{label: 'SOH', attr: 'soh', unit: '%', pointName: 'SOH'},
|
||||
{label: '平均温度', attr: 'averageTemperature', unit: '℃', pointName: '平均温度'},
|
||||
{label: '绝缘电阻', attr: 'insulationResistance', unit: 'Ω', pointName: '绝缘电阻'},
|
||||
],
|
||||
tableData:[
|
||||
{name:'1#电池堆-1#电池簇',voltage:'742.8',electric:'-4.4',soc:'98',maxVoltage:'3.301',minVoltage:'3.102',maxTemperature:'12.8',minTemperature:'11.3'},
|
||||
{name:'1#电池堆-2#电池簇',voltage:'790.1',electric:'-4.2',soc:'90',maxVoltage:'3.391',minVoltage:'3.192',maxTemperature:'13.5',minTemperature:'11.4'},
|
||||
{name:'1#电池堆-3#电池簇',voltage:'740.3',electric:'-4.5',soc:'94',maxVoltage:'3.101',minVoltage:'3.198',maxTemperature:'10.9',minTemperature:'11.5'},
|
||||
{name:'1#电池堆-4#电池簇',voltage:'744.9',electric:'-4.5',soc:'99',maxVoltage:'3.221',minVoltage:'3.234',maxTemperature:'11.4',minTemperature:'11.6'},
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
handleCardClass(item) {
|
||||
const {workStatus = ''} = item
|
||||
return !(Object.keys(this.CLUSTERWorkStatusOptions).includes(item.workStatus)) ? "timing-card-container" : workStatus === '9' ? 'warning-card-container' : 'running-card-container'
|
||||
},
|
||||
// 查看设备电位表格
|
||||
pointDetail(row, dataType) {
|
||||
const {siteId, deviceId} = row
|
||||
this.$refs.pointTable.showTable({siteId, deviceId, deviceCategory: 'CLUSTER'}, dataType)
|
||||
},
|
||||
showChart(pointName, deviceId) {
|
||||
pointName && this.$refs.pointChart.showChart({pointName, deviceCategory: 'CLUSTER', deviceId})
|
||||
},
|
||||
updateData() {
|
||||
this.loading = true
|
||||
getBMSBatteryCluster(this.siteId).then(response => {
|
||||
this.baseInfoList = JSON.parse(JSON.stringify(response?.data || []));
|
||||
}).finally(() => {
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
init() {
|
||||
this.updateData()
|
||||
this.updateInterval(this.updateData)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
::v-deep {
|
||||
//描述列表样式
|
||||
.descriptions-main{
|
||||
padding:24px 300px 24px 24px;
|
||||
.descriptions-main {
|
||||
padding: 24px 300px 24px 24px;
|
||||
}
|
||||
.descriptions-main-bottom{
|
||||
padding:14px 300px 14px 24px;
|
||||
|
||||
.descriptions-main-bottom {
|
||||
padding: 14px 300px 14px 24px;
|
||||
}
|
||||
}
|
||||
|
||||
// 进度条样式
|
||||
.process-container{
|
||||
width:100px;
|
||||
.process-container {
|
||||
width: 100px;
|
||||
position: absolute;
|
||||
right:70px;
|
||||
top:50%;
|
||||
right: 70px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
.process-line-bg{
|
||||
|
||||
.process-line-bg {
|
||||
position: relative;
|
||||
width:100%;
|
||||
width: 100%;
|
||||
height: 110px;
|
||||
background-color:#fff2cb ;
|
||||
background-color: #fff2cb;
|
||||
border-radius: 6px;
|
||||
box-shadow: 0 0 10px #fff2cb, 0 0 0 rgba(255, 242, 203, 0.5);
|
||||
.process-line{
|
||||
|
||||
.process-line {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
@ -151,9 +240,10 @@ export default {
|
||||
box-shadow: 0 0 10px #ffbf14, 0 0 0 rgba(255, 191, 20, 0.5);
|
||||
}
|
||||
}
|
||||
.process{
|
||||
margin-top:15px;
|
||||
color:#666666;
|
||||
|
||||
.process {
|
||||
margin-top: 15px;
|
||||
color: #666666;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,101 +1,227 @@
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<el-card shadow="always" class="common-card-container common-card-container-body-no-padding common-card-container-no-title-bg">
|
||||
<div slot="header">
|
||||
<span class="large-title">电池堆一</span>
|
||||
</div>
|
||||
<div class="descriptions-main">
|
||||
<el-descriptions direction="vertical" :column="3" :colon="false">
|
||||
<el-descriptions-item labelClassName="descriptions-label" contentClassName="descriptions-direction keep" :span="1" label="工作状态" >放电</el-descriptions-item>
|
||||
<el-descriptions-item labelClassName="descriptions-label" contentClassName="descriptions-direction" :span="1" label="与PCS通信">正常</el-descriptions-item>
|
||||
<el-descriptions-item labelClassName="descriptions-label" contentClassName="descriptions-direction" :span="1" label="与EMS通信">正常</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</div>
|
||||
<div class="descriptions-main descriptions-main-bg-color">
|
||||
<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">{{item.value}} <span v-if="item.unit" v-html="item.unit"></span></el-descriptions-item>
|
||||
</el-descriptions>
|
||||
<!-- 进度-->
|
||||
<div class="process-container">
|
||||
<div class="process-line-bg">
|
||||
<div class="process-line"></div>
|
||||
<div v-loading="loading">
|
||||
<div v-for="(baseInfo,index) in baseInfoList" :key="index+'bmszlContainer'" style="margin-bottom:25px;">
|
||||
<el-card
|
||||
:class="handleCardClass(baseInfo)"
|
||||
class="sbjk-card-container common-card-container-body-no-padding common-card-container-no-title-bg"
|
||||
shadow="always">
|
||||
<div slot="header">
|
||||
<span class="large-title">{{ baseInfo.deviceName }}</span>
|
||||
<div class="info">
|
||||
<div>数据更新时间:{{ baseInfo.dataUpdateTime || '-' }}</div>
|
||||
</div>
|
||||
<div class="alarm">
|
||||
<el-button type="primary" round size="small" style="margin-right:20px;"
|
||||
@click="pointDetail(baseInfo,'point')">详细
|
||||
</el-button>
|
||||
<el-badge :hidden="!baseInfo.alarmNum" :value="baseInfo.alarmNum || 0" class="item">
|
||||
<i
|
||||
class="el-icon-message-solid alarm-icon"
|
||||
@click="pointDetail(baseInfo,'alarmPoint')"
|
||||
></i>
|
||||
</el-badge>
|
||||
</div>
|
||||
<div class="process">当前SOC : 25%</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
<el-table
|
||||
class="common-table"
|
||||
:data="tableData"
|
||||
stripe
|
||||
style="width: 100%;margin-top:25px;">
|
||||
<el-table-column
|
||||
prop=""
|
||||
label="名称">
|
||||
<template slot-scope="scope">
|
||||
<span v-html="scope.row.name"></span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="average"
|
||||
label="单体平均值"
|
||||
>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="min"
|
||||
label="单体最小值">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="minID"
|
||||
label="单体最小值ID">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="max"
|
||||
label="单体最大值">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="maxID"
|
||||
label="单体最大值ID">
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="descriptions-main">
|
||||
<el-descriptions :colon="false" :column="3" direction="vertical">
|
||||
<el-descriptions-item
|
||||
contentClassName="descriptions-direction work-status"
|
||||
label="工作状态" labelClassName="descriptions-label">
|
||||
{{ STACKWorkStatusOptions[baseInfo.workStatus] }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item :span="1" contentClassName="descriptions-direction" label="与PCS通信"
|
||||
labelClassName="descriptions-label">
|
||||
{{ $store.state.ems.communicationStatusOptions[baseInfo.pcsCommunicationStatus] }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item :span="1" contentClassName="descriptions-direction" label="与EMS通信"
|
||||
labelClassName="descriptions-label">
|
||||
{{ $store.state.ems.communicationStatusOptions[baseInfo.emsCommunicationStatus] }}
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</div>
|
||||
<div class="descriptions-main descriptions-main-bg-color">
|
||||
<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">
|
||||
<span class="pointer" @click="showChart(item.pointName || '',baseInfo.deviceId)">
|
||||
{{ baseInfo[item.attr] | formatNumber }}<span v-if="item.unit" v-html="item.unit"></span>
|
||||
</span>
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
<!-- 进度-->
|
||||
<div class="process-container">
|
||||
<div class="process-line-bg">
|
||||
<div :style="{height:baseInfo.stackSoc+'%'}" class="process-line"></div>
|
||||
</div>
|
||||
<div class="process pointer" @click="showChart('当前SOC',baseInfo.deviceId)">当前SOC :
|
||||
{{ baseInfo.stackSoc }}%
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<el-table
|
||||
:data="baseInfo.batteryDataList"
|
||||
class="common-table"
|
||||
max-height="500"
|
||||
stripe
|
||||
style="width: 100%;margin-top:25px;">
|
||||
<el-table-column
|
||||
label="簇号"
|
||||
prop="clusterId">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="簇电压"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span class="pointer"
|
||||
@click="showChart('簇电压',scope.row.clusterId,'CLUSTER')">{{ scope.row.clusterVoltage }} V</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="簇电流">
|
||||
<template slot-scope="scope">
|
||||
<span class="pointer"
|
||||
@click="showChart('簇电流',scope.row.clusterId,'CLUSTER')">{{ scope.row.clusterCurrent }} A</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="簇SOC">
|
||||
<template slot-scope="scope">
|
||||
<span class="pointer"
|
||||
@click="showChart('当前SOC',scope.row.clusterId,'CLUSTER')">{{ scope.row.currentSoc }} %</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="单体最高电压"
|
||||
prop="maxVoltage">
|
||||
<template slot-scope="scope">
|
||||
<span class="pointer"
|
||||
@click="showChart('最高单体电压',scope.row.clusterId,'CLUSTER')">{{
|
||||
scope.row.maxCellVoltage
|
||||
}} V</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="电池号码"
|
||||
prop="maxCellVoltageId">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="单体最低电压"
|
||||
prop="minVoltage">
|
||||
<template slot-scope="scope">
|
||||
<span class="pointer"
|
||||
@click="showChart('最低单体电压',scope.row.clusterId,'CLUSTER')">{{
|
||||
scope.row.minCellVoltage
|
||||
}} V</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="电池号码"
|
||||
prop="minCellVoltageId">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="单体最高温度">
|
||||
<template slot-scope="scope">
|
||||
<span class="pointer"
|
||||
@click="showChart('最高单体温度',scope.row.clusterId,'CLUSTER')">{{
|
||||
scope.row.maxCellTemp
|
||||
}} ℃</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="电池号码"
|
||||
prop="maxCellTempId">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="单体最低温度"
|
||||
prop="minTemperature">
|
||||
<template slot-scope="scope">
|
||||
<span class="pointer"
|
||||
@click="showChart('最低单体温度',scope.row.clusterId,'CLUSTER')">{{
|
||||
scope.row.minCellTemp
|
||||
}} ℃</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="电池号码"
|
||||
prop="minCellTempId">
|
||||
</el-table-column>
|
||||
|
||||
</el-table>
|
||||
</el-card>
|
||||
</div>
|
||||
<el-empty v-show="baseInfoList.length<=0" :image-size="200"></el-empty>
|
||||
<point-chart ref="pointChart" :site-id="siteId"/>
|
||||
<point-table ref="pointTable"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {getBMSOverView} from '@/api/ems/dzjk'
|
||||
import getQuerySiteId from "@/mixins/ems/getQuerySiteId";
|
||||
import intervalUpdate from "@/mixins/ems/intervalUpdate";
|
||||
import pointChart from "./../PointChart.vue";
|
||||
import PointTable from "@/views/ems/site/sblb/PointTable.vue";
|
||||
import {mapState} from "vuex";
|
||||
|
||||
export default {
|
||||
components:{},
|
||||
name: 'DzjkSbjkBmszl',
|
||||
components: {pointChart, PointTable},
|
||||
mixins: [getQuerySiteId, intervalUpdate],
|
||||
computed: {
|
||||
...mapState({
|
||||
STACKWorkStatusOptions: state => state?.ems?.STACKWorkStatusOptions || {},
|
||||
})
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
statusData:[
|
||||
{label:'工作状态',value:'',attr:''},
|
||||
{label:'与PCS通信',value:'',attr:''},
|
||||
{label:'与EMS通信',value:'',attr:''},
|
||||
],
|
||||
infoData:[
|
||||
{label:'电池堆总电压',value:'742',attr:'',unit:'V'},
|
||||
{label:'可充电量',value:'100',attr:'',unit:'kWh'},
|
||||
{label:'累计充电量',value:'100',attr:'',unit:'kWh'},
|
||||
{label:'电池堆总电流',value:'-12.7',attr:'',unit:'A'},
|
||||
{label:'可放电量',value:'300',attr:'',unit:'kWh'},
|
||||
{label:'累计放电量',value:'300',attr:'',unit:'kWh'},
|
||||
{label:'SOH',value:'99',attr:'',unit:'%'},
|
||||
{label:'平均温度',value:'20',attr:'',unit:'℃'},
|
||||
{label:'绝缘电阻',value:'1000',attr:'',unit:'Ω'},
|
||||
],
|
||||
tableData:[
|
||||
{name:'电压(V)',average:'20',min:10,minID:'1',max:'30',maxID:'2'},
|
||||
{name:'温度(℃)',average:'20',min:10,minID:'1',max:'30',maxID:'2'},
|
||||
{name:'SOC(%)',average:'20',min:10,minID:'1',max:'30',maxID:'2'},
|
||||
loading: false,
|
||||
baseInfoList: [],
|
||||
infoData: [
|
||||
{label: '电池堆总电压', attr: 'stackVoltage', unit: 'V', pointName: '电池堆电压'},
|
||||
{label: '可充电量', attr: 'availableChargeCapacity', unit: 'kWh', pointName: '可充电量'},
|
||||
{label: '累计充电量', attr: 'totalChargeCapacity', unit: 'kWh', pointName: '累计充电量'},
|
||||
{label: '电池堆总电流', attr: 'stackCurrent', unit: 'A', pointName: '电池堆总电流'},
|
||||
{label: '可放电量', attr: 'availableDischargeCapacity', unit: 'kWh', pointName: '可放电量'},
|
||||
{label: '累计放电量', attr: 'totalDischargeCapacity', unit: 'kWh', pointName: '累计放电量'},
|
||||
{label: 'SOH', attr: 'stackSoh', unit: '%', pointName: 'SOH'},
|
||||
{label: '平均温度', attr: 'operatingTemp', unit: '℃', pointName: '平均温度'},
|
||||
{label: '绝缘电阻', attr: 'stackInsulationResistance', unit: 'Ω', pointName: '绝缘电阻'},
|
||||
]
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleCardClass(item) {
|
||||
const {workStatus = ''} = item
|
||||
return !Object.keys(this.STACKWorkStatusOptions).find(i => i === workStatus) ? "timing-card-container" : workStatus === '9' ? 'warning-card-container' : 'running-card-container'
|
||||
},
|
||||
|
||||
// 查看设备电位表格
|
||||
pointDetail(row, dataType) {
|
||||
const {siteId, deviceId} = row
|
||||
this.$refs.pointTable.showTable({siteId, deviceId, deviceCategory: 'STACK'}, dataType)
|
||||
},
|
||||
showChart(pointName, deviceId, deviceCategory = 'STACK') {
|
||||
pointName && this.$refs.pointChart.showChart({pointName, deviceCategory, deviceId})
|
||||
},
|
||||
updateData() {
|
||||
this.loading = true
|
||||
getBMSOverView(this.siteId).then(response => {
|
||||
this.baseInfoList = JSON.parse(JSON.stringify(response?.data || []));
|
||||
}).finally(() => {
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
init() {
|
||||
this.updateData()
|
||||
this.updateInterval(this.updateData)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
<style lang="scss" scoped>
|
||||
::v-deep {
|
||||
//描述列表样式
|
||||
.descriptions-main {
|
||||
@ -106,34 +232,38 @@ export default {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 进度条样式
|
||||
.process-container{
|
||||
width:100px;
|
||||
.process-container {
|
||||
width: 100px;
|
||||
position: absolute;
|
||||
right:70px;
|
||||
top:50%;
|
||||
right: 70px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
.process-line-bg{
|
||||
|
||||
.process-line-bg {
|
||||
position: relative;
|
||||
width:100%;
|
||||
width: 100%;
|
||||
height: 110px;
|
||||
background-color:#fff2cb ;
|
||||
background-color: #fff2cb;
|
||||
border-radius: 6px;
|
||||
box-shadow: 0 0 10px #fff2cb, 0 0 0 rgba(255, 242, 203, 0.5);
|
||||
.process-line{
|
||||
|
||||
.process-line {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
height: 25%;
|
||||
height: 0;
|
||||
background-color: #fc6c6c;
|
||||
border-radius: 0 0 6px 6px;
|
||||
box-shadow: 0 0 10px rgb(252 108 108), 0 0 0 rgba(252, 108, 108, 0.5);
|
||||
}
|
||||
}
|
||||
.process{
|
||||
margin-top:15px;
|
||||
color:#666666;
|
||||
|
||||
.process {
|
||||
margin-top: 15px;
|
||||
color: #666666;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,146 +1,237 @@
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<el-card shadow="always" class="common-card-container zb-common-card-container">
|
||||
<div slot="header">
|
||||
<span class="large-title">1#总表</span>
|
||||
<div class="status">
|
||||
<div>通信中断</div>
|
||||
<div>数据更新时间:2024-10-11 12:00:00</div>
|
||||
</div>
|
||||
<div v-loading="loading">
|
||||
<el-card
|
||||
v-for="(item,index) in list"
|
||||
:key="index+'dbList'"
|
||||
shadow="always"
|
||||
class="sbjk-card-container list"
|
||||
:class="{
|
||||
'timing-card-container':!['0','2'].includes(item.emsCommunicationStatus),
|
||||
'warning-card-container':item.emsCommunicationStatus === '2',
|
||||
'running-card-container':item.emsCommunicationStatus === '0'
|
||||
}"
|
||||
>
|
||||
<div slot="header">
|
||||
<span class="large-title">{{ item.deviceName }}</span>
|
||||
<div class="info">
|
||||
<div>
|
||||
{{
|
||||
communicationStatusOptions[item.emsCommunicationStatus] || '-'
|
||||
}}
|
||||
</div>
|
||||
<el-table
|
||||
class="common-table"
|
||||
:data="zbTableData"
|
||||
stripe
|
||||
style="width: 100%;">
|
||||
<el-table-column
|
||||
prop="name"
|
||||
label="类别">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="zong"
|
||||
label="总/kWh"
|
||||
>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="jian"
|
||||
label="尖/kWh">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="feng"
|
||||
label="峰/kWh">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="ping"
|
||||
label="平/kWh">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="gu"
|
||||
label="谷/kWh">
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-card>
|
||||
<el-card shadow="always" class="common-card-container cnb-common-card-container">
|
||||
<div slot="header">
|
||||
<span class="large-title">2#储能表</span>
|
||||
<div class="status">
|
||||
<div>通信正常</div>
|
||||
<div>数据更新时间:2024-10-11 12:00:00</div>
|
||||
</div>
|
||||
</div>
|
||||
<el-table
|
||||
class="common-table"
|
||||
:data="cnbTableData"
|
||||
stripe
|
||||
style="width: 100%;">
|
||||
<el-table-column
|
||||
prop="name"
|
||||
label="类别">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="zong"
|
||||
label="总/kWh"
|
||||
>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="jian"
|
||||
label="尖/kWh">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="feng"
|
||||
label="峰/kWh">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="ping"
|
||||
label="平/kWh">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="gu"
|
||||
label="谷/kWh">
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-card>
|
||||
<div>数据更新时间:{{ item.dataUpdateTime || '-' }}</div>
|
||||
</div>
|
||||
<div class="alarm">
|
||||
<el-button type="primary" round size="small" style="margin-right:20px;" @click="pointDetail(item,'point')">
|
||||
详细
|
||||
</el-button>
|
||||
<el-badge :hidden="!item.alarmNum" :value="item.alarmNum || 0" class="item">
|
||||
<i
|
||||
class="el-icon-message-solid alarm-icon"
|
||||
@click="pointDetail(item,'alarmPoint')"
|
||||
></i>
|
||||
</el-badge>
|
||||
</div>
|
||||
</div>
|
||||
<el-row class="device-info-row">
|
||||
<el-col v-for="(tempDataItem,tempDataIndex) in (deviceIdTypeMsg[item.deviceId] || otherTypeMsg)"
|
||||
:key="tempDataIndex+'dbTempData'"
|
||||
:span="8" class="device-info-col">
|
||||
<span class="pointer" @click="showChart(tempDataItem.pointName,item.deviceId)">
|
||||
<span class="left">{{ tempDataItem.name }}</span> <span class="right">{{ item[tempDataItem.attr] || '-' }}<span
|
||||
v-html="tempDataItem.unit"></span></span>
|
||||
</span>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-card>
|
||||
<el-empty v-show="list.length<=0" :image-size="200"></el-empty>
|
||||
<point-chart ref="pointChart" :site-id="siteId"/>
|
||||
<point-table ref="pointTable"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<script>
|
||||
import pointChart from "./../PointChart.vue";
|
||||
import getQuerySiteId from "@/mixins/ems/getQuerySiteId";
|
||||
import {getAmmeterDataList} from "@/api/ems/dzjk";
|
||||
import intervalUpdate from "@/mixins/ems/intervalUpdate";
|
||||
import PointTable from "@/views/ems/site/sblb/PointTable.vue";
|
||||
import {mapState} from "vuex";
|
||||
|
||||
export default {
|
||||
name:'DzjkSbjkDb',
|
||||
name: "DzjkSbjkDb",
|
||||
mixins: [getQuerySiteId, intervalUpdate],
|
||||
components: {PointTable, pointChart},
|
||||
computed: {
|
||||
|
||||
...mapState({
|
||||
communicationStatusOptions: state => state?.ems?.communicationStatusOptions || {},
|
||||
})
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
zbTableData:[
|
||||
{name:'累计充电量',zong:1000,jian:2000,feng:1500,ping:500,gu:40},
|
||||
{name:'累计放电量',zong:1000,jian:2000,feng:1500,ping:500,gu:40},
|
||||
{name:'日充电量',zong:1000,jian:2000,feng:1500,ping:500,gu:40},
|
||||
{name:'日放电量',zong:1000,jian:2000,feng:1500,ping:500,gu:40},
|
||||
],
|
||||
cnbTableData:[
|
||||
{name:'累计充电量',zong:1000,jian:2000,feng:1500,ping:500,gu:40},
|
||||
{name:'累计放电量',zong:1000,jian:2000,feng:1500,ping:500,gu:40},
|
||||
{name:'日充电量',zong:1000,jian:2000,feng:1500,ping:500,gu:40},
|
||||
{name:'日放电量',zong:1000,jian:2000,feng:1500,ping:500,gu:40},
|
||||
loading: false,
|
||||
list: [],
|
||||
deviceIdTypeMsg: {
|
||||
'LOAD': [
|
||||
{
|
||||
name: '正向有功电能',
|
||||
attr: 'forwardActive',
|
||||
pointName: '正向有功电能',
|
||||
unit: 'kWh'
|
||||
},
|
||||
{
|
||||
name: '反向有功电能',
|
||||
attr: 'reverseActive',
|
||||
pointName: '反向有功电能',
|
||||
unit: 'kWh'
|
||||
},
|
||||
{
|
||||
name: '正向无功电能',
|
||||
attr: 'forwardReactive',
|
||||
pointName: '正向无功电能',
|
||||
unit: 'kvarh'
|
||||
},
|
||||
{
|
||||
name: '反向无功电能',
|
||||
attr: 'reverseReactive',
|
||||
pointName: '反向无功电能',
|
||||
unit: 'kvarh'
|
||||
},
|
||||
{
|
||||
name: '有功功率',
|
||||
attr: 'activePower',
|
||||
pointName: '总有功功率',
|
||||
unit: 'kW'
|
||||
},
|
||||
{
|
||||
name: '无功功率',
|
||||
attr: 'reactivePower',
|
||||
pointName: '总无功功率',
|
||||
unit: 'kvar'
|
||||
}
|
||||
],
|
||||
'METE': [
|
||||
{
|
||||
name: '正向有功电能',
|
||||
attr: 'forwardActive',
|
||||
pointName: '正向有功电能',
|
||||
unit: 'kWh'
|
||||
},
|
||||
{
|
||||
name: '反向有功电能',
|
||||
attr: 'reverseActive',
|
||||
pointName: '反向有功电能',
|
||||
unit: 'kWh'
|
||||
},
|
||||
{
|
||||
name: '正向无功电能',
|
||||
attr: 'forwardReactive',
|
||||
pointName: '正向无功电能',
|
||||
unit: 'kvarh'
|
||||
},
|
||||
{
|
||||
name: '反向无功电能',
|
||||
attr: 'reverseReactive',
|
||||
pointName: '反向无功电能',
|
||||
unit: 'kvarh'
|
||||
},
|
||||
{
|
||||
name: '有功功率',
|
||||
attr: 'activePower',
|
||||
pointName: '总有功功率',
|
||||
unit: 'kW'
|
||||
},
|
||||
{
|
||||
name: '无功功率',
|
||||
attr: 'reactivePower',
|
||||
pointName: '总无功功率',
|
||||
unit: 'kvar'
|
||||
}
|
||||
],
|
||||
'METEGF': [
|
||||
{
|
||||
name: '有功电能',
|
||||
attr: 'activeEnergy',
|
||||
pointName: '有功电能',
|
||||
unit: 'kWh'
|
||||
},
|
||||
{
|
||||
name: '无功电能',
|
||||
attr: 'reactiveEnergy',
|
||||
pointName: '无功电能',
|
||||
unit: 'kvarh'
|
||||
},
|
||||
{
|
||||
name: '有功功率',
|
||||
attr: 'activePower',
|
||||
pointName: '总有功功率',
|
||||
unit: 'kW'
|
||||
},
|
||||
{
|
||||
name: '无功功率',
|
||||
attr: 'reactivePower',
|
||||
pointName: '总无功功率',
|
||||
unit: 'kvar'
|
||||
}
|
||||
]
|
||||
},
|
||||
otherTypeMsg: [
|
||||
{
|
||||
name: '正向有功电能',
|
||||
attr: 'forwardActive',
|
||||
pointName: '正向有功电能',
|
||||
unit: 'kWh'
|
||||
},
|
||||
{
|
||||
name: '反向有功电能',
|
||||
attr: 'reverseActive',
|
||||
pointName: '反向有功电能',
|
||||
unit: 'kWh'
|
||||
},
|
||||
{
|
||||
name: '有功功率',
|
||||
attr: 'activePower',
|
||||
pointName: '总有功功率',
|
||||
unit: 'kW'
|
||||
},
|
||||
]
|
||||
}
|
||||
};
|
||||
},
|
||||
methods:{
|
||||
|
||||
methods: {
|
||||
// 查看设备电位表格
|
||||
pointDetail(row, dataType) {
|
||||
const {deviceId} = row
|
||||
this.$refs.pointTable.showTable({siteId: this.siteId, deviceId, deviceCategory: 'AMMETER'}, dataType)
|
||||
},
|
||||
showChart(pointName, deviceId) {
|
||||
pointName && this.$refs.pointChart.showChart({pointName, deviceCategory: 'AMMETER', deviceId})
|
||||
},
|
||||
updateData() {
|
||||
this.loading = true;
|
||||
getAmmeterDataList(this.siteId)
|
||||
.then((response) => {
|
||||
this.list = response?.data || []
|
||||
})
|
||||
.finally(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
init() {
|
||||
this.updateData()
|
||||
this.updateInterval(this.updateData)
|
||||
},
|
||||
},
|
||||
mounted(){
|
||||
|
||||
}
|
||||
}
|
||||
mounted() {
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.zb-common-card-container,.cnb-common-card-container{
|
||||
::v-deep{
|
||||
.el-card__header{
|
||||
padding:10px 14px;
|
||||
background-color: #FC6B69;
|
||||
color:#ffffff;
|
||||
position: relative;
|
||||
}
|
||||
.sbjk-card-container {
|
||||
&.list:not(:last-child) {
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
}
|
||||
.cnb-common-card-container{
|
||||
margin-top:25px;
|
||||
::v-deep{
|
||||
.el-card__header{
|
||||
background-color: #05AEA3;
|
||||
}
|
||||
}
|
||||
}
|
||||
.status{
|
||||
position: absolute;
|
||||
right:14px;
|
||||
top:50%;
|
||||
transform: translateY(-50%);
|
||||
color: #ffffff;
|
||||
font-size: 12px;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
|
||||
120
src/views/ems/dzjk/sbjk/dh/index.vue
Normal file
@ -0,0 +1,120 @@
|
||||
<template>
|
||||
<div v-loading="loading">
|
||||
<el-card
|
||||
v-for="(item,index) in list"
|
||||
:key="index+'ylLise'"
|
||||
class="sbjk-card-container running-card-container"
|
||||
shadow="always">
|
||||
<div slot="header">
|
||||
<span class="large-title">{{ item.deviceName }}</span>
|
||||
<div class="info">
|
||||
<div>数据更新时间:{{ item.dataUpdateTime || '-' }}</div>
|
||||
</div>
|
||||
<div class="alarm">
|
||||
<el-button type="primary" round size="small" style="margin-right:20px;" @click="pointDetail(item,'point')">
|
||||
详细
|
||||
</el-button>
|
||||
<el-badge :hidden="!item.alarmNum" :value="item.alarmNum || 0" class="item">
|
||||
<i
|
||||
class="el-icon-message-solid alarm-icon"
|
||||
@click="pointDetail(item,'alarmPoint')"
|
||||
></i>
|
||||
</el-badge>
|
||||
</div>
|
||||
</div>
|
||||
<el-row class="device-info-row">
|
||||
<el-col v-for="(tempDataItem,tempDataIndex) in tempData" :key="tempDataIndex+'hdTempData'" :span="12"
|
||||
class="device-info-col">
|
||||
<span class="pointer" @click="showChart(tempDataItem.title,item.deviceId)">
|
||||
<span class="left">{{ tempDataItem.title }}</span> <span
|
||||
class="right">{{ item[tempDataItem.attr] || '-' }}<span
|
||||
v-html="tempDataItem.unit"></span></span>
|
||||
</span>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-card>
|
||||
<el-empty v-show="list.length<=0" :image-size="200"></el-empty>
|
||||
<point-chart ref="pointChart" :site-id="siteId"/>
|
||||
<point-table ref="pointTable"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<script>
|
||||
import getQuerySiteId from "@/mixins/ems/getQuerySiteId";
|
||||
import {getDhDataList} from '@/api/ems/dzjk'
|
||||
import intervalUpdate from "@/mixins/ems/intervalUpdate";
|
||||
import pointChart from "./../PointChart.vue";
|
||||
import PointTable from "@/views/ems/site/sblb/PointTable.vue";
|
||||
|
||||
export default {
|
||||
name: 'DzjkSbjkDh',
|
||||
mixins: [getQuerySiteId, intervalUpdate],
|
||||
components: {pointChart, PointTable},
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
list: [],
|
||||
tempData: [
|
||||
{title: '湿度', attr: 'humidity', unit: ''},
|
||||
{title: '温度', attr: 'temperature', unit: '℃'},
|
||||
]
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 查看设备电位表格
|
||||
pointDetail(row, dataType) {
|
||||
const {deviceId} = row
|
||||
this.$refs.pointTable.showTable({siteId: this.siteId, deviceId, deviceCategory: 'DH'}, dataType)
|
||||
},
|
||||
showChart(pointName, deviceId) {
|
||||
pointName && this.$refs.pointChart.showChart({pointName, deviceCategory: 'DH', deviceId})
|
||||
},
|
||||
updateData() {
|
||||
this.loading = true
|
||||
getDhDataList(this.siteId).then(response => {
|
||||
this.list = JSON.parse(JSON.stringify(response?.data || []));
|
||||
}).finally(() => {
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
init() {
|
||||
this.updateData()
|
||||
this.updateInterval(this.updateData)
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.sbjk-card-container {
|
||||
&:not(:last-child) {
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
|
||||
.el-row {
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -27,10 +27,11 @@ export default {
|
||||
this.chart = echarts.init(document.querySelector('#dtdcChart'))
|
||||
},
|
||||
setOption() {
|
||||
const source = [['日期','电压','温度','SOC','SOH']]
|
||||
source.push(['1月','12','13','14','15'],['2月','12','13','14','15'])
|
||||
this.chart.setOption({
|
||||
color:['#FFBD00','#3C81FF'],
|
||||
color:['#FFBD00','#3C81FF','#05AEA3','#F86F70'],
|
||||
legend: {
|
||||
left: 'center',
|
||||
bottom: '10',
|
||||
},
|
||||
tooltip: {
|
||||
@ -43,26 +44,37 @@ export default {
|
||||
color:"#333333",
|
||||
},
|
||||
xAxis: {
|
||||
data: ['1月','2月','3月','4月','5月','6月','7月','8月','9月','10月','11月','12月'],
|
||||
type: 'category',
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
},
|
||||
dataset:{
|
||||
source
|
||||
// source: [['日期','充电量','放电量']]
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name:'昨天',
|
||||
data: [80,92,1,34,90,130,320,80,9,91,34,90],
|
||||
name:'电压',
|
||||
type: 'bar',
|
||||
|
||||
},{
|
||||
name:'今天',
|
||||
data: [820,932,901,934,1290,1330,1320,820,932,901,934,1290],
|
||||
name:'温度',
|
||||
type: 'bar',
|
||||
},
|
||||
{
|
||||
name:'SOC',
|
||||
type: 'bar',
|
||||
|
||||
},{
|
||||
name:'SOH',
|
||||
type: 'bar',
|
||||
}]
|
||||
})
|
||||
this.chart.hideLoading()
|
||||
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.initChart()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
199
src/views/ems/dzjk/sbjk/dtdc/ChartDetail.vue
Normal file
@ -0,0 +1,199 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
:visible.sync="dialogTableVisible"
|
||||
:close-on-click-modal="false"
|
||||
show-close
|
||||
destroy-on-close
|
||||
lock-scroll
|
||||
append-to-body
|
||||
width="700px"
|
||||
class="ems-dialog chart-detail-dialog"
|
||||
:before-close="handleColsed"
|
||||
>
|
||||
<el-card
|
||||
shadow="always"
|
||||
class="common-card-container time-range-card"
|
||||
style="margin-top: 20px"
|
||||
>
|
||||
<div slot="header" class="time-range-header">
|
||||
<span class="card-title"></span>
|
||||
<date-range-select ref="dateRangeSelect" @updateDate="updateDate" />
|
||||
</div>
|
||||
<div class="card-main" v-loading="loading">
|
||||
<div id="lineChart" style="height: 310px"></div>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as echarts from "echarts";
|
||||
import resize from "@/mixins/ems/resize";
|
||||
import { getSingleBatteryData } from "@/api/ems/dzjk";
|
||||
import DateRangeSelect from "@/components/Ems/DateRangeSelect/index.vue";
|
||||
export default {
|
||||
components: { DateRangeSelect },
|
||||
mixins: [resize],
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
siteId: "",
|
||||
deviceId: "",
|
||||
clusterDeviceId: "",
|
||||
dataType: "", //展示的数据类型 空值展示所有数据
|
||||
pickerOptions: {
|
||||
disabledDate(time) {
|
||||
return time.getTime() > Date.now();
|
||||
},
|
||||
},
|
||||
dialogTableVisible: false,
|
||||
dateRange: [],
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
// 更新时间范围 重置图表
|
||||
updateDate(data) {
|
||||
this.dateRange = data || [];
|
||||
this.getData();
|
||||
},
|
||||
handleColsed(done) {
|
||||
if (!this.chart) {
|
||||
return done();
|
||||
}
|
||||
this.chart.dispose();
|
||||
this.chart = null;
|
||||
done();
|
||||
},
|
||||
getData() {
|
||||
if (this.loading) return;
|
||||
this.loading = true;
|
||||
this.chart.showLoading();
|
||||
const {
|
||||
siteId,
|
||||
deviceId,
|
||||
clusterDeviceId,
|
||||
dateRange: [startDate = "", endDate = ""],
|
||||
} = this;
|
||||
getSingleBatteryData({
|
||||
siteId,
|
||||
deviceId,
|
||||
clusterDeviceId,
|
||||
startDate,
|
||||
endDate,
|
||||
})
|
||||
.then((response) => {
|
||||
this.setOption(response?.data || []);
|
||||
})
|
||||
.finally(() => {
|
||||
this.loading = false;
|
||||
this.chart.hideLoading();
|
||||
});
|
||||
},
|
||||
initChart({ siteId, clusterDeviceId, deviceId }, dataType) {
|
||||
this.siteId = siteId;
|
||||
this.clusterDeviceId = clusterDeviceId;
|
||||
this.deviceId = deviceId;
|
||||
this.dataType = dataType;
|
||||
this.dialogTableVisible = true;
|
||||
this.$nextTick(() => {
|
||||
!this.chart &&
|
||||
(this.chart = echarts.init(document.querySelector("#lineChart")));
|
||||
this.$refs.dateRangeSelect.init();
|
||||
});
|
||||
},
|
||||
setOption(data) {
|
||||
const obj = {
|
||||
voltage: "电压",
|
||||
temperature: "温度",
|
||||
soc: "SOC",
|
||||
soh: "SOH",
|
||||
};
|
||||
let source,
|
||||
series,
|
||||
{ dataType } = this;
|
||||
if (dataType) {
|
||||
source = [["日期", obj[dataType]]];
|
||||
data.forEach((item) => {
|
||||
source.push([item.dataTimestamp, item[dataType]]);
|
||||
});
|
||||
series = [
|
||||
{
|
||||
name: obj[dataType],
|
||||
type: "line",
|
||||
},
|
||||
];
|
||||
} else {
|
||||
source = [["日期", "电压", "温度", "SOC", "SOH"]];
|
||||
data.forEach((item) => {
|
||||
source.push([
|
||||
item.dataTimestamp,
|
||||
item.voltage,
|
||||
item.temperature,
|
||||
item.soc,
|
||||
item.soh,
|
||||
]);
|
||||
});
|
||||
series = [
|
||||
{
|
||||
name: "电压",
|
||||
type: "line",
|
||||
},
|
||||
{
|
||||
name: "温度",
|
||||
type: "line",
|
||||
},
|
||||
{
|
||||
name: "SOC",
|
||||
type: "line",
|
||||
},
|
||||
{
|
||||
name: "SOH",
|
||||
type: "line",
|
||||
},
|
||||
];
|
||||
}
|
||||
this.chart &&
|
||||
this.chart.setOption({
|
||||
color: ["#FFBD00", "#3C81FF", "#05AEA3", "#F86F70"],
|
||||
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,
|
||||
});
|
||||
},
|
||||
},
|
||||
mounted() {},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.chart-detail-dialog {
|
||||
::v-deep {
|
||||
.el-dialog__body {
|
||||
padding-top: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
193
src/views/ems/dzjk/sbjk/dtdc/List.vue
Normal file
@ -0,0 +1,193 @@
|
||||
<template>
|
||||
<div>
|
||||
<template v-if="totalSize.length === 0">
|
||||
<el-empty :size="200"></el-empty>
|
||||
</template>
|
||||
<template v-else>
|
||||
<div class="lists-container clearfix">
|
||||
<div
|
||||
class="lists"
|
||||
v-for="(item, index) in tableData"
|
||||
:key="index + 'dtdcList'"
|
||||
:class="handleListClass(item)"
|
||||
>
|
||||
<div style="font-size: 10px; font-weight: 600">
|
||||
{{ item.clusterDeviceId }}
|
||||
</div>
|
||||
<div>#{{ item.deviceId }}</div>
|
||||
<div class="dy pointer" @click="chartDetail(item, '电压 (V)')">
|
||||
{{ item.voltage }}V
|
||||
</div>
|
||||
<div class="wd pointer" @click="chartDetail(item, '温度 (℃)')">
|
||||
{{ item.temperature }}℃
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- <el-pagination
|
||||
v-show="tableData.length > 0"
|
||||
background
|
||||
@size-change="(val) => $emit('handleSizeChange', val)"
|
||||
@current-change="(val) => $emit('handleCurrentChange', val)"
|
||||
: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> -->
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
pointIdList: {
|
||||
require: true,
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {};
|
||||
},
|
||||
},
|
||||
tableData: {
|
||||
require: true,
|
||||
type: Array,
|
||||
default: () => {
|
||||
return [];
|
||||
},
|
||||
},
|
||||
totalSize: {
|
||||
require: true,
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
// pageNum: {
|
||||
// require: true,
|
||||
// type: Number,
|
||||
// default: 1,
|
||||
// },
|
||||
// pageSize: {
|
||||
// require: true,
|
||||
// type: Number,
|
||||
// default: 10,
|
||||
// },
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
//最低单体温度 最高温度 最低电压 最高电压 todo 这里的顺序需要和图形组件里的顺序保持一致,
|
||||
colorMap: {
|
||||
0: "minwd",
|
||||
1: "maxwd",
|
||||
2: "mindy",
|
||||
3: "maxdy",
|
||||
},
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
//处理图形class 对应高亮设置
|
||||
handleListClass(item) {
|
||||
let className = "";
|
||||
const { clusterDeviceId, deviceId } = item,
|
||||
clusterIdList = Object.keys(this.pointIdList);
|
||||
if (clusterIdList.includes(clusterDeviceId)) {
|
||||
const index = this.pointIdList[clusterDeviceId].findIndex(
|
||||
(ids) => ids === parseInt(deviceId)
|
||||
);
|
||||
if (index > -1) {
|
||||
className = this.colorMap[index];
|
||||
}
|
||||
}
|
||||
return className;
|
||||
},
|
||||
//查看表格行图表
|
||||
chartDetail(row, dataType = "") {
|
||||
const { clusterDeviceId, deviceId } = row;
|
||||
this.$emit("chart", { ...row, dataType });
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.lists-container {
|
||||
padding: 20px 0;
|
||||
.lists {
|
||||
margin: 10px 5px;
|
||||
padding: 5px 9px;
|
||||
font-size: 11px;
|
||||
line-height: 20px;
|
||||
border: 1.6px solid #09ada3;
|
||||
border-radius: 5px;
|
||||
position: relative;
|
||||
color: #333333;
|
||||
float: left;
|
||||
box-sizing: content-box;
|
||||
min-width: 60px;
|
||||
width: auto;
|
||||
&::before {
|
||||
display: block;
|
||||
content: "";
|
||||
top: -7px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
position: absolute;
|
||||
width: 45%;
|
||||
height: 0;
|
||||
border-bottom: 7px solid #09ada3;
|
||||
border-left: 5px solid transparent;
|
||||
border-right: 5px solid transparent;
|
||||
}
|
||||
&.minwd {
|
||||
border-color: #3794ff;
|
||||
.wd {
|
||||
color: #3794ff;
|
||||
}
|
||||
&::before {
|
||||
border-bottom-color: #3794ff;
|
||||
}
|
||||
}
|
||||
&.maxwd {
|
||||
border-color: #ff3a3b;
|
||||
.wd {
|
||||
color: #ff3a3b;
|
||||
}
|
||||
&::before {
|
||||
border-bottom-color: #ff3a3b;
|
||||
}
|
||||
}
|
||||
&.mindy {
|
||||
border-color: #de6902;
|
||||
.dy {
|
||||
color: #de6902;
|
||||
}
|
||||
&::before {
|
||||
border-bottom-color: #de6902;
|
||||
}
|
||||
}
|
||||
&.maxdy {
|
||||
border-color: #ffb521;
|
||||
.dy {
|
||||
color: #ffb521;
|
||||
}
|
||||
&::before {
|
||||
border-bottom-color: #ffb521;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.dtdc-pagination {
|
||||
::v-deep {
|
||||
.el-button {
|
||||
padding: 2px 10px !important;
|
||||
font-size: 11px;
|
||||
line-height: 16px;
|
||||
}
|
||||
.activeBtn {
|
||||
background-color: #09ada3;
|
||||
border-color: #09ada3;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
127
src/views/ems/dzjk/sbjk/dtdc/Table.vue
Normal file
@ -0,0 +1,127 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-table
|
||||
class="common-table"
|
||||
:data="tableData"
|
||||
stripe
|
||||
style="width: 100%; margin-top: 25px"
|
||||
>
|
||||
<el-table-column prop="deviceId" label="单体编号"></el-table-column>
|
||||
<el-table-column prop="clusterDeviceId" label="簇号"></el-table-column>
|
||||
<el-table-column prop="voltage" label="电压 (V)">
|
||||
<template slot-scope="scope">
|
||||
<el-button
|
||||
@click="chartDetail(scope.row, '电压 (V)')"
|
||||
type="text"
|
||||
size="small"
|
||||
>
|
||||
{{ scope.row.voltage }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="temperature" label="温度 (℃)">
|
||||
<template slot-scope="scope">
|
||||
<el-button
|
||||
@click="chartDetail(scope.row, '温度 (℃)')"
|
||||
type="text"
|
||||
size="small"
|
||||
>
|
||||
{{ scope.row.temperature }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="soc" label="SOC (%)">
|
||||
<template slot-scope="scope">
|
||||
<el-button
|
||||
@click="chartDetail(scope.row, 'SOC (%)')"
|
||||
type="text"
|
||||
size="small"
|
||||
>
|
||||
{{ scope.row.soc }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="soh" label="SOH (%)">
|
||||
<template slot-scope="scope">
|
||||
<el-button
|
||||
@click="chartDetail(scope.row, 'SOH (%)')"
|
||||
type="text"
|
||||
size="small"
|
||||
>
|
||||
{{ scope.row.soh }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="160">
|
||||
<template slot-scope="scope">
|
||||
<el-button @click="$emit('pointDetail',scope.row,'point')" type="text" size="small">
|
||||
详细
|
||||
</el-button>
|
||||
<el-button @click="$emit('pointDetail',scope.row,'alarmPoint')" type="text" size="small">
|
||||
报警点位详细
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- <el-pagination
|
||||
v-show="tableData.length > 0"
|
||||
background
|
||||
@size-change="(val) => $emit('handleSizeChange', val)"
|
||||
@current-change="(val) => $emit('handleCurrentChange', val)"
|
||||
: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>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
tableData: {
|
||||
require: true,
|
||||
type: Array,
|
||||
default: () => {
|
||||
return [];
|
||||
},
|
||||
},
|
||||
pointIdList: {
|
||||
require: true,
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {};
|
||||
},
|
||||
},
|
||||
totalSize: {
|
||||
require: true,
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
// pageNum: {
|
||||
// require: true,
|
||||
// type: Number,
|
||||
// default: 1,
|
||||
// },
|
||||
// pageSize: {
|
||||
// require: true,
|
||||
// type: Number,
|
||||
// default: 10,
|
||||
// },
|
||||
},
|
||||
data() {
|
||||
return {};
|
||||
},
|
||||
methods: {
|
||||
//查看表格行图表
|
||||
chartDetail(row, dataType = "") {
|
||||
this.$emit("chart", {...row, dataType});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style></style>
|
||||
@ -1,120 +1,354 @@
|
||||
|
||||
<template>
|
||||
<el-card shadow="always" class="common-card-container common-card-container-no-title-bg">
|
||||
<div slot="header">
|
||||
<span class="large-title">单体电池实时数据</span>
|
||||
</div>
|
||||
<!-- 搜索栏-->
|
||||
<div class="select-container">
|
||||
<el-form :inline="true">
|
||||
<el-form-item label="电池堆">
|
||||
<el-select v-model="search.dcd" placeholder="请选择" :loading="loading" loading-text="正在加载数据">
|
||||
<el-option :label="item.name" :value="item.id" v-for="(item,index) in dcdOptions" :key="index+'dcdOptions'"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="电池簇">
|
||||
<el-select v-model="search.dcc" placeholder="请选择" :loading="loading" loading-text="正在加载数据">
|
||||
<el-option :label="item.name" :value="item.id" v-for="(item,index) in dccOptions" :key="index+'dccOptions'"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="warning" @click="onSearch" native-type="button">搜索</el-button>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button @click="onReset" native-type="button">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-card
|
||||
v-loading="loading"
|
||||
shadow="always"
|
||||
class="sbjk-card-container common-card-container-no-title-bg running-card-container"
|
||||
>
|
||||
<div slot="header">
|
||||
<span class="large-title">单体电池实时数据</span>
|
||||
</div>
|
||||
<!-- 搜索栏-->
|
||||
<el-form :inline="true" class="select-container">
|
||||
<el-form-item label="编号">
|
||||
<el-input
|
||||
v-model="search.batteryId"
|
||||
placeholder="请输入"
|
||||
clearable
|
||||
style="width: 150px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="电池堆">
|
||||
<el-select
|
||||
v-model="search.stackId"
|
||||
placeholder="请选择"
|
||||
@change="changeStackId"
|
||||
>
|
||||
<el-option
|
||||
:label="item.deviceName"
|
||||
:value="item.id"
|
||||
v-for="(item, index) in stackOptions"
|
||||
:key="index + 'stackOptions'"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="电池簇">
|
||||
<el-select
|
||||
v-model="search.clusterId"
|
||||
:no-data-text="
|
||||
!search.stackId && stackOptions.length > 0
|
||||
? '请先选择电池堆'
|
||||
: '无数据'
|
||||
"
|
||||
placeholder="请选择"
|
||||
:loading="clusterloading"
|
||||
loading-text="正在加载数据"
|
||||
>
|
||||
<el-option
|
||||
:label="item.deviceName"
|
||||
:value="item.id"
|
||||
v-for="(item, index) in clusterOptions"
|
||||
:key="index + 'clusterOptions'"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="onSearch" native-type="button"
|
||||
>搜索</el-button
|
||||
>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button @click="onReset" native-type="button">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<!-- 切换 -->
|
||||
<div class="tip-container">
|
||||
<div class="color-tip" v-show="activeBtn === 'list'">
|
||||
单体信息
|
||||
<span class="tip minwd">最低单体温度</span>
|
||||
<span class="tip maxwd">最高单体温度</span>
|
||||
<span class="tip mindy">单体最低电压</span>
|
||||
<span class="tip maxdy">单体最高电压</span>
|
||||
</div>
|
||||
<div style="margin:30px 0;box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);">
|
||||
<!-- 四个选择按钮-->
|
||||
<el-row style="">
|
||||
<el-col :xs="24" :sm="24" :lg="24">
|
||||
<el-button-group>
|
||||
<el-button v-for="(item,index) in btnList" :key="index+'dtdcBtns'" type="warning" :class="{'activeBtn' : activeBtn === item.id}" @click="changeDataType(item.id)">{{item.name}}</el-button>
|
||||
</el-button-group>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<!-- 图表-->
|
||||
<el-row style="background:#fff;margin:30px 0;">
|
||||
<el-col :xs="24" :sm="24" :lg="24">
|
||||
<bar-chart ref="barChart"/>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</el-card>
|
||||
<el-button-group class="ems-btns-group">
|
||||
<el-button
|
||||
:class="{ activeBtn: activeBtn === 'table' }"
|
||||
@click="changeMenu('table')"
|
||||
>图表</el-button
|
||||
>
|
||||
<el-button
|
||||
:class="{ activeBtn: activeBtn === 'list' }"
|
||||
@click="changeMenu('list')"
|
||||
>图形</el-button
|
||||
>
|
||||
</el-button-group>
|
||||
</div>
|
||||
<component
|
||||
:is="activeBtn === 'table' ? 'DtdcTable' : 'DtdcList'"
|
||||
:tableData="tableData"
|
||||
:totalSize="totalSize"
|
||||
:pointIdList="pointIdList"
|
||||
@chart="chartDetail"
|
||||
@pointDetail="pointDetail"
|
||||
></component>
|
||||
<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>
|
||||
<chart-detail ref="chartDetail" />
|
||||
<point-chart ref="pointChart" :site-id="siteId" />
|
||||
<point-table ref="pointTable"/>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
|
||||
<script>
|
||||
import BarChart from './BarChart'
|
||||
import BarChart from "./BarChart";
|
||||
import {
|
||||
getStackNameList,
|
||||
getClusterNameList,
|
||||
getClusterDataInfoList,
|
||||
} from "@/api/ems/dzjk";
|
||||
import getQuerySiteId from "@/mixins/ems/getQuerySiteId";
|
||||
import ChartDetail from "./ChartDetail.vue";
|
||||
import Table from "./Table.vue";
|
||||
import List from "./List.vue";
|
||||
import pointChart from "./../PointChart.vue";
|
||||
import PointTable from "@/views/ems/site/sblb/PointTable.vue";
|
||||
export default {
|
||||
name:'DzjkSbjkDtdc',
|
||||
components:{BarChart},
|
||||
name: "DzjkSbjkDtdc",
|
||||
mixins: [getQuerySiteId],
|
||||
components: {
|
||||
PointTable,
|
||||
BarChart,
|
||||
ChartDetail,
|
||||
DtdcTable: Table,
|
||||
DtdcList: List,
|
||||
pointChart,
|
||||
},
|
||||
computed: {
|
||||
pointIdList() {
|
||||
let obj = {};
|
||||
this.pointData.forEach((item) => {
|
||||
const {
|
||||
maxCellTempId,
|
||||
maxCellVoltageId,
|
||||
minCellTempId,
|
||||
minCellVoltageId,
|
||||
} = item;
|
||||
obj[item.clusterId] = [
|
||||
parseInt(minCellTempId || 0),
|
||||
parseInt(maxCellTempId || 0),
|
||||
parseInt(minCellVoltageId || 0),
|
||||
parseInt(maxCellVoltageId || 0),
|
||||
]; //最低单体温度 最高温度 最低电压 最高电压 todo 这里的顺序需要和图形组件里的顺序保持一致,
|
||||
});
|
||||
return obj;
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
btnList:[
|
||||
{name:'电压',id:'dy'},
|
||||
{name:'温度',id:'wd'},
|
||||
{name:'SOC',id:'soc'},
|
||||
{name:'SOH',id:'soh'},
|
||||
],
|
||||
activeBtn:'dy',
|
||||
loading:false,
|
||||
search:{dcd:'',dcc:''},
|
||||
dcdOptions:[
|
||||
{name:'电池堆1',id:1},
|
||||
{name:'电池堆2',id:2},
|
||||
{name:'电池堆3',id:3},
|
||||
],
|
||||
dccOptions:[
|
||||
{name:'电池簇1',id:1},
|
||||
{name:'电池簇2',id:2},
|
||||
]
|
||||
}
|
||||
loading: false,
|
||||
clusterloading: false,
|
||||
search: { stackId: "", clusterId: "", batteryId: "" },
|
||||
stackOptions: [], //{id:'',deviceName:''}
|
||||
clusterOptions: [], //{id:'',deviceName:''}
|
||||
tableData: [],
|
||||
pointData: [],
|
||||
pageSize: 40, //分页栏当前每个数据总数
|
||||
pageNum: 1, //分页栏当前页数
|
||||
totalSize: 0, //table表格数据总数
|
||||
activeBtn: "table",
|
||||
};
|
||||
},
|
||||
methods:{
|
||||
methods: {
|
||||
// 查看设备电位表格
|
||||
pointDetail(row,dataType){
|
||||
const {deviceId,clusterDeviceId} = row
|
||||
this.$refs.pointTable.showTable({siteId:this.siteId,deviceId,deviceCategory:'BATTERY',parentId:clusterDeviceId},dataType)
|
||||
},
|
||||
changeMenu(menu) {
|
||||
const { activeBtn } = this;
|
||||
activeBtn !== menu && (this.activeBtn = menu);
|
||||
},
|
||||
//查看表格行图表
|
||||
chartDetail({ deviceId, clusterDeviceId, dataType = "" }) {
|
||||
dataType &&
|
||||
this.$refs.pointChart.showChart({
|
||||
pointName: dataType,
|
||||
deviceCategory:'BATTERY',
|
||||
deviceId: clusterDeviceId,
|
||||
child: [deviceId],
|
||||
});
|
||||
},
|
||||
// 分页
|
||||
handleSizeChange(val) {
|
||||
this.pageSize = val;
|
||||
this.$nextTick(() => {
|
||||
this.getTableData();
|
||||
});
|
||||
},
|
||||
handleCurrentChange(val) {
|
||||
this.pageNum = val;
|
||||
this.$nextTick(() => {
|
||||
this.getTableData();
|
||||
});
|
||||
},
|
||||
// 搜索
|
||||
onSearch(){
|
||||
this.getData()
|
||||
onSearch() {
|
||||
this.pageNum = 1; //每次搜索从1开始搜索
|
||||
this.getTableData();
|
||||
},
|
||||
// 重置
|
||||
onReset(){
|
||||
this.search.dcd=''
|
||||
this.search.dcc=''
|
||||
this.getData()
|
||||
// 清空搜索栏选中数据
|
||||
// 清空电池簇列表,保留电池堆列表
|
||||
onReset() {
|
||||
this.search = { stackId: "", clusterId: "", batteryId: "" };
|
||||
this.clusterOptions = [];
|
||||
this.pageNum = 1;
|
||||
this.getTableData();
|
||||
},
|
||||
// 获取数据
|
||||
getData(){
|
||||
this.$refs.barChart.chart.showLoading()
|
||||
//获取完成后 传入data todo传参
|
||||
this.$refs.barChart.setOption()
|
||||
},
|
||||
changeDataType(id){
|
||||
if(id !== this.activeBtn){
|
||||
console.log('点击了不同的菜单,更新数据')
|
||||
this.activeBtn=id;
|
||||
changeStackId(val) {
|
||||
if (val) {
|
||||
console.log(
|
||||
"选择了电池堆,需要获取对应的电池簇",
|
||||
val,
|
||||
this.search.stackId
|
||||
);
|
||||
this.search.clusterId = "";
|
||||
this.getClusterList();
|
||||
}
|
||||
},
|
||||
|
||||
//表格数据
|
||||
getTableData() {
|
||||
this.loading = true;
|
||||
const {
|
||||
stackId: stackDeviceId,
|
||||
clusterId: clusterDeviceId,
|
||||
batteryId,
|
||||
} = this.search;
|
||||
const { siteId, pageNum, pageSize } = this;
|
||||
getClusterDataInfoList({
|
||||
stackDeviceId,
|
||||
clusterDeviceId,
|
||||
siteId,
|
||||
batteryId,
|
||||
pageNum,
|
||||
pageSize,
|
||||
})
|
||||
.then((response) => {
|
||||
this.tableData = response?.rows?.[0]?.batteryList || []; //todo check
|
||||
this.pointData = response?.rows?.[0]?.clusterList || []; //todo check
|
||||
this.totalSize = response?.total || 0;
|
||||
})
|
||||
.finally(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
getStackList() {
|
||||
getStackNameList(this.siteId).then((response) => {
|
||||
this.stackOptions = JSON.parse(JSON.stringify(response?.data || []));
|
||||
});
|
||||
},
|
||||
getClusterList() {
|
||||
this.clusterloading = true;
|
||||
getClusterNameList({
|
||||
stackDeviceId: this.search.stackId,
|
||||
siteId: this.siteId,
|
||||
})
|
||||
.then((response) => {
|
||||
this.clusterOptions = JSON.parse(
|
||||
JSON.stringify(response?.data || [])
|
||||
);
|
||||
})
|
||||
.finally(() => {
|
||||
this.clusterloading = false;
|
||||
});
|
||||
},
|
||||
init() {
|
||||
// 只有页面初次加载或切换站点的时候调用电池堆列表,其他情况不需要
|
||||
this.search = { stackId: "", clusterId: "", batteryId: "" }; //保证切换站点时,清空选择项
|
||||
this.clusterOptions = [];
|
||||
this.pageNum = 1;
|
||||
this.totalSize = 0;
|
||||
this.getStackList();
|
||||
this.getTableData();
|
||||
},
|
||||
},
|
||||
mounted(){
|
||||
this.$refs.barChart.initChart()
|
||||
this.getData()
|
||||
|
||||
}
|
||||
}
|
||||
mounted() {},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.select-container{
|
||||
.el-form--inline .el-form-item{
|
||||
margin-right: 20px;
|
||||
.tip-container {
|
||||
text-align: right;
|
||||
position: relative;
|
||||
.color-tip {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 0;
|
||||
transform: translateY(-50%);
|
||||
font-size: 11px;
|
||||
line-height: 12px;
|
||||
color: #333;
|
||||
.tip {
|
||||
padding-left: 30px;
|
||||
position: relative;
|
||||
&::before {
|
||||
display: block;
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 14px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
&.minwd {
|
||||
color: #3794ff;
|
||||
&::before {
|
||||
background: #3794ff;
|
||||
}
|
||||
}
|
||||
&.maxwd {
|
||||
color: #ff3a3b;
|
||||
&::before {
|
||||
background: #ff3a3b;
|
||||
}
|
||||
}
|
||||
&.mindy {
|
||||
color: #de6902;
|
||||
&::before {
|
||||
background: #de6902;
|
||||
}
|
||||
}
|
||||
&.maxdy {
|
||||
color: #ffb521;
|
||||
&::before {
|
||||
background: #ffb521;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
::v-deep {
|
||||
.el-button-group.ems-btns-group {
|
||||
& > .el-button {
|
||||
padding: 5px 30px !important;
|
||||
font-size: 11px;
|
||||
line-height: 16px;
|
||||
// padding-left: 50px;
|
||||
// padding-right: 50px;
|
||||
// font-size: 16px;
|
||||
// line-height: 24px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.activeBtn{
|
||||
background-color: #FFF2CB;
|
||||
border-color: #FFF2CB;
|
||||
color: #666666;
|
||||
font-weight: 600;
|
||||
}
|
||||
</style>
|
||||
|
||||
133
src/views/ems/dzjk/sbjk/ems/index.vue
Normal file
@ -0,0 +1,133 @@
|
||||
<template>
|
||||
<div v-loading="loading" class="ems">
|
||||
<el-card
|
||||
v-for="(item,index) in list"
|
||||
:key="index+'emsList'"
|
||||
class="sbjk-card-container list running-card-container"
|
||||
shadow="always"
|
||||
>
|
||||
<div slot="header">
|
||||
<span class="large-title">{{ item.deviceName }}</span>
|
||||
<div class="info">
|
||||
<div>
|
||||
EMS控制模式: {{
|
||||
item.emsStatus === 0 ? '自动' : '手动'
|
||||
}}
|
||||
</div>
|
||||
<div>数据更新时间:{{ item.dataUpdateTime }}</div>
|
||||
</div>
|
||||
<div class="alarm">
|
||||
<el-button size="small" round style="margin-right:20px;" type="primary" @click="pointDetail(item,'point')">详细
|
||||
</el-button>
|
||||
<el-badge :hidden="!item.alarmNum" :value="item.alarmNum || 0" class="item">
|
||||
<i
|
||||
class="el-icon-message-solid alarm-icon"
|
||||
@click="pointDetail(item,'alarmPoint')"
|
||||
></i>
|
||||
</el-badge>
|
||||
</div>
|
||||
</div>
|
||||
<el-row class="device-info-row">
|
||||
<el-col v-for="(tempDataItem,tempDataIndex) in bmsDataList" :key="tempDataIndex+'bmsTempData'"
|
||||
:span="6" class="device-info-col">
|
||||
<span class="pointer" @click="showChart(tempDataItem.name,item.deviceId)">
|
||||
<span class="left">{{ tempDataItem.name }}</span> <span class="right">{{ item[tempDataItem.attr] }}<span
|
||||
v-html="tempDataItem.unit"></span></span>
|
||||
</span>
|
||||
</el-col>
|
||||
<el-col v-for="(tempDataItem,tempDataIndex) in pcsDataList" :key="tempDataIndex+'pcsTempData'"
|
||||
:span="6" class="device-info-col">
|
||||
<span class="pointer" @click="showChart(tempDataItem.name,item.deviceId)">
|
||||
<span class="left">{{ tempDataItem.name }}</span> <span class="right">{{ item[tempDataItem.attr] }}<span
|
||||
v-html="tempDataItem.unit"></span></span>
|
||||
</span>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-card>
|
||||
|
||||
<el-empty v-show="list.length <= 0" :image-size="200"></el-empty>
|
||||
<point-chart ref="pointChart" :site-id="siteId"/>
|
||||
<point-table ref="pointTable"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import pointChart from "./../PointChart.vue";
|
||||
import PointTable from "@/views/ems/site/sblb/PointTable.vue";
|
||||
import getQuerySiteId from "@/mixins/ems/getQuerySiteId";
|
||||
import {getEmsDataList} from "@/api/ems/dzjk";
|
||||
import intervalUpdate from "@/mixins/ems/intervalUpdate";
|
||||
|
||||
export default {
|
||||
name: "DzjkSbjkEms",
|
||||
components: {pointChart, PointTable},
|
||||
mixins: [getQuerySiteId, intervalUpdate],
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
list: [],
|
||||
bmsDataList: [{
|
||||
name: 'BMS1SOC',
|
||||
attr: 'bms1Soc'
|
||||
},
|
||||
{
|
||||
name: 'BMS2SOC',
|
||||
attr: 'bms2Soc'
|
||||
},
|
||||
{
|
||||
name: 'BMS3SOC',
|
||||
attr: 'bms3Soc'
|
||||
},
|
||||
{
|
||||
name: 'BMS4SOC',
|
||||
attr: 'bms4Soc'
|
||||
}],
|
||||
pcsDataList: [{
|
||||
name: 'PCS-1有功功率',
|
||||
attr: 'pcs1Yggl'
|
||||
},
|
||||
{
|
||||
name: 'PCS-2有功功率',
|
||||
attr: 'pcs2Yggl'
|
||||
},
|
||||
{
|
||||
name: 'PCS-3有功功率',
|
||||
attr: 'pcs3Yggl'
|
||||
},
|
||||
{
|
||||
name: 'PCS-4有功功率',
|
||||
attr: 'pcs4Yggl'
|
||||
}]
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
// 查看设备电位表格
|
||||
pointDetail(row, dataType) {
|
||||
const {deviceId} = row
|
||||
this.$refs.pointTable.showTable({siteId: this.siteId, deviceId, deviceCategory: 'EMS'}, dataType)
|
||||
},
|
||||
showChart(pointName, deviceId) {
|
||||
pointName &&
|
||||
this.$refs.pointChart.showChart({pointName, deviceCategory: 'EMS', deviceId});
|
||||
},
|
||||
getData() {
|
||||
this.loading = true;
|
||||
getEmsDataList(this.siteId)
|
||||
.then((response) => {
|
||||
const data = response?.data || {};
|
||||
this.list = JSON.parse(JSON.stringify(data));
|
||||
})
|
||||
.finally(() => (this.loading = false));
|
||||
},
|
||||
updateData() {
|
||||
this.getData();
|
||||
},
|
||||
init() {
|
||||
this.updateData();
|
||||
this.updateInterval(this.updateData);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
@ -1,69 +1,70 @@
|
||||
<template>
|
||||
<div class="ems-dashboard-editor-container sbjk-ems-dashboard-editor-container">
|
||||
<div class="router-container">
|
||||
<div>
|
||||
<div class="route-link" :class="{'active':item.name === $route.name}" v-for="(item,index) in childrenRoute" :key="index+'dzjkChildrenRoute'">
|
||||
<div class="ems-dashboard-editor-container ems-third-menu-container" v-loading="loading">
|
||||
<el-menu
|
||||
class="ems-third-menu"
|
||||
:default-active="$route.name"
|
||||
background-color="#ffffff"
|
||||
text-color="#666666"
|
||||
active-text-color="#ffffff"
|
||||
>
|
||||
<el-menu-item :index="item.name" v-for="(item,index) in categoryRouter" :key="index+'dzjkChildrenRoute'">
|
||||
<router-link style="height: 100%;width: 100%;display: block" :to="{path:item.path,query:$route.query}">
|
||||
{{item.meta.title}}
|
||||
</router-link>
|
||||
</el-menu-item>
|
||||
</el-menu>
|
||||
<div class="ems-content-container ems-content-container-padding sbjk-ems-content-container">
|
||||
<keep-alive>
|
||||
<router-view></router-view>
|
||||
</keep-alive>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ems-content-container ems-content-container-padding sbjk-ems-content-container">
|
||||
<keep-alive>
|
||||
<router-view></router-view>
|
||||
</keep-alive>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import getQuerySiteId from "@/mixins/ems/getQuerySiteId";
|
||||
import { dzjk } from '@/router/ems'
|
||||
const childrenRoute = dzjk[0].children[0].children.find(item=> item.name==='DjzkSbjk').children//获取到单站监控-设备监控下面的字路由
|
||||
console.log('设备监控子路由',childrenRoute)
|
||||
import {mapState} from "vuex";
|
||||
const childrenRoute = dzjk[0].children[0].children.find(item=> item.name==='DzjkSbjk').children//获取到单站监控-设备监控下面的字路由
|
||||
export default {
|
||||
name:'DzjkSbjk',
|
||||
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 {
|
||||
childrenRoute,
|
||||
activeMenu:''
|
||||
activeMenu:'',
|
||||
loading:false,
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
console.log('当前设备监控页面路由',this.$route)
|
||||
methods:{
|
||||
init(){
|
||||
this.loading=true
|
||||
this.$store.dispatch('getSiteDeviceCategory',this.siteId).finally(()=>this.loading=false)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.sbjk-ems-dashboard-editor-container{
|
||||
display: flex;
|
||||
padding:0;
|
||||
background: #FFFFFF;
|
||||
}
|
||||
.router-container{
|
||||
&>div{
|
||||
border: 1px solid #dcdfe6;
|
||||
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, .12), 0 0 6px 0 rgba(0, 0, 0, .04);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.route-link{
|
||||
width: 104px;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
background-color: #ffffff;
|
||||
color: #666666;
|
||||
font-size: 14px;
|
||||
text-align: center;
|
||||
}
|
||||
.route-link.active{
|
||||
background-color: #FFBE29 ;
|
||||
color: #333333;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
.sbjk-ems-content-container{
|
||||
margin-top:0;
|
||||
padding-top:0;
|
||||
|
||||
@ -1,107 +1,324 @@
|
||||
|
||||
<template>
|
||||
<div class="pcs-ems-dashboard-editor-container">
|
||||
<real-time-base-info/>
|
||||
<el-container class="pcs-container">
|
||||
<el-header class="pcs-header">
|
||||
<div class="pcs-title">PCS</div>
|
||||
<div class="pcs-status">
|
||||
<div>通信中断</div>
|
||||
<div>数据更新时间:2024-10-11 12:00:00</div>
|
||||
<div v-loading="loading" class="pcs-ems-dashboard-editor-container">
|
||||
<!-- 顶部六个方块-->
|
||||
<real-time-base-info :data="runningHeadData"/>
|
||||
<div
|
||||
v-for="(pcsItem, pcsIndex) in pcsList"
|
||||
:key="pcsIndex + 'PcsHome'"
|
||||
style="margin-bottom: 25px"
|
||||
>
|
||||
<el-card
|
||||
:class="handleCardClass(pcsItem)"
|
||||
class="sbjk-card-container common-card-container-body-no-padding common-card-container-no-title-bg"
|
||||
shadow="always"
|
||||
>
|
||||
<div slot="header">
|
||||
<span class="large-title"
|
||||
>{{ pcsItem.deviceName }}</span
|
||||
>
|
||||
<div class="info">
|
||||
<div>
|
||||
{{
|
||||
$store.state.ems.communicationStatusOptions[
|
||||
pcsItem.communicationStatus
|
||||
]
|
||||
}}
|
||||
</div>
|
||||
<div>数据更新时间:{{ pcsItem.dataUpdateTime }}</div>
|
||||
</div>
|
||||
<div class="alarm">
|
||||
<el-button type="primary" round size="small" style="margin-right:20px;"
|
||||
@click="pointDetail(pcsItem,'point')">
|
||||
详细
|
||||
</el-button>
|
||||
<el-badge :hidden="!pcsItem.alarmNum" :value="pcsItem.alarmNum || 0" class="item">
|
||||
<i
|
||||
class="el-icon-message-solid alarm-icon"
|
||||
@click="pointDetail(pcsItem,'alarmPoint')"
|
||||
></i>
|
||||
</el-badge>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pcs-btns">
|
||||
<el-button type="warning" size="small">警告按钮</el-button>
|
||||
<el-button size="small">默认按钮</el-button>
|
||||
</div>
|
||||
</el-header>
|
||||
<el-main style="padding: 0">
|
||||
<div class="descriptions-main">
|
||||
<el-descriptions direction="vertical" :column="4" :colon="false">
|
||||
<el-descriptions-item labelClassName="descriptions-label" contentClassName="descriptions-direction danger" :span="1" label="工作状态">停止</el-descriptions-item>
|
||||
<el-descriptions-item labelClassName="descriptions-label" contentClassName="descriptions-direction" :span="1" label="并网状态">并网</el-descriptions-item>
|
||||
<el-descriptions-item labelClassName="descriptions-label" contentClassName="descriptions-direction save" :span="1" label="设备状态">在线</el-descriptions-item>
|
||||
<el-descriptions-item labelClassName="descriptions-label" contentClassName="descriptions-direction" :span="1" label="控制模式">远程</el-descriptions-item>
|
||||
<el-descriptions :colon="false" :column="4" direction="vertical">
|
||||
<el-descriptions-item
|
||||
contentClassName="descriptions-direction work-status"
|
||||
:span="1"
|
||||
label="工作状态"
|
||||
labelClassName="descriptions-label"
|
||||
>{{
|
||||
PCSWorkStatusOptions[pcsItem.workStatus]
|
||||
}}
|
||||
</el-descriptions-item
|
||||
>
|
||||
<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 === '1' ? '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 labelClassName="descriptions-label" contentClassName="descriptions-direction" direction="vertical" :column="4" :colon="false">
|
||||
<el-descriptions-item v-for="(item,index) in infoData" :key="index+'pcsInfoData'" :span="1" :label="item.label">{{item.value}} <span v-if="item.unit" v-html="item.unit"></span></el-descriptions-item>
|
||||
<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>
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</div>
|
||||
<div class="descriptions-main">
|
||||
<el-descriptions labelClassName="descriptions-label" contentClassName="descriptions-direction keep" direction="vertical" :column="4" :colon="false">
|
||||
<el-descriptions-item labelClassName="descriptions-label" contentClassName="descriptions-direction keep" :span="4" label="支路一">放电中</el-descriptions-item>
|
||||
<el-descriptions-item labelClassName="descriptions-label" contentClassName="descriptions-direction" :span="1" label="直流功率">-9.8kW</el-descriptions-item>
|
||||
<el-descriptions-item labelClassName="descriptions-label" contentClassName="descriptions-direction" :span="1" label="直流电压">720.4V</el-descriptions-item>
|
||||
<el-descriptions-item labelClassName="descriptions-label" contentClassName="descriptions-direction" :span="1" label="直流电流">-13.1A</el-descriptions-item>
|
||||
<div
|
||||
v-for="(item, index) in pcsItem.pcsBranchInfoList"
|
||||
:key="index + 'pcsBranchInfoList'"
|
||||
class="descriptions-main"
|
||||
>
|
||||
<el-descriptions
|
||||
:colon="false"
|
||||
:column="4"
|
||||
contentClassName="descriptions-direction keep"
|
||||
direction="vertical"
|
||||
labelClassName="descriptions-label"
|
||||
>
|
||||
<el-descriptions-item
|
||||
: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-main>
|
||||
</el-container>
|
||||
</el-card>
|
||||
</div>
|
||||
<el-empty v-show="pcsList.length <= 0" :image-size="200"></el-empty>
|
||||
<point-chart ref="pointChart" :site-id="siteId"/>
|
||||
<point-table ref="pointTable"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import pointChart from "./../PointChart.vue";
|
||||
import PointTable from "@/views/ems/site/sblb/PointTable.vue";
|
||||
import RealTimeBaseInfo from "./../RealTimeBaseInfo.vue";
|
||||
import getQuerySiteId from "@/mixins/ems/getQuerySiteId";
|
||||
import {getPcsDetailInfo, getRunningHeadInfo} from "@/api/ems/dzjk";
|
||||
import intervalUpdate from "@/mixins/ems/intervalUpdate";
|
||||
import {mapState} from "vuex";
|
||||
|
||||
export default {
|
||||
components:{RealTimeBaseInfo},
|
||||
name: "DzjkSbjkPcs",
|
||||
components: {RealTimeBaseInfo, pointChart, PointTable},
|
||||
mixins: [getQuerySiteId, intervalUpdate],
|
||||
computed: {
|
||||
...mapState({
|
||||
PCSWorkStatusOptions: state => state?.ems?.PCSWorkStatusOptions || {},
|
||||
})
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
infoData:[
|
||||
{label:'总交流有功电率',value:'-7.2',attr:'',unit:'kW'},
|
||||
{label:'当天交流充电量',value:'0',attr:'',unit:'kWh'},
|
||||
{label:'A相电压',value:'12',attr:'',unit:'V'},
|
||||
{label:'A相电流',value:'20',attr:'',unit:'A'},
|
||||
{label:'总交流无功电率',value:'-0.1',attr:'',unit:'kVar'},
|
||||
{label:'当天交流放电量',value:'145',attr:'',unit:'kWh'},
|
||||
{label:'B相电压',value:'12',attr:'',unit:'V'},
|
||||
{label:'B相电流',value:'20',attr:'',unit:'A'},
|
||||
{label:'总交流视在功率',value:'8',attr:'',unit:'kVA'},
|
||||
{label:'PCS模块温度',value:'40',attr:'',unit:'℃'},
|
||||
{label:'C相电压',value:'12',attr:'',unit:'V'},
|
||||
{label:'C相电流',value:'20',attr:'',unit:'A'},
|
||||
{label:'总交流功率因数',value:'-0.9',attr:'',unit:''},
|
||||
{label:'PCS环境温度',value:'12',attr:'',unit:'℃'},
|
||||
{label:'交流频率',value:'102',attr:'',unit:'Hz'}
|
||||
loading: false,
|
||||
runningHeadData: {}, //运行信息
|
||||
pcsList: [],
|
||||
infoData: [
|
||||
{
|
||||
label: "总交流有功功率",
|
||||
attr: "totalActivePower",
|
||||
unit: "kW",
|
||||
pointName: "总交流有功功率",
|
||||
},
|
||||
{
|
||||
label: "当天交流充电量",
|
||||
attr: "dailyAcChargeEnergy",
|
||||
unit: "kWh",
|
||||
pointName: "当天交流充电量 (kWh)",
|
||||
},
|
||||
{label: "A相电压", attr: "aPhaseVoltage", unit: "V", 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的支路列表
|
||||
};
|
||||
},
|
||||
|
||||
}
|
||||
methods: {
|
||||
handleCardClass(item) {
|
||||
const {workStatus = ''} = item
|
||||
return workStatus === '1' || !Object.keys(this.PCSWorkStatusOptions).find(i => i === workStatus) ? "timing-card-container" : workStatus === '2' ? 'warning-card-container' : 'running-card-container'
|
||||
},
|
||||
// 查看设备电位表格
|
||||
pointDetail(row, dataType) {
|
||||
const {deviceId} = row
|
||||
this.$refs.pointTable.showTable({siteId: this.siteId, deviceId, deviceCategory: 'PCS'}, dataType)
|
||||
},
|
||||
showChart(pointName, deviceId, isBranch = false) {
|
||||
pointName &&
|
||||
this.$refs.pointChart.showChart({pointName, deviceCategory: isBranch ? 'BRANCH' : 'PCS', deviceId});
|
||||
},
|
||||
//6个方块数据
|
||||
getRunningHeadData() {
|
||||
getRunningHeadInfo(this.siteId).then((response) => {
|
||||
this.runningHeadData = response?.data || {};
|
||||
});
|
||||
},
|
||||
getPcsList() {
|
||||
this.loading = true;
|
||||
getPcsDetailInfo(this.siteId)
|
||||
.then((response) => {
|
||||
const data = response?.data || {};
|
||||
this.pcsList = JSON.parse(JSON.stringify(data));
|
||||
})
|
||||
.finally(() => (this.loading = false));
|
||||
},
|
||||
updateData() {
|
||||
this.getRunningHeadData();
|
||||
this.getPcsList();
|
||||
},
|
||||
init() {
|
||||
this.updateData();
|
||||
this.updateInterval(this.updateData);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.pcs-container{
|
||||
margin-top: 25px;
|
||||
//红色标题
|
||||
.pcs-header{
|
||||
background: #FC6B69;
|
||||
display: flex;
|
||||
position: relative;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
padding: 0;
|
||||
height: 60px;
|
||||
border-radius: 6px 6px 0 0;
|
||||
.pcs-title{
|
||||
color: #ffffff;
|
||||
font-size: 20px;
|
||||
font-weight: 500;
|
||||
line-height: 20px;
|
||||
padding: 0 50px 0 25px;
|
||||
}
|
||||
.pcs-status{
|
||||
color: #ffffff;
|
||||
font-size: 12px;
|
||||
line-height: 20px;
|
||||
}
|
||||
.pcs-btns{
|
||||
position: absolute;
|
||||
right: 25px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<style lang="scss" scoped></style>
|
||||
|
||||
@ -1,8 +1,10 @@
|
||||
|
||||
<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">
|
||||
<span class="card-title">储能功率曲线</span>
|
||||
<span class="card-title">PCS有功功率/PCS无功功率</span>
|
||||
</div>
|
||||
<div style="height: 360px" id="cnglqxChart"/>
|
||||
</el-card>
|
||||
@ -10,72 +12,133 @@
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
<script>
|
||||
import * as echarts from 'echarts'
|
||||
require('echarts/theme/macarons') // echarts theme
|
||||
import resize from '@/mixins/ems/resize'
|
||||
import * as echarts from "echarts";
|
||||
import resize from "@/mixins/ems/resize";
|
||||
import {storagePower} from "@/api/ems/dzjk";
|
||||
|
||||
export default {
|
||||
mixins: [resize],
|
||||
data() {
|
||||
return {
|
||||
chart: null
|
||||
}
|
||||
chart: null,
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.$nextTick(() => {
|
||||
this.initChart()
|
||||
})
|
||||
this.chart = echarts.init(document.querySelector("#cnglqxChart"));
|
||||
},
|
||||
beforeDestroy() {
|
||||
if (!this.chart) {
|
||||
return
|
||||
return;
|
||||
}
|
||||
this.chart.dispose()
|
||||
this.chart = null
|
||||
this.chart.dispose();
|
||||
this.chart = null;
|
||||
},
|
||||
methods: {
|
||||
initChart() {
|
||||
this.chart = echarts.init(document.querySelector('#cnglqxChart'))
|
||||
this.setOptions()
|
||||
init(siteId, timeRange) {
|
||||
this.chart.showLoading();
|
||||
const [startTime = '', endTime = ''] = timeRange;
|
||||
storagePower(siteId, startTime, endTime)
|
||||
.then((response) => {
|
||||
this.setOption(response?.data?.pcsPowerList || []);
|
||||
})
|
||||
.finally(() => {
|
||||
this.chart.hideLoading();
|
||||
});
|
||||
},
|
||||
setOptions() {
|
||||
|
||||
this.chart.setOption({
|
||||
color:['#FFBD00','#3C81FF'],
|
||||
setOption(data) {
|
||||
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) => {
|
||||
return {
|
||||
value: i.pcsTotalActPower,
|
||||
year: i.dateDay || ''
|
||||
}
|
||||
}
|
||||
)
|
||||
},
|
||||
{
|
||||
type: "line",
|
||||
name: `${element.deviceId}无功功率`,
|
||||
areaStyle: {
|
||||
// color:'#FFBD00'
|
||||
},
|
||||
data: (element.energyStoragePowList || []).map(
|
||||
(i) => {
|
||||
return {
|
||||
value: i.pcsTotalReactivePower,
|
||||
year: i.dateDay || ''
|
||||
}
|
||||
}
|
||||
),
|
||||
}
|
||||
);
|
||||
});
|
||||
this.chart && this.chart.setOption({
|
||||
legend: {
|
||||
left: 'center',
|
||||
bottom: '10',
|
||||
left: "center",
|
||||
top: "5",
|
||||
itemWidth: 10,
|
||||
itemHeight: 5,
|
||||
textStyle: {
|
||||
fontSize: 9,
|
||||
},
|
||||
},
|
||||
grid: {
|
||||
containLabel: true,
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: { // 坐标轴指示器,坐标轴触发有效
|
||||
type: 'shadow' // 默认为直线,可选为:'line' | 'shadow'
|
||||
show: true,
|
||||
trigger: "axis",
|
||||
axisPointer: {
|
||||
// 坐标轴指示器,坐标轴触发有效
|
||||
type: "shadow", // 默认为直线,可选为:'line' | 'shadow'
|
||||
},
|
||||
formatter: (params) => {
|
||||
if (params.length <= 0) return
|
||||
let result = (params[0].data.year || '') + ' ' + params[0].name + '<div>'
|
||||
params.forEach(item => {
|
||||
const {color, seriesName, value} = item
|
||||
result += `<div style="position: relative;padding-left:20px;line-height: 20px;">
|
||||
<div style="position: absolute;top:50%;left:0;width:12px;height:12px;border-radius:100%;background: ${color};transform: translateY(-50%)"></div>
|
||||
<span>${seriesName}</span><span style="margin-left:20px;font-weight: 700">${value}</span></div>`
|
||||
})
|
||||
result += '</div>'
|
||||
return result
|
||||
}
|
||||
},
|
||||
textStyle:{
|
||||
color:"#333333",
|
||||
},
|
||||
xAxis: {
|
||||
data: ['1月','2月','3月','4月','5月','6月','7月','8月','9月','10月','11月','12月'],
|
||||
textStyle: {
|
||||
color: "#333333",
|
||||
},
|
||||
xAxis: {type: "category", data: xdata},
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
type: "value",
|
||||
},
|
||||
// POC昨日有功功率、POC昨日无功功率
|
||||
series: [
|
||||
dataZoom: [
|
||||
{
|
||||
name:'POC实时有功功率',
|
||||
data: [80,92,1,34,90,130,320,80,9,91,34,90],
|
||||
type: 'line',
|
||||
|
||||
},{
|
||||
name:'POC实时无功功率',
|
||||
data: [820,932,901,934,1290,1330,1320,820,932,901,934,1290],
|
||||
type: 'line',
|
||||
}]
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type: "inside",
|
||||
start: 0,
|
||||
end: 100,
|
||||
},
|
||||
{
|
||||
start: 0,
|
||||
end: 100,
|
||||
},
|
||||
],
|
||||
series,
|
||||
}, true);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@ -1,81 +1,122 @@
|
||||
|
||||
<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">
|
||||
<span class="card-title">电池平均SOC</span>
|
||||
<span class="card-title">平均SOC</span>
|
||||
</div>
|
||||
<div style="height: 360px" id="dcpjsocChart"/>
|
||||
<div style="height: 360px" id="dcpjsocChart" />
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
<script>
|
||||
import * as echarts from 'echarts'
|
||||
require('echarts/theme/macarons') // echarts theme
|
||||
import resize from '@/mixins/ems/resize'
|
||||
|
||||
import * as echarts from "echarts";
|
||||
import resize from "@/mixins/ems/resize";
|
||||
import { batteryAveSoc } from "@/api/ems/dzjk";
|
||||
export default {
|
||||
mixins: [resize],
|
||||
data() {
|
||||
return {
|
||||
chart: null
|
||||
}
|
||||
chart: null,
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.$nextTick(() => {
|
||||
this.initChart()
|
||||
})
|
||||
this.chart = echarts.init(document.querySelector("#dcpjsocChart"));
|
||||
},
|
||||
beforeDestroy() {
|
||||
if (!this.chart) {
|
||||
return
|
||||
return;
|
||||
}
|
||||
this.chart.dispose()
|
||||
this.chart = null
|
||||
this.chart.dispose();
|
||||
this.chart = null;
|
||||
},
|
||||
methods: {
|
||||
initChart() {
|
||||
this.chart = echarts.init(document.querySelector('#dcpjsocChart'))
|
||||
this.setOptions()
|
||||
init(siteId,timeRange) {
|
||||
this.chart.showLoading();
|
||||
const [startTime='', endTime=''] = timeRange;
|
||||
batteryAveSoc(siteId,startTime,endTime)
|
||||
.then((response) => {
|
||||
this.setOption(response?.data?.batteryAveSOCList || []);
|
||||
})
|
||||
.finally(() => {
|
||||
this.chart.hideLoading();
|
||||
});
|
||||
},
|
||||
setOptions() {
|
||||
|
||||
this.chart.setOption({
|
||||
color:['#FFBD00','#3C81FF'],
|
||||
setOption(data) {
|
||||
let xdata = [],
|
||||
ydata = [];
|
||||
data.forEach((element) => {
|
||||
xdata.push(element.createDate);
|
||||
ydata.push({
|
||||
value:element.batterySOC,
|
||||
year:element.dateDay,
|
||||
});
|
||||
});
|
||||
this.chart && this.chart.setOption({
|
||||
legend: {
|
||||
left: 'center',
|
||||
bottom: '10',
|
||||
left: "center",
|
||||
top: "5",
|
||||
itemWidth: 10,
|
||||
itemHeight: 5,
|
||||
textStyle: {
|
||||
fontSize: 9,
|
||||
},
|
||||
},
|
||||
grid: {
|
||||
containLabel: true,
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: { // 坐标轴指示器,坐标轴触发有效
|
||||
type: 'shadow' // 默认为直线,可选为:'line' | 'shadow'
|
||||
show:true,
|
||||
trigger: "axis",
|
||||
axisPointer: {
|
||||
// 坐标轴指示器,坐标轴触发有效
|
||||
type: "shadow", // 默认为直线,可选为:'line' | 'shadow'
|
||||
},
|
||||
formatter :(params)=>{
|
||||
if(params.length <= 0) return
|
||||
let result = (params[0].data.year || '')+' '+params[0].name + '<div>'
|
||||
params.forEach(item=>{
|
||||
const {color,seriesName,value} = item
|
||||
result += `<div style="position: relative;padding-left:20px;line-height: 20px;">
|
||||
<div style="position: absolute;top:50%;left:0;width:12px;height:12px;border-radius:100%;background: ${color};transform: translateY(-50%)"></div>
|
||||
<span>${seriesName}</span><span style="margin-left:20px;font-weight: 700">${value}</span></div>`
|
||||
})
|
||||
result+='</div>'
|
||||
return result
|
||||
}
|
||||
},
|
||||
textStyle:{
|
||||
color:"#333333",
|
||||
},
|
||||
xAxis: {
|
||||
data: ['1月','2月','3月','4月','5月','6月','7月','8月','9月','10月','11月','12月'],
|
||||
textStyle: {
|
||||
color: "#333333",
|
||||
},
|
||||
xAxis: { type: "category", data: xdata },
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
type: "value",
|
||||
},
|
||||
// POC昨日有功功率、POC昨日无功功率
|
||||
dataZoom: [
|
||||
{
|
||||
type: "inside",
|
||||
start: 0,
|
||||
end: 100,
|
||||
},
|
||||
{
|
||||
start: 0,
|
||||
end: 100,
|
||||
},
|
||||
],
|
||||
series: [
|
||||
{
|
||||
name:'昨日同时段电池平均SOC',
|
||||
data: [80,92,1,34,90,130,320,80,9,91,34,90],
|
||||
type: 'scatter',
|
||||
|
||||
},{
|
||||
name:'实时电池平均SOC',
|
||||
data: [820,932,901,934,1290,1330,1320,820,932,901,934,1290],
|
||||
type: 'scatter',
|
||||
}]
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type: "line",
|
||||
name: `平均SOC`,
|
||||
areaStyle: {
|
||||
// color:'#FFBD00'
|
||||
},
|
||||
data: ydata,
|
||||
},
|
||||
],
|
||||
},true);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@ -1,81 +1,125 @@
|
||||
|
||||
<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">
|
||||
<span class="card-title">电池平均温度</span>
|
||||
</div>
|
||||
<div style="height: 360px" id="dcpjwdChart"/>
|
||||
<div style="height: 360px" id="dcpjwdChart" />
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
<script>
|
||||
import * as echarts from 'echarts'
|
||||
require('echarts/theme/macarons') // echarts theme
|
||||
import resize from '@/mixins/ems/resize'
|
||||
import * as echarts from "echarts";
|
||||
import resize from "@/mixins/ems/resize";
|
||||
import { batteryAveTemp } from "@/api/ems/dzjk";
|
||||
|
||||
export default {
|
||||
mixins: [resize],
|
||||
data() {
|
||||
return {
|
||||
chart: null
|
||||
}
|
||||
chart: null,
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.$nextTick(() => {
|
||||
this.initChart()
|
||||
})
|
||||
this.chart = echarts.init(document.querySelector("#dcpjwdChart"));
|
||||
},
|
||||
beforeDestroy() {
|
||||
if (!this.chart) {
|
||||
return
|
||||
return;
|
||||
}
|
||||
this.chart.dispose()
|
||||
this.chart = null
|
||||
this.chart.dispose();
|
||||
this.chart = null;
|
||||
},
|
||||
methods: {
|
||||
initChart() {
|
||||
this.chart = echarts.init(document.querySelector('#dcpjwdChart'))
|
||||
this.setOptions()
|
||||
init(siteId,timeRange) {
|
||||
this.chart.showLoading();
|
||||
const [startTime='', endTime=''] = timeRange;
|
||||
batteryAveTemp(siteId,startTime,endTime)
|
||||
.then((response) => {
|
||||
this.setOption(response?.data?.batteryAveTempList || []);
|
||||
})
|
||||
.finally(() => {
|
||||
this.chart.hideLoading();
|
||||
});
|
||||
},
|
||||
setOptions() {
|
||||
|
||||
this.chart.setOption({
|
||||
color:['#FFBD00','#3C81FF'],
|
||||
setOption(data) {
|
||||
let xdata = [],
|
||||
ydata = [];
|
||||
data.forEach((element) => {
|
||||
xdata.push(element.createDate);
|
||||
ydata.push(
|
||||
{
|
||||
value: element.batteryTemp,
|
||||
year: element.dateDay
|
||||
}
|
||||
);
|
||||
});
|
||||
this.chart && this.chart.setOption({
|
||||
legend: {
|
||||
left: 'center',
|
||||
bottom: '10',
|
||||
left: "center",
|
||||
top: "5",
|
||||
itemWidth: 10,
|
||||
itemHeight: 5,
|
||||
textStyle: {
|
||||
fontSize: 9,
|
||||
},
|
||||
},
|
||||
grid: {
|
||||
containLabel: true,
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: { // 坐标轴指示器,坐标轴触发有效
|
||||
type: 'shadow' // 默认为直线,可选为:'line' | 'shadow'
|
||||
show:true,
|
||||
trigger: "axis",
|
||||
axisPointer: {
|
||||
// 坐标轴指示器,坐标轴触发有效
|
||||
type: "shadow", // 默认为直线,可选为:'line' | 'shadow'
|
||||
},
|
||||
formatter :(params)=>{
|
||||
if(params.length <= 0) return
|
||||
let result = (params[0].data.year || '')+' '+params[0].name + '<div>'
|
||||
params.forEach(item=>{
|
||||
const {color,seriesName,value} = item
|
||||
result += `<div style="position: relative;padding-left:20px;line-height: 20px;">
|
||||
<div style="position: absolute;top:50%;left:0;width:12px;height:12px;border-radius:100%;background: ${color};transform: translateY(-50%)"></div>
|
||||
<span>${seriesName}</span><span style="margin-left:20px;font-weight: 700">${value}</span></div>`
|
||||
})
|
||||
result+='</div>'
|
||||
return result
|
||||
}
|
||||
},
|
||||
textStyle:{
|
||||
color:"#333333",
|
||||
},
|
||||
xAxis: {
|
||||
data: ['1月','2月','3月','4月','5月','6月','7月','8月','9月','10月','11月','12月'],
|
||||
textStyle: {
|
||||
color: "#333333",
|
||||
},
|
||||
xAxis: { type: "category", data: xdata },
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
type: "value",
|
||||
},
|
||||
// POC昨日有功功率、POC昨日无功功率
|
||||
dataZoom: [
|
||||
{
|
||||
type: "inside",
|
||||
start: 0,
|
||||
end: 100,
|
||||
},
|
||||
{
|
||||
start: 0,
|
||||
end: 100,
|
||||
},
|
||||
],
|
||||
series: [
|
||||
{
|
||||
name:'昨日同时段温度',
|
||||
data: [80,92,1,34,90,130,320,80,9,91,34,90],
|
||||
type: 'line',
|
||||
|
||||
},{
|
||||
name:'实时温度',
|
||||
data: [820,932,901,934,1290,1330,1320,820,932,901,934,1290],
|
||||
type: 'line',
|
||||
}]
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type: "line",
|
||||
name: `电池平均温度`,
|
||||
areaStyle: {
|
||||
// color:'#FFBD00'
|
||||
},
|
||||
data: ydata,
|
||||
},
|
||||
],
|
||||
},true);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@ -1,81 +1,125 @@
|
||||
|
||||
<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">
|
||||
<span class="card-title">Poc平均温度</span>
|
||||
<span class="card-title">PCS最高温度</span>
|
||||
</div>
|
||||
<div style="height: 360px" id="pocpjwdChart"/>
|
||||
<div style="height: 360px" id="pocpjwdChart" />
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
<script>
|
||||
import * as echarts from 'echarts'
|
||||
require('echarts/theme/macarons') // echarts theme
|
||||
import resize from '@/mixins/ems/resize'
|
||||
import * as echarts from "echarts";
|
||||
import resize from "@/mixins/ems/resize";
|
||||
import { pcsMaxTemp } from "@/api/ems/dzjk";
|
||||
|
||||
export default {
|
||||
mixins: [resize],
|
||||
data() {
|
||||
return {
|
||||
chart: null
|
||||
}
|
||||
chart: null,
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.$nextTick(() => {
|
||||
this.initChart()
|
||||
})
|
||||
this.chart = echarts.init(document.querySelector("#pocpjwdChart"));
|
||||
},
|
||||
beforeDestroy() {
|
||||
if (!this.chart) {
|
||||
return
|
||||
return;
|
||||
}
|
||||
this.chart.dispose()
|
||||
this.chart = null
|
||||
this.chart.dispose();
|
||||
this.chart = null;
|
||||
},
|
||||
methods: {
|
||||
initChart() {
|
||||
this.chart = echarts.init(document.querySelector('#pocpjwdChart'))
|
||||
this.setOptions()
|
||||
init(siteId,timeRange) {
|
||||
this.chart.showLoading();
|
||||
const [startTime='', endTime=''] = timeRange;
|
||||
pcsMaxTemp(siteId,startTime,endTime)
|
||||
.then((response) => {
|
||||
this.setOption(response?.data?.pcsMaxTempList || []);
|
||||
})
|
||||
.finally(() => {
|
||||
this.chart.hideLoading();
|
||||
});
|
||||
},
|
||||
setOptions() {
|
||||
|
||||
this.chart.setOption({
|
||||
color:['#FFBD00','#3C81FF'],
|
||||
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) => {
|
||||
return {
|
||||
value: i.temp,
|
||||
year: i.dateDay
|
||||
}
|
||||
}),
|
||||
});
|
||||
});
|
||||
this.chart && this.chart.setOption({
|
||||
legend: {
|
||||
left: 'center',
|
||||
bottom: '10',
|
||||
left: "center",
|
||||
top: "5",
|
||||
itemWidth: 10,
|
||||
itemHeight: 5,
|
||||
textStyle: {
|
||||
fontSize: 9,
|
||||
},
|
||||
},
|
||||
grid: {
|
||||
containLabel: true,
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: { // 坐标轴指示器,坐标轴触发有效
|
||||
type: 'shadow' // 默认为直线,可选为:'line' | 'shadow'
|
||||
show:true,
|
||||
trigger: "axis",
|
||||
axisPointer: {
|
||||
// 坐标轴指示器,坐标轴触发有效
|
||||
type: "shadow", // 默认为直线,可选为:'line' | 'shadow'
|
||||
},
|
||||
formatter :(params)=>{
|
||||
if(params.length <= 0) return
|
||||
let result = (params[0].data.year || '')+' '+params[0].name + '<div>'
|
||||
params.forEach(item=>{
|
||||
const {color,seriesName,value} = item
|
||||
result += `<div style="position: relative;padding-left:20px;line-height: 20px;">
|
||||
<div style="position: absolute;top:50%;left:0;width:12px;height:12px;border-radius:100%;background: ${color};transform: translateY(-50%)"></div>
|
||||
<span>${seriesName}</span><span style="margin-left:20px;font-weight: 700">${value}</span></div>`
|
||||
})
|
||||
result+='</div>'
|
||||
return result
|
||||
}
|
||||
},
|
||||
textStyle:{
|
||||
color:"#333333",
|
||||
},
|
||||
xAxis: {
|
||||
data: ['1月','2月','3月','4月','5月','6月','7月','8月','9月','10月','11月','12月'],
|
||||
textStyle: {
|
||||
color: "#333333",
|
||||
},
|
||||
xAxis: { type: "category", data: xdata },
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
type: "value",
|
||||
},
|
||||
// POC昨日有功功率、POC昨日无功功率
|
||||
series: [
|
||||
dataZoom: [
|
||||
{
|
||||
name:'昨日同时段温度',
|
||||
data: [80,92,1,34,90,130,320,80,9,91,34,90],
|
||||
type: 'bar',
|
||||
|
||||
},{
|
||||
name:'实时温度',
|
||||
data: [820,932,901,934,1290,1330,1320,820,932,901,934,1290],
|
||||
type: 'bar',
|
||||
}]
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type: "inside",
|
||||
start: 0,
|
||||
end: 100,
|
||||
},
|
||||
{
|
||||
start: 0,
|
||||
end: 100,
|
||||
},
|
||||
],
|
||||
series,
|
||||
},true);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@ -2,22 +2,24 @@
|
||||
<template>
|
||||
<div class="ssyx-ems-dashboard-editor-container">
|
||||
<!-- 6个方块-->
|
||||
<real-time-base-info/>
|
||||
<real-time-base-info :data="runningHeadData"/>
|
||||
<!-- 时间选择 -->
|
||||
<date-range-select ref="dateRangeSelect" @updateDate="updateDate" style="margin-top:20px;"/>
|
||||
<!-- echart图表-->
|
||||
<el-row :gutter="32" style="background:#fff;margin:30px 0;">
|
||||
<el-col :xs="24" :sm="12" :lg="12">
|
||||
<cnglqx-chart/>
|
||||
<cnglqx-chart ref='cnglqx'/>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :lg="12">
|
||||
<pocpjwd-chart/>
|
||||
<pocpjwd-chart ref='pocpjwd'/>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="32" style="margin:30px 0;">
|
||||
<el-col :xs="24" :sm="12" :lg="12">
|
||||
<dcpjsoc-chart/>
|
||||
<dcpjsoc-chart ref="dcpjsoc"/>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :lg="12">
|
||||
<dcpjwd-chart/>
|
||||
<dcpjwd-chart ref="dcpjwd"/>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
@ -27,18 +29,58 @@
|
||||
|
||||
</style>
|
||||
<script>
|
||||
import DateRangeSelect from '@/components/Ems/DateRangeSelect/index.vue'
|
||||
import RealTimeBaseInfo from "./../RealTimeBaseInfo.vue";
|
||||
import CnglqxChart from './CnglqxChart.vue'
|
||||
import PocpjwdChart from './PocpjwdChart.vue'
|
||||
import DcpjwdChart from './DcpjwdChart.vue'
|
||||
import DcpjsocChart from './DcpjsocChart.vue'
|
||||
import getQuerySiteId from "@/mixins/ems/getQuerySiteId";
|
||||
import {getRunningHeadInfo} from '@/api/ems/dzjk'
|
||||
import intervalUpdate from "@/mixins/ems/intervalUpdate";
|
||||
|
||||
export default {
|
||||
components:{RealTimeBaseInfo,CnglqxChart,PocpjwdChart,DcpjwdChart,DcpjsocChart},
|
||||
name:'DzjkSbjkSsyx',
|
||||
components:{RealTimeBaseInfo,CnglqxChart,PocpjwdChart,DcpjwdChart,DcpjsocChart,DateRangeSelect},
|
||||
mixins:[getQuerySiteId,intervalUpdate],
|
||||
data() {
|
||||
return {
|
||||
runningHeadData:{},//运行信息
|
||||
timeRange:[],
|
||||
isInit:true
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
//6个方块数据
|
||||
getRunningHeadData(){
|
||||
getRunningHeadInfo(this.siteId).then(response => {
|
||||
this.runningHeadData = response?.data || {}
|
||||
})
|
||||
},
|
||||
// 更新时间范围 重置图表
|
||||
updateDate(data){
|
||||
this.timeRange=data
|
||||
!this.isInit && this.updateChart()
|
||||
this.isInit = false
|
||||
},
|
||||
updateChart(){
|
||||
this.$refs.cnglqx.init(this.siteId,this.timeRange||[])
|
||||
this.$refs.pocpjwd.init(this.siteId,this.timeRange||[])
|
||||
this.$refs.dcpjsoc.init(this.siteId,this.timeRange||[])
|
||||
this.$refs.dcpjwd.init(this.siteId,this.timeRange||[])
|
||||
this.updateInterval(this.updateData)
|
||||
},
|
||||
updateData(){
|
||||
this.getRunningHeadData()
|
||||
this.updateChart()
|
||||
},
|
||||
init(){
|
||||
this.$refs.dateRangeSelect.init(true)
|
||||
this.$nextTick(()=>{
|
||||
this.updateData()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
134
src/views/ems/dzjk/sbjk/xf/index.vue
Normal file
@ -0,0 +1,134 @@
|
||||
<template>
|
||||
<div v-loading="loading">
|
||||
<el-card
|
||||
v-for="(item,index) in list"
|
||||
:key="index+'ylLise'"
|
||||
class="sbjk-card-container running-card-container"
|
||||
:class="{
|
||||
'warning-card-container':item.emsCommunicationStatus && item.emsCommunicationStatus !== '0',
|
||||
'running-card-container':item.emsCommunicationStatus === '0'
|
||||
}"
|
||||
shadow="always">
|
||||
<div slot="header">
|
||||
<span class="large-title">{{ item.deviceName }}</span>
|
||||
<div class="info">
|
||||
<div>
|
||||
{{
|
||||
$store.state.ems.communicationStatusOptions[
|
||||
item.emsCommunicationStatus
|
||||
]
|
||||
}}
|
||||
</div>
|
||||
<div>数据更新时间:{{ item.dataUpdateTime || '-' }}</div>
|
||||
</div>
|
||||
<div class="alarm">
|
||||
<el-button type="primary" round size="small" style="margin-right:20px;" @click="pointDetail(item,'point')">
|
||||
详细
|
||||
</el-button>
|
||||
<el-badge :hidden="!item.alarmNum" :value="item.alarmNum || 0" class="item">
|
||||
<i
|
||||
class="el-icon-message-solid alarm-icon"
|
||||
@click="pointDetail(item,'alarmPoint')"
|
||||
></i>
|
||||
</el-badge>
|
||||
</div>
|
||||
</div>
|
||||
<el-row class="device-info-row">
|
||||
<el-col v-for="(tempDataItem,tempDataIndex) in tempData" :key="tempDataIndex+'hdTempData'" :span="12"
|
||||
class="device-info-col">
|
||||
<span class="pointer" @click="showChart(tempDataItem.title,item.deviceId)">
|
||||
<span class="left">{{ tempDataItem.title }}</span> <span class="right">{{
|
||||
item[tempDataItem.attr] || '-'
|
||||
}}<span
|
||||
v-html="tempDataItem.unit"></span></span>
|
||||
</span>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-card>
|
||||
<el-empty v-show="list.length<=0" :image-size="200"></el-empty>
|
||||
<point-chart ref="pointChart" :site-id="siteId"/>
|
||||
<point-table ref="pointTable"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<script>
|
||||
import getQuerySiteId from "@/mixins/ems/getQuerySiteId";
|
||||
import {getXfDataList} from '@/api/ems/dzjk'
|
||||
import intervalUpdate from "@/mixins/ems/intervalUpdate";
|
||||
import pointChart from "./../PointChart.vue";
|
||||
import PointTable from "@/views/ems/site/sblb/PointTable.vue";
|
||||
|
||||
export default {
|
||||
name: 'DzjkSbjkXf',
|
||||
mixins: [getQuerySiteId, intervalUpdate],
|
||||
components: {pointChart, PointTable},
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
list: [],
|
||||
tempData: [
|
||||
{title: '主电源备用电池状态', attr: 'dczt', unit: ''},
|
||||
{title: '手自动状态延时状态', attr: 'yszt', unit: ''},
|
||||
{title: '启动喷洒气体喷洒状态', attr: 'pszt', unit: ''},
|
||||
{title: '压力开关状态电磁阀状态', attr: 'dcfzt', unit: ''},
|
||||
]
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 查看设备电位表格
|
||||
pointDetail(row, dataType) {
|
||||
const {deviceId} = row
|
||||
this.$refs.pointTable.showTable({siteId: this.siteId, deviceId, deviceCategory: 'XF'}, dataType)
|
||||
},
|
||||
showChart(pointName, deviceId) {
|
||||
pointName && this.$refs.pointChart.showChart({pointName, deviceCategory: 'XF', deviceId})
|
||||
},
|
||||
updateData() {
|
||||
this.loading = true
|
||||
getXfDataList(this.siteId).then(response => {
|
||||
this.list = JSON.parse(JSON.stringify(response?.data || []));
|
||||
}).finally(() => {
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
init() {
|
||||
this.updateData()
|
||||
this.updateInterval(this.updateData)
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.sbjk-card-container {
|
||||
&:not(:last-child) {
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
|
||||
.el-row {
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -1,144 +1,103 @@
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<div class="yl-item-container">
|
||||
<div class="header">
|
||||
<div class="header-title">1#液冷</div>
|
||||
<div>工作模式:<span class="header-values">运行</span></div>
|
||||
<div>当前温度:<span class="header-values">12℃</span></div>
|
||||
<div v-loading="loading">
|
||||
<el-card
|
||||
v-for="(item,index) in list"
|
||||
:key="index+'ylLise'"
|
||||
class="sbjk-card-container running-card-container"
|
||||
shadow="always">
|
||||
<div slot="header">
|
||||
<span class="large-title">{{ item.deviceName }}</span>
|
||||
<div class="info">
|
||||
<div>数据更新时间:{{ item.dataUpdateTime || '-' }}</div>
|
||||
</div>
|
||||
<div class="content">
|
||||
<el-row>
|
||||
<el-col v-for="(item,index) in tempData" :key="index+'ylTempData'" :span="8">{{item.title}}:{{item.value}}℃</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="yl-item-container yl-warn-item-container">
|
||||
<div class="header">
|
||||
<div class="header-title">2#液冷</div>
|
||||
<div>工作模式:<span class="header-values">运行</span></div>
|
||||
<div>当前温度:<span class="header-values">12℃</span></div>
|
||||
</div>
|
||||
<div class="content">
|
||||
<el-row>
|
||||
<el-col v-for="(item,index) in tempData" :key="index+'ylTempData'" :span="8">{{item.title}}:{{item.value}}℃</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</div>
|
||||
<div class="yl-item-container">
|
||||
<div class="header">
|
||||
<div class="header-title">3#液冷</div>
|
||||
<div>工作模式:<span class="header-values">运行</span></div>
|
||||
<div>当前温度:<span class="header-values">12℃</span></div>
|
||||
</div>
|
||||
<div class="content">
|
||||
<el-row>
|
||||
<el-col v-for="(item,index) in tempData" :key="index+'ylTempData'" :span="8">{{item.title}}:{{item.value}}℃</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="yl-item-container yl-warn-item-container">
|
||||
<div class="header">
|
||||
<div class="header-title">4#液冷</div>
|
||||
<div>工作模式:<span class="header-values">运行</span></div>
|
||||
<div>当前温度:<span class="header-values">12℃</span></div>
|
||||
</div>
|
||||
<div class="content">
|
||||
<el-row>
|
||||
<el-col v-for="(item,index) in tempData" :key="index+'ylTempData'" :span="8">{{item.title}}:{{item.value}}℃</el-col>
|
||||
</el-row>
|
||||
<div class="alarm">
|
||||
<el-button type="primary" round size="small" style="margin-right:20px;" @click="pointDetail(item,'point')">
|
||||
详细
|
||||
</el-button>
|
||||
<el-badge :hidden="!item.alarmNum" :value="item.alarmNum || 0" class="item">
|
||||
<i
|
||||
class="el-icon-message-solid alarm-icon"
|
||||
@click="pointDetail(item,'alarmPoint')"
|
||||
></i>
|
||||
</el-badge>
|
||||
</div>
|
||||
</div>
|
||||
<el-row class="device-info-row">
|
||||
<el-col v-for="(tempDataItem,tempDataIndex) in tempData" :key="tempDataIndex+'ylTempData'" :span="8"
|
||||
class="device-info-col">
|
||||
<span class="pointer" @click="showChart(tempDataItem.title,item.deviceId)">
|
||||
<span class="left">{{ tempDataItem.title }}</span> <span
|
||||
class="right">{{ item[tempDataItem.attr] || '-' }}<span
|
||||
v-html="tempDataItem.unit"></span></span>
|
||||
</span>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-card>
|
||||
<el-empty v-show="list.length<=0" :image-size="200"></el-empty>
|
||||
<point-chart ref="pointChart" :site-id="siteId"/>
|
||||
<point-table ref="pointTable"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<script>
|
||||
import getQuerySiteId from "@/mixins/ems/getQuerySiteId";
|
||||
import {getCoolingDataList} from '@/api/ems/dzjk'
|
||||
import intervalUpdate from "@/mixins/ems/intervalUpdate";
|
||||
import pointChart from "./../PointChart.vue";
|
||||
import PointTable from "@/views/ems/site/sblb/PointTable.vue";
|
||||
|
||||
export default {
|
||||
name:'DzjkSbjkYl',
|
||||
name: 'DzjkSbjkYl',
|
||||
mixins: [getQuerySiteId, intervalUpdate],
|
||||
components: {pointChart, PointTable},
|
||||
data() {
|
||||
return {
|
||||
tempData:[
|
||||
{title:'制热开启点',value:12,attr:''},
|
||||
{title:'制冷开启点',value:23,attr:''},
|
||||
{title:'高温告警点',value:30,attr:''},
|
||||
{title:'制热停止点',value:24,attr:''},
|
||||
{title:'制冷停止点',value:21,attr:''},
|
||||
{title:'低温告警点',value:10,attr:''},
|
||||
|
||||
loading: false,
|
||||
list: [],
|
||||
tempData: [
|
||||
{title: '供水温度', attr: 'gsTemp', unit: '℃'},
|
||||
{title: '回水温度', attr: 'hsTemp', unit: '℃'},
|
||||
{title: '供水压力', attr: 'gsPressure', unit: 'bar'},
|
||||
{title: '回水压力', attr: 'hsPressure', unit: 'bar'},
|
||||
{title: '冷源水温度', attr: 'lysTemp', unit: '℃'},
|
||||
{title: 'VB01开度', attr: 'vb01Kd', unit: '%'},
|
||||
{title: 'VB02开度', attr: 'vb02Kd', unit: '%'},
|
||||
]
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
|
||||
methods: {
|
||||
// 查看设备电位表格
|
||||
pointDetail(row, dataType) {
|
||||
const {deviceId} = row
|
||||
this.$refs.pointTable.showTable({siteId: this.siteId, deviceId, deviceCategory: 'COOLING'}, dataType)
|
||||
},
|
||||
showChart(pointName, deviceId) {
|
||||
pointName && this.$refs.pointChart.showChart({pointName, deviceCategory: 'COOLING', deviceId})
|
||||
},
|
||||
updateData() {
|
||||
this.loading = true
|
||||
getCoolingDataList(this.siteId).then(response => {
|
||||
this.list = JSON.parse(JSON.stringify(response?.data || []));
|
||||
}).finally(() => {
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
init() {
|
||||
this.updateData()
|
||||
this.updateInterval(this.updateData)
|
||||
}
|
||||
},
|
||||
mounted(){
|
||||
mounted() {
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.yl-item-container{
|
||||
border-radius: 5px;
|
||||
background-color: #EBF6F6;
|
||||
&:not(:last-child){
|
||||
.sbjk-card-container {
|
||||
&:not(:last-child) {
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
.header{
|
||||
line-height: 40px;
|
||||
font-size: 14px;
|
||||
>div{
|
||||
display: inline-block;
|
||||
margin-right: 40px;
|
||||
}
|
||||
.header-title{
|
||||
border-radius: 5px 0 5px 0;
|
||||
color:#ffffff;
|
||||
width: 120px;
|
||||
height: 40px;
|
||||
font-size: 16px;
|
||||
background-color: #05AEA3;
|
||||
text-align: center;
|
||||
}
|
||||
.header-values{
|
||||
color: #05AEA3;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
.content{
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
204
src/views/ems/dzjk/tjbb/dbbb/index.vue
Normal file
@ -0,0 +1,204 @@
|
||||
|
||||
<template>
|
||||
<div style="width:100%" v-loading="loading">
|
||||
<!-- 搜索栏-->
|
||||
<el-form :inline="true" class="select-container">
|
||||
<el-form-item label="时间选择">
|
||||
<el-date-picker
|
||||
v-model="dateRange"
|
||||
type="daterange"
|
||||
range-separator="至"
|
||||
start-placeholder="开始日期"
|
||||
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-button type="primary" @click="onSearch" native-type="button">搜索</el-button>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button @click="onReset" native-type="button">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<!--表格-->
|
||||
<el-table
|
||||
class="common-table"
|
||||
:data="tableData"
|
||||
stripe
|
||||
style="width: 100%;margin-top:25px;">
|
||||
<!-- 汇总列-->
|
||||
<el-table-column label="汇总">
|
||||
<el-table-column
|
||||
prop="dataTime"
|
||||
label="日期"
|
||||
width="120">
|
||||
</el-table-column>
|
||||
</el-table-column>
|
||||
<!--充电量列-->
|
||||
<el-table-column label="充电量" align="center">
|
||||
<el-table-column
|
||||
align="center"
|
||||
prop="activePeakKwh"
|
||||
label="尖">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
align="center"
|
||||
prop="activeHighKwh"
|
||||
label="峰">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
align="center"
|
||||
prop="activeFlatKwh"
|
||||
label="平">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
align="center"
|
||||
prop="activeValleyKwh"
|
||||
label="谷">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
align="center"
|
||||
prop="activeTotalKwh"
|
||||
label="总">
|
||||
</el-table-column>
|
||||
</el-table-column>
|
||||
<!--充电量列-->
|
||||
<el-table-column label="放电量" align="center">
|
||||
<el-table-column
|
||||
align="center"
|
||||
prop="reActivePeakKwh"
|
||||
label="尖">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
align="center"
|
||||
prop="reActiveHighKwh"
|
||||
label="峰">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
align="center"
|
||||
prop="reActiveFlatKwh"
|
||||
label="平">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
align="center"
|
||||
prop="reActiveValleyKwh"
|
||||
label="谷">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
align="center"
|
||||
prop="reActiveTotalKwh"
|
||||
label="总">
|
||||
</el-table-column>
|
||||
</el-table-column>
|
||||
<!-- 效率-->
|
||||
<el-table-column label="效率(%)" align="center">
|
||||
<el-table-column
|
||||
align="center"
|
||||
prop="effect">
|
||||
</el-table-column>
|
||||
</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>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<script>
|
||||
import getQuerySiteId from "@/mixins/ems/getQuerySiteId";
|
||||
import { getAmmeterData} from '@/api/ems/dzjk'
|
||||
import {formatDate} from "@/filters/ems";
|
||||
export default {
|
||||
name:'DzjkTjbbDbbb',
|
||||
mixins: [getQuerySiteId],
|
||||
data() {
|
||||
return {
|
||||
loading:false,
|
||||
pickerOptions:{
|
||||
disabledDate(time) {
|
||||
return time.getTime() > Date.now();
|
||||
},
|
||||
},
|
||||
defaultDateRange:[],//默认展示的时间
|
||||
dateRange:[],
|
||||
tableData:[],
|
||||
pageSize:10,//分页栏当前每个数据总数
|
||||
pageNum:1,//分页栏当前页数
|
||||
totalSize:0,//table表格数据总数
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
// 搜索
|
||||
onSearch(){
|
||||
this.pageNum =1//每次搜索从1开始搜索
|
||||
this.getData()
|
||||
},
|
||||
// 重置
|
||||
onReset(){
|
||||
this.dateRange=this.defaultDateRange
|
||||
this.pageNum =1//每次搜索从1开始搜索
|
||||
this.getData()
|
||||
},
|
||||
// 分页
|
||||
handleSizeChange(val) {
|
||||
this.pageSize = val;
|
||||
this.$nextTick(()=>{
|
||||
this.getData()
|
||||
})
|
||||
},
|
||||
handleCurrentChange(val) {
|
||||
this.pageNum = val
|
||||
this.$nextTick(()=>{
|
||||
this.getData()
|
||||
})
|
||||
},
|
||||
// 获取数据
|
||||
getData(){
|
||||
this.loading=true
|
||||
const {siteId,pageNum,pageSize} =this
|
||||
const [startTime='',endTime='']=(this.dateRange || [])
|
||||
getAmmeterData({siteId:siteId,startTime,endTime,pageSize,pageNum}).then(response=>{
|
||||
this.tableData=response?.rows || [];
|
||||
this.totalSize = response?.total || 0
|
||||
}).finally(()=> {
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
init(){
|
||||
this.dateRange=[]
|
||||
this.tableData=[]
|
||||
this.totalSize=0
|
||||
this.pageSize=10
|
||||
this.pageNum = 1
|
||||
const now = new Date().getTime();
|
||||
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()
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
::v-deep{
|
||||
.common-table.el-table .el-table__header-wrapper th, .common-table.el-table .el-table__fixed-header-wrapper th{
|
||||
border-bottom: 1px solid #dfe6ec;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
191
src/views/ems/dzjk/tjbb/dcdqx/index.vue
Normal file
@ -0,0 +1,191 @@
|
||||
<template>
|
||||
<el-card
|
||||
shadow="always"
|
||||
class="common-card-container time-range-card"
|
||||
style="margin-top: 20px"
|
||||
>
|
||||
<div slot="header" class="time-range-header">
|
||||
<span class="card-title"> </span>
|
||||
<date-range-select ref="dateRangeSelect" @updateDate="updateDate" />
|
||||
</div>
|
||||
<div class="card-main" v-loading="loading">
|
||||
<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>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as echarts from "echarts";
|
||||
import resize from "@/mixins/ems/resize";
|
||||
import getQuerySiteId from "@/mixins/ems/getQuerySiteId";
|
||||
import { getStackData, getStackNameList } from "@/api/ems/dzjk";
|
||||
import { formatDate } from "@/filters/ems";
|
||||
import DateRangeSelect from "@/components/Ems/DateRangeSelect/index.vue";
|
||||
export default {
|
||||
name: "DzjkTjbbDcdqx",
|
||||
components: { DateRangeSelect },
|
||||
mixins: [resize, getQuerySiteId],
|
||||
data() {
|
||||
return {
|
||||
pickerOptions: {
|
||||
disabledDate(time) {
|
||||
return time.getTime() > Date.now();
|
||||
},
|
||||
},
|
||||
dateRange: [],
|
||||
loading: false,
|
||||
activeBtn: "1",
|
||||
btnList: [
|
||||
{ name: "堆平均维度", id: "1", attr: ["temp"], source: ["有功功率"] },
|
||||
{ name: "堆电压", id: "2", attr: ["voltage"], source: ["堆电压"] },
|
||||
{ name: "堆电流", id: "3", attr: ["current"], source: ["堆电流"] },
|
||||
{ name: "堆soc", id: "4", attr: ["soc"], source: ["堆soc"] },
|
||||
],
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
changeDataType(id) {
|
||||
if (id !== this.activeBtn) {
|
||||
this.activeBtn = id;
|
||||
this.getData();
|
||||
}
|
||||
},
|
||||
// 更新时间范围 重置图表
|
||||
updateDate(data) {
|
||||
this.dateRange = data || [];
|
||||
this.getData();
|
||||
},
|
||||
getData() {
|
||||
const { siteId, activeBtn } = this;
|
||||
const [start = "", end = ""] = this.dateRange || [];
|
||||
//接口调用完成之后 设置图表、结束loading
|
||||
this.loading = true;
|
||||
getStackData({
|
||||
siteId,
|
||||
startTime: formatDate(start),
|
||||
endTime: formatDate(end),
|
||||
dataType: activeBtn,
|
||||
})
|
||||
.then((response) => {
|
||||
this.setOption(response?.data || []);
|
||||
})
|
||||
.finally(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
compareDate(date1, date2) {
|
||||
console.log("比较时间", date1, date2);
|
||||
// 年2025-09/天2025-09-15/时2025-09-15/10:00
|
||||
if (date1.indexOf(":") > -1 && date2.indexOf(":") > -1) {
|
||||
return parseInt(date1) - parseInt(date2);
|
||||
}
|
||||
const [date1_Y = "", date1_M = "", date1_D = ""] = date1.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
|
||||
);
|
||||
},
|
||||
setOption(data) {
|
||||
const ele = this.btnList.find((item) => {
|
||||
return item.id === this.activeBtn;
|
||||
});
|
||||
const sourceBase = JSON.parse(JSON.stringify(ele.source));
|
||||
// sourceBase={name:'堆平均维度',id:'1',attr:['temp'],source:['有功功率']},
|
||||
const source = [];
|
||||
const sourceTop = ["日期"];
|
||||
let map = {},
|
||||
mapArr = [];
|
||||
// 生成所有{日期:[],日期:[]}格式的对象和所有包含所有日期的[日期1,日期2...]
|
||||
data.forEach((item) => {
|
||||
item.dataList.forEach((inner) => {
|
||||
// 日期格式
|
||||
// 年2025-09/天2025-09-15/时2025-09-15/10:00
|
||||
// 所有数据的日期格式一致
|
||||
if (!map[inner.statisDate]) {
|
||||
map[inner.statisDate] = [];
|
||||
mapArr.push(inner.statisDate);
|
||||
}
|
||||
});
|
||||
});
|
||||
data.forEach((item, itemIndex) => {
|
||||
const dataTimeList = item.dataList.map((i) => i.statisDate);
|
||||
const noDataTime = mapArr.filter((i) => !dataTimeList.includes(i));
|
||||
sourceBase.forEach((outer, outerIndex) => {
|
||||
sourceTop.push(`${item.deviceId}-${outer}`);
|
||||
noDataTime.forEach((i) => map[i].push(""));
|
||||
item.dataList.forEach((inner, innerIndex) => {
|
||||
map[inner.statisDate].push(inner[ele.attr[outerIndex]]);
|
||||
});
|
||||
});
|
||||
});
|
||||
mapArr = mapArr.sort((a, b) => this.compareDate(a, b));
|
||||
mapArr.forEach((item) => {
|
||||
source.push([item, ...map[item]]);
|
||||
});
|
||||
source.unshift(sourceTop);
|
||||
this.chart.setOption(
|
||||
{
|
||||
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",
|
||||
};
|
||||
}),
|
||||
},
|
||||
true
|
||||
);
|
||||
},
|
||||
initChart() {
|
||||
this.chart = echarts.init(document.querySelector("#dcdEchart"));
|
||||
},
|
||||
init() {
|
||||
this.$nextTick(() => {
|
||||
this.initChart();
|
||||
this.$refs.dateRangeSelect.init();
|
||||
});
|
||||
},
|
||||
},
|
||||
beforeDestroy() {
|
||||
if (!this.chart) {
|
||||
return;
|
||||
}
|
||||
this.chart.dispose();
|
||||
this.chart = null;
|
||||
},
|
||||
};
|
||||
</script>
|
||||
203
src/views/ems/dzjk/tjbb/dcwd/index.vue
Normal file
@ -0,0 +1,203 @@
|
||||
|
||||
<template>
|
||||
<div v-loading="loading">
|
||||
<!-- 搜索栏-->
|
||||
<el-form :inline="true" class="select-container">
|
||||
<el-form-item label="电池堆">
|
||||
<el-select v-model="search.stackId" placeholder="请选择" @change="changeStackId">
|
||||
<el-option :label="item.deviceName" :value="item.id" v-for="(item,index) in stackOptions" :key="index+'dcdOptions'"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="电池簇">
|
||||
<el-select v-model="search.clusterId" :no-data-text="!search.stackId && stackOptions.length > 0 ? '请先选择电池堆':'无数据'" placeholder="请选择" :loading="clusterloading" loading-text="正在加载数据">
|
||||
<el-option :label="item.deviceName" :value="item.id" v-for="(item,index) in clusterOptions" :key="index+'dccOptions'"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="时间选择">
|
||||
<el-date-picker
|
||||
v-model="search.date"
|
||||
type="date"
|
||||
:picker-options="pickerOptions"
|
||||
:default-value="defaultDate">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="onSearch" native-type="button">搜索</el-button>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button @click="onReset" native-type="button">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div style="margin:30px 0;">
|
||||
<!--表格-->
|
||||
<el-table
|
||||
class="common-table"
|
||||
:data="tableData"
|
||||
stripe
|
||||
max-height="500"
|
||||
style="width: 100%;margin-top:25px;">
|
||||
<el-table-column
|
||||
prop="statisDate"
|
||||
width="100"
|
||||
label="时间">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="maxTemp"
|
||||
label="最高温(℃)">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="maxTempId"
|
||||
label="单体ID">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="minTemp"
|
||||
label="最低温(℃)">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="minTempId"
|
||||
label="单体ID">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="maxVoltage"
|
||||
label="最高压(V)">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="maxVoltageId"
|
||||
label="单体ID">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="minVoltage"
|
||||
label="最低压(V)">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="minVoltageId"
|
||||
label="单体ID">
|
||||
</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>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<script>
|
||||
import {getStackNameList, getClusterNameList, getClusterData} from '@/api/ems/dzjk'
|
||||
import getQuerySiteId from "@/mixins/ems/getQuerySiteId";
|
||||
import {formatDate} from "@/utils";
|
||||
export default {
|
||||
name:'DzjkTjbbDcwd',
|
||||
mixins:[getQuerySiteId],
|
||||
data() {
|
||||
return {
|
||||
pickerOptions:{
|
||||
disabledDate(time) {
|
||||
return time.getTime() > Date.now();
|
||||
},
|
||||
},
|
||||
defaultDate:'',//默认展示的时间
|
||||
loading:false,
|
||||
clusterloading:false,
|
||||
search:{stackId:'',clusterId:'',date:''},
|
||||
stackOptions:[],//{id:'',deviceName:''}
|
||||
clusterOptions:[],//{id:'',deviceName:''}
|
||||
tableData:[],
|
||||
pageSize:10,//分页栏当前每个数据总数
|
||||
pageNum:1,//分页栏当前页数
|
||||
totalSize:0,//table表格数据总数
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
// 分页
|
||||
handleSizeChange(val) {
|
||||
this.pageSize = val;
|
||||
this.$nextTick(()=>{
|
||||
this.getTableData()
|
||||
})
|
||||
},
|
||||
handleCurrentChange(val) {
|
||||
this.pageNum = val
|
||||
this.$nextTick(()=>{
|
||||
this.getTableData()
|
||||
})
|
||||
},
|
||||
// 搜索
|
||||
onSearch(){
|
||||
this.pageNum =1//每次搜索从1开始搜索
|
||||
this.getTableData()
|
||||
},
|
||||
// 重置
|
||||
onReset(){
|
||||
this.search.date=''
|
||||
this.pageNum = 1
|
||||
this.getTableData()
|
||||
},
|
||||
changeStackId(val){
|
||||
if(val){
|
||||
this.search.clusterId=''
|
||||
this.getClusterList()
|
||||
}
|
||||
},
|
||||
//表格数据
|
||||
async getTableData(){
|
||||
const {stackId,clusterId,date} =this.search
|
||||
const {siteId,pageNum,pageSize}=this
|
||||
if(!stackId) return
|
||||
this.loading=true;
|
||||
await getClusterData({dateTime:formatDate(date),stackId,clusterId,siteId,pageNum,pageSize}).then(response => {
|
||||
this.tableData=response?.rows || [];
|
||||
this.totalSize = response?.total || 0
|
||||
}).finally(()=>{
|
||||
this.loading=false;
|
||||
})
|
||||
},
|
||||
async getStackList(){
|
||||
await getStackNameList(this.siteId).then(response => {
|
||||
const data = JSON.parse(JSON.stringify(response?.data || []))
|
||||
this.stackOptions = data
|
||||
this.search.stackId = data.length > 0 ? data[0].id : ''
|
||||
})
|
||||
},
|
||||
async getClusterList(){
|
||||
this.clusterloading =true
|
||||
await getClusterNameList({stackDeviceId: this.search.stackId, siteId: this.siteId}).then(response => {
|
||||
const data = JSON.parse(JSON.stringify(response?.data || []))
|
||||
this.clusterOptions = data
|
||||
this.search.clusterId = data.length > 0 ? data[0].id : ''
|
||||
}).finally(() => {this.clusterloading =false})
|
||||
},
|
||||
async init(){
|
||||
this.loading = true
|
||||
this.search={stackId:'',clusterId:'',date:''}
|
||||
this.stackOptions=[]//{id:'',deviceName:''}
|
||||
this.clusterOptions=[]//{id:'',deviceName:''}
|
||||
this.tableData=[]
|
||||
// 只有页面初次加载或切换站点的时候调用电池堆列表,其他情况不需要
|
||||
await this.getStackList()
|
||||
if(this.search.stackId){
|
||||
await this.getClusterList()
|
||||
await this.onReset()
|
||||
}else{
|
||||
this.loading = false
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
},
|
||||
mounted(){
|
||||
this.defaultDate = new Date()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
151
src/views/ems/dzjk/tjbb/glqx/index.vue
Normal file
@ -0,0 +1,151 @@
|
||||
<template>
|
||||
<el-card
|
||||
shadow="always"
|
||||
class="common-card-container time-range-card"
|
||||
style="margin-top: 20px"
|
||||
>
|
||||
<div slot="header" class="time-range-header">
|
||||
<span class="card-title">功率曲线</span>
|
||||
<date-range-select
|
||||
ref="dateRangeSelect"
|
||||
@reset="resetTime"
|
||||
@updateDate="updateDate"
|
||||
/>
|
||||
</div>
|
||||
<div class="card-main" v-loading="loading">
|
||||
<div id="glqxEchart" style="height: 310px"></div>
|
||||
</div>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as echarts from "echarts";
|
||||
import resize from "@/mixins/ems/resize";
|
||||
import getQuerySiteId from "@/mixins/ems/getQuerySiteId";
|
||||
import { getPcsNameList, getPowerData } from "@/api/ems/dzjk";
|
||||
import { formatDate } from "@/filters/ems";
|
||||
import DateRangeSelect from "@/components/Ems/DateRangeSelect/index.vue";
|
||||
export default {
|
||||
name: "DzjkTjbbGlqx",
|
||||
components: { DateRangeSelect },
|
||||
mixins: [resize, getQuerySiteId],
|
||||
data() {
|
||||
return {
|
||||
pickerOptions: {
|
||||
disabledDate(time) {
|
||||
return time.getTime() > Date.now();
|
||||
},
|
||||
},
|
||||
dateRange: [],
|
||||
loading: false,
|
||||
dateRangeInit: true,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
// 更新时间范围 重置图表
|
||||
updateDate(data) {
|
||||
this.dateRange = data || [];
|
||||
this.getData();
|
||||
},
|
||||
resetTime() {
|
||||
this.dateRangeInit = true;
|
||||
},
|
||||
getData() {
|
||||
const { siteId } = this;
|
||||
let [start = "", end = ""] = this.dateRange || [];
|
||||
//接口调用完成之后 设置图表、结束loading
|
||||
this.loading = true;
|
||||
if (this.dateRangeInit) {
|
||||
start = "";
|
||||
end = "";
|
||||
this.dateRangeInit = false;
|
||||
}
|
||||
getPowerData({
|
||||
siteId,
|
||||
startDate: formatDate(start),
|
||||
endDate: formatDate(end),
|
||||
})
|
||||
.then((response) => {
|
||||
this.setOption(response?.data || []);
|
||||
})
|
||||
.finally(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
setOption(data) {
|
||||
const source = [["日期", "电网功率", "负载功率", "储能功率", "光伏功率"]];
|
||||
data.forEach((item) => {
|
||||
source.push([
|
||||
item.statisDate,
|
||||
item.gridPower,
|
||||
item.loadPower,
|
||||
item.storagePower,
|
||||
item.pvPower,
|
||||
]);
|
||||
});
|
||||
this.chart.setOption(
|
||||
{
|
||||
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: [
|
||||
{
|
||||
type: "line",
|
||||
},
|
||||
{
|
||||
type: "line",
|
||||
},
|
||||
{
|
||||
type: "line",
|
||||
},
|
||||
{
|
||||
type: "line",
|
||||
},
|
||||
],
|
||||
},
|
||||
true
|
||||
);
|
||||
},
|
||||
initChart() {
|
||||
if (this.chart) return;
|
||||
this.chart = echarts.init(document.querySelector("#glqxEchart"));
|
||||
},
|
||||
init() {
|
||||
this.$nextTick(() => {
|
||||
this.dateRangeInit = true;
|
||||
this.initChart();
|
||||
this.$refs.dateRangeSelect.init();
|
||||
});
|
||||
},
|
||||
},
|
||||
|
||||
beforeDestroy() {
|
||||
if (!this.chart) {
|
||||
return;
|
||||
}
|
||||
this.chart.dispose();
|
||||
this.chart = null;
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@ -1,42 +1,16 @@
|
||||
<template>
|
||||
<el-card shadow="always" class="common-card-container" style="margin-top:20px">
|
||||
<div slot="header">
|
||||
<el-card shadow="always" class="common-card-container time-range-card" style="margin-top:20px">
|
||||
<div slot="header" class="time-range-header">
|
||||
<span class="card-title">电量指标</span>
|
||||
<date-range-select ref="dateRangeSelect" @updateDate="updateDate"/>
|
||||
</div>
|
||||
<div class="card-main">
|
||||
<!-- 搜索栏-->
|
||||
<div class="select-container">
|
||||
<el-form :inline="true">
|
||||
<el-form-item label="设备类型">
|
||||
<el-select v-model="sjwd" placeholder="请选择" :loading="loading" loading-text="正在加载数据">
|
||||
<el-option :label="item.name" :value="item.id" v-for="(item,index) in sjwdOptions" :key="index+'syzbSjwdOptions'"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="时间选择">
|
||||
<el-date-picker
|
||||
v-model="dateRange"
|
||||
type="datetimerange"
|
||||
range-separator="至"
|
||||
start-placeholder="开始时间"
|
||||
:picker-options="pickerOptions"
|
||||
:default-value="defaultDateRange"
|
||||
end-placeholder="结束时间">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="warning" @click="onSearch" native-type="button">搜索</el-button>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button @click="onReset" native-type="button">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<div class="card-main" v-loading="loading">
|
||||
<div class="total-data">
|
||||
<div>总充电量:<span class="point">1390988kWh</span></div>
|
||||
<div>总放电量:<span class="point">988kWh</span></div>
|
||||
<div>总效益:<span class="point">99%</span></div>
|
||||
<div>总充电量:<span class="point">{{totalChargedCap | formatNumber}}kWh</span></div>
|
||||
<div>总放电量:<span class="point">{{totalDisChargedCap | formatNumber}}kWh</span></div>
|
||||
<div>综合效率:<span class="point">{{efficiency | formatNumber}}%</span></div>
|
||||
</div>
|
||||
<div id="dlzbChart" style="height: 310px"></div>
|
||||
<div id="dlzbChart" style="height: 310px;"></div>
|
||||
</div>
|
||||
</el-card>
|
||||
</template>
|
||||
@ -44,8 +18,13 @@
|
||||
<script>
|
||||
import * as echarts from 'echarts'
|
||||
import resize from "@/mixins/ems/resize";
|
||||
import getQuerySiteId from "@/mixins/ems/getQuerySiteId";
|
||||
import {getElectricData} from '@/api/ems/dzjk'
|
||||
import {formatDate} from '@/filters/ems'
|
||||
import DateRangeSelect from '@/components/Ems/DateRangeSelect/index.vue'
|
||||
export default {
|
||||
mixins: [resize],
|
||||
components: {DateRangeSelect},
|
||||
mixins: [resize,getQuerySiteId],
|
||||
data() {
|
||||
return {
|
||||
pickerOptions:{
|
||||
@ -53,81 +32,111 @@ export default {
|
||||
return time.getTime() > Date.now();
|
||||
},
|
||||
},
|
||||
defaultDateRange:[],//默认展示的时间
|
||||
dateRange:[],
|
||||
sjwd:'',
|
||||
sjwdOptions:[
|
||||
{name:'时间一',id:1},
|
||||
{name:'时间二',id:2},
|
||||
],
|
||||
loading:false,
|
||||
chart: null
|
||||
|
||||
chart: null,
|
||||
totalChargedCap:'',
|
||||
totalDisChargedCap:'',
|
||||
efficiency:''
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 搜索
|
||||
onSearch(){
|
||||
// 更新时间范围 重置图表
|
||||
updateDate(data){
|
||||
this.dateRange=data || []
|
||||
this.getData()
|
||||
},
|
||||
// 重置
|
||||
onReset(){
|
||||
this.dateRange=[]
|
||||
this.sjwd=''
|
||||
this.getData()
|
||||
},
|
||||
getData(){
|
||||
this.loading=true;
|
||||
this.chart.showLoading()
|
||||
//接口调用完成之后 设置图表、结束loading
|
||||
this.setOption()
|
||||
this.loading=false;
|
||||
this.chart.hideLoading()
|
||||
},
|
||||
setOption(data){
|
||||
// const source = [['日期','充电量','放电量']]
|
||||
// data.forEach(item=>{
|
||||
// source.push([item.ammeterDate, item.chargedCap,item.disChargedCap])
|
||||
// })
|
||||
setOption(data,unit){
|
||||
const source = [['日期','充电量','放电量','效率']]
|
||||
data.forEach(item=>{
|
||||
source.push([item.ammeterDate, item.chargedCap,item.disChargedCap,item.dailyEfficiency])
|
||||
})
|
||||
this.chart.setOption({
|
||||
color:['#FFBD00','#3C81FF'],
|
||||
// legend: {
|
||||
// left: 'right',
|
||||
// bottom: '10',
|
||||
// },
|
||||
tooltip: {},
|
||||
xAxis: { type: 'category' },
|
||||
yAxis: { type: 'value' },
|
||||
grid:{top:30},
|
||||
dataset:{
|
||||
// source
|
||||
source:[//格式
|
||||
['product','收益1','收益2'],
|
||||
['今天',10,20],
|
||||
['昨天',20,30],
|
||||
]
|
||||
legend: {
|
||||
left: 'center',
|
||||
bottom: '15',
|
||||
},
|
||||
grid: {
|
||||
top:40,
|
||||
containLabel: true
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: { // 坐标轴指示器,坐标轴触发有效
|
||||
type: 'shadow' // 默认为直线,可选为:'line' | 'shadow'
|
||||
}
|
||||
},
|
||||
xAxis: [{
|
||||
type: 'category',
|
||||
name:`单位:${unit}`,
|
||||
nameLocation:'center',
|
||||
nameGap:30
|
||||
}],
|
||||
yAxis: [{
|
||||
type: 'value',
|
||||
name:'充电量/放电量kWh',
|
||||
axisLine: {
|
||||
lineStyle:{
|
||||
color: '#333333',
|
||||
},
|
||||
onZero:false
|
||||
}
|
||||
},{
|
||||
type: 'value',
|
||||
name:'效率%',
|
||||
axisLine: {
|
||||
lineStyle:{
|
||||
color: '#333333',
|
||||
},
|
||||
onZero:false
|
||||
}
|
||||
}],
|
||||
dataset:{
|
||||
source
|
||||
},
|
||||
//所有充放电颜色保持统一
|
||||
series: [
|
||||
{
|
||||
yAxisIndex:0,
|
||||
type: 'bar',//柱状图
|
||||
color:'#4472c4'
|
||||
},
|
||||
{
|
||||
yAxisIndex:0,
|
||||
type: 'bar',//柱状图
|
||||
}
|
||||
color:'#70ad47'
|
||||
},
|
||||
{
|
||||
yAxisIndex:1,
|
||||
type: 'line',//柱状图
|
||||
color:'#FFBD00'
|
||||
},
|
||||
]
|
||||
})
|
||||
},
|
||||
initChart() {
|
||||
this.chart = echarts.init(document.querySelector('#dlzbChart'));
|
||||
getData(){
|
||||
this.loading=true;
|
||||
//接口调用完成之后 设置图表、结束loading
|
||||
const [start='',end='']=this.dateRange || [];
|
||||
const startDate=formatDate(start),endDate = formatDate(end)
|
||||
getElectricData({siteId:this.siteId,startDate,endDate}).then(response => {
|
||||
const {totalChargedCap='',totalDisChargedCap='',efficiency='',sevenDayDisChargeStats=[],unit=''}=response?.data || {}
|
||||
this.setOption(sevenDayDisChargeStats || [],unit)
|
||||
this.totalChargedCap=totalChargedCap
|
||||
this.totalDisChargedCap=totalDisChargedCap
|
||||
this.efficiency=efficiency
|
||||
}).finally(() => {
|
||||
this.loading=false;
|
||||
})
|
||||
},
|
||||
init(){
|
||||
this.$nextTick(()=>{
|
||||
this.chart = echarts.init(document.querySelector('#dlzbChart'));
|
||||
this.$refs.dateRangeSelect.init()
|
||||
})
|
||||
|
||||
}
|
||||
},
|
||||
mounted(){
|
||||
const now = new Date();
|
||||
const lastMonth = new Date(now.getFullYear(), now.getMonth() - 1, 1);
|
||||
this.defaultDateRange = [lastMonth, now];
|
||||
this.initChart()
|
||||
this.getData()
|
||||
},
|
||||
beforeDestroy() {
|
||||
if (!this.chart) {
|
||||
return
|
||||
@ -144,7 +153,7 @@ export default {
|
||||
line-height: 18px;
|
||||
color: #333333;
|
||||
font-size: 16px;
|
||||
padding:10px 0;
|
||||
padding:20px 0;
|
||||
>div{
|
||||
display: inline-block;
|
||||
margin-right: 20px;
|
||||
|
||||
@ -7,15 +7,10 @@
|
||||
<!-- 搜索栏-->
|
||||
<div class="select-container">
|
||||
<el-form :inline="true">
|
||||
<el-form-item label="设备类型">
|
||||
<el-select v-model="sjwd" placeholder="请选择" :loading="loading" loading-text="正在加载数据">
|
||||
<el-option :label="item.name" :value="item.id" v-for="(item,index) in sjwdOptions" :key="index+'syzbSjwdOptions'"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="时间选择">
|
||||
<el-date-picker
|
||||
v-model="dateRange"
|
||||
type="datetimerange"
|
||||
type="daterange"
|
||||
range-separator="至"
|
||||
start-placeholder="开始时间"
|
||||
:picker-options="pickerOptions"
|
||||
@ -24,7 +19,7 @@
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="warning" @click="onSearch" native-type="button">搜索</el-button>
|
||||
<el-button type="primary" @click="onSearch" native-type="button">搜索</el-button>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button @click="onReset" native-type="button">重置</el-button>
|
||||
@ -53,11 +48,6 @@ export default {
|
||||
},
|
||||
defaultDateRange:[],//默认展示的时间
|
||||
dateRange:[],
|
||||
sjwd:'',
|
||||
sjwdOptions:[
|
||||
{name:'时间一',id:1},
|
||||
{name:'时间二',id:2},
|
||||
],
|
||||
loading:false,
|
||||
chart: null
|
||||
|
||||
@ -71,7 +61,6 @@ export default {
|
||||
// 重置
|
||||
onReset(){
|
||||
this.dateRange=[]
|
||||
this.sjwd=''
|
||||
this.getData()
|
||||
},
|
||||
getData(){
|
||||
@ -100,9 +89,12 @@ export default {
|
||||
dataset:{
|
||||
// source
|
||||
source:[//格式
|
||||
['product','收益1','收益2'],
|
||||
['今天',10,20],
|
||||
['昨天',20,30],
|
||||
['product','收入','支出'],
|
||||
['6/10',10,20],
|
||||
['6/11',20,30],
|
||||
['6/12',20,34],
|
||||
['6/13',20,90],
|
||||
['6/14',20,3],
|
||||
]
|
||||
},
|
||||
series: [
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<syzb/>
|
||||
<!-- <syzb/>-->
|
||||
<dlzb/>
|
||||
</div>
|
||||
</template>
|
||||
@ -10,6 +10,7 @@
|
||||
import Syzb from "./Syzb.vue";
|
||||
import Dlzb from "./Dlzb.vue";
|
||||
export default {
|
||||
name:'DzjkTjbbGltj',
|
||||
components: {Syzb,Dlzb}
|
||||
}
|
||||
</script>
|
||||
|
||||
@ -1,14 +1,19 @@
|
||||
<template>
|
||||
<div class="ems-dashboard-editor-container tjbb-ems-dashboard-editor-container">
|
||||
<div class="router-container">
|
||||
<div>
|
||||
<div class="route-link" :class="{'active':item.name === $route.name}" v-for="(item,index) in childrenRoute" :key="index+'tjbbChildrenRoute'">
|
||||
<router-link style="height: 100%;width: 100%;display: block" :to="{path:item.path,query:$route.query}">
|
||||
{{item.meta.title}}
|
||||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ems-dashboard-editor-container ems-third-menu-container">
|
||||
<el-menu
|
||||
class="ems-third-menu"
|
||||
:default-active="$route.name"
|
||||
background-color="#ffffff"
|
||||
text-color="#666666"
|
||||
active-text-color="#ffffff"
|
||||
>
|
||||
<el-menu-item :index="item.name" v-for="(item,index) in childrenRoute" :key="index+'tjbbChildrenRoute'">
|
||||
<router-link style="height: 100%;width: 100%;display: block;" :to="{path:item.path,query:$route.query}">
|
||||
{{item.meta.title}}
|
||||
</router-link>
|
||||
</el-menu-item>
|
||||
</el-menu>
|
||||
|
||||
<div class="ems-content-container ems-content-container-padding tjbb-ems-content-container">
|
||||
<keep-alive>
|
||||
<router-view></router-view>
|
||||
@ -20,9 +25,10 @@
|
||||
|
||||
<script>
|
||||
import { dzjk } from '@/router/ems'
|
||||
const childrenRoute = dzjk[0].children[0].children.find(item=> item.name==='DjzkTjbb').children//获取到统计报表下面的字路由
|
||||
const childrenRoute = dzjk[0].children[0].children.find(item=> item.name==='DzjkTjbb').children//获取到统计报表下面的字路由
|
||||
console.log('设备监控子路由',childrenRoute)
|
||||
export default {
|
||||
name:'DzjkTjbb',
|
||||
data(){
|
||||
return {
|
||||
childrenRoute,
|
||||
@ -37,33 +43,6 @@ export default {
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.tjbb-ems-dashboard-editor-container{
|
||||
display: flex;
|
||||
padding:0;
|
||||
background: #FFFFFF;
|
||||
}
|
||||
.router-container{
|
||||
&>div{
|
||||
border: 1px solid #dcdfe6;
|
||||
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, .12), 0 0 6px 0 rgba(0, 0, 0, .04);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.route-link{
|
||||
width: 104px;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
background-color: #ffffff;
|
||||
color: #666666;
|
||||
font-size: 14px;
|
||||
text-align: center;
|
||||
}
|
||||
.route-link.active{
|
||||
background-color: #FFBE29 ;
|
||||
color: #333333;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
.tjbb-ems-content-container{
|
||||
margin-top:0;
|
||||
padding-top:0;
|
||||
|
||||
207
src/views/ems/dzjk/tjbb/pcsqx/index.vue
Normal file
@ -0,0 +1,207 @@
|
||||
<template>
|
||||
<el-card
|
||||
shadow="always"
|
||||
class="common-card-container time-range-card"
|
||||
style="margin-top: 20px"
|
||||
>
|
||||
<div slot="header" class="time-range-header">
|
||||
<span class="card-title"> </span>
|
||||
<date-range-select ref="dateRangeSelect" @updateDate="updateDate" />
|
||||
</div>
|
||||
<div class="card-main" v-loading="loading">
|
||||
<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>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as echarts from "echarts";
|
||||
import resize from "@/mixins/ems/resize";
|
||||
import getQuerySiteId from "@/mixins/ems/getQuerySiteId";
|
||||
import { getPCSData, getPcsNameList } from "@/api/ems/dzjk";
|
||||
import { formatDate } from "@/filters/ems";
|
||||
import DateRangeSelect from "@/components/Ems/DateRangeSelect/index.vue";
|
||||
export default {
|
||||
name: "DzjkTjbbPcsqx",
|
||||
components: { DateRangeSelect },
|
||||
mixins: [resize, getQuerySiteId],
|
||||
data() {
|
||||
return {
|
||||
pickerOptions: {
|
||||
disabledDate(time) {
|
||||
return time.getTime() > Date.now();
|
||||
},
|
||||
},
|
||||
dateRange: [],
|
||||
loading: false,
|
||||
activeBtn: "1",
|
||||
btnList: [
|
||||
{
|
||||
name: "有功功率",
|
||||
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: {
|
||||
changeDataType(id) {
|
||||
if (id !== this.activeBtn) {
|
||||
console.log("点击了不同的菜单,更新数据");
|
||||
this.activeBtn = id;
|
||||
this.getData();
|
||||
}
|
||||
},
|
||||
// 更新时间范围 重置图表
|
||||
updateDate(data) {
|
||||
this.dateRange = data || [];
|
||||
this.getData();
|
||||
},
|
||||
getData() {
|
||||
const { siteId, activeBtn } = this;
|
||||
const [start = "", end = ""] = this.dateRange || [];
|
||||
this.loading = true;
|
||||
//接口调用完成之后 设置图表、结束loading
|
||||
getPCSData({
|
||||
siteId,
|
||||
startTime: formatDate(start),
|
||||
endTime: formatDate(end),
|
||||
dataType: activeBtn,
|
||||
})
|
||||
.then((response) => {
|
||||
this.setOption(response?.data || []);
|
||||
})
|
||||
.finally(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
compareDate(date1, date2) {
|
||||
console.log("比较时间", date1, date2);
|
||||
// 年2025-09/天2025-09-15/时2025-09-15/10:00
|
||||
if (date1.indexOf(":") > -1 && date2.indexOf(":") > -1) {
|
||||
return parseInt(date1) - parseInt(date2);
|
||||
}
|
||||
const [date1_Y = "", date1_M = "", date1_D = ""] = date1.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
|
||||
);
|
||||
},
|
||||
setOption(data) {
|
||||
const ele = this.btnList.find((item) => {
|
||||
return item.id === this.activeBtn;
|
||||
});
|
||||
const sourceBase = JSON.parse(JSON.stringify(ele.source));
|
||||
// sourceBase={name:'堆平均维度',id:'1',attr:['temp'],source:['有功功率']},
|
||||
const source = [];
|
||||
const sourceTop = ["日期"];
|
||||
let map = {},
|
||||
mapArr = [];
|
||||
// 生成所有{日期:[],日期:[]}格式的对象和所有包含所有日期的[日期1,日期2...]
|
||||
data.forEach((item) => {
|
||||
item.dataList.forEach((inner) => {
|
||||
// 日期格式
|
||||
// 年2025-09/天2025-09-15/时2025-09-15/10:00
|
||||
// 所有数据的日期格式一致
|
||||
if (!map[inner.statisDate]) {
|
||||
map[inner.statisDate] = [];
|
||||
mapArr.push(inner.statisDate);
|
||||
}
|
||||
});
|
||||
});
|
||||
data.forEach((item, itemIndex) => {
|
||||
const dataTimeList = item.dataList.map((i) => i.statisDate);
|
||||
const noDataTime = mapArr.filter((i) => !dataTimeList.includes(i));
|
||||
sourceBase.forEach((outer, outerIndex) => {
|
||||
sourceTop.push(`${item.deviceId}-${outer}`);
|
||||
noDataTime.forEach((i) => map[i].push(""));
|
||||
item.dataList.forEach((inner, innerIndex) => {
|
||||
map[inner.statisDate].push(inner[ele.attr[outerIndex]]);
|
||||
});
|
||||
});
|
||||
});
|
||||
mapArr = mapArr.sort((a, b) => this.compareDate(a, b));
|
||||
mapArr.forEach((item) => {
|
||||
source.push([item, ...map[item]]);
|
||||
});
|
||||
source.unshift(sourceTop);
|
||||
this.chart.setOption(
|
||||
{
|
||||
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",
|
||||
};
|
||||
}),
|
||||
},
|
||||
true
|
||||
);
|
||||
},
|
||||
initChart() {
|
||||
this.chart = echarts.init(document.querySelector("#pcsEchart"));
|
||||
},
|
||||
init() {
|
||||
this.$nextTick(() => {
|
||||
this.initChart();
|
||||
this.$refs.dateRangeSelect.init();
|
||||
});
|
||||
},
|
||||
},
|
||||
beforeDestroy() {
|
||||
if (!this.chart) {
|
||||
return;
|
||||
}
|
||||
this.chart.dispose();
|
||||
this.chart = null;
|
||||
},
|
||||
};
|
||||
</script>
|
||||
215
src/views/ems/dzjk/tjbb/sybb/index.vue
Normal file
@ -0,0 +1,215 @@
|
||||
<template>
|
||||
<div style="width:100%" v-loading="loading">
|
||||
<!-- 搜索栏-->
|
||||
<el-form :inline="true" class="select-container">
|
||||
<el-form-item label="时间选择">
|
||||
<el-date-picker
|
||||
v-model="dateRange"
|
||||
type="daterange"
|
||||
range-separator="至"
|
||||
start-placeholder="开始日期"
|
||||
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-button type="primary" @click="onSearch" native-type="button">搜索</el-button>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button @click="onReset" native-type="button">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<!--表格-->
|
||||
<el-table
|
||||
class="common-table"
|
||||
:data="tableData"
|
||||
show-summary
|
||||
stripe
|
||||
style="width: 100%;margin-top:25px;">
|
||||
<!-- 汇总列-->
|
||||
<el-table-column label="汇总" min-width="100px" align="center">
|
||||
<el-table-column
|
||||
prop="dataTime"
|
||||
label="日期"
|
||||
min-width="100px" align="center">
|
||||
</el-table-column>
|
||||
</el-table-column>
|
||||
<!--充电量列-->
|
||||
<el-table-column label="充电价格" align="center">
|
||||
<el-table-column
|
||||
align="center"
|
||||
prop="activePeakPrice"
|
||||
label="尖">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
align="center"
|
||||
prop="activeHighPrice"
|
||||
label="峰">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
align="center"
|
||||
prop="activeFlatPrice"
|
||||
label="平">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
align="center"
|
||||
prop="activeValleyPrice"
|
||||
label="谷">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
align="center"
|
||||
prop="activeTotalPrice"
|
||||
label="总">
|
||||
</el-table-column>
|
||||
</el-table-column>
|
||||
<!--充电量列-->
|
||||
<el-table-column label="放电价格" align="center">
|
||||
<el-table-column
|
||||
align="center"
|
||||
prop="reActivePeakPrice"
|
||||
label="尖">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
align="center"
|
||||
prop="reActiveHighPrice"
|
||||
label="峰">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
align="center"
|
||||
prop="reActiveFlatPrice"
|
||||
label="平">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
align="center"
|
||||
prop="reActiveValleyPrice"
|
||||
label="谷">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
align="center"
|
||||
prop="reActiveTotalPrice"
|
||||
label="总">
|
||||
</el-table-column>
|
||||
</el-table-column>
|
||||
<!-- 实际收益-->
|
||||
<el-table-column label="" align="center" fixed="right">
|
||||
<el-table-column
|
||||
prop="actualRevenue"
|
||||
label="实际收益"
|
||||
align="center">
|
||||
</el-table-column>
|
||||
</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>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<script>
|
||||
import getQuerySiteId from "@/mixins/ems/getQuerySiteId";
|
||||
import {getAmmeterRevenueData} from '@/api/ems/dzjk'
|
||||
import {formatDate} from "@/filters/ems";
|
||||
|
||||
export default {
|
||||
name: 'DzjkTjbbSybb',
|
||||
mixins: [getQuerySiteId],
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
pickerOptions: {
|
||||
disabledDate(time) {
|
||||
return time.getTime() > Date.now();
|
||||
},
|
||||
},
|
||||
defaultDateRange: [],//默认展示的时间
|
||||
dateRange: [],
|
||||
tableData: [],
|
||||
pageSize: 10,//分页栏当前每个数据总数
|
||||
pageNum: 1,//分页栏当前页数
|
||||
totalSize: 0,//table表格数据总数
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 搜索
|
||||
onSearch() {
|
||||
this.pageNum = 1//每次搜索从1开始搜索
|
||||
this.getData()
|
||||
},
|
||||
// 重置
|
||||
onReset() {
|
||||
this.dateRange = this.defaultDateRange
|
||||
this.pageNum = 1//每次搜索从1开始搜索
|
||||
this.getData()
|
||||
},
|
||||
// 分页
|
||||
handleSizeChange(val) {
|
||||
this.pageSize = val;
|
||||
this.$nextTick(() => {
|
||||
this.getData()
|
||||
})
|
||||
},
|
||||
handleCurrentChange(val) {
|
||||
this.pageNum = val
|
||||
this.$nextTick(() => {
|
||||
this.getData()
|
||||
})
|
||||
},
|
||||
// 获取数据
|
||||
getData() {
|
||||
this.loading = true
|
||||
const {siteId, pageNum, pageSize} = this
|
||||
const [startTime = '', endTime = ''] = (this.dateRange || [])
|
||||
getAmmeterRevenueData({siteId: siteId, startTime, endTime, pageSize, pageNum}).then(response => {
|
||||
this.tableData = response?.rows || [];
|
||||
this.totalSize = response?.total || 0
|
||||
}).finally(() => {
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
init() {
|
||||
this.dateRange = []
|
||||
this.tableData = []
|
||||
this.totalSize = 0
|
||||
this.pageSize = 10
|
||||
this.pageNum = 1
|
||||
let now = new Date(), lastDay = now.getTime(), firstDay = new Date(now.setDate(1)).getTime();
|
||||
this.defaultDateRange = [formatDate(firstDay), formatDate(lastDay)];
|
||||
this.dateRange = [formatDate(firstDay), formatDate(lastDay)];
|
||||
this.getData()
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
::v-deep {
|
||||
.common-table.el-table {
|
||||
.el-table__header-wrapper th, .common-table.el-table .el-table__fixed-header-wrapper th {
|
||||
border-bottom: 1px solid #dfe6ec;
|
||||
}
|
||||
|
||||
.el-table__footer-wrapper {
|
||||
tbody td.el-table__cell {
|
||||
color: #000;
|
||||
font-weight: bolder;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
</style>
|
||||
650
src/views/ems/dzjk/zxlt/index.vue
Normal file
@ -0,0 +1,650 @@
|
||||
<template>
|
||||
<div class="ems-dashboard-editor-container" v-loading="loading">
|
||||
<div class="container" v-show="!empty">
|
||||
<!-- 云、电脑 -->
|
||||
<div class="top">
|
||||
<div class="cloud-container">
|
||||
<div class="cloud">
|
||||
<span style="z-index: 2; position: relative">云</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="double-arrows">
|
||||
<div class="top-arrows"></div>
|
||||
<div class="bottom-arrows"></div>
|
||||
</div>
|
||||
<div class="computer">
|
||||
<img src="@/assets/images/ems/computer.png" alt=""/>
|
||||
<span style="z-index: 2; position: relative">ems</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="outer-border">
|
||||
<!-- 电表-->
|
||||
<div class="row-lists-container" v-if="showDb">
|
||||
<div class="row-title">电表({{ db.length }})</div>
|
||||
<div
|
||||
class="row-lists"
|
||||
v-for="outter in Math.ceil(db.length / 3)"
|
||||
:key="outter + 'row'"
|
||||
>
|
||||
<template v-for="(item, index) in handlerList('db', outter)">
|
||||
<div :key="index" class="row-items">
|
||||
<div
|
||||
style="position: relative; z-index: 2; background-color: #fff"
|
||||
>
|
||||
<div
|
||||
class="status"
|
||||
:class="
|
||||
item.deviceStatus === '1' ? 'status-running' : ''
|
||||
"
|
||||
>
|
||||
{{ deviceStatusOptions[item.deviceStatus] }}
|
||||
</div>
|
||||
<div class="row-items-img">
|
||||
<img
|
||||
class="img-db"
|
||||
:src="require('@/assets/images/ems/db.png')"
|
||||
/>
|
||||
<div class="name">{{ item.deviceName }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 冷却-->
|
||||
<div class="row-lists-container" v-if="showLq">
|
||||
<div class="row-title">冷却({{ lq.length }})</div>
|
||||
<div
|
||||
class="row-lists"
|
||||
v-for="outter in Math.ceil(lq.length / 3)"
|
||||
:key="outter + 'row'"
|
||||
>
|
||||
<template v-for="(item, index) in handlerList('lq', outter)">
|
||||
<div :key="index" class="row-items">
|
||||
<div
|
||||
style="position: relative; z-index: 2; background-color: #fff"
|
||||
>
|
||||
<div
|
||||
class="status"
|
||||
:class="
|
||||
item.deviceStatus === '1' ? 'status-running' : ''
|
||||
"
|
||||
>
|
||||
{{ deviceStatusOptions[item.deviceStatus] }}
|
||||
</div>
|
||||
<div class="row-items-img">
|
||||
<img
|
||||
class="img-lq"
|
||||
:src="require('@/assets/images/ems/lq.png')"
|
||||
/>
|
||||
<div class="name">{{ item.deviceName }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 没有上级设备的bms -->
|
||||
<div
|
||||
class="row-lists-container"
|
||||
v-if="bmsHasParentLength !== bms.length"
|
||||
>
|
||||
<div class="row-title">BMS({{ bmsNoParent.length }})</div>
|
||||
<div
|
||||
class="row-lists"
|
||||
v-for="outter in Math.ceil(bmsNoParent.length / 3)"
|
||||
:key="outter + 'row'"
|
||||
>
|
||||
<template
|
||||
v-for="(item, index) in handlerList('bmsNoParent', outter)"
|
||||
>
|
||||
<div :key="index" class="row-items">
|
||||
<div
|
||||
style="position: relative; z-index: 2; background-color: #fff"
|
||||
>
|
||||
<div
|
||||
class="status"
|
||||
:class="
|
||||
item.deviceStatus === '1' ? 'status-running' : ''
|
||||
"
|
||||
>
|
||||
{{ deviceStatusOptions[item.deviceStatus] }}
|
||||
</div>
|
||||
<div class="row-items-img row-items-img-bms">
|
||||
<div style="position:relative;">
|
||||
<img
|
||||
class="img-bms"
|
||||
:src="require('@/assets/images/ems/bms.png')"
|
||||
/>
|
||||
<div class="num">{{ item.batteryNum || 0 }}</div>
|
||||
</div>
|
||||
<div class="name">{{ item.deviceName }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- pcs -->
|
||||
<div
|
||||
class="row-lists-container row-lists-container-with-children"
|
||||
v-if="showPcs"
|
||||
>
|
||||
<div class="row-title">
|
||||
PCS({{ pcs.length }}){{
|
||||
pcsHasChildren.length > 0 ? `、BMS(${pcsHasChildren.length})` : ""
|
||||
}}
|
||||
</div>
|
||||
<div
|
||||
class="row-lists"
|
||||
v-for="outter in Math.ceil(pcs.length / 3)"
|
||||
:key="outter + 'row'"
|
||||
>
|
||||
<template v-for="(item, index) in handlerList('pcs', outter)">
|
||||
<div :key="index" class="row-items">
|
||||
<!-- 上级设备 -->
|
||||
<div class="parent-dash">
|
||||
<div
|
||||
class="status"
|
||||
:class="
|
||||
item.deviceStatus === '1' ? 'status-running' : ''
|
||||
"
|
||||
>
|
||||
{{ deviceStatusOptions[item.deviceStatus] }}
|
||||
</div>
|
||||
<div class="row-items-img">
|
||||
<img
|
||||
class="img-pcs"
|
||||
:src="require('@/assets/images/ems/pcs.png')"
|
||||
/>
|
||||
<div class="name">{{ item.deviceName }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 下级设备 -->
|
||||
<div
|
||||
class="children-dash"
|
||||
v-if="item.children && item.children.length > 0"
|
||||
>
|
||||
<div
|
||||
class="status"
|
||||
:class="
|
||||
item.children[0].deviceStatus === '1'
|
||||
? 'status-running'
|
||||
: ''
|
||||
"
|
||||
>
|
||||
{{
|
||||
deviceStatusOptions[
|
||||
item.children[0].deviceStatus
|
||||
]
|
||||
}}
|
||||
</div>
|
||||
<div class="row-items-img row-items-img-bms">
|
||||
<div style="position: relative">
|
||||
<img
|
||||
class="img-bms"
|
||||
:src="require('@/assets/images/ems/bms.png')"
|
||||
/>
|
||||
<div class="num">{{ item.batteryNum || 0 }}</div>
|
||||
</div>
|
||||
<div class="name">{{ item.children[0].deviceName }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<el-empty v-show="empty" :image-size="200"></el-empty>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {getDeviceList} from "@/api/ems/site";
|
||||
import getQuerySiteId from "@/mixins/ems/getQuerySiteId";
|
||||
import {mapState} from "vuex";
|
||||
|
||||
export default {
|
||||
name: "DzjkZxlt",
|
||||
mixins: [getQuerySiteId],
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
pcs: [],
|
||||
bms: [],
|
||||
db: [],
|
||||
lq: [],
|
||||
bmsNoParent: [],
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
deviceStatusOptions: (state) =>
|
||||
state.ems.deviceStatusOptions,
|
||||
}),
|
||||
|
||||
showPcs() {
|
||||
return this.pcs.length > 0;
|
||||
},
|
||||
showBms() {
|
||||
return this.bms.length > 0;
|
||||
},
|
||||
showDb() {
|
||||
return this.db.length > 0;
|
||||
},
|
||||
showLq() {
|
||||
return this.lq.length > 0;
|
||||
},
|
||||
bmsHasParentLength() {
|
||||
let count = 0;
|
||||
this.pcs.forEach((item) => (count += item.children.length));
|
||||
return count;
|
||||
},
|
||||
pcsHasChildren() {
|
||||
return this.pcs.filter(
|
||||
(item) => item.children && item.children.length > 0
|
||||
);
|
||||
},
|
||||
empty() {
|
||||
return !this.showBms && !this.showPcs && !this.showDb && !this.showLq;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
handlerList(type, index) {
|
||||
const arr = this[type];
|
||||
const max = index * 3 > arr.length ? arr.length % 3 : 3;
|
||||
let result = [];
|
||||
for (let i = 1; i <= max; i++) {
|
||||
result.push(arr[i - 1 + 3 * (index - 1)]);
|
||||
}
|
||||
return result;
|
||||
},
|
||||
init() {
|
||||
this.pcs = [];
|
||||
this.bms = [];
|
||||
this.lq = [];
|
||||
this.db = [];
|
||||
this.bmsNoParent = [];
|
||||
this.loading = true;
|
||||
getDeviceList(this.siteId)
|
||||
.then((response) => {
|
||||
const data = JSON.parse(JSON.stringify(response?.data || []));
|
||||
let pcs = [],
|
||||
bms = [],
|
||||
db = [],
|
||||
lq = [],
|
||||
bmsNoParent = [];
|
||||
data.forEach((item) => {
|
||||
// 电表
|
||||
if (item.deviceCategory === "AMMETER") {
|
||||
db.push({...item, children: []});
|
||||
} else if (item.deviceCategory === "PCS") {
|
||||
// pcs
|
||||
pcs.push({...item, children: []});
|
||||
} else if (item.deviceCategory === "STACK") {
|
||||
// bms
|
||||
bms.push({...item, children: []});
|
||||
} else if (item.deviceCategory === "COOLING") {
|
||||
// 液冷
|
||||
lq.push({...item, children: []});
|
||||
}
|
||||
});
|
||||
bms.forEach((item, index) => {
|
||||
if (item.parentId) {
|
||||
pcs
|
||||
.find((pcsItem) => pcsItem.deviceId === item.parentId)
|
||||
.children.push(item);
|
||||
} else {
|
||||
bmsNoParent.push(item);
|
||||
}
|
||||
});
|
||||
this.pcs = pcs;
|
||||
this.bms = bms;
|
||||
this.lq = lq;
|
||||
this.db = db;
|
||||
this.bmsNoParent = bmsNoParent;
|
||||
})
|
||||
.finally(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
$sqDistance: 30px;
|
||||
$borderColor: #174a8e;
|
||||
$lineColor: #86bcc7;
|
||||
|
||||
.ems-dashboard-editor-container {
|
||||
background-color: #ffffff;
|
||||
padding: 0;
|
||||
color: #666666;
|
||||
|
||||
.container {
|
||||
display: flex;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
//云 、计算机 、箭头
|
||||
.top {
|
||||
z-index: 2;
|
||||
width: fit-content;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
// position: absolute;
|
||||
// top: 50%;
|
||||
// left: 0;
|
||||
// transform: translateY(-50%);
|
||||
//云 样式
|
||||
.cloud-container {
|
||||
margin: 0 auto;
|
||||
|
||||
.cloud {
|
||||
width: 60px;
|
||||
height: 26px;
|
||||
background: #cbebfd;
|
||||
border-radius: 100px;
|
||||
position: relative;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
font-size: 14px;
|
||||
line-height: 26px;
|
||||
}
|
||||
|
||||
.cloud:before,
|
||||
.cloud:after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
background: #cbebfd;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
border-radius: 100%;
|
||||
}
|
||||
|
||||
.cloud:before {
|
||||
top: -9px;
|
||||
left: 8px;
|
||||
}
|
||||
|
||||
.cloud:after {
|
||||
top: -6px;
|
||||
right: 9px;
|
||||
}
|
||||
}
|
||||
|
||||
//双箭头
|
||||
.double-arrows {
|
||||
height: fit-content;
|
||||
margin: 0 10px;
|
||||
text-align: center;
|
||||
|
||||
.top-arrows,
|
||||
.bottom-arrows {
|
||||
height: 4px;
|
||||
width: 30px;
|
||||
background-color: #5ea9df;
|
||||
margin: 0 10px;
|
||||
position: relative;
|
||||
|
||||
&::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 0;
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.top-arrows {
|
||||
vertical-align: super;
|
||||
}
|
||||
|
||||
.top-arrows::after {
|
||||
top: -4px;
|
||||
border-bottom: 6px solid transparent;
|
||||
border-left: 6px solid transparent;
|
||||
border-right: 6px solid #5ea9df;
|
||||
border-top: 6px solid transparent;
|
||||
left: -11px;
|
||||
}
|
||||
|
||||
.bottom-arrows {
|
||||
margin-top: 8px;
|
||||
|
||||
&::after {
|
||||
top: -4px;
|
||||
border-top: 6px solid transparent;
|
||||
border-left: 6px solid #5ea9df;
|
||||
border-right: 6px solid transparent;
|
||||
border-bottom: 6px solid transparent;
|
||||
right: -11px;
|
||||
left: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//电脑
|
||||
.computer {
|
||||
text-align: center;
|
||||
font-size: 14px;
|
||||
line-height: 16px;
|
||||
font-weight: bold;
|
||||
position: relative;
|
||||
background: #fff;
|
||||
|
||||
img {
|
||||
width: 80px;
|
||||
height: auto;
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.outer-border {
|
||||
position: relative;
|
||||
width: fit-content;
|
||||
border: 1.5px solid $borderColor;
|
||||
padding-left: 40px;
|
||||
margin-left: -40px;
|
||||
display: flex;
|
||||
// 设备列表
|
||||
.row-lists-container {
|
||||
font-size: 10px;
|
||||
position: relative;
|
||||
padding: 10px 20px;
|
||||
display: flex;
|
||||
|
||||
&:not(:first-child) {
|
||||
background: linear-gradient(
|
||||
to top,
|
||||
transparent 0%,
|
||||
transparent 50%,
|
||||
#ccc 50%,
|
||||
#ccc 100%
|
||||
);
|
||||
background-size: 1px 10px;
|
||||
background-repeat: repeat-y;
|
||||
}
|
||||
|
||||
.row-title {
|
||||
position: absolute;
|
||||
left: -$sqDistance - 30px;
|
||||
top: -20px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
color: #000;
|
||||
font-weight: bolder;
|
||||
}
|
||||
|
||||
.row-lists {
|
||||
position: relative;
|
||||
|
||||
.row-items {
|
||||
position: relative;
|
||||
padding: 5px 0;
|
||||
background: #fff;
|
||||
// &:not(:first-child) {
|
||||
padding-top: 20px; //todo
|
||||
// }
|
||||
&::after {
|
||||
z-index: 1;
|
||||
content: "";
|
||||
display: block;
|
||||
height: 25px;
|
||||
width: 3px;
|
||||
background: $lineColor;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: -10px;
|
||||
transform: scale(0.4, 1);
|
||||
}
|
||||
|
||||
// 设备状态
|
||||
.status {
|
||||
margin: 0 auto 4px;
|
||||
width: fit-content;
|
||||
height: 18px;
|
||||
padding: 0 8px;
|
||||
box-sizing: border-box;
|
||||
text-align: center;
|
||||
font-size: 8px;
|
||||
line-height: 18px;
|
||||
border: 1px solid #08ffff;
|
||||
border-radius: 2px;
|
||||
background: #aaaaaa;
|
||||
color: #ffffff;
|
||||
|
||||
&.status-running {
|
||||
background: #00c69c;
|
||||
}
|
||||
}
|
||||
|
||||
// 图片+设备名称
|
||||
.row-items-img {
|
||||
position: relative;
|
||||
padding-top: 12px;
|
||||
|
||||
&.row-items-img-bms {
|
||||
padding-top: 14px;
|
||||
|
||||
.num {
|
||||
position: absolute;
|
||||
top: -2px;
|
||||
right: -2px;
|
||||
font-size: 10px;
|
||||
line-height: 10px;
|
||||
padding: 2px 4px;
|
||||
text-align: center;
|
||||
border-radius: 10px;
|
||||
background-color: #03c69d;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
img {
|
||||
width: 80px;
|
||||
height: auto;
|
||||
display: block;
|
||||
position: relative;
|
||||
|
||||
&.img-lq {
|
||||
width: 50px;
|
||||
}
|
||||
|
||||
&.img-pcs {
|
||||
width: 50px;
|
||||
}
|
||||
|
||||
&.img-db {
|
||||
width: 56px;
|
||||
}
|
||||
}
|
||||
|
||||
.name {
|
||||
position: absolute;
|
||||
top: 1px;
|
||||
left: 0;
|
||||
color: #666;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 有下级设备
|
||||
.row-lists-container-with-children {
|
||||
.row-lists {
|
||||
&:not(:last-child) {
|
||||
margin-right: 30px;
|
||||
}
|
||||
|
||||
.row-items {
|
||||
display: flex;
|
||||
|
||||
&::after {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.parent-dash {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
background-color: #fff;
|
||||
|
||||
> div {
|
||||
z-index: 2;
|
||||
position: inherit;
|
||||
}
|
||||
|
||||
&::after {
|
||||
z-index: 1;
|
||||
content: "";
|
||||
display: block;
|
||||
height: 45px;
|
||||
width: 3px;
|
||||
background: $lineColor;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: -30px;
|
||||
transform: scale(0.4, 1);
|
||||
}
|
||||
}
|
||||
|
||||
.children-dash {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
background-color: #fff;
|
||||
margin: -20px 0 0 26px;
|
||||
height: fit-content;
|
||||
|
||||
> div {
|
||||
z-index: 2;
|
||||
position: inherit;
|
||||
}
|
||||
|
||||
&::after {
|
||||
z-index: 1;
|
||||
content: "";
|
||||
display: block;
|
||||
width: 44px;
|
||||
height: 1px;
|
||||
background: #ec7f8c;
|
||||
position: absolute;
|
||||
left: -33px;
|
||||
bottom: -10px;
|
||||
transform: rotate(-34deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -3,7 +3,7 @@
|
||||
<el-card shadow="always" class="common-card-container common-card-container-body-no-padding">
|
||||
<div slot="header">
|
||||
<span class="card-title">电量指标</span>
|
||||
<el-button style="float: right; padding: 3px 0" type="text" size="small">按年</el-button>
|
||||
<!-- <el-button style="float: right; padding: 3px 0" type="text" size="small">按年</el-button>-->
|
||||
</div>
|
||||
<div style="height: 360px" id="dlzbChart"/>
|
||||
</el-card>
|
||||
@ -12,7 +12,6 @@
|
||||
<style scoped lang="scss"></style>
|
||||
<script>
|
||||
import * as echarts from 'echarts'
|
||||
require('echarts/theme/macarons') // echarts theme
|
||||
import resize from '@/mixins/ems/resize'
|
||||
|
||||
export default {
|
||||
@ -22,11 +21,6 @@ export default {
|
||||
chart: null
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.$nextTick(() => {
|
||||
this.initChart()
|
||||
})
|
||||
},
|
||||
beforeDestroy() {
|
||||
if (!this.chart) {
|
||||
return
|
||||
@ -35,15 +29,22 @@ export default {
|
||||
this.chart = null
|
||||
},
|
||||
methods: {
|
||||
initChart() {
|
||||
this.chart = echarts.init(document.querySelector('#dlzbChart'), 'macarons')
|
||||
this.setOptions()
|
||||
initChart(data) {
|
||||
this.chart = echarts.init(document.querySelector('#dlzbChart'))
|
||||
this.setOption(data)
|
||||
},
|
||||
setOptions() {
|
||||
setOption(data) {
|
||||
const source=[['日期','充电量','放电量']]
|
||||
data.forEach(item => {
|
||||
source.push([item.dateMonth,item.chargeEnergy,item.disChargeEnergy])
|
||||
})
|
||||
this.chart.setOption({
|
||||
grid: {
|
||||
containLabel: true
|
||||
},
|
||||
legend: {
|
||||
left: 'center',
|
||||
bottom: '10',
|
||||
bottom: '15',
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
@ -55,7 +56,7 @@ export default {
|
||||
color:"#333333",
|
||||
},
|
||||
xAxis: {
|
||||
data: ['1月','2月','3月','4月','5月','6月','7月','8月','9月','10月','11月','12月'],
|
||||
type: 'category',
|
||||
axisLine: {
|
||||
lineStyle:{
|
||||
color: '#333333',
|
||||
@ -70,10 +71,10 @@ export default {
|
||||
}
|
||||
}
|
||||
},
|
||||
dataset:{source},
|
||||
series: [
|
||||
{
|
||||
name:'充电量',
|
||||
data: [80,92,1,34,90,130,320,80,9,91,34,90],
|
||||
type: 'line',
|
||||
itemStyle: {
|
||||
color: '#F86F70',
|
||||
@ -85,7 +86,6 @@ export default {
|
||||
}
|
||||
},{
|
||||
name:'放电量',
|
||||
data: [820,932,901,934,1290,1330,1320,820,932,901,934,1290],
|
||||
type: 'line',
|
||||
itemStyle: {
|
||||
color: '#488AFF',
|
||||
|
||||
@ -11,7 +11,6 @@
|
||||
<style scoped lang="scss"></style>
|
||||
<script>
|
||||
import * as echarts from 'echarts'
|
||||
require('echarts/theme/macarons') // echarts theme
|
||||
import resize from '@/mixins/ems/resize'
|
||||
|
||||
export default {
|
||||
@ -21,11 +20,6 @@ export default {
|
||||
chart: null
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.$nextTick(() => {
|
||||
this.initChart()
|
||||
})
|
||||
},
|
||||
beforeDestroy() {
|
||||
if (!this.chart) {
|
||||
return
|
||||
@ -34,16 +28,23 @@ export default {
|
||||
this.chart = null
|
||||
},
|
||||
methods: {
|
||||
initChart() {
|
||||
this.chart = echarts.init(document.querySelector('#gjdjfbChart'), 'macarons')
|
||||
this.setOptions()
|
||||
initChart(data) {
|
||||
this.chart = echarts.init(document.querySelector('#gjdjfbChart'))
|
||||
this.setOption(data)
|
||||
},
|
||||
setOptions() {
|
||||
setOption(data) {
|
||||
const source=[['告警等级','告警数量','告警占比']]
|
||||
data.forEach(item => {
|
||||
source.push([item.level,item.dataNum,item.percent])
|
||||
})
|
||||
this.chart.setOption({
|
||||
color:['#3C81FF','#FFBE29'],
|
||||
grid: {
|
||||
containLabel: true
|
||||
},
|
||||
legend: {
|
||||
left: 'center',
|
||||
bottom: '10',
|
||||
bottom: '15',
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
@ -55,7 +56,7 @@ export default {
|
||||
color:"#333333",
|
||||
},
|
||||
xAxis: {
|
||||
data: ['A级','B级','C级','D级','E级','F级'],
|
||||
type: 'category',
|
||||
axisLine: {
|
||||
lineStyle:{
|
||||
color: '#333333',
|
||||
@ -79,19 +80,18 @@ export default {
|
||||
onZero:false
|
||||
}
|
||||
}],
|
||||
dataset:{source},
|
||||
series: [
|
||||
{
|
||||
name:'数据一',
|
||||
yAxisIndex:0,
|
||||
data: [80,92,1,34,90,130,320],
|
||||
type: 'line',
|
||||
},
|
||||
{
|
||||
name:'数据二',
|
||||
yAxisIndex:1,
|
||||
data: [89,9,80,4,100,30,30],
|
||||
type: 'bar',
|
||||
}
|
||||
{
|
||||
name:'告警数量',
|
||||
yAxisIndex:0,
|
||||
type: 'line',
|
||||
},
|
||||
{
|
||||
name:'告警占比',
|
||||
yAxisIndex:1,
|
||||
type: 'bar',
|
||||
}
|
||||
]
|
||||
})
|
||||
}
|
||||
|
||||