光伏功能页面
This commit is contained in:
@ -64,7 +64,6 @@ export default {
|
||||
aioPower: 'AIO Power',
|
||||
loadPower: 'Load Power',
|
||||
powerFactor: 'Fa-Power',
|
||||
|
||||
stationName: 'Name of Power Station',
|
||||
stationType: 'Type of Power Station',
|
||||
stationLocation: 'Location of Power Station',
|
||||
@ -81,7 +80,6 @@ export default {
|
||||
tree: 'Tree',
|
||||
discabinet: 'Distribution cabinet',
|
||||
chargingPile: 'Charging pile',
|
||||
|
||||
chargingDischarging: 'Cumulative charge and discharge',
|
||||
sevenDay: 'Nearly Seven Days',
|
||||
monthDay: 'Nearly a Month',
|
||||
@ -108,7 +106,6 @@ export default {
|
||||
energyStorage: 'Energy Storage',
|
||||
energyStorageMeter: 'Energy Storage Meter',
|
||||
crane: 'Crane',
|
||||
|
||||
realtimeAlarm: 'Real-Time Alarms',
|
||||
accessPoint: 'Device Access Point',
|
||||
environmentalData: 'Environmental Control Data',
|
||||
@ -120,27 +117,23 @@ export default {
|
||||
refSetting: 'Refrigeration Setting',
|
||||
shutPoint: 'Fan Shutdown Point',
|
||||
heatSetting: 'Heating Setting',
|
||||
|
||||
cabinetTem: 'Temperature of Energy Storage Cabinet',
|
||||
cabinetHum: 'Humidity of Energy Storage Cabinet',
|
||||
dieselTem: 'Diesel Generator Temperature',
|
||||
dieselLevel: 'Diesel Generator Oil Level',
|
||||
dieselDenerators: 'Diesel Generator',
|
||||
|
||||
runCurve: 'Run Time Curve',
|
||||
runData: 'Run Time Data',
|
||||
power: 'Power',
|
||||
air: 'Air Conditioning',
|
||||
device: 'Device',
|
||||
chargingandDischarging: 'Electricity',
|
||||
|
||||
alarmDevices: 'Alarm Devices',
|
||||
NormalDevices: 'Normal Devices',
|
||||
DeviceNo: 'Device No',
|
||||
DeviceType: 'Device Type',
|
||||
DeviceState: 'Device State',
|
||||
AlarmTime: 'Alarm time',
|
||||
|
||||
oneControl: 'One-click Control',
|
||||
col: 'Indicators',
|
||||
state: 'State',
|
||||
@ -163,12 +156,10 @@ export default {
|
||||
issusedMsg: 'This operation will send data items in sequence. Do you confirm the sending?',
|
||||
cancel: 'Cancel',
|
||||
sure: 'Sure',
|
||||
|
||||
Loadpower: 'Load Active Power',
|
||||
pvpower: 'Photovoltaic Active Power',
|
||||
PCSpower: 'PCS Active Power',
|
||||
Dieselpower: 'Diesel Generator Power',
|
||||
|
||||
waterSuper: 'Water Supply Temperature',
|
||||
ambientTem: 'Ambient Temperature',
|
||||
returnTemperature: 'Return Water Temperature',
|
||||
@ -177,7 +168,6 @@ export default {
|
||||
engineV: 'Diesel Generator voltage',
|
||||
powerfrequency: 'Generate Electricity Frequency',
|
||||
engineC: 'Diesel Generator Current',
|
||||
|
||||
onepcsPower: '1-PCS Active Power',
|
||||
twopcsPower: '2-PCS Active Power',
|
||||
onebmsSoc: '1-BMS-SOC',
|
||||
@ -224,6 +214,16 @@ export default {
|
||||
generation: 'Generation',
|
||||
yhl: 'Fuel',
|
||||
jsfs: 'Count method',
|
||||
saveSuccess: 'Save successful'
|
||||
saveSuccess: 'Save successful',
|
||||
todayElectricityGeneration: "Today's Electricity Generation",
|
||||
totalPowerGeneration: 'Cumulative Power Generation',
|
||||
totalRevenue: 'Cumulative Earnings',
|
||||
ratedPowerofInverter: 'Rated power of inverter',
|
||||
energyTrend: 'Energy Trend',
|
||||
month: 'month',
|
||||
year: 'year',
|
||||
powerGenerationCapacity: 'power generation capacity',
|
||||
powerGeneration: 'power generation',
|
||||
revenueTrend: 'Revenue Trend'
|
||||
}
|
||||
}
|
||||
|
||||
@ -13,7 +13,6 @@ export default {
|
||||
totalDischarge: '总放电量',
|
||||
dailyCharge: '日充电量',
|
||||
dailyDischarge: '日放电量',
|
||||
day: '天',
|
||||
frequency: '频率',
|
||||
rechPower: '可充功率',
|
||||
disRechPower: '可放功率',
|
||||
@ -64,7 +63,6 @@ export default {
|
||||
aioPower: '一体机功率',
|
||||
loadPower: '负载功率',
|
||||
refluxAmmeter: '防逆流电表',
|
||||
|
||||
stationName: '电站名称',
|
||||
stationType: '电站类型',
|
||||
stationLocation: '电站位置',
|
||||
@ -78,7 +76,6 @@ export default {
|
||||
coal: '等效节约煤',
|
||||
income: '等效经济收入',
|
||||
tree: '棵',
|
||||
|
||||
chargingDischarging: '累计充放电量',
|
||||
sevenDay: '近七天',
|
||||
monthDay: '近一月',
|
||||
@ -106,7 +103,6 @@ export default {
|
||||
energyStorageMeter: '储能电表',
|
||||
crane: '塔吊',
|
||||
powerFactor: '功率因数',
|
||||
|
||||
realtimeAlarm: '实时告警',
|
||||
accessPoint: '设备接入点',
|
||||
environmentalData: '环控数据',
|
||||
@ -118,27 +114,23 @@ export default {
|
||||
refSetting: '制冷设定',
|
||||
shutPoint: '风机停机点',
|
||||
heatSetting: '制热设定',
|
||||
|
||||
cabinetTem: '储能柜温度',
|
||||
cabinetHum: '储能柜湿度',
|
||||
dieselTem: '柴发温度',
|
||||
dieselLevel: '柴发油位',
|
||||
dieselDenerators: '柴发',
|
||||
|
||||
runCurve: '运行曲线',
|
||||
runData: '运行数据',
|
||||
power: '功率',
|
||||
air: '空调',
|
||||
device: '设备',
|
||||
chargingandDischarging: '充放电量',
|
||||
|
||||
alarmDevices: '告警设备',
|
||||
NormalDevices: '正常设备',
|
||||
DeviceNo: '设备编号',
|
||||
DeviceType: '设备类型',
|
||||
DeviceState: '设备状态',
|
||||
AlarmTime: '告警时间',
|
||||
|
||||
oneControl: '一键控制',
|
||||
col: '指标',
|
||||
state: '状态',
|
||||
@ -161,12 +153,10 @@ export default {
|
||||
issusedMsg: '此操作将会按顺序下发数据项,是否确认下发?',
|
||||
cancel: '取消',
|
||||
sure: '确认',
|
||||
|
||||
Loadpower: '负载有功功率',
|
||||
pvpower: '光伏有功功率',
|
||||
PCSpower: 'PCS有功功率',
|
||||
Dieselpower: '柴发有功功率',
|
||||
|
||||
waterSuper: '供水温度',
|
||||
ambientTem: '环境温度',
|
||||
returnTemperature: '回水温度',
|
||||
@ -175,7 +165,6 @@ export default {
|
||||
engineV: '柴发电压',
|
||||
powerfrequency: '发电频率',
|
||||
engineC: '柴发电流',
|
||||
|
||||
onepcsPower: '1-PCS有功功率',
|
||||
twopcsPower: '2-PCS有功功率',
|
||||
onebmsSoc: '1-BMS-SOC',
|
||||
@ -222,6 +211,17 @@ export default {
|
||||
generation: '发电量',
|
||||
yhl: '油耗量',
|
||||
jsfs: '计算方式',
|
||||
saveSuccess: '保存成功'
|
||||
saveSuccess: '保存成功',
|
||||
todayElectricityGeneration: '当日发电量',
|
||||
totalPowerGeneration: '累计发电量',
|
||||
totalRevenue: '累计收益',
|
||||
ratedPowerofInverter: '逆变器额定功率',
|
||||
energyTrend: '能量趋势',
|
||||
day: '日',
|
||||
month: '月',
|
||||
year: '年',
|
||||
powerGenerationCapacity: '发电功率',
|
||||
powerGeneration: '发电量',
|
||||
revenueTrend: '收益趋势'
|
||||
}
|
||||
}
|
||||
|
||||
@ -78,7 +78,6 @@ export default {
|
||||
acRea: 'Active/Reactive',
|
||||
active: 'Active',
|
||||
reactive: 'Reactive',
|
||||
|
||||
eqptRunState: 'Eqpt Run State',
|
||||
cumCharge: 'Cumulative charge',
|
||||
cumDischarge: 'Cumulative discharge',
|
||||
@ -103,10 +102,17 @@ export default {
|
||||
rightHum: 'Right Humidity',
|
||||
leftTem: 'Left Temperature',
|
||||
rightTem: 'Right Temperature',
|
||||
|
||||
dataDisplay: 'Data Display',
|
||||
|
||||
airTopo: 'Air Conditioning Topology',
|
||||
airTem: 'Air Conditioning Temperature'
|
||||
airTem: 'Air Conditioning Temperature',
|
||||
batVoltage: 'BAT voltage',
|
||||
batCurrent: 'BAT current',
|
||||
busVoltage: 'BUS voltage',
|
||||
busCurrent: 'BUS current',
|
||||
dc: 'DC',
|
||||
dcVoltage: 'DC voltage',
|
||||
operatingPower: 'operating power',
|
||||
powerGenerationCapacity: 'power generation capacity',
|
||||
powerGeneration: 'Power Generation'
|
||||
}
|
||||
}
|
||||
|
||||
@ -103,10 +103,17 @@ export default {
|
||||
rightHum: '右侧湿度',
|
||||
leftTem: '左侧温度',
|
||||
rightTem: '右侧温度',
|
||||
|
||||
dataDisplay: '数据展示',
|
||||
|
||||
airTopo: '空调拓扑图',
|
||||
airTem: '空调温度'
|
||||
airTem: '空调温度',
|
||||
batVoltage: 'BAT电压',
|
||||
batCurrent: 'BAT电流',
|
||||
busVoltage: 'BAT电压',
|
||||
busCurrent: 'BAT电流',
|
||||
dc: '直流电流',
|
||||
dcVoltage: '直流电压',
|
||||
operatingPower: '运行功率',
|
||||
powerGenerationCapacity: '发电功率',
|
||||
powerGeneration: '发电'
|
||||
}
|
||||
}
|
||||
|
||||
@ -522,6 +522,7 @@ export default {
|
||||
hint: 'Hint',
|
||||
delSuccess: 'Delete Success',
|
||||
addSuccess: 'Add Success',
|
||||
editSuccess: 'Edit Success', repairRecord: 'repairRecord' }
|
||||
editSuccess: 'Edit Success', repairRecord: 'repairRecord'
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -174,7 +174,21 @@ export default {
|
||||
computeding: 'Computing,The current progress is:',
|
||||
laterQuery: '%,Please enquire later.',
|
||||
earningReport: 'Earning Report',
|
||||
bill: 'Bill'
|
||||
bill: 'Bill',
|
||||
|
||||
powerGenerationStatus: 'power Generation Status',
|
||||
totalStringCapacity: 'Total string capacity',
|
||||
currentMonthlyPowerGeneration: 'Current monthly power generation',
|
||||
monthlyPowerGeneration: 'Monthly power generation',
|
||||
cumulativePowerGeneration: 'cumulative power generation',
|
||||
equivalentPowerGenerationTime: 'Equivalent power generation time',
|
||||
peakACpower: 'Peak AC power',
|
||||
gridConnectedDuration: 'grid-connected duration',
|
||||
projectRevenueSituation: 'Project revenue situation',
|
||||
monthlyPVpowerGeneration: 'Monthly PV power generation',
|
||||
monthlyInverterPowerGeneration: 'Monthly inverter power generation',
|
||||
monthlyIncome: 'Monthly income',
|
||||
powerGeneration: 'Power Generation'
|
||||
},
|
||||
region: {
|
||||
regionName: 'Region Name',
|
||||
|
||||
@ -134,7 +134,6 @@ export default {
|
||||
dayHighPrice: '日最高电价',
|
||||
dayLowtPrice: '日最低电价',
|
||||
close: '关闭'
|
||||
|
||||
},
|
||||
state: {
|
||||
month: '月份',
|
||||
@ -173,7 +172,21 @@ export default {
|
||||
computeding: '计算中,当前进度为',
|
||||
laterQuery: '%,请稍后查询。',
|
||||
earningReport: '收益报表',
|
||||
bill: '账单'
|
||||
bill: '账单',
|
||||
|
||||
powerGenerationStatus: '项目发电情况',
|
||||
totalStringCapacity: '组串总容量',
|
||||
currentMonthlyPowerGeneration: '本月发电量',
|
||||
cumulativePowerGeneration: '累计发电量',
|
||||
equivalentPowerGenerationTime: '等价发电时',
|
||||
peakACpower: '峰值交流功率',
|
||||
monthlyPowerGeneration: '月发电量',
|
||||
projectRevenueSituation: '项目收益情况',
|
||||
monthlyPVpowerGeneration: '本月PV发电量',
|
||||
monthlyInverterPowerGeneration: '本月逆变器发电量',
|
||||
monthlyIncome: '本月收益',
|
||||
gridConnectedDuration: '并网时长',
|
||||
powerGeneration: '发电量'
|
||||
},
|
||||
region: {
|
||||
regionName: '区域名称',
|
||||
|
||||
@ -53,6 +53,14 @@ export default {
|
||||
ammeter: 'PA',
|
||||
cabinet: 'Cabinet',
|
||||
diesel: 'Diesel',
|
||||
qtScreenTitle: 'New smart energy operation platform'
|
||||
qtScreenTitle: 'New smart energy operation platform',
|
||||
pvScreenTitle: 'Zetatech Smart PV management and control platform',
|
||||
todayEarning: 'Today Earning',
|
||||
dailyPowerGeneration: 'Daily Power Generation',
|
||||
yearlyPowerGeneration: 'Yearly Power Generation',
|
||||
cumulativePowerGeneration: 'Cumulative Power Generation',
|
||||
powerGenerationEarningRanking: 'Power generation earnings ranking',
|
||||
powerGenerationRanking: 'Power generation ranking',
|
||||
powerGeneration: 'power generation'
|
||||
}
|
||||
}
|
||||
|
||||
@ -53,6 +53,15 @@ export default {
|
||||
ammeter: '电表',
|
||||
cabinet: '储能柜',
|
||||
diesel: '柴发',
|
||||
qtScreenTitle: '新一代智慧能源运营平台'
|
||||
qtScreenTitle: '新一代智慧能源运营平台',
|
||||
|
||||
pvScreenTitle: '智慧光伏管控平台',
|
||||
todayEarning: '今日收益',
|
||||
dailyPowerGeneration: '日发电量',
|
||||
yearlyPowerGeneration: '年发电量',
|
||||
cumulativePowerGeneration: '累计发电量',
|
||||
powerGenerationEarningRanking: '发电收益排名',
|
||||
powerGenerationRanking: '发电量排名',
|
||||
powerGeneration: '发电'
|
||||
}
|
||||
}
|
||||
|
||||
@ -262,7 +262,7 @@ export default {
|
||||
policyTemCurve: 'Policy Template Curve/kW',
|
||||
exitSaveExit: 'Please save or exit the edit first',
|
||||
distributeSuccess: 'Distribute Succeeded',
|
||||
numRange: 'The number range is -99999999-99999999到99999999之间'
|
||||
numRange: 'Between -99999999 and 99999999'
|
||||
},
|
||||
loadForecast: {
|
||||
conditions: 'Current operating conditions',
|
||||
|
||||
@ -35,7 +35,8 @@ export default {
|
||||
maxValue: 'You can select up to',
|
||||
point: 'points',
|
||||
pointError: 'Only one point can be selected for ordinary points or cell dismantling'
|
||||
}, deviceUpgrade: {
|
||||
},
|
||||
deviceUpgrade: {
|
||||
powerStation: 'PowerStation',
|
||||
device: 'Device',
|
||||
deviceType: 'DeviceType',
|
||||
@ -80,5 +81,6 @@ export default {
|
||||
pleaseSelectTime: 'Please Select Time',
|
||||
pleaseFillinUpgradeReason: 'Please Fill in Upgrade Reason',
|
||||
pleaseUploadUpgradeFile: 'Please Upload Upgrade File',
|
||||
uploadSuccessful: 'Upload Successful' }
|
||||
uploadSuccessful: 'Upload Successful'
|
||||
}
|
||||
}
|
||||
|
||||
@ -14,6 +14,7 @@ const whiteList = [
|
||||
'/screen',
|
||||
'/new-screen',
|
||||
'/new-screen-zz',
|
||||
'/new-screen-zz-pv',
|
||||
'/common-screen',
|
||||
'/app-privacy-en.html'
|
||||
] // no redirect whitelist
|
||||
|
||||
@ -87,6 +87,12 @@ export const constantRoutes = [
|
||||
name: 'new-screen-zz',
|
||||
meta: { title: '管控大屏' }
|
||||
},
|
||||
{
|
||||
path: '/new-screen-zz-pv',
|
||||
component: () => import('@/views/new-screen-zz-pv/index.vue'),
|
||||
name: 'new-screen-zz-pv',
|
||||
meta: { title: '光伏大屏' }
|
||||
},
|
||||
{
|
||||
path: '/dashboard-test',
|
||||
component: Layout,
|
||||
@ -99,6 +105,18 @@ export const constantRoutes = [
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '/dashboard-pv',
|
||||
component: Layout,
|
||||
children: [
|
||||
{
|
||||
path: 'dashboard-pv',
|
||||
component: () => import('@/views/dashboard-pv/index.vue'),
|
||||
name: 'dashboard-pv',
|
||||
meta: { title: 'dashboard-pv', icon: 'dashboard', affix: true }
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '/dashboard-zhongzi',
|
||||
component: Layout,
|
||||
|
||||
@ -33,8 +33,13 @@ const revenueRouter = {
|
||||
component: () => import('@/views/revenue-management/proxy-price/index.vue'),
|
||||
name: 'proxy-price',
|
||||
meta: { title: 'proxy-price' }
|
||||
},
|
||||
{
|
||||
path: 'pv-earnings-statement',
|
||||
component: () => import('@/views/revenue-management/pv-earnings-statement/index.vue'),
|
||||
name: 'pv-earnings-statement',
|
||||
meta: { title: '光伏收益报表' }
|
||||
}
|
||||
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
269
src/views/dashboard-pv/components/bottom-left/standard-215.vue
Normal file
269
src/views/dashboard-pv/components/bottom-left/standard-215.vue
Normal file
@ -0,0 +1,269 @@
|
||||
<template>
|
||||
<div class="bottom-left-wrapper">
|
||||
<ItemBox :title="$t('dashboard.energyTrend')">
|
||||
<div slot="header">
|
||||
<div class="header-right-box">
|
||||
<div
|
||||
class="header-title"
|
||||
:class="{ active: currentType === 'day' }"
|
||||
@click="selectTime('day')"
|
||||
>
|
||||
{{ $t("dashboard.day") }}
|
||||
</div>
|
||||
<div
|
||||
class="header-title"
|
||||
:class="{ active: currentType === 'month' }"
|
||||
@click="selectTime('month')"
|
||||
>
|
||||
{{ $t("dashboard.month") }}
|
||||
</div>
|
||||
<div
|
||||
class="header-title"
|
||||
:class="{ active: currentType === 'year' }"
|
||||
@click="selectTime('year')"
|
||||
>
|
||||
{{ $t("dashboard.year") }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-loading="loading" class="charts-box">
|
||||
<Chart
|
||||
ref="chart"
|
||||
:key="key"
|
||||
:options="powerOptions"
|
||||
:class-name="'chart'"
|
||||
/>
|
||||
</div>
|
||||
</ItemBox>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// import * as echarts from 'echarts'
|
||||
import { GetPCSElecData } from '@/api/home-page/index'
|
||||
|
||||
export default {
|
||||
name: 'Index',
|
||||
props: {
|
||||
stationId: {
|
||||
type: Number,
|
||||
default: undefined
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
powerOptions: undefined,
|
||||
currentType: 'day',
|
||||
color: ['#9A66E4'],
|
||||
loading: false,
|
||||
key: 0
|
||||
}
|
||||
},
|
||||
created() {},
|
||||
|
||||
mounted() {
|
||||
const timeData = []
|
||||
const totalPoints = (24 * 60) / 5
|
||||
const currentTime = Date.now()
|
||||
for (let i = 0; i < totalPoints; i++) {
|
||||
const pointTimestamp = currentTime - i * 5 * 60 * 1000
|
||||
const date = new Date(pointTimestamp)
|
||||
const formattedTime = `${date.getFullYear()}-${(date.getMonth() + 1)
|
||||
.toString()
|
||||
.padStart(2, '0')}-${date.getDate().toString().padStart(2, '0')} ${date
|
||||
.getHours()
|
||||
.toString()
|
||||
.padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}`
|
||||
timeData.push(formattedTime)
|
||||
}
|
||||
timeData.reverse()
|
||||
const currentData = []
|
||||
for (let i = 0; i < timeData.length; i++) {
|
||||
currentData.push({
|
||||
date: timeData[i],
|
||||
chargeElec: Number((Math.random() * 1500 + 1400).toFixed(2))
|
||||
})
|
||||
}
|
||||
this.initCharts(currentData, 1)
|
||||
},
|
||||
methods: {
|
||||
selectTime(type) {
|
||||
this.currentType = type
|
||||
this.getData()
|
||||
},
|
||||
getData() {
|
||||
this.getElecData()
|
||||
// this.getIncomeData()
|
||||
},
|
||||
async getElecData() {
|
||||
this.loading = true
|
||||
const params = {
|
||||
stationId: this.stationId,
|
||||
type: this.currentType
|
||||
}
|
||||
try {
|
||||
const res = await GetPCSElecData(params)
|
||||
console.log(res)
|
||||
// this.initCharts(res.data, 1)
|
||||
} catch (error) {
|
||||
// console.log(error);
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
initCharts(val, type) {
|
||||
const x_data = []
|
||||
const charge_data = []
|
||||
// const discharge_data = []
|
||||
// let benefit_data = [0, 0, 0, 0, 0, 0, 0]
|
||||
if (val && val.length > 0) {
|
||||
val.forEach((item) => {
|
||||
x_data.push(item.date)
|
||||
charge_data.push(item.chargeElec)
|
||||
// discharge_data.push(item.dischargeElec)
|
||||
})
|
||||
}
|
||||
this.powerOptions = {
|
||||
grid: {
|
||||
top: '25%',
|
||||
left: '5%',
|
||||
right: '5%',
|
||||
bottom: '5%',
|
||||
containLabel: true
|
||||
},
|
||||
legend: {},
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
backgroundColor: 'rgba(0,0,0,0,)',
|
||||
borderColor: 'rgba(0,0,0,0,);',
|
||||
borderWidth: 0,
|
||||
textStyle: {
|
||||
width: 160,
|
||||
height: 250,
|
||||
lineHeight: 24,
|
||||
color: '#ffffff',
|
||||
fontSize: '14',
|
||||
fontFamily: 'SourceHanSansCN-Normal'
|
||||
},
|
||||
formatter: (params) => {
|
||||
// 获取xAxis data中的数据
|
||||
let dataStr = `<div><p style="font-weight:bold;margin:0 8px 15px;">${params[0].name}</p></div>`
|
||||
params.forEach((item) => {
|
||||
dataStr += `<div>
|
||||
<div style="margin: 0 8px;">
|
||||
<span style="display:inline-block;margin-right:5px;width:10px;height:10px;background-color:${this.color[0]};"></span>
|
||||
<span>${item.seriesName}</span>
|
||||
<span style="float:right;color:#00C8FF;margin-left:20px;">${item.data}</span>
|
||||
</div>
|
||||
</div>`
|
||||
})
|
||||
const div = `<div style='border: 1px solid ;
|
||||
border-image: linear-gradient(130deg, #FFFFFF 0%, rgba(201,255,243,0.00) 22%, rgba(201,255,243,0.00) 75%, rgba(201,255,243,0.00) 80%, #FFFFFF 99%, #FFFFFF 99%) 1;
|
||||
box-shadow: inset 0px 2px 16px 0px rgba(0, 148, 255, 0.4);' >${dataStr}</div>`
|
||||
return div
|
||||
}
|
||||
},
|
||||
xAxis: [
|
||||
{
|
||||
type: 'category',
|
||||
data: x_data,
|
||||
axisLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: '#90e9d8'
|
||||
}
|
||||
},
|
||||
axisLabel: {
|
||||
show: true,
|
||||
color: '#CEEBFF'
|
||||
},
|
||||
|
||||
axisTick: {
|
||||
show: false
|
||||
}
|
||||
}
|
||||
],
|
||||
yAxis: [
|
||||
{
|
||||
type: 'value',
|
||||
name: `kWh`,
|
||||
nameTextStyle: {
|
||||
color: ' rgba(255, 255, 255, 0.5)'
|
||||
},
|
||||
axisLine: {
|
||||
show: false,
|
||||
lineStyle: {
|
||||
color: '#90e9d8'
|
||||
}
|
||||
},
|
||||
axisLabel: {
|
||||
show: true,
|
||||
color: '#CEEBFF'
|
||||
},
|
||||
axisTick: {
|
||||
show: false
|
||||
},
|
||||
splitLine: {
|
||||
show: true, // 强制显示分割线(默认已开启,确保不被隐藏)
|
||||
lineStyle: {
|
||||
type: 'dashed', // 线型设为虚线
|
||||
color: 'rgba(255,255,255,0.2)', // 虚线颜色(可自定义,如 #999、rgba(0,0,0,0.1))
|
||||
width: 1, // 虚线宽度
|
||||
dashOffset: 5 // 虚线偏移量(可选,调整虚线起始位置)
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
series: [
|
||||
{
|
||||
name: `${this.$t('dashboard.powerGeneration')}`,
|
||||
type: 'line',
|
||||
symbol: 'none',
|
||||
data: charge_data,
|
||||
barWidth: 14, // 柱状图的宽度
|
||||
color: '#9A66E4'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.bottom-left-wrapper {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.header-right-box {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
|
||||
.header-title {
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
letter-spacing: 0em;
|
||||
color: rgba(206, 235, 255, 0.5);
|
||||
white-space: nowrap;
|
||||
padding: 0 10px;
|
||||
cursor: pointer;
|
||||
font-family: Source Han Sans CN;
|
||||
|
||||
&.active {
|
||||
color: #ffffff;
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
rgba(0, 148, 255, 0) 0%,
|
||||
rgba(0, 148, 255, 0.43) 51%,
|
||||
rgba(0, 148, 255, 0) 99%
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.charts-box {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
color: rgba(154, 102, 228, 1);
|
||||
}
|
||||
</style>
|
||||
307
src/views/dashboard-pv/components/bottom-right/common.vue
Normal file
307
src/views/dashboard-pv/components/bottom-right/common.vue
Normal file
@ -0,0 +1,307 @@
|
||||
<template>
|
||||
<div class="bottom-left-wrapper">
|
||||
<ItemBox :title="$t('dashboard.revenueTrend')">
|
||||
<div v-loading="loading" class="charts-box">
|
||||
<Chart :options="runOptions" :class-name="'chart'" />
|
||||
</div>
|
||||
</ItemBox>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { GetRealtimeCurve } from '@/api/home-page/index'
|
||||
import * as echarts from 'echarts'
|
||||
import { chartYIndex } from '@/utils/index'
|
||||
|
||||
export default {
|
||||
name: 'Index',
|
||||
props: {
|
||||
stationId: {
|
||||
type: Number,
|
||||
default: 0
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
runOptions: undefined,
|
||||
serviceList: [],
|
||||
nameArr: [],
|
||||
color: [],
|
||||
color2: [
|
||||
[
|
||||
{
|
||||
offset: 0.0,
|
||||
color: 'rgba(206, 235, 255, 0.1)'
|
||||
},
|
||||
{
|
||||
offset: 1,
|
||||
color: 'rgba(206, 235, 255, 0.2)'
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
offset: 0.0,
|
||||
color: 'rgba(255, 184, 0, 0.1)'
|
||||
},
|
||||
{
|
||||
offset: 1,
|
||||
color: 'rgba(255, 184, 0, 0.2)'
|
||||
}
|
||||
]
|
||||
],
|
||||
loading: false
|
||||
}
|
||||
},
|
||||
computed: {},
|
||||
watch: {},
|
||||
created() {},
|
||||
mounted() {
|
||||
// this.initCharts()
|
||||
},
|
||||
methods: {
|
||||
async getData() {
|
||||
this.loading = true
|
||||
const params = {
|
||||
stationId: this.stationId
|
||||
}
|
||||
try {
|
||||
const res = await GetRealtimeCurve(params)
|
||||
this.initCharts(res.data)
|
||||
} catch (error) {
|
||||
// console.log(error)
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
initCharts(val) {
|
||||
let x_data = []
|
||||
const valueArr = []
|
||||
this.nameArr = []
|
||||
if (val && val.length > 0) {
|
||||
val.forEach((item, index) => {
|
||||
valueArr.push(item.list)
|
||||
this.nameArr.push(item.deviceName + item.name)
|
||||
if (item.list.length) {
|
||||
x_data = []
|
||||
item.list.forEach((el) => {
|
||||
x_data.push(el.date)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
// val[0].
|
||||
const valueArr2 = []
|
||||
valueArr.forEach((item, index) => {
|
||||
const arr = []
|
||||
item.forEach((item2, index2) => {
|
||||
arr.push(item2.digital)
|
||||
valueArr2[index] = arr
|
||||
})
|
||||
})
|
||||
this.serviceList = []
|
||||
valueArr2.forEach((item, index) => {
|
||||
this.serviceList.push({
|
||||
data: item,
|
||||
type: 'line',
|
||||
name: this.nameArr[index],
|
||||
showSymbol: false,
|
||||
yAxisIndex: chartYIndex(val[index]),
|
||||
color: this.color[index],
|
||||
lineStyle: {
|
||||
color: this.color[index]
|
||||
},
|
||||
areaStyle: {
|
||||
color: new echarts.graphic.LinearGradient(
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
this.color2[index]
|
||||
)
|
||||
}
|
||||
})
|
||||
})
|
||||
} else {
|
||||
this.runOptions = {
|
||||
title: {
|
||||
text: `${this.$t('dashboard.noData')}`,
|
||||
x: 'center',
|
||||
y: 'center',
|
||||
textStyle: {
|
||||
fontSize: 14,
|
||||
fontWeight: 'normal'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
this.runOptions = {
|
||||
grid: {
|
||||
top: '25%',
|
||||
left: '5%',
|
||||
right: '3%',
|
||||
bottom: '5%',
|
||||
containLabel: true
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
backgroundColor: 'rgba(0,0,0,0,)',
|
||||
borderColor: 'rgba(0,0,0,0,);',
|
||||
borderWidth: 0,
|
||||
textStyle: {
|
||||
width: 160,
|
||||
height: 250,
|
||||
lineHeight: 24,
|
||||
color: '#ffffff',
|
||||
fontSize: '14',
|
||||
fontFamily: 'SourceHanSansCN-Normal'
|
||||
},
|
||||
formatter: (params) => {
|
||||
// 获取xAxis data中的数据
|
||||
let dataStr = `<div><p style="font-weight:bold;margin:0 8px 15px;">${params[0].name}</p></div>`
|
||||
params.forEach((item) => {
|
||||
dataStr += `<div>
|
||||
<div style="margin: 0 8px;">
|
||||
<span style="display:inline-block;margin-right:5px;width:10px;height:10px;background-color:${
|
||||
item.color
|
||||
};"></span>
|
||||
<span>${item.seriesName}</span>
|
||||
<span style="float:right;color:#00C8FF;margin-left:20px;">${
|
||||
item.data === null ? '' : item.data
|
||||
}</span>
|
||||
</div>
|
||||
</div>`
|
||||
})
|
||||
const div = `<div style='border: 1px solid ;
|
||||
border-image: linear-gradient(130deg, #FFFFFF 0%, rgba(201,255,243,0.00) 22%, rgba(201,255,243,0.00) 75%, rgba(201,255,243,0.00) 80%, #FFFFFF 99%, #FFFFFF 99%) 1;
|
||||
box-shadow: inset 0px 2px 16px 0px rgba(0, 148, 255, 0.4);' >${dataStr}</div>`
|
||||
return div
|
||||
}
|
||||
},
|
||||
|
||||
legend: {
|
||||
type: 'scroll',
|
||||
top: 20,
|
||||
bottom: 20,
|
||||
padding: [0, 180],
|
||||
icon: 'circle',
|
||||
align: 'left',
|
||||
itemWidth: 10,
|
||||
itemHeight: 8,
|
||||
itemGap: 15,
|
||||
textStyle: {
|
||||
color: '#fff',
|
||||
rich: {
|
||||
name: {
|
||||
fontSize: 12,
|
||||
color: '#ffffff',
|
||||
padding: [0, 10, 0, 0]
|
||||
},
|
||||
num: {
|
||||
fontSize: 16,
|
||||
color: '#ffffff'
|
||||
},
|
||||
unit: {
|
||||
fontSize: 16,
|
||||
color: '#ffffff'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
xAxis: {
|
||||
data: x_data,
|
||||
axisLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: '#90e9d8'
|
||||
}
|
||||
},
|
||||
axisLabel: {
|
||||
show: true,
|
||||
color: '#CEEBFF'
|
||||
},
|
||||
|
||||
axisTick: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
yAxis: [
|
||||
{
|
||||
name: `${this.$t('dashboard.power')}(kW)`,
|
||||
type: 'value',
|
||||
nameTextStyle: {
|
||||
color: ' rgba(255, 255, 255, 0.5)'
|
||||
},
|
||||
axisLine: {
|
||||
show: false,
|
||||
lineStyle: {
|
||||
color: '#90e9d8'
|
||||
}
|
||||
},
|
||||
axisLabel: {
|
||||
show: true,
|
||||
color: '#CEEBFF'
|
||||
},
|
||||
|
||||
axisTick: {
|
||||
show: false
|
||||
},
|
||||
min: function(value) {
|
||||
return Math.floor(
|
||||
(Math.abs(value.min) < value.max
|
||||
? -value.max * 1.05
|
||||
: value.min * 1.05
|
||||
).toFixed(2)
|
||||
)
|
||||
},
|
||||
max: function(value) {
|
||||
return Math.ceil(
|
||||
(Math.abs(value.min) < value.max
|
||||
? value.max * 1.05
|
||||
: -value.min * 1.05
|
||||
).toFixed(2)
|
||||
)
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'SOC(%)',
|
||||
type: 'value',
|
||||
max: 100,
|
||||
min: -100,
|
||||
ming: 0,
|
||||
nameTextStyle: {
|
||||
color: ' rgba(255, 255, 255, 0.5)'
|
||||
},
|
||||
axisLine: {
|
||||
show: false,
|
||||
lineStyle: {
|
||||
color: '#90e9d8'
|
||||
}
|
||||
},
|
||||
axisLabel: {
|
||||
show: true,
|
||||
color: '#CEEBFF'
|
||||
},
|
||||
|
||||
axisTick: {
|
||||
show: false
|
||||
}
|
||||
}
|
||||
],
|
||||
series: this.serviceList
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.bottom-left-wrapper {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.charts-box {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
284
src/views/dashboard-pv/components/bottom-right/disposition.vue
Normal file
284
src/views/dashboard-pv/components/bottom-right/disposition.vue
Normal file
@ -0,0 +1,284 @@
|
||||
<template>
|
||||
<div class="bottom-left-wrapper">
|
||||
<ItemBox
|
||||
:title="$t('dashboard.revenueTrend')"
|
||||
@handleSetting="handleSetting"
|
||||
>
|
||||
<!-- <ItemBox :title="$t('dashboard.revenueTrend')"
|
||||
:show-curve-setting="true"
|
||||
@handleSetting="handleSetting"> -->
|
||||
<div slot="header">
|
||||
<div class="header-right-box">
|
||||
<div
|
||||
class="header-title"
|
||||
:class="{ active: currentType === 'month' }"
|
||||
@click="selectTime('month')"
|
||||
>
|
||||
{{ $t("dashboard.month") }}
|
||||
</div>
|
||||
<div
|
||||
class="header-title"
|
||||
:class="{ active: currentType === 'year' }"
|
||||
@click="selectTime('year')"
|
||||
>
|
||||
{{ $t("dashboard.year") }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-loading="loading" class="charts-box">
|
||||
<Chart :options="runOptions" :class-name="'chart'" />
|
||||
</div>
|
||||
</ItemBox>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { GetDynamicRealtimeCurve } from '@/api/home-page/index'
|
||||
import * as echarts from 'echarts'
|
||||
// import { chartYIndex } from '@/utils/index'
|
||||
export default {
|
||||
name: 'Index',
|
||||
props: {
|
||||
stationId: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
permissionId: {
|
||||
type: Number,
|
||||
default: null
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
currentType: 'month',
|
||||
runOptions: undefined,
|
||||
serviceList: [],
|
||||
nameArr: [],
|
||||
color: ['#FF9900'],
|
||||
color2: [
|
||||
[
|
||||
{
|
||||
offset: 0.0,
|
||||
color: 'rgba(206, 235, 255, 0.1)'
|
||||
},
|
||||
{
|
||||
offset: 1,
|
||||
color: 'rgba(206, 235, 255, 0.2)'
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
offset: 0.0,
|
||||
color: 'rgba(255, 184, 0, 0.1)'
|
||||
},
|
||||
{
|
||||
offset: 1,
|
||||
color: 'rgba(255, 184, 0, 0.2)'
|
||||
}
|
||||
]
|
||||
],
|
||||
loading: false
|
||||
}
|
||||
},
|
||||
computed: {},
|
||||
watch: {},
|
||||
created() {},
|
||||
mounted() {
|
||||
const currentData = []
|
||||
for (let i = 1; i < 32; i++) {
|
||||
currentData.push({
|
||||
date: i,
|
||||
chargeElec: Number((Math.random() * 9000 + 1000).toFixed(2))
|
||||
})
|
||||
}
|
||||
this.initCharts(currentData, 1)
|
||||
},
|
||||
methods: {
|
||||
selectTime(type) {
|
||||
this.currentType = type
|
||||
this.getData()
|
||||
},
|
||||
handleSetting() {
|
||||
this.$emit('handleSetting')
|
||||
},
|
||||
async getData() {
|
||||
this.loading = true
|
||||
const params = {
|
||||
stationId: this.stationId,
|
||||
pageLocation: 'runChart',
|
||||
permissionId: this.permissionId
|
||||
}
|
||||
try {
|
||||
const res = await GetDynamicRealtimeCurve(params)
|
||||
if (res.data) {
|
||||
// this.initCharts(res.data)
|
||||
}
|
||||
} catch (error) {
|
||||
// console.log(error)
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
// 新增代码
|
||||
|
||||
initCharts(val, type) {
|
||||
const x_data = []
|
||||
const charge_data = []
|
||||
// const discharge_data = []
|
||||
// let benefit_data = [0, 0, 0, 0, 0, 0, 0]
|
||||
if (val && val.length > 0) {
|
||||
val.forEach((item) => {
|
||||
x_data.push(item.date)
|
||||
charge_data.push(item.chargeElec)
|
||||
// discharge_data.push(item.dischargeElec)
|
||||
})
|
||||
}
|
||||
this.runOptions = {
|
||||
grid: {
|
||||
top: '25%',
|
||||
left: '5%',
|
||||
right: '5%',
|
||||
bottom: '5%',
|
||||
containLabel: true
|
||||
},
|
||||
legend: {},
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
backgroundColor: 'rgba(0,0,0,0,)',
|
||||
borderColor: 'rgba(0,0,0,0,);',
|
||||
borderWidth: 0,
|
||||
textStyle: {
|
||||
width: 160,
|
||||
height: 250,
|
||||
lineHeight: 24,
|
||||
color: '#ffffff',
|
||||
fontSize: '14',
|
||||
fontFamily: 'SourceHanSansCN-Normal'
|
||||
},
|
||||
formatter: (params) => {
|
||||
// 获取xAxis data中的数据
|
||||
let dataStr = `<div><p style="font-weight:bold;margin:0 8px 15px;">${params[0].name}</p></div>`
|
||||
params.forEach((item) => {
|
||||
dataStr += `<div>
|
||||
<div style="margin: 0 8px;">
|
||||
<span style="display:inline-block;margin-right:5px;width:10px;height:10px;background-color:${this.color[0]};"></span>
|
||||
<span>${item.seriesName}</span>
|
||||
<span style="float:right;color:#00C8FF;margin-left:20px;">${item.data}</span>
|
||||
</div>
|
||||
</div>`
|
||||
})
|
||||
const div = `<div style='border: 1px solid ;
|
||||
border-image: linear-gradient(130deg, #FFFFFF 0%, rgba(201,255,243,0.00) 22%, rgba(201,255,243,0.00) 75%, rgba(201,255,243,0.00) 80%, #FFFFFF 99%, #FFFFFF 99%) 1;
|
||||
box-shadow: inset 0px 2px 16px 0px rgba(0, 148, 255, 0.4);' >${dataStr}</div>`
|
||||
return div
|
||||
}
|
||||
},
|
||||
xAxis: [
|
||||
{
|
||||
type: 'category',
|
||||
data: x_data,
|
||||
axisLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: '#90e9d8'
|
||||
}
|
||||
},
|
||||
axisLabel: {
|
||||
show: true,
|
||||
color: '#CEEBFF'
|
||||
},
|
||||
|
||||
axisTick: {
|
||||
show: false
|
||||
}
|
||||
}
|
||||
],
|
||||
yAxis: [
|
||||
{
|
||||
type: 'value',
|
||||
name: this.$t('glance.wRMB'),
|
||||
nameTextStyle: {
|
||||
color: ' rgba(255, 255, 255, 0.5)'
|
||||
},
|
||||
axisLine: {
|
||||
show: false,
|
||||
lineStyle: {
|
||||
color: '#90e9d8'
|
||||
}
|
||||
},
|
||||
axisLabel: {
|
||||
show: true,
|
||||
color: '#CEEBFF'
|
||||
},
|
||||
axisTick: {
|
||||
show: false
|
||||
},
|
||||
splitLine: {
|
||||
show: true, // 强制显示分割线(默认已开启,确保不被隐藏)
|
||||
lineStyle: {
|
||||
type: 'dashed', // 线型设为虚线
|
||||
color: 'rgba(255,255,255,0.2)', // 虚线颜色(可自定义,如 #999、rgba(0,0,0,0.1))
|
||||
width: 1, // 虚线宽度
|
||||
dashOffset: 5 // 虚线偏移量(可选,调整虚线起始位置)
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
series: [
|
||||
{
|
||||
name: `${this.$t('state.powerGeneration')}`,
|
||||
type: 'bar',
|
||||
data: charge_data,
|
||||
barWidth: 14, // 柱状图的宽度
|
||||
color: '#ff9900',
|
||||
itemStyle: {
|
||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||
{ offset: 0, color: 'rgba(255, 153, 0,0.90)' },
|
||||
{ offset: 1, color: 'rgba(255, 153, 0, 0.0)' }
|
||||
])
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.bottom-left-wrapper {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.header-right-box {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
|
||||
.header-title {
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
letter-spacing: 0em;
|
||||
color: rgba(206, 235, 255, 0.5);
|
||||
white-space: nowrap;
|
||||
padding: 0 10px;
|
||||
cursor: pointer;
|
||||
font-family: Source Han Sans CN;
|
||||
|
||||
&.active {
|
||||
color: #ffffff;
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
rgba(0, 148, 255, 0) 0%,
|
||||
rgba(0, 148, 255, 0.43) 51%,
|
||||
rgba(0, 148, 255, 0) 99%
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.charts-box {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
297
src/views/dashboard-pv/components/bottom-right/standard-215.vue
Normal file
297
src/views/dashboard-pv/components/bottom-right/standard-215.vue
Normal file
@ -0,0 +1,297 @@
|
||||
<template>
|
||||
<div class="bottom-left-wrapper">
|
||||
<ItemBox :title="$t('dashboard.revenueTrend')">
|
||||
<div v-loading="loading" class="charts-box">
|
||||
<Chart :options="runOptions" :class-name="'chart'" />
|
||||
</div>
|
||||
</ItemBox>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { GetRealtimeCurve } from '@/api/home-page/index'
|
||||
import * as echarts from 'echarts'
|
||||
import { chartYIndex } from '@/utils/index'
|
||||
|
||||
export default {
|
||||
name: 'Index',
|
||||
props: {
|
||||
stationId: {
|
||||
type: Number,
|
||||
default: 0
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
runOptions: undefined,
|
||||
serviceList: [],
|
||||
nameArr: [],
|
||||
color: [],
|
||||
color2: [[{
|
||||
offset: 0.0,
|
||||
color: 'rgba(206, 235, 255, 0.1)'
|
||||
},
|
||||
{
|
||||
offset: 1,
|
||||
color: 'rgba(206, 235, 255, 0.2)'
|
||||
}], [
|
||||
{
|
||||
offset: 0.0,
|
||||
color: 'rgba(255, 184, 0, 0.1)'
|
||||
},
|
||||
{
|
||||
offset: 1,
|
||||
color: 'rgba(255, 184, 0, 0.2)'
|
||||
}
|
||||
]],
|
||||
loading: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
language() {
|
||||
return this.$store.getters.language || undefined
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
language: {
|
||||
handler(val) {
|
||||
this.getData()
|
||||
}
|
||||
},
|
||||
deep: true
|
||||
},
|
||||
created() {},
|
||||
mounted() {
|
||||
// this.initCharts()
|
||||
},
|
||||
methods: {
|
||||
async getData() {
|
||||
this.loading = true
|
||||
const params = {
|
||||
stationId: this.stationId
|
||||
}
|
||||
try {
|
||||
const res = await GetRealtimeCurve(params)
|
||||
this.initCharts(res.data)
|
||||
} catch (error) {
|
||||
// console.log(error)
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
initCharts(val) {
|
||||
let x_data = []
|
||||
const valueArr = []
|
||||
this.nameArr = []
|
||||
if (val && val.length > 0) {
|
||||
val.forEach((item, index) => {
|
||||
valueArr.push(item.list.length ? item.list : [''])
|
||||
this.nameArr.push(item.deviceName + item.name)
|
||||
if (item.list.length) {
|
||||
x_data = []
|
||||
item.list.forEach((el) => {
|
||||
x_data.push(el.date)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
const valueArr2 = []
|
||||
valueArr.forEach((item, index) => {
|
||||
const arr = []
|
||||
item.forEach((item2, index2) => {
|
||||
arr.push(item2.digital)
|
||||
valueArr2[index] = arr
|
||||
})
|
||||
})
|
||||
|
||||
this.serviceList = []
|
||||
valueArr2.forEach((item, index) => {
|
||||
this.serviceList.push({
|
||||
data: item,
|
||||
type: 'line',
|
||||
name: this.nameArr[index],
|
||||
showSymbol: false,
|
||||
yAxisIndex: chartYIndex(val[index]),
|
||||
color: this.color[index],
|
||||
lineStyle: {
|
||||
color: this.color[index]
|
||||
},
|
||||
// areaStyle: {
|
||||
// color: '#CEEBFF',
|
||||
// opacity: 0.1
|
||||
// },
|
||||
// 设置面积区域为渐变效果
|
||||
areaStyle: {
|
||||
color: new echarts.graphic.LinearGradient(0, 1, 0, 0, this.color2[index])
|
||||
}
|
||||
})
|
||||
})
|
||||
} else {
|
||||
this.runOptions = {
|
||||
title: {
|
||||
text: `${this.$t('dashboard.noData')}`,
|
||||
x: 'center',
|
||||
y: 'center',
|
||||
textStyle: {
|
||||
fontSize: 14,
|
||||
fontWeight: 'normal'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
this.runOptions = {
|
||||
grid: {
|
||||
top: '25%',
|
||||
left: '5%',
|
||||
right: '3%',
|
||||
bottom: '5%',
|
||||
containLabel: true
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
backgroundColor: 'rgba(0,0,0,0,)',
|
||||
borderColor: 'rgba(0,0,0,0,);',
|
||||
borderWidth: 0,
|
||||
textStyle: {
|
||||
width: 160,
|
||||
height: 250,
|
||||
lineHeight: 24,
|
||||
color: '#ffffff',
|
||||
fontSize: '14',
|
||||
fontFamily: 'SourceHanSansCN-Normal'
|
||||
},
|
||||
formatter: params => {
|
||||
// 获取xAxis data中的数据
|
||||
let dataStr = `<div><p style="font-weight:bold;margin:0 8px 15px;">${params[0].name}</p></div>`
|
||||
params.forEach(item => {
|
||||
dataStr += `<div>
|
||||
<div style="margin: 0 8px;">
|
||||
<span style="display:inline-block;margin-right:5px;width:10px;height:10px;background-color:${item.color};"></span>
|
||||
<span>${item.seriesName}</span>
|
||||
<span style="float:right;color:#00C8FF;margin-left:20px;">${item.data === null ? '' : item.data}</span>
|
||||
</div>
|
||||
</div>`
|
||||
})
|
||||
const div = `<div style='border: 1px solid ;
|
||||
border-image: linear-gradient(130deg, #FFFFFF 0%, rgba(201,255,243,0.00) 22%, rgba(201,255,243,0.00) 75%, rgba(201,255,243,0.00) 80%, #FFFFFF 99%, #FFFFFF 99%) 1;
|
||||
box-shadow: inset 0px 2px 16px 0px rgba(0, 148, 255, 0.4);' >${dataStr}</div>`
|
||||
return div
|
||||
}
|
||||
},
|
||||
|
||||
legend: {
|
||||
type: 'scroll',
|
||||
top: 20,
|
||||
bottom: 20,
|
||||
padding: [0, 180],
|
||||
icon: 'circle',
|
||||
align: 'left',
|
||||
itemWidth: 10,
|
||||
itemHeight: 8,
|
||||
itemGap: 15,
|
||||
textStyle: {
|
||||
color: '#fff',
|
||||
rich: {
|
||||
name: {
|
||||
fontSize: 12,
|
||||
color: '#ffffff',
|
||||
padding: [0, 10, 0, 0]
|
||||
},
|
||||
num: {
|
||||
fontSize: 16,
|
||||
color: '#ffffff'
|
||||
},
|
||||
unit: {
|
||||
fontSize: 16,
|
||||
color: '#ffffff'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
xAxis: {
|
||||
data: x_data,
|
||||
axisLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: '#90e9d8'
|
||||
}
|
||||
},
|
||||
axisLabel: {
|
||||
show: true,
|
||||
color: '#CEEBFF'
|
||||
},
|
||||
|
||||
axisTick: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
yAxis: [{
|
||||
name: `${this.$t('dashboard.power')}(kW)`,
|
||||
type: 'value',
|
||||
nameTextStyle: {
|
||||
color: ' rgba(255, 255, 255, 0.5)'
|
||||
},
|
||||
axisLine: {
|
||||
show: false,
|
||||
lineStyle: {
|
||||
color: '#90e9d8'
|
||||
}
|
||||
},
|
||||
axisLabel: {
|
||||
show: true,
|
||||
color: '#CEEBFF'
|
||||
},
|
||||
|
||||
axisTick: {
|
||||
show: false
|
||||
},
|
||||
min: function(value) {
|
||||
return Math.floor((Math.abs(value.min) < value.max ? -value.max * 1.05 : value.min * 1.05).toFixed(2))
|
||||
},
|
||||
max: function(value) {
|
||||
return Math.ceil((Math.abs(value.min) < value.max ? value.max * 1.05 : -value.min * 1.05).toFixed(2))
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'SOC(%)',
|
||||
type: 'value',
|
||||
max: 100,
|
||||
min: -100,
|
||||
ming: 0,
|
||||
nameTextStyle: {
|
||||
color: ' rgba(255, 255, 255, 0.5)'
|
||||
},
|
||||
axisLine: {
|
||||
show: false,
|
||||
lineStyle: {
|
||||
color: '#90e9d8'
|
||||
}
|
||||
},
|
||||
axisLabel: {
|
||||
show: true,
|
||||
color: '#CEEBFF'
|
||||
},
|
||||
|
||||
axisTick: {
|
||||
show: false
|
||||
}
|
||||
|
||||
}],
|
||||
series: this.serviceList
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.bottom-left-wrapper{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.charts-box{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
182
src/views/dashboard-pv/components/center-right/common.vue
Normal file
182
src/views/dashboard-pv/components/center-right/common.vue
Normal file
@ -0,0 +1,182 @@
|
||||
<template>
|
||||
<div class="huankong-wrap">
|
||||
<ItemBox :title="$t('dashboard.environmentalData')">
|
||||
<div v-if="airArr.length" v-loading="loading" class="box">
|
||||
<template v-for="(item,index) in airArr">
|
||||
<div :key="index" class="air-box">
|
||||
<div class="value">{{ item.value }}</div>
|
||||
<div class="label">
|
||||
<span class="air-left-jt " />
|
||||
<span class="air-icon left" />
|
||||
<span />
|
||||
<span class="name">{{ item.name }}</span>
|
||||
<span class="air-icon right" />
|
||||
<span class="air-right-jt " />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
</div>
|
||||
<div v-else class="box">
|
||||
<div class="empty">{{ $t("dashboard.noData") }}</div>
|
||||
</div>
|
||||
</ItemBox>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { GetAirConfig } from '@/api/home-page/index'
|
||||
export default {
|
||||
name: 'Index',
|
||||
props: {
|
||||
stationId: {
|
||||
type: Number,
|
||||
default: 0
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
hkList: [],
|
||||
statusData: {
|
||||
dischargCapacity: '',
|
||||
rechargeCapacity: '',
|
||||
grid: '',
|
||||
loading: false
|
||||
|
||||
},
|
||||
airArr: []
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
||||
},
|
||||
watch: {},
|
||||
created() {
|
||||
|
||||
},
|
||||
mounted() { },
|
||||
methods: {
|
||||
async getData() {
|
||||
this.loading = true
|
||||
try {
|
||||
const res = await GetAirConfig({ stationId: this.stationId })
|
||||
this.airArr = res.data
|
||||
// console.log(this.airArr)
|
||||
} catch (error) {
|
||||
// console.log(error);
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
async GetStatusMonitor() {
|
||||
// this.loading = true
|
||||
// const params = {
|
||||
// stationId: this.stationId
|
||||
// }
|
||||
// try {
|
||||
// const { data } = await GetCircleCtr(params)
|
||||
// this.hkList = data
|
||||
// } catch (error) {
|
||||
// // console.log(error);
|
||||
// } finally {
|
||||
// this.loading = false
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.huankong-wrap {
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
.box {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
flex-wrap: wrap;
|
||||
padding: 10px;
|
||||
height: 302px;
|
||||
overflow: auto;
|
||||
.empty {
|
||||
width: 100%;
|
||||
height: 280px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-family: Source Han Sans CN;
|
||||
font-size: 16px;
|
||||
color: rgba(206, 235, 255, 0.7);
|
||||
}
|
||||
.air-box {
|
||||
min-width: 120px;
|
||||
width: 47%;
|
||||
height: 60px;
|
||||
margin: 10px 0 0 0;
|
||||
background: url(../../../../assets/images/air-bg.png);
|
||||
background-size: 100% 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
.label {
|
||||
min-width: 86px;
|
||||
width: 100%;
|
||||
flex: 1;
|
||||
font-family: Source Han Sans CN;
|
||||
font-size: 14px;
|
||||
color: rgba(206, 235, 255, 0.7);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
.name{
|
||||
text-align: center;
|
||||
// min-width: 88px;
|
||||
}
|
||||
.air-icon {
|
||||
display: inline-block;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
background: url(../../../../assets/images/air-icon.png);
|
||||
background-size: 100% 100%;
|
||||
}
|
||||
.air-left-jt {
|
||||
display: inline-block;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
line-height: 0px;
|
||||
background: url(../../../../assets/images/air-left.png);
|
||||
background-size: 100% 100%;
|
||||
margin-right: 10px;
|
||||
}
|
||||
.air-right-jt {
|
||||
display: inline-block;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
line-height: 0px;
|
||||
background: url(../../../../assets/images/air-right.png);
|
||||
background-size: 100% 100%;
|
||||
margin-left: 10px;
|
||||
}
|
||||
.left {
|
||||
margin-right: 10px;
|
||||
}
|
||||
.right {
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.value {
|
||||
width: 100%;
|
||||
flex: 1;
|
||||
font-family: DIN;
|
||||
font-size: 22px;
|
||||
color: #ffffff;
|
||||
text-shadow: 0px 0px 10px 0px #0094ff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
</style>
|
||||
179
src/views/dashboard-pv/components/center-right/disposition.vue
Normal file
179
src/views/dashboard-pv/components/center-right/disposition.vue
Normal file
@ -0,0 +1,179 @@
|
||||
<template>
|
||||
<div class="huankong-wrap">
|
||||
<ItemBox :title="$t('dashboard.environmentalData')" :show-point-setting="true" @handleSetting="handleSetting">
|
||||
<div v-if="airArr.length" v-loading="loading" class="box">
|
||||
<div v-for="(item,index) in airArr" :key="index" class="air-box">
|
||||
<div class="value">{{ item.value }}</div>
|
||||
<div class="label">
|
||||
<span class="air-left-jt " />
|
||||
<span class="air-icon left" />
|
||||
<span />
|
||||
<span class="name">{{ item.name }}</span>
|
||||
<span class="air-icon right" />
|
||||
<span class="air-right-jt " />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div v-else class="box">
|
||||
<div class="empty">{{ $t("dashboard.noData") }}</div>
|
||||
</div>
|
||||
</ItemBox>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { DynamicConfigPoint } from '@/api/home-page/index'
|
||||
|
||||
export default {
|
||||
name: 'Index',
|
||||
props: {
|
||||
stationId: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
permissionId: {
|
||||
type: Number,
|
||||
default: 0
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
hkList: [],
|
||||
statusData: {
|
||||
dischargCapacity: '',
|
||||
rechargeCapacity: '',
|
||||
grid: '',
|
||||
loading: false,
|
||||
permissionId: null
|
||||
|
||||
},
|
||||
airArr: []
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
||||
},
|
||||
watch: {},
|
||||
created() {
|
||||
|
||||
},
|
||||
mounted() { },
|
||||
methods: {
|
||||
handleSetting() {
|
||||
this.$emit('handleSetting')
|
||||
},
|
||||
async getData() {
|
||||
this.loading = true
|
||||
try {
|
||||
const res = await DynamicConfigPoint({
|
||||
pageLocation: 'airData',
|
||||
permissionId: this.permissionId,
|
||||
stationId: this.stationId })
|
||||
this.airArr = res.data
|
||||
// console.log(this.airArr)
|
||||
} catch (error) {
|
||||
// console.log(error);
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.huankong-wrap {
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
.box {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
flex-wrap: wrap;
|
||||
padding: 10px;
|
||||
height: 302px;
|
||||
overflow: auto;
|
||||
.empty {
|
||||
width: 100%;
|
||||
height: 280px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-family: Source Han Sans CN;
|
||||
font-size: 16px;
|
||||
color: rgba(206, 235, 255, 0.7);
|
||||
}
|
||||
.air-box {
|
||||
min-width: 120px;
|
||||
width: 47%;
|
||||
height: 60px;
|
||||
margin: 10px 0 0 0;
|
||||
background: url(../../../../assets/images/air-bg.png);
|
||||
background-size: 100% 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
.label {
|
||||
min-width: 86px;
|
||||
width: 100%;
|
||||
flex: 1;
|
||||
font-family: Source Han Sans CN;
|
||||
font-size: 14px;
|
||||
color: rgba(206, 235, 255, 0.7);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
.name{
|
||||
text-align: center;
|
||||
// min-width: 88px;
|
||||
}
|
||||
.air-icon {
|
||||
display: inline-block;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
background: url(../../../../assets/images/air-icon.png);
|
||||
background-size: 100% 100%;
|
||||
}
|
||||
.air-left-jt {
|
||||
display: inline-block;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
line-height: 0px;
|
||||
background: url(../../../../assets/images/air-left.png);
|
||||
background-size: 100% 100%;
|
||||
margin-right: 10px;
|
||||
}
|
||||
.air-right-jt {
|
||||
display: inline-block;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
line-height: 0px;
|
||||
background: url(../../../../assets/images/air-right.png);
|
||||
background-size: 100% 100%;
|
||||
margin-left: 10px;
|
||||
}
|
||||
.left {
|
||||
margin-right: 10px;
|
||||
}
|
||||
.right {
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.value {
|
||||
width: 100%;
|
||||
flex: 1;
|
||||
font-family: DIN;
|
||||
font-size: 22px;
|
||||
color: #ffffff;
|
||||
text-shadow: 0px 0px 10px 0px #0094ff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
</style>
|
||||
334
src/views/dashboard-pv/components/center-right/standard-215.vue
Normal file
334
src/views/dashboard-pv/components/center-right/standard-215.vue
Normal file
@ -0,0 +1,334 @@
|
||||
<template>
|
||||
<div class="huankong-wrap">
|
||||
<ItemBox :title="$t('dashboard.environmentalData')">
|
||||
<div v-loading="loading" class="box">
|
||||
<div class="zhengxiang">
|
||||
<div class="left">
|
||||
<el-tooltip :content="$t('dashboard.indoorTem') + '(℃)'" placement="top" effect="dark">
|
||||
<div class="label">{{ $t('dashboard.indoorTem') }}(℃)</div>
|
||||
</el-tooltip>
|
||||
<div class="value">{{ toFix(formModel.airconditionInnerTemperature) }}</div>
|
||||
|
||||
<el-tooltip :content="$t('dashboard.heatBackLash') + '(℃)'" placement="top" effect="dark">
|
||||
<div class="label">{{ $t('dashboard.heatBackLash') }}(℃)</div>
|
||||
</el-tooltip>
|
||||
<div class="value">{{ toFix(formModel.airconditionReturnHot) }}</div>
|
||||
</div>
|
||||
<div class="center">
|
||||
<div class="label">{{ $t('dashboard.air') }}</div>
|
||||
</div>
|
||||
<div class="right">
|
||||
<el-tooltip :content="$t('dashboard.condensation') + '(℃)'" placement="top" effect="dark">
|
||||
<div class="label">{{ $t('dashboard.condensation') }}(℃)</div>
|
||||
</el-tooltip>
|
||||
<div class="value">{{ toFix(formModel.airconditionCondensation) }}</div>
|
||||
|
||||
<el-tooltip :content="$t('dashboard.coolBackLash') + '(℃)'" placement="top" effect="dark">
|
||||
<div class="label">{{ $t('dashboard.coolBackLash') }}(℃)</div>
|
||||
</el-tooltip>
|
||||
<div class="value">{{ toFix(formModel.airconditionReturnCold) }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="zhengxiang">
|
||||
<div class="left">
|
||||
<el-tooltip :content="$t('dashboard.indoorHum') + '(%)'" placement="top" effect="dark">
|
||||
<div class="label">{{ $t('dashboard.indoorHum') }}(%)</div>
|
||||
</el-tooltip>
|
||||
<div class="value">{{ toFix(formModel.airconditionInnerHumidity) }}</div>
|
||||
|
||||
<el-tooltip :content="$t('dashboard.shutPoint')" placement="top" effect="dark">
|
||||
<div class="label">{{ $t('dashboard.shutPoint') }}</div>
|
||||
</el-tooltip>
|
||||
<div class="value">{{ toFix(formModel.airconditionFanStopPoint) }}</div>
|
||||
</div>
|
||||
<div class="center">
|
||||
<!-- <div class="value">1</div> -->
|
||||
<div class="label">{{ $t('dashboard.air') }}</div>
|
||||
<!-- <div class="label">(kWh)</div> -->
|
||||
</div>
|
||||
<div class="right">
|
||||
<el-tooltip :content="$t('dashboard.refSetting') + '(℃)'" placement="top" effect="dark">
|
||||
<div class="label">{{ $t('dashboard.refSetting') }}(℃)</div>
|
||||
</el-tooltip>
|
||||
|
||||
<div class="value">{{ toFix(formModel.airconditionSetCold) }}</div>
|
||||
<el-tooltip :content="$t('dashboard.heatSetting') + '(℃)'" placement="top" effect="dark">
|
||||
<div class="label">{{ $t('dashboard.heatSetting') }}(℃)</div>
|
||||
</el-tooltip>
|
||||
<div class="value">{{ toFix(formModel.airconditionSetHot) }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- <div v-else class="box">
|
||||
<div class="empty">暂无数据</div>
|
||||
</div> -->
|
||||
</ItemBox>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { GetShanghaiKJYAirData } from '@/api/homePage-integrated/index'
|
||||
|
||||
export default {
|
||||
name: 'Index',
|
||||
props: {
|
||||
stationId: {
|
||||
type: Number,
|
||||
default: 0
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
hkList: [],
|
||||
formModel: {},
|
||||
loading: false,
|
||||
colList: ['airconditionInnerTemperature', 'airconditionReturnHot', 'airconditionCondensation', 'airconditionReturnCold', 'airconditionInnerHumidity', 'airconditionFanStopPoint', 'airconditionSetCold', 'airconditionSetHot']
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
||||
},
|
||||
watch: {},
|
||||
created() {
|
||||
},
|
||||
mounted() {
|
||||
|
||||
},
|
||||
methods: {
|
||||
toFix(val) {
|
||||
if (val) {
|
||||
const result = Number(val).toFixed(2)
|
||||
return result
|
||||
} else if (val === 0) {
|
||||
return 0
|
||||
} else {
|
||||
return ''
|
||||
}
|
||||
},
|
||||
async getData() {
|
||||
this.loading = true
|
||||
const params = {
|
||||
stationId: this.stationId,
|
||||
colList: this.colList
|
||||
}
|
||||
try {
|
||||
const { data } = await GetShanghaiKJYAirData(params)
|
||||
this.formModel = data
|
||||
} catch (error) {
|
||||
// console.log(error);
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.huankong-wrap{
|
||||
width: 100%;
|
||||
}
|
||||
.box {
|
||||
|
||||
.empty{
|
||||
width: 100%;
|
||||
height: 302px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-family: Source Han Sans CN;
|
||||
font-size: 16px;
|
||||
color: rgba(206, 235, 255, 0.7);
|
||||
|
||||
}
|
||||
// padding-top: 25px;
|
||||
// padding-bottom: 20px;
|
||||
.zhengxiang {
|
||||
width: 100%;
|
||||
// min-width: 362px;
|
||||
height: 135px;
|
||||
// background: url(../../../../../assets/images/dianbiao-zxdn-bg.png) no-repeat;
|
||||
// background:url(../../../../assets/images/dianbiao-zxdn-bg.png);
|
||||
// background-size: 100% 100%;
|
||||
margin: 10px 0;
|
||||
display: flex;
|
||||
|
||||
.left {
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
background:url(../../../../assets/images/yuan-left.png);
|
||||
background-size: 100% 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
// padding-left: 10%;
|
||||
.label {
|
||||
margin-left: 10px;
|
||||
max-width: 100%;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
min-width: 86px;
|
||||
// width: 100%;
|
||||
// flex: 1;
|
||||
font-family: Source Han Sans CN;
|
||||
font-size: 14px;
|
||||
color: rgba(206, 235, 255, 0.7);
|
||||
// display: flex;
|
||||
text-align: center;
|
||||
height: 35px;
|
||||
line-height: 40px;
|
||||
// align-items: center;
|
||||
// justify-content: center;
|
||||
}
|
||||
|
||||
.value {
|
||||
width: 100%;
|
||||
flex: 1;
|
||||
font-family: DIN;
|
||||
font-size: 22px;
|
||||
color: #FFFFFF;
|
||||
text-shadow: 0px 0px 10px 0px #0094FF;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
|
||||
.center {
|
||||
background:url(../../../../assets/images/yuan-center.png);
|
||||
background-size: 100% 100%;
|
||||
width: 220px;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
.label {
|
||||
width: 100%;
|
||||
font-family: Source Han Sans CN;
|
||||
font-size: 14px;
|
||||
color: rgba(206, 235, 255, 0.7);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.value {
|
||||
width: 100%;
|
||||
font-family: DIN;
|
||||
font-size: 30px;
|
||||
color: #FFFFFF;
|
||||
text-align: center;
|
||||
text-shadow: 0px 0px 10px 0px #0094FF;
|
||||
}
|
||||
}
|
||||
|
||||
.right {
|
||||
flex: 1;
|
||||
// padding-right: 10%;
|
||||
height: 100%;
|
||||
background:url(../../../../assets/images/yuan-right.png);
|
||||
background-size: 100% 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
text-align: right;
|
||||
.label {
|
||||
margin-right: 10px;
|
||||
max-width: 113px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
min-width: 86px;
|
||||
// width: 100%;
|
||||
// flex: 1;
|
||||
font-family: Source Han Sans CN;
|
||||
font-size: 14px;
|
||||
color: rgba(206, 235, 255, 0.7);
|
||||
text-align: center;
|
||||
height: 35px;
|
||||
line-height: 40px;
|
||||
// justify-content: center;
|
||||
}
|
||||
|
||||
.value {
|
||||
width: 100%;
|
||||
flex: 1;
|
||||
font-family: DIN;
|
||||
font-size: 22px;
|
||||
color: #FFFFFF;
|
||||
text-shadow: 0px 0px 10px 0px #0094FF;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.yougonglv-wrap {
|
||||
width: 100%;
|
||||
min-width: 367px;
|
||||
min-height: 67px;
|
||||
background: url(../../../../assets/images/zongyougong-bg.png) no-repeat;
|
||||
background-size: 100% auto;
|
||||
margin: 10px 0;
|
||||
|
||||
.top {
|
||||
height: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding-left: 20%;
|
||||
width: 100%;
|
||||
|
||||
.name {
|
||||
display: inline-block;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.top-value {
|
||||
display: inline-block;
|
||||
font-size: 22px;
|
||||
padding-right: 20px;
|
||||
color: #fff;
|
||||
|
||||
.value {
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
.unit {
|
||||
color: #CEEBFF;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bottom {
|
||||
height: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-left: 20%;
|
||||
|
||||
.item {
|
||||
display: inline-block;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.name {
|
||||
color: #CEEBFF
|
||||
}
|
||||
|
||||
.value {
|
||||
display: inline-block;
|
||||
padding-left: 5px;
|
||||
min-width: 35px;
|
||||
background: url(../../../../assets/images/jb.png) no-repeat;
|
||||
background-size: cover;
|
||||
color: #CEEBFF;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
207
src/views/dashboard-pv/components/itemBox/position.vue
Normal file
207
src/views/dashboard-pv/components/itemBox/position.vue
Normal file
@ -0,0 +1,207 @@
|
||||
<template>
|
||||
<div class="item-box">
|
||||
<div class="item-top">
|
||||
<el-popover
|
||||
placement="bottom"
|
||||
width="240"
|
||||
trigger="click"
|
||||
@show="changeTitle = title"
|
||||
@hide="handleSaveTitle"
|
||||
>
|
||||
<el-input v-model="changeTitle" maxlength="25" />
|
||||
<div slot="reference" class="top-title">{{ title }}</div>
|
||||
</el-popover>
|
||||
<div class="header-right">
|
||||
<slot name="header" />
|
||||
<i
|
||||
v-if="showPointSetting"
|
||||
slot="reference"
|
||||
v-permission="['business:dynamicConfig:addPointList']"
|
||||
class="el-icon-setting"
|
||||
style="
|
||||
font-size: 22px;
|
||||
cursor: pointer;
|
||||
color: #ceebff;
|
||||
margin-right: 3px;
|
||||
"
|
||||
@click="handleSetting"
|
||||
/>
|
||||
<i
|
||||
v-if="showCurveSetting"
|
||||
slot="reference"
|
||||
v-permission="['business:dynamicConfig:addCurveList']"
|
||||
class="el-icon-setting"
|
||||
style="
|
||||
font-size: 22px;
|
||||
cursor: pointer;
|
||||
color: #ceebff;
|
||||
margin-right: 3px;
|
||||
"
|
||||
@click="handleSetting"
|
||||
/>
|
||||
<svg-icon
|
||||
v-if="showScreen"
|
||||
:style="svgStyle"
|
||||
:icon-class="isFullscreen ? 'exit-fullscreen' : 'fullscreen'"
|
||||
@click="click"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item-con">
|
||||
<slot />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import screenfull from 'screenfull'
|
||||
export default {
|
||||
name: 'Index',
|
||||
components: {},
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
titleId: {
|
||||
type: [String, Number],
|
||||
default: ''
|
||||
},
|
||||
showPointSetting: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
showCurveSetting: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
showScreen: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
svgStyle: {
|
||||
display: 'inline-block',
|
||||
cursor: 'pointer',
|
||||
fill: '#ceebff',
|
||||
width: '16px',
|
||||
height: '16px',
|
||||
verticalAlign: '10px',
|
||||
marginRight: '5px'
|
||||
},
|
||||
isFullscreen: false,
|
||||
changeTitle: ''
|
||||
}
|
||||
},
|
||||
computed: {},
|
||||
watch: {},
|
||||
created() {},
|
||||
mounted() {
|
||||
this.init()
|
||||
},
|
||||
methods: {
|
||||
handleSaveTitle() {
|
||||
this.$emit('handleSaveTitle', this.changeTitle, this.titleId)
|
||||
},
|
||||
handleSetting() {
|
||||
this.$emit('handleSetting')
|
||||
},
|
||||
change() {
|
||||
this.isFullscreen = screenfull.isFullscreen
|
||||
},
|
||||
init() {
|
||||
if (screenfull.enabled) {
|
||||
screenfull.on('change', this.change)
|
||||
}
|
||||
},
|
||||
destroy() {
|
||||
if (screenfull.enabled) {
|
||||
screenfull.off('change', this.change)
|
||||
}
|
||||
},
|
||||
click() {
|
||||
this.$emit('screenFull', this.isFullscreen)
|
||||
const element = document.getElementById('app-main') // 指定全屏区域元素
|
||||
element.style.background =
|
||||
'url(' + require('../../../../assets/images/dashboardBg.png') + ')'
|
||||
if (screenfull.isEnabled) {
|
||||
screenfull.request(element)
|
||||
}
|
||||
screenfull.toggle(element)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.item-box {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
||||
.item-top {
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
opacity: 1;
|
||||
box-sizing: border-box;
|
||||
// border: 1px solid;
|
||||
// background: #003235;
|
||||
background-image: var(--item-header-bg);
|
||||
background-size: 100% 40px;
|
||||
// border-image: linear-gradient(
|
||||
// 11deg,
|
||||
// rgba(0, 148, 255, 0.5) 37%,
|
||||
// rgba(0, 148, 255, 0.5) 37%,
|
||||
// rgba(0, 148, 255, 0) 44%
|
||||
// )
|
||||
// 1;
|
||||
box-shadow: inset 0px 2px 16px 0px rgba(0, 148, 255, 0.15);
|
||||
// background:var(--table-bg);
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
.top-title {
|
||||
// width: 100%;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
font-size: 20px;
|
||||
font-weight: normal;
|
||||
letter-spacing: 0.2em;
|
||||
color: #ceebff;
|
||||
text-shadow: 0px 0px 10px #0094ff;
|
||||
font-family: var(--font-family);
|
||||
|
||||
padding: 0 10px;
|
||||
// background: linear-gradient(180deg, #c9fff3 0%, #c3fff2 13%, #32ffd2 63%);
|
||||
}
|
||||
.header-right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-left: auto;
|
||||
}
|
||||
}
|
||||
.item-con {
|
||||
flex: 1;
|
||||
margin-top: 5px;
|
||||
width: 100%;
|
||||
background:var(--table-bg);
|
||||
box-sizing: border-box;
|
||||
border: 1px solid;
|
||||
border-image: linear-gradient(
|
||||
108deg,
|
||||
#ffffff -7%,
|
||||
rgba(201, 255, 243, 0) 16%,
|
||||
rgba(201, 255, 243, 0) 75%,
|
||||
rgba(201, 255, 243, 0) 81%,
|
||||
#ffffff 102%,
|
||||
#ffffff 102%
|
||||
)
|
||||
1;
|
||||
box-shadow: inset 0px 2px 16px 0px rgba(0, 148, 255, 0.15);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -0,0 +1,244 @@
|
||||
<template>
|
||||
<div class="top-center-wrapper">
|
||||
<ItemBox :title="$t('dashboard.runCurve')">
|
||||
<div v-loading="loading" class="charts-box">
|
||||
<Chart
|
||||
ref="chart"
|
||||
:key="key"
|
||||
:options="powerOptions"
|
||||
:class-name="'chart'"
|
||||
/>
|
||||
</div>
|
||||
</ItemBox>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// import * as echarts from 'echarts'
|
||||
import { GetPCSElecData } from '@/api/home-page/index'
|
||||
|
||||
export default {
|
||||
name: 'Index',
|
||||
props: {
|
||||
stationId: {
|
||||
type: Number,
|
||||
default: undefined
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
powerOptions: undefined,
|
||||
currentType: 'day',
|
||||
color: ['#00A0E9'],
|
||||
loading: false,
|
||||
key: 0
|
||||
}
|
||||
},
|
||||
created() {},
|
||||
|
||||
mounted() {
|
||||
const timeData = []
|
||||
const totalPoints = (24 * 60) / 5
|
||||
const currentTime = Date.now()
|
||||
for (let i = 0; i < totalPoints; i++) {
|
||||
const pointTimestamp = currentTime - i * 5 * 60 * 1000
|
||||
const date = new Date(pointTimestamp)
|
||||
const formattedTime = `${date.getFullYear()}-${(date.getMonth() + 1)
|
||||
.toString()
|
||||
.padStart(2, '0')}-${date.getDate().toString().padStart(2, '0')} ${date
|
||||
.getHours()
|
||||
.toString()
|
||||
.padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}`
|
||||
timeData.push(formattedTime)
|
||||
}
|
||||
timeData.reverse()
|
||||
const currentData = []
|
||||
for (let i = 0; i < timeData.length; i++) {
|
||||
currentData.push({
|
||||
date: timeData[i],
|
||||
chargeElec: Number((Math.random() * 1500 + 1400).toFixed(2))
|
||||
})
|
||||
}
|
||||
this.initCharts(currentData, 1)
|
||||
},
|
||||
methods: {
|
||||
selectTime(type) {
|
||||
this.currentType = type
|
||||
this.getData()
|
||||
},
|
||||
getData() {
|
||||
this.getElecData()
|
||||
// this.getIncomeData()
|
||||
},
|
||||
async getElecData() {
|
||||
this.loading = true
|
||||
const params = {
|
||||
stationId: this.stationId,
|
||||
type: this.currentType
|
||||
}
|
||||
try {
|
||||
const res = await GetPCSElecData(params)
|
||||
console.log(res)
|
||||
// this.initCharts(res.data, 1)
|
||||
} catch (error) {
|
||||
// console.log(error);
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
// 新增代码
|
||||
|
||||
initCharts(val, type) {
|
||||
const x_data = []
|
||||
const charge_data = []
|
||||
// const discharge_data = []
|
||||
// let benefit_data = [0, 0, 0, 0, 0, 0, 0]
|
||||
if (val && val.length > 0) {
|
||||
val.forEach((item) => {
|
||||
x_data.push(item.date)
|
||||
charge_data.push(item.chargeElec)
|
||||
// discharge_data.push(item.dischargeElec)
|
||||
})
|
||||
}
|
||||
this.powerOptions = {
|
||||
grid: {
|
||||
top: '25%',
|
||||
left: '5%',
|
||||
right: '5%',
|
||||
bottom: '5%',
|
||||
containLabel: true
|
||||
},
|
||||
legend: {},
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
backgroundColor: 'rgba(0,0,0,0,)',
|
||||
borderColor: 'rgba(0,0,0,0,);',
|
||||
borderWidth: 0,
|
||||
textStyle: {
|
||||
width: 160,
|
||||
height: 250,
|
||||
lineHeight: 24,
|
||||
color: '#ffffff',
|
||||
fontSize: '14',
|
||||
fontFamily: 'SourceHanSansCN-Normal'
|
||||
},
|
||||
formatter: (params) => {
|
||||
// 获取xAxis data中的数据
|
||||
let dataStr = `<div><p style="font-weight:bold;margin:0 8px 15px;">${params[0].name}</p></div>`
|
||||
params.forEach((item) => {
|
||||
dataStr += `<div>
|
||||
<div style="margin: 0 8px;">
|
||||
<span style="display:inline-block;margin-right:5px;width:10px;height:10px;background-color:${this.color[0]};"></span>
|
||||
<span>${item.seriesName}</span>
|
||||
<span style="float:right;color:#00C8FF;margin-left:20px;">${item.data}</span>
|
||||
</div>
|
||||
</div>`
|
||||
})
|
||||
const div = `<div style='border: 1px solid ;
|
||||
border-image: linear-gradient(130deg, #FFFFFF 0%, rgba(201,255,243,0.00) 22%, rgba(201,255,243,0.00) 75%, rgba(201,255,243,0.00) 80%, #FFFFFF 99%, #FFFFFF 99%) 1;
|
||||
box-shadow: inset 0px 2px 16px 0px rgba(0, 148, 255, 0.4);' >${dataStr}</div>`
|
||||
return div
|
||||
}
|
||||
},
|
||||
xAxis: [
|
||||
{
|
||||
type: 'category',
|
||||
data: x_data,
|
||||
axisLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: '#90e9d8'
|
||||
}
|
||||
},
|
||||
axisLabel: {
|
||||
show: true,
|
||||
color: '#CEEBFF'
|
||||
},
|
||||
|
||||
axisTick: {
|
||||
show: false
|
||||
}
|
||||
}
|
||||
],
|
||||
yAxis: [
|
||||
{
|
||||
type: 'value',
|
||||
name: `kWh`,
|
||||
nameTextStyle: {
|
||||
color: ' rgba(255, 255, 255, 0.5)'
|
||||
},
|
||||
axisLine: {
|
||||
show: false,
|
||||
lineStyle: {
|
||||
color: '#90e9d8'
|
||||
}
|
||||
},
|
||||
axisLabel: {
|
||||
show: true,
|
||||
color: '#CEEBFF'
|
||||
},
|
||||
axisTick: {
|
||||
show: false
|
||||
},
|
||||
splitLine: {
|
||||
show: true, // 强制显示分割线(默认已开启,确保不被隐藏)
|
||||
lineStyle: {
|
||||
type: 'dashed', // 线型设为虚线
|
||||
color: 'rgba(255,255,255,0.2)', // 虚线颜色(可自定义,如 #999、rgba(0,0,0,0.1))
|
||||
width: 1, // 虚线宽度
|
||||
dashOffset: 5 // 虚线偏移量(可选,调整虚线起始位置)
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
series: [
|
||||
{
|
||||
name: `${this.$t('dashboard.powerGenerationCapacity')}`,
|
||||
type: 'line',
|
||||
smooth: true,
|
||||
symbol: 'none',
|
||||
data: charge_data,
|
||||
barWidth: 14, // 柱状图的宽度
|
||||
color: '#00C8FF'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.top-center-wrapper {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
.header-right-box {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
.header-title {
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
letter-spacing: 0em;
|
||||
color: rgba(206, 235, 255, 0.5);
|
||||
white-space: nowrap;
|
||||
padding: 0 10px;
|
||||
cursor: pointer;
|
||||
font-family: Source Han Sans CN;
|
||||
|
||||
&.active {
|
||||
color: #ffffff;
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
rgba(0, 148, 255, 0) 0%,
|
||||
rgba(0, 148, 255, 0.43) 51%,
|
||||
rgba(0, 148, 255, 0) 99%
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
.charts-box {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
508
src/views/dashboard-pv/components/top-left/common-mwh.vue
Normal file
508
src/views/dashboard-pv/components/top-left/common-mwh.vue
Normal file
@ -0,0 +1,508 @@
|
||||
<template>
|
||||
<div class="top-left-box">
|
||||
<ItemBox :title="$t('dashboard.stationData')">
|
||||
<div slot="header">
|
||||
<div class="header-right-box">
|
||||
<div class="header-title" :class="{'active':currentIndex === 0}" @click="changeType(0)">{{ $t('dashboard.dataOverView') }}</div>
|
||||
<div class="header-title" :class="{'active':currentIndex === 1}" @click="changeType(1)">{{ $t('dashboard.stationInfo') }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="currentIndex === 0" v-loading="loading" class="box">
|
||||
<StationData :table-data="overflowData" />
|
||||
</div>
|
||||
<div v-else v-loading="loading" class="box">
|
||||
<StationData :table-data="totalData" />
|
||||
</div>
|
||||
<el-dialog
|
||||
:append-to-body="true"
|
||||
title="日充放统计规则"
|
||||
:visible.sync="ruleShow"
|
||||
center
|
||||
width="30%"
|
||||
:close-on-click-modal="false"
|
||||
>
|
||||
<el-form :model="timeForm" label-width="120px">
|
||||
<el-form-item label="前一日" class="select-box">
|
||||
<el-select
|
||||
v-model="timeForm.beforeTime"
|
||||
style="width:100%"
|
||||
placeholder="请选择"
|
||||
@change="selectRuleTime"
|
||||
>
|
||||
<template slot="prefix">
|
||||
<span style="padding-left: 5px;">
|
||||
<i class="el-icon-time" />
|
||||
</span>
|
||||
</template>
|
||||
<el-option
|
||||
v-for="item in timeList"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="今日">
|
||||
<el-time-picker
|
||||
v-model="timeForm.nowDayTime"
|
||||
style="width:100%"
|
||||
:clearable="false"
|
||||
readonly
|
||||
placeholder="请选择时间"
|
||||
value-format="HH:mm:ss"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="cancelRule">取 消</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
:loading="timeSubmitLoading"
|
||||
@click="sureRule"
|
||||
>确 定</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</ItemBox>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { GetPcsStationData, addElecMeterConfig,
|
||||
updateElecMeterConfig } from '@/api/home-page/index'
|
||||
import { GetRAPcsTotalData } from '@/api/homePage-integrated/index'
|
||||
import { ToDegrees } from '@/utils/index'
|
||||
import dayImg from '../../../../assets/station-data/run-day.png'
|
||||
export default {
|
||||
name: 'Index',
|
||||
props: {
|
||||
stationId: {
|
||||
type: Number,
|
||||
default: 0
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
dayImg,
|
||||
currentIndex: 0,
|
||||
overflowData: [{
|
||||
name: this.$t('dashboard.safeDays'),
|
||||
id: 'operationDays',
|
||||
picture: dayImg,
|
||||
unit: this.$t('dashboard.day'),
|
||||
value: 0
|
||||
}, {
|
||||
name: this.$t('dashboard.totalCapacity'),
|
||||
id: 'totalCapacity',
|
||||
picture: dayImg,
|
||||
unit: 'kWh',
|
||||
value: 0
|
||||
}, {
|
||||
name: this.$t('dashboard.systemConversionEfficiency'),
|
||||
id: 'systemEfficiency',
|
||||
picture: dayImg,
|
||||
unit: '%',
|
||||
value: 0
|
||||
}, {
|
||||
name: this.$t('dashboard.currentPower'),
|
||||
id: 'currentPower',
|
||||
picture: dayImg,
|
||||
unit: 'kW',
|
||||
value: 0
|
||||
}, {
|
||||
name: this.$t('dashboard.totalCharge'),
|
||||
id: 'totalChargeElec',
|
||||
picture: dayImg,
|
||||
unit: 'MWh',
|
||||
value: 0
|
||||
}, {
|
||||
name: this.$t('dashboard.totalDischarge'),
|
||||
id: 'totalDischargeElec',
|
||||
picture: dayImg,
|
||||
unit: 'MWh',
|
||||
value: 0
|
||||
}, {
|
||||
name: this.$t('dashboard.dailyCharge'),
|
||||
id: 'dailyChargeElec',
|
||||
picture: dayImg,
|
||||
unit: 'MWh',
|
||||
value: 0,
|
||||
click: true
|
||||
}, {
|
||||
name: this.$t('dashboard.dailyDischarge'),
|
||||
id: 'dailyDischargeElec',
|
||||
picture: dayImg,
|
||||
unit: 'MWh',
|
||||
value: 0
|
||||
}],
|
||||
totalData: [{
|
||||
name: this.$t('dashboard.stationName'),
|
||||
id: 'name',
|
||||
picture: dayImg,
|
||||
value: 0
|
||||
}, {
|
||||
name: this.$t('dashboard.stationType'),
|
||||
id: 'type',
|
||||
picture: dayImg,
|
||||
value: 0
|
||||
}, {
|
||||
name: this.$t('dashboard.stationLocation'),
|
||||
id: 'address',
|
||||
picture: dayImg,
|
||||
value: 0
|
||||
},
|
||||
{
|
||||
name: this.$t('dashboard.commTime'),
|
||||
id: 'createTime',
|
||||
picture: dayImg,
|
||||
value: 0
|
||||
},
|
||||
{
|
||||
name: this.$t('dashboard.log'),
|
||||
id: 'longitude',
|
||||
picture: dayImg,
|
||||
value: 0
|
||||
},
|
||||
{
|
||||
name: this.$t('dashboard.lat'),
|
||||
id: 'latitude',
|
||||
picture: dayImg,
|
||||
value: 0
|
||||
}],
|
||||
stationType: [],
|
||||
loading: false,
|
||||
ruleShow: false,
|
||||
timeForm: {
|
||||
beforeTime: undefined,
|
||||
nowDayTime: undefined
|
||||
},
|
||||
timeSubmitLoading: false,
|
||||
timeOperate: 1, // 1 新增 2 编辑
|
||||
timeList: []
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
stationTypeList() {
|
||||
return this.$store.getters.dicts['stationType'] || []
|
||||
},
|
||||
language() {
|
||||
return this.$store.getters.language || undefined
|
||||
}
|
||||
|
||||
},
|
||||
watch: {
|
||||
dailyTime: {
|
||||
handler(val) {
|
||||
if (val) {
|
||||
this.timeForm = val
|
||||
this.timeOperate = val.timeOperate
|
||||
this.GetPcsTotalData()
|
||||
}
|
||||
},
|
||||
deep: true,
|
||||
immediate: true
|
||||
},
|
||||
language: {
|
||||
handler() {
|
||||
this.overflowData = [{
|
||||
name: this.$t('dashboard.safeDays'),
|
||||
id: 'operationDays',
|
||||
picture: dayImg,
|
||||
unit: this.$t('dashboard.day'),
|
||||
value: 0
|
||||
}, {
|
||||
name: this.$t('dashboard.totalCapacity'),
|
||||
id: 'totalCapacity',
|
||||
picture: dayImg,
|
||||
unit: 'kWh',
|
||||
value: 0
|
||||
}, {
|
||||
name: this.$t('dashboard.systemConversionEfficiency'),
|
||||
id: 'systemEfficiency',
|
||||
picture: dayImg,
|
||||
unit: '%',
|
||||
value: 0
|
||||
}, {
|
||||
name: this.$t('dashboard.currentPower'),
|
||||
id: 'currentPower',
|
||||
picture: dayImg,
|
||||
unit: 'kW',
|
||||
value: 0
|
||||
}, {
|
||||
name: this.$t('dashboard.totalCharge'),
|
||||
id: 'totalChargeElec',
|
||||
picture: dayImg,
|
||||
unit: 'MWh',
|
||||
value: 0
|
||||
}, {
|
||||
name: this.$t('dashboard.totalDischarge'),
|
||||
id: 'totalDischargeElec',
|
||||
picture: dayImg,
|
||||
unit: 'MWh',
|
||||
value: 0
|
||||
}, {
|
||||
name: this.$t('dashboard.dailyCharge'),
|
||||
id: 'dailyChargeElec',
|
||||
picture: dayImg,
|
||||
unit: 'MWh',
|
||||
value: 0,
|
||||
click: true
|
||||
}, {
|
||||
name: this.$t('dashboard.dailyDischarge'),
|
||||
id: 'dailyDischargeElec',
|
||||
picture: dayImg,
|
||||
unit: 'MWh',
|
||||
value: 0
|
||||
}]
|
||||
this.totalData = [{
|
||||
name: this.$t('dashboard.stationName'),
|
||||
id: 'name',
|
||||
picture: dayImg,
|
||||
value: 0
|
||||
}, {
|
||||
name: this.$t('dashboard.stationType'),
|
||||
id: 'type',
|
||||
picture: dayImg,
|
||||
value: 0
|
||||
}, {
|
||||
name: this.$t('dashboard.stationLocation'),
|
||||
id: 'address',
|
||||
picture: dayImg,
|
||||
value: 0
|
||||
},
|
||||
{
|
||||
name: this.$t('dashboard.commTime'),
|
||||
id: 'createTime',
|
||||
picture: dayImg,
|
||||
value: 0
|
||||
},
|
||||
{
|
||||
name: this.$t('dashboard.log'),
|
||||
id: 'longitude',
|
||||
picture: dayImg,
|
||||
value: 0
|
||||
},
|
||||
{
|
||||
name: this.$t('dashboard.lat'),
|
||||
id: 'latitude',
|
||||
picture: dayImg,
|
||||
value: 0
|
||||
}]
|
||||
},
|
||||
deep: true
|
||||
}
|
||||
},
|
||||
created() {
|
||||
// console.log(this.stationTypeList)
|
||||
this.getTimeList()
|
||||
},
|
||||
mounted() { },
|
||||
methods: {
|
||||
getStationTypeName(item) {
|
||||
const typeIndex = this.stationTypeList.findIndex(t => Number(t.value) === Number(item))
|
||||
return this.stationTypeList[typeIndex].label
|
||||
},
|
||||
changeType(val) {
|
||||
this.currentIndex = val
|
||||
},
|
||||
getData() {
|
||||
this.GetPcsStationData()
|
||||
this.GetPcsTotalData()
|
||||
},
|
||||
async GetPcsStationData() {
|
||||
this.loading = true
|
||||
const params = {
|
||||
stationId: this.stationId
|
||||
}
|
||||
try {
|
||||
const { data } = await GetPcsStationData(params)
|
||||
this.totalData.forEach((item) => {
|
||||
item.value = data[item.id]
|
||||
if (item.id === 'type') {
|
||||
item.value = this.getStationTypeName(item.value)
|
||||
}
|
||||
if (item.id === 'longitude') {
|
||||
item.value = ToDegrees(item.value, 1)
|
||||
}
|
||||
if (item.id === 'latitude') {
|
||||
item.value = ToDegrees(item.value, 2)
|
||||
}
|
||||
})
|
||||
} catch (error) {
|
||||
// console.log(error);
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
|
||||
async GetPcsTotalData() {
|
||||
this.loading = true
|
||||
const params = {
|
||||
stationId: this.stationId
|
||||
}
|
||||
try {
|
||||
const { data } = await GetRAPcsTotalData(params)
|
||||
this.overflowData.forEach((item) => {
|
||||
if (data[item.id]) {
|
||||
item.value = data[item.id]
|
||||
}
|
||||
if (item.id === 'systemEfficiency') {
|
||||
item.value = (item.value * 100).toFixed(2)
|
||||
}
|
||||
if (item.id === 'totalChargeElec' && item.value >= 1E4) {
|
||||
item.unit = 'MWh'
|
||||
item.value = (Number(item.value) / 1E3).toFixed(2) + ''
|
||||
}
|
||||
if (item.id === 'totalDischargeElec' && item.value >= 1E4) {
|
||||
item.unit = 'MWh'
|
||||
item.value = (Number(item.value) / 1E3).toFixed(2) + ''
|
||||
}
|
||||
if (item.id === 'dailyChargeElec' && item.value >= 1E4) {
|
||||
item.unit = 'MWh'
|
||||
item.value = (Number(item.value) / 1E3).toFixed(2) + ''
|
||||
}
|
||||
if (item.id === 'dailyDischargeElec' && item.value >= 1E4) {
|
||||
item.unit = 'MWh'
|
||||
item.value = (Number(item.value) / 1E3).toFixed(2) + ''
|
||||
}
|
||||
if (item.id === 'currentPower' && item.value >= 1E4) {
|
||||
item.unit = 'MW'
|
||||
item.value = (Number(item.value) / 1E3).toFixed(2) + ''
|
||||
}
|
||||
})
|
||||
} catch (error) {
|
||||
// console.log(error);
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
getTimeList() {
|
||||
for (let i = 0; i < 24; i++) {
|
||||
this.timeList.push({
|
||||
label: `${i < 10 ? '0' + i : i}:00:00`,
|
||||
value: `${i < 10 ? '0' + i : i}:00:00`
|
||||
})
|
||||
}
|
||||
},
|
||||
setRule() {
|
||||
this.ruleShow = true
|
||||
},
|
||||
selectRuleTime(val) {
|
||||
this.timeForm.nowDayTime = this.getEightTime('2020-07-28 ' + val)
|
||||
},
|
||||
cancelRule() {
|
||||
this.ruleShow = false
|
||||
},
|
||||
sureRule() {
|
||||
if (this.timeOperate === 1) {
|
||||
// 新增
|
||||
this.timeSubmitLoading = true
|
||||
const param = {
|
||||
stationId: this.stationId,
|
||||
beginTime: this.timeForm.beforeTime,
|
||||
endTime: this.timeForm.nowDayTime
|
||||
}
|
||||
addElecMeterConfig(param)
|
||||
.then((res) => {
|
||||
this.$message.success('新增成功')
|
||||
this.ruleShow = false
|
||||
this.$emit('updateTime')
|
||||
})
|
||||
.finally(() => {
|
||||
this.timeSubmitLoading = false
|
||||
})
|
||||
} else {
|
||||
// 编辑
|
||||
this.timeSubmitLoading = true
|
||||
const param = {
|
||||
stationId: this.stationId,
|
||||
beginTime: this.timeForm.beforeTime,
|
||||
endTime: this.timeForm.nowDayTime,
|
||||
id: this.timeForm.id
|
||||
}
|
||||
updateElecMeterConfig(param)
|
||||
.then((res) => {
|
||||
this.$message.success('更新成功')
|
||||
this.ruleShow = false
|
||||
this.$emit('updateTime')
|
||||
})
|
||||
.finally(() => {
|
||||
this.timeSubmitLoading = false
|
||||
})
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 指定时间的多少小时或多少分钟之后的时间
|
||||
* @param {*} str 2020-07-28 15:00:00
|
||||
*/
|
||||
getEightTime(str) {
|
||||
const t = new Date(str).getTime() + 24 * 60 * 60 * 1000 - 1 // 24小时 * 60分钟 * 60秒 * 1000
|
||||
const d = new Date(t)
|
||||
let theMonth = d.getMonth() + 1
|
||||
let theDate = d.getDate()
|
||||
let theHours = d.getHours()
|
||||
let theMinutes = d.getMinutes()
|
||||
let theSecond = d.getSeconds()
|
||||
if (theMonth < 10) {
|
||||
theMonth = '0' + theMonth
|
||||
}
|
||||
if (theDate < 10) {
|
||||
theDate = '0' + theDate
|
||||
}
|
||||
if (theHours < 10) {
|
||||
theHours = '0' + theHours
|
||||
}
|
||||
if (theMinutes < 10) {
|
||||
theMinutes = '0' + theMinutes
|
||||
}
|
||||
if (theSecond < 10) {
|
||||
theSecond = '0' + theSecond
|
||||
}
|
||||
// let date = d.getFullYear() + '-' + theMonth + '-' + theDate
|
||||
const time = theHours + ':' + theMinutes + ':' + theSecond
|
||||
// let Spare = date + ' ' + time
|
||||
// console.log(date)
|
||||
// console.log(time)
|
||||
// console.log(Spare)
|
||||
return time
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
::v-deep .item-con{
|
||||
overflow:auto;
|
||||
}
|
||||
.top-left-box{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
.header-right-box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.header-title {
|
||||
white-space: nowrap;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
letter-spacing: 0em;
|
||||
color: rgba(206, 235, 255, 0.5);
|
||||
padding: 0 10px;
|
||||
cursor: pointer;
|
||||
font-family: Source Han Sans CN;
|
||||
|
||||
&.active{
|
||||
color: #ffffff;
|
||||
background: linear-gradient(90deg, rgba(0,148,255,0.00) 0%, rgba(0,148,255,0.43) 51%, rgba(0,148,255,0.00) 99%);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.box{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 10px;
|
||||
padding-bottom: 0;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
</style>
|
||||
509
src/views/dashboard-pv/components/top-left/common.vue
Normal file
509
src/views/dashboard-pv/components/top-left/common.vue
Normal file
@ -0,0 +1,509 @@
|
||||
<template>
|
||||
<div class="top-left-box">
|
||||
<ItemBox :title="$t('dashboard.stationData')">
|
||||
<div slot="header">
|
||||
<div class="header-right-box">
|
||||
<div class="header-title" :class="{'active':currentIndex === 0}" @click="changeType(0)">{{ $t('dashboard.dataOverView') }}</div>
|
||||
<div class="header-title" :class="{'active':currentIndex === 1}" @click="changeType(1)">{{ $t('dashboard.stationInfo') }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="currentIndex === 0" v-loading="loading" class="box">
|
||||
<StationData :table-data="overflowData" />
|
||||
</div>
|
||||
<div v-else v-loading="loading" class="box">
|
||||
<StationData :table-data="totalData" />
|
||||
</div>
|
||||
<el-dialog
|
||||
:append-to-body="true"
|
||||
title="日充放统计规则"
|
||||
:visible.sync="ruleShow"
|
||||
center
|
||||
width="30%"
|
||||
:close-on-click-modal="false"
|
||||
>
|
||||
<el-form :model="timeForm" label-width="120px">
|
||||
<el-form-item label="前一日" class="select-box">
|
||||
<el-select
|
||||
v-model="timeForm.beforeTime"
|
||||
style="width:100%"
|
||||
placeholder="请选择"
|
||||
@change="selectRuleTime"
|
||||
>
|
||||
<template slot="prefix">
|
||||
<span style="padding-left: 5px;">
|
||||
<i class="el-icon-time" />
|
||||
</span>
|
||||
</template>
|
||||
<el-option
|
||||
v-for="item in timeList"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="今日">
|
||||
<el-time-picker
|
||||
v-model="timeForm.nowDayTime"
|
||||
style="width:100%"
|
||||
:clearable="false"
|
||||
readonly
|
||||
placeholder="请选择时间"
|
||||
value-format="HH:mm:ss"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="cancelRule">取 消</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
:loading="timeSubmitLoading"
|
||||
@click="sureRule"
|
||||
>确 定</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</ItemBox>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { GetPcsStationData, addElecMeterConfig,
|
||||
updateElecMeterConfig } from '@/api/home-page/index'
|
||||
import { GetRAPcsTotalData } from '@/api/homePage-integrated/index'
|
||||
import { ToDegrees } from '@/utils/index'
|
||||
import disImg from '../../../../assets/station-data/total-discharge.png'
|
||||
export default {
|
||||
name: 'Index',
|
||||
props: {
|
||||
stationId: {
|
||||
type: Number,
|
||||
default: 0
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
disImg,
|
||||
currentIndex: 0,
|
||||
totalData: [{
|
||||
name: this.$t('dashboard.stationName'),
|
||||
id: 'name',
|
||||
picture: disImg,
|
||||
value: 0
|
||||
}, {
|
||||
name: this.$t('dashboard.stationType'),
|
||||
id: 'type',
|
||||
picture: disImg,
|
||||
value: 0
|
||||
}, {
|
||||
name: this.$t('dashboard.stationLocation'),
|
||||
id: 'address',
|
||||
picture: disImg,
|
||||
value: 0
|
||||
},
|
||||
{
|
||||
name: this.$t('dashboard.commTime'),
|
||||
id: 'createTime',
|
||||
picture: disImg,
|
||||
value: 0
|
||||
},
|
||||
{
|
||||
name: this.$t('dashboard.log'),
|
||||
id: 'longitude',
|
||||
picture: disImg,
|
||||
value: 0
|
||||
},
|
||||
{
|
||||
name: this.$t('dashboard.lat'),
|
||||
id: 'latitude',
|
||||
picture: disImg,
|
||||
value: 0
|
||||
}],
|
||||
overflowData: [{
|
||||
name: this.$t('dashboard.safeDays'),
|
||||
id: 'operationDays',
|
||||
picture: disImg,
|
||||
value: 0,
|
||||
unit: this.$t('dashboard.day')
|
||||
}, {
|
||||
name: this.$t('dashboard.totalCapacity'),
|
||||
id: 'totalCapacity',
|
||||
picture: disImg,
|
||||
value: 0,
|
||||
unit: 'kWh'
|
||||
}, {
|
||||
name: this.$t('dashboard.systemConversionEfficiency'),
|
||||
id: 'systemEfficiency',
|
||||
picture: disImg,
|
||||
value: 0,
|
||||
unit: '%'
|
||||
}, {
|
||||
name: this.$t('dashboard.currentPower'),
|
||||
id: 'currentPower',
|
||||
picture: disImg,
|
||||
value: 0,
|
||||
unit: 'kW'
|
||||
}, {
|
||||
name: this.$t('dashboard.totalCharge'),
|
||||
id: 'totalChargeElec',
|
||||
picture: disImg,
|
||||
value: 0,
|
||||
unit: 'kWh'
|
||||
}, {
|
||||
name: this.$t('dashboard.totalDischarge'),
|
||||
id: 'totalDischargeElec',
|
||||
picture: disImg,
|
||||
value: 0,
|
||||
unit: 'kWh'
|
||||
}, {
|
||||
name: this.$t('dashboard.dailyCharge'),
|
||||
id: 'dailyChargeElec',
|
||||
picture: disImg,
|
||||
value: 0,
|
||||
unit: 'kWh',
|
||||
click: true
|
||||
}, {
|
||||
name: this.$t('dashboard.dailyDischarge'),
|
||||
id: 'dailyDischargeElec',
|
||||
picture: disImg,
|
||||
value: 0,
|
||||
unit: 'kWh'
|
||||
}],
|
||||
stationType: [],
|
||||
loading: false,
|
||||
ruleShow: false,
|
||||
timeForm: {
|
||||
beforeTime: undefined,
|
||||
nowDayTime: undefined
|
||||
},
|
||||
timeSubmitLoading: false,
|
||||
timeOperate: 1, // 1 新增 2 编辑
|
||||
timeList: []
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
stationTypeList() {
|
||||
return this.$store.getters.dicts['stationType'] || []
|
||||
},
|
||||
language() {
|
||||
return this.$store.getters.language || undefined
|
||||
}
|
||||
|
||||
},
|
||||
watch: {
|
||||
dailyTime: {
|
||||
handler(val) {
|
||||
if (val) {
|
||||
this.timeForm = val
|
||||
this.timeOperate = val.timeOperate
|
||||
this.GetPcsTotalData()
|
||||
}
|
||||
},
|
||||
deep: true,
|
||||
immediate: true
|
||||
},
|
||||
language: {
|
||||
handler() {
|
||||
this.totalData = [{
|
||||
name: this.$t('dashboard.stationName'),
|
||||
id: 'name',
|
||||
picture: disImg,
|
||||
value: 0
|
||||
}, {
|
||||
name: this.$t('dashboard.stationType'),
|
||||
id: 'type',
|
||||
picture: disImg,
|
||||
value: 0
|
||||
}, {
|
||||
name: this.$t('dashboard.stationLocation'),
|
||||
id: 'address',
|
||||
picture: disImg,
|
||||
value: 0
|
||||
},
|
||||
{
|
||||
name: this.$t('dashboard.commTime'),
|
||||
id: 'createTime',
|
||||
picture: disImg,
|
||||
value: 0
|
||||
},
|
||||
{
|
||||
name: this.$t('dashboard.log'),
|
||||
id: 'longitude',
|
||||
picture: disImg,
|
||||
value: 0
|
||||
},
|
||||
{
|
||||
name: this.$t('dashboard.lat'),
|
||||
id: 'latitude',
|
||||
picture: disImg,
|
||||
value: 0
|
||||
}]
|
||||
this.overflowData = [{
|
||||
name: this.$t('dashboard.safeDays') + `(${this.$t('dashboard.day')})`,
|
||||
id: 'operationDays',
|
||||
picture: disImg,
|
||||
value: 0,
|
||||
unit: this.$t('dashboard.day')
|
||||
}, {
|
||||
name: this.$t('dashboard.totalCapacity'),
|
||||
id: 'totalCapacity',
|
||||
picture: disImg,
|
||||
value: 0,
|
||||
unit: 'kWh'
|
||||
}, {
|
||||
name: this.$t('dashboard.systemConversionEfficiency'),
|
||||
id: 'systemEfficiency',
|
||||
picture: disImg,
|
||||
value: 0,
|
||||
unit: '%'
|
||||
}, {
|
||||
name: this.$t('dashboard.currentPower'),
|
||||
id: 'currentPower',
|
||||
picture: disImg,
|
||||
value: 0,
|
||||
unit: 'kW'
|
||||
}, {
|
||||
name: this.$t('dashboard.totalCharge'),
|
||||
id: 'totalChargeElec',
|
||||
picture: disImg,
|
||||
value: 0,
|
||||
unit: 'kWh'
|
||||
}, {
|
||||
name: this.$t('dashboard.totalDischarge'),
|
||||
id: 'totalDischargeElec',
|
||||
picture: disImg,
|
||||
value: 0,
|
||||
unit: 'kWh'
|
||||
}, {
|
||||
name: this.$t('dashboard.dailyCharge'),
|
||||
id: 'dailyChargeElec',
|
||||
picture: disImg,
|
||||
value: 0,
|
||||
unit: 'kWh',
|
||||
click: true
|
||||
}, {
|
||||
name: this.$t('dashboard.dailyDischarge'),
|
||||
id: 'dailyDischargeElec',
|
||||
picture: disImg,
|
||||
value: 0,
|
||||
unit: 'kWh'
|
||||
}]
|
||||
},
|
||||
deep: true
|
||||
}
|
||||
},
|
||||
created() {
|
||||
// console.log(this.stationTypeList)
|
||||
this.getTimeList()
|
||||
},
|
||||
mounted() { },
|
||||
methods: {
|
||||
getStationTypeName(item) {
|
||||
const typeIndex = this.stationTypeList.findIndex(t => Number(t.value) === Number(item))
|
||||
return this.stationTypeList[typeIndex].label
|
||||
},
|
||||
changeType(val) {
|
||||
this.currentIndex = val
|
||||
},
|
||||
getData() {
|
||||
this.GetPcsStationData()
|
||||
this.GetPcsTotalData()
|
||||
},
|
||||
async GetPcsStationData() {
|
||||
this.loading = true
|
||||
const params = {
|
||||
stationId: this.stationId
|
||||
}
|
||||
try {
|
||||
const { data } = await GetPcsStationData(params)
|
||||
this.totalData.forEach((item) => {
|
||||
item.value = data[item.id]
|
||||
if (item.id === 'type') {
|
||||
item.value = this.getStationTypeName(item.value)
|
||||
}
|
||||
if (item.id === 'longitude') {
|
||||
item.value = ToDegrees(item.value, 1)
|
||||
}
|
||||
if (item.id === 'latitude') {
|
||||
item.value = ToDegrees(item.value, 2)
|
||||
}
|
||||
})
|
||||
} catch (error) {
|
||||
// console.log(error);
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
|
||||
async GetPcsTotalData() {
|
||||
this.loading = true
|
||||
const params = {
|
||||
stationId: this.stationId
|
||||
}
|
||||
try {
|
||||
const { data } = await GetRAPcsTotalData(params)
|
||||
this.overflowData.forEach((item) => {
|
||||
if (data[item.id]) {
|
||||
item.value = data[item.id]
|
||||
}
|
||||
if (item.id === 'systemEfficiency') {
|
||||
item.value = (item.value * 100).toFixed(2)
|
||||
}
|
||||
if (item.id === 'totalChargeElec' && item.value >= 1E4) {
|
||||
item.unit = 'MWh'
|
||||
item.value = (Number(item.value) / 1E3).toFixed(2) + ''
|
||||
}
|
||||
if (item.id === 'totalDischargeElec' && item.value >= 1E4) {
|
||||
item.unit = 'MWh'
|
||||
item.value = (Number(item.value) / 1E3).toFixed(2) + ''
|
||||
}
|
||||
if (item.id === 'dailyChargeElec' && item.value >= 1E4) {
|
||||
item.unit = 'MWh'
|
||||
item.value = (Number(item.value) / 1E3).toFixed(2) + ''
|
||||
}
|
||||
if (item.id === 'dailyDischargeElec' && item.value >= 1E4) {
|
||||
item.unit = 'MWh'
|
||||
item.value = (Number(item.value) / 1E3).toFixed(2) + ''
|
||||
}
|
||||
if (item.id === 'currentPower' && item.value >= 1E4) {
|
||||
item.unit = 'MW'
|
||||
item.value = (Number(item.value) / 1E3).toFixed(2) + ''
|
||||
}
|
||||
})
|
||||
} catch (error) {
|
||||
// console.log(error);
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
getTimeList() {
|
||||
for (let i = 0; i < 24; i++) {
|
||||
this.timeList.push({
|
||||
label: `${i < 10 ? '0' + i : i}:00:00`,
|
||||
value: `${i < 10 ? '0' + i : i}:00:00`
|
||||
})
|
||||
}
|
||||
},
|
||||
setRule() {
|
||||
this.ruleShow = true
|
||||
},
|
||||
selectRuleTime(val) {
|
||||
this.timeForm.nowDayTime = this.getEightTime('2020-07-28 ' + val)
|
||||
},
|
||||
cancelRule() {
|
||||
this.ruleShow = false
|
||||
},
|
||||
sureRule() {
|
||||
if (this.timeOperate === 1) {
|
||||
// 新增
|
||||
this.timeSubmitLoading = true
|
||||
const param = {
|
||||
stationId: this.stationId,
|
||||
beginTime: this.timeForm.beforeTime,
|
||||
endTime: this.timeForm.nowDayTime
|
||||
}
|
||||
addElecMeterConfig(param)
|
||||
.then((res) => {
|
||||
this.$message.success('新增成功')
|
||||
this.ruleShow = false
|
||||
this.$emit('updateTime')
|
||||
})
|
||||
.finally(() => {
|
||||
this.timeSubmitLoading = false
|
||||
})
|
||||
} else {
|
||||
// 编辑
|
||||
this.timeSubmitLoading = true
|
||||
const param = {
|
||||
stationId: this.stationId,
|
||||
beginTime: this.timeForm.beforeTime,
|
||||
endTime: this.timeForm.nowDayTime,
|
||||
id: this.timeForm.id
|
||||
}
|
||||
updateElecMeterConfig(param)
|
||||
.then((res) => {
|
||||
this.$message.success('更新成功')
|
||||
this.ruleShow = false
|
||||
this.$emit('updateTime')
|
||||
})
|
||||
.finally(() => {
|
||||
this.timeSubmitLoading = false
|
||||
})
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 指定时间的多少小时或多少分钟之后的时间
|
||||
* @param {*} str 2020-07-28 15:00:00
|
||||
*/
|
||||
getEightTime(str) {
|
||||
const t = new Date(str).getTime() + 24 * 60 * 60 * 1000 - 1 // 24小时 * 60分钟 * 60秒 * 1000
|
||||
const d = new Date(t)
|
||||
let theMonth = d.getMonth() + 1
|
||||
let theDate = d.getDate()
|
||||
let theHours = d.getHours()
|
||||
let theMinutes = d.getMinutes()
|
||||
let theSecond = d.getSeconds()
|
||||
if (theMonth < 10) {
|
||||
theMonth = '0' + theMonth
|
||||
}
|
||||
if (theDate < 10) {
|
||||
theDate = '0' + theDate
|
||||
}
|
||||
if (theHours < 10) {
|
||||
theHours = '0' + theHours
|
||||
}
|
||||
if (theMinutes < 10) {
|
||||
theMinutes = '0' + theMinutes
|
||||
}
|
||||
if (theSecond < 10) {
|
||||
theSecond = '0' + theSecond
|
||||
}
|
||||
// let date = d.getFullYear() + '-' + theMonth + '-' + theDate
|
||||
const time = theHours + ':' + theMinutes + ':' + theSecond
|
||||
// let Spare = date + ' ' + time
|
||||
// console.log(date)
|
||||
// console.log(time)
|
||||
// console.log(Spare)
|
||||
return time
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
::v-deep .item-con{
|
||||
overflow:auto;
|
||||
}
|
||||
.top-left-box{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
.header-right-box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.header-title {
|
||||
white-space: nowrap;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
letter-spacing: 0em;
|
||||
color: rgba(206, 235, 255, 0.5);
|
||||
padding: 0 10px;
|
||||
cursor: pointer;
|
||||
font-family: Source Han Sans CN;
|
||||
|
||||
&.active{
|
||||
color: #ffffff;
|
||||
background: linear-gradient(90deg, rgba(0,148,255,0.00) 0%, rgba(0,148,255,0.43) 51%, rgba(0,148,255,0.00) 99%);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.box{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 10px;
|
||||
padding-bottom: 0;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
</style>
|
||||
378
src/views/dashboard-pv/components/top-left/disposition.vue
Normal file
378
src/views/dashboard-pv/components/top-left/disposition.vue
Normal file
@ -0,0 +1,378 @@
|
||||
<template>
|
||||
<div class="top-left-box">
|
||||
<ItemBox :title="$t('dashboard.stationData')" :show-point-setting="true" @handleSetting="handleSetting">
|
||||
<div slot="header">
|
||||
<div class="header-right-box">
|
||||
<div class="header-title" :class="{'active':currentIndex === 0}" @click="changeType(0)">{{ $t('dashboard.dataOverView') }}</div>
|
||||
<div class="header-title" :class="{'active':currentIndex === 1}" @click="changeType(1)">{{ $t('dashboard.stationInfo') }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="currentIndex === 0" v-loading="loading" class="box">
|
||||
<StationData
|
||||
:table-data=" stationId !== 1069 ? [ ...overflowData,...dynamicData] : [ ...dynamicData]"
|
||||
/>
|
||||
</div>
|
||||
<div v-else v-loading="loading" class="box">
|
||||
<StationData :table-data="totalData" />
|
||||
</div>
|
||||
</ItemBox>
|
||||
|
||||
<el-dialog :title="$t('dashboard.pzsjy')" :visible.sync="configVisible" width="30%" @close="closeConfig">
|
||||
<el-form ref="configForm" :model="configForm" :rules="rules" label-width="135px">
|
||||
<el-form-item :label="$t('dashboard.time')" prop="time">
|
||||
<el-date-picker v-model="configForm.time" style="width: 100%" type="date" :picker-options="pickerOptionsStart" value-format="yyyy-MM-dd" :placeholder="$t('remote.pleaseSelect')" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="$t('dashboard.generation') + '(kWh)'" prop="param1">
|
||||
<el-input-number v-model="configForm.param1" style="width: 100%" :max="9999999" :min="-9999999" :controls="false" :placeholder="$t('remote.pleaseInput')" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('dashboard.yhl') + '(L)'" prop="param2">
|
||||
<el-input-number v-model="configForm.param2" style="width: 100%" :max="9999999" :min="-9999999" :controls="false" :placeholder="$t('remote.pleaseInput')" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('dashboard.jsfs')" prop="countMethod">
|
||||
<el-select v-model="configForm.countMethod" style="width:100%" :placeholder="$t('remote.pleaseSelect')">
|
||||
<el-option v-for="item in countMethod" :key="item.id" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
</el-form>
|
||||
|
||||
<span slot="footer">
|
||||
<el-button @click="closeConfig">{{ $t('dashboard.cancel') }}</el-button>
|
||||
<el-button type="primary" :loading="sureLoading" @click="sureConfig">{{ $t('dashboard.sure') }}</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ToDegrees } from '@/utils/index'
|
||||
import { GetPcsStationData, DynamicConfigPoint, SetDataConfig } from '@/api/home-page/index'
|
||||
import { GetRAPcsTotalData } from '@/api/homePage-integrated/index'
|
||||
import dayImg from '../../../../assets/station-data/run-day.png'
|
||||
import capImg from '../../../../assets/station-data/Installed-capacity.png'
|
||||
import disImg from '../../../../assets/station-data/total-discharge.png'
|
||||
import otherImg from '../../../../assets/station-data/station-data.png'
|
||||
export default {
|
||||
name: 'Index',
|
||||
props: {
|
||||
stationId: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
permissionId: {
|
||||
type: Number,
|
||||
default: 0
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
currentIndex: 0,
|
||||
dayImg,
|
||||
capImg,
|
||||
disImg,
|
||||
otherImg,
|
||||
overflowData: [{
|
||||
name: this.$t('dashboard.safeDays') + `(${this.$t('dashboard.day')})`,
|
||||
id: 'operationDays',
|
||||
picture: dayImg,
|
||||
value: 0
|
||||
}, {
|
||||
name: this.$t('dashboard.totalCapacity') + `(kWh)`,
|
||||
id: 'totalCapacity',
|
||||
picture: capImg,
|
||||
value: 0
|
||||
}, {
|
||||
name: this.$t('dashboard.systemConversionEfficiency') + `(%)`,
|
||||
id: 'systemEfficiency',
|
||||
picture: disImg,
|
||||
value: 0
|
||||
}],
|
||||
totalData: [{
|
||||
name: this.$t('dashboard.stationName'),
|
||||
id: 'name',
|
||||
picture: disImg,
|
||||
value: 0
|
||||
}, {
|
||||
name: this.$t('dashboard.stationType'),
|
||||
id: 'type',
|
||||
picture: disImg,
|
||||
value: 0
|
||||
}, {
|
||||
name: this.$t('dashboard.stationLocation'),
|
||||
id: 'address',
|
||||
picture: disImg,
|
||||
value: 0
|
||||
},
|
||||
{
|
||||
name: this.$t('dashboard.commTime'),
|
||||
id: 'createTime',
|
||||
picture: disImg,
|
||||
value: 0
|
||||
},
|
||||
{
|
||||
name: this.$t('dashboard.log'),
|
||||
id: 'longitude',
|
||||
picture: disImg,
|
||||
value: 0
|
||||
},
|
||||
{
|
||||
name: this.$t('dashboard.lat'),
|
||||
id: 'latitude',
|
||||
picture: disImg,
|
||||
value: 0
|
||||
}],
|
||||
stationType: [],
|
||||
loading: false,
|
||||
timeForm: {
|
||||
beforeTime: undefined,
|
||||
nowDayTime: undefined
|
||||
},
|
||||
dynamicData: [],
|
||||
configVisible: false,
|
||||
configForm: {
|
||||
countMethod: '4'
|
||||
},
|
||||
sureLoading: false,
|
||||
selectItem: {},
|
||||
rules: {
|
||||
time: [{ required: true, message: this.$t('remote.pleaseSelect'), trigger: 'change' }],
|
||||
param1: [{ required: true, message: this.$t('remote.pleaseInput'), trigger: 'blur' }],
|
||||
param2: [{ required: true, message: this.$t('remote.pleaseInput'), trigger: 'blur' }],
|
||||
countMethod: [{ required: true, message: this.$t('remote.pleaseSelect'), trigger: 'change' }]
|
||||
},
|
||||
pickerOptionsStart: {
|
||||
// 时间不能大于当前时间
|
||||
disabledDate: (time) => {
|
||||
return time.getTime() > Date.now()
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
stationTypeList() {
|
||||
return this.$store.getters.dicts['stationType'] || []
|
||||
},
|
||||
countMethod() {
|
||||
return this.$store.getters.dicts['commonCountSymbol'] || []
|
||||
},
|
||||
permission() {
|
||||
return this.$store.getters.permissions
|
||||
},
|
||||
language() {
|
||||
return this.$store.getters.language || undefined
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
watch: {
|
||||
language: {
|
||||
handler() {
|
||||
this.overflowData = [{
|
||||
name: this.$t('dashboard.safeDays') + `(${this.$t('dashboard.day')})`,
|
||||
id: 'operationDays',
|
||||
picture: dayImg,
|
||||
value: 0
|
||||
}, {
|
||||
name: this.$t('dashboard.totalCapacity') + `(kWh)`,
|
||||
id: 'totalCapacity',
|
||||
picture: capImg,
|
||||
value: 0
|
||||
}, {
|
||||
name: this.$t('dashboard.systemConversionEfficiency') + `(%)`,
|
||||
id: 'systemEfficiency',
|
||||
picture: disImg,
|
||||
value: 0
|
||||
}]
|
||||
this.totalData = [{
|
||||
name: this.$t('dashboard.stationName'),
|
||||
id: 'name',
|
||||
picture: disImg,
|
||||
value: 0
|
||||
}, {
|
||||
name: this.$t('dashboard.stationType'),
|
||||
id: 'type',
|
||||
picture: disImg,
|
||||
value: 0
|
||||
}, {
|
||||
name: this.$t('dashboard.stationLocation'),
|
||||
id: 'address',
|
||||
picture: disImg,
|
||||
value: 0
|
||||
},
|
||||
{
|
||||
name: this.$t('dashboard.commTime'),
|
||||
id: 'createTime',
|
||||
picture: disImg,
|
||||
value: 0
|
||||
},
|
||||
{
|
||||
name: this.$t('dashboard.log'),
|
||||
id: 'longitude',
|
||||
picture: disImg,
|
||||
value: 0
|
||||
},
|
||||
{
|
||||
name: this.$t('dashboard.lat'),
|
||||
id: 'latitude',
|
||||
picture: disImg,
|
||||
value: 0
|
||||
}]
|
||||
},
|
||||
deep: true
|
||||
}
|
||||
},
|
||||
mounted() { },
|
||||
methods: {
|
||||
configData(item) {
|
||||
if (item.isConfig && this.permission.includes('business:DataConfig:configData')) {
|
||||
this.selectItem = item
|
||||
this.configVisible = true
|
||||
this.$nextTick(() => {
|
||||
this.$refs.configForm.clearValidate()
|
||||
})
|
||||
}
|
||||
},
|
||||
sureConfig() {
|
||||
this.$refs.configForm.validate(async(valid) => {
|
||||
if (valid) {
|
||||
this.sureLoading = true
|
||||
try {
|
||||
await SetDataConfig({
|
||||
...this.configForm,
|
||||
stationId: this.selectItem.stationId,
|
||||
srcId: this.selectItem.srcId,
|
||||
deviceType: this.selectItem.deviceType,
|
||||
col: this.selectItem.col
|
||||
})
|
||||
this.$message.success(this.$t('dashboard.saveSuccess'))
|
||||
this.getData()
|
||||
this.closeConfig()
|
||||
} finally {
|
||||
this.sureLoading = false
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
closeConfig() {
|
||||
this.configForm = {
|
||||
countMethod: '4'
|
||||
}
|
||||
this.configVisible = false
|
||||
},
|
||||
handleSetting() {
|
||||
this.$emit('handleSetting')
|
||||
},
|
||||
getStationTypeName(item) {
|
||||
const typeIndex = this.stationTypeList.findIndex(t => Number(t.value) === Number(item))
|
||||
return this.stationTypeList[typeIndex].label
|
||||
},
|
||||
changeType(val) {
|
||||
this.currentIndex = val
|
||||
},
|
||||
getData() {
|
||||
this.GetPcsStationData()
|
||||
this.GetPcsTotalData()
|
||||
},
|
||||
async GetPcsStationData() {
|
||||
this.loading = true
|
||||
const params = {
|
||||
stationId: this.stationId
|
||||
}
|
||||
try {
|
||||
const { data } = await GetPcsStationData(params)
|
||||
this.totalData.forEach((item) => {
|
||||
item.value = data[item.id]
|
||||
if (item.id === 'type') {
|
||||
item.value = this.getStationTypeName(item.value)
|
||||
}
|
||||
if (item.id === 'longitude') {
|
||||
item.value = ToDegrees(item.value, 1)
|
||||
}
|
||||
if (item.id === 'latitude') {
|
||||
item.value = ToDegrees(item.value, 2)
|
||||
}
|
||||
})
|
||||
} catch (error) {
|
||||
// console.log(error);
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
|
||||
async GetPcsTotalData() {
|
||||
this.loading = true
|
||||
const params = {
|
||||
stationId: this.stationId,
|
||||
pageLocation: 'stationData',
|
||||
permissionId: this.permissionId
|
||||
}
|
||||
try {
|
||||
const { data } = await GetRAPcsTotalData(params)
|
||||
const res = await DynamicConfigPoint(params)
|
||||
this.overflowData.forEach((item) => {
|
||||
if (data[item.id]) {
|
||||
item.value = data[item.id]
|
||||
}
|
||||
if (item.id === 'systemEfficiency') {
|
||||
item.value = (item.value * 100).toFixed(2)
|
||||
}
|
||||
})
|
||||
this.dynamicData = res.data
|
||||
this.dynamicData.forEach((item) => {
|
||||
item.picture = otherImg
|
||||
})
|
||||
} catch (error) {
|
||||
// console.log(error);
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
::v-deep .item-con {
|
||||
overflow: auto;
|
||||
}
|
||||
.top-left-box {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
.header-right-box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.header-title {
|
||||
white-space: nowrap;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
letter-spacing: 0em;
|
||||
color: rgba(206, 235, 255, 0.5);
|
||||
padding: 0 10px;
|
||||
cursor: pointer;
|
||||
font-family: Source Han Sans CN;
|
||||
|
||||
&.active {
|
||||
color: #ffffff;
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
rgba(0, 148, 255, 0) 0%,
|
||||
rgba(0, 148, 255, 0.43) 51%,
|
||||
rgba(0, 148, 255, 0) 99%
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.box {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 10px;
|
||||
padding-bottom: 0;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
</style>
|
||||
498
src/views/dashboard-pv/components/top-left/standard-215.vue
Normal file
498
src/views/dashboard-pv/components/top-left/standard-215.vue
Normal file
@ -0,0 +1,498 @@
|
||||
<template>
|
||||
<div class="top-left-box">
|
||||
<ItemBox :title="$t('dashboard.stationData')">
|
||||
<div slot="header">
|
||||
<div class="header-right-box">
|
||||
<div class="header-title" :class="{ 'active': currentIndex === 0 }" @click="changeType(0)">{{ $t('dashboard.dataOverView') }}</div>
|
||||
<div class="header-title" :class="{ 'active': currentIndex === 1 }" @click="changeType(1)">{{ $t('dashboard.stationInfo') }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="currentIndex === 0" v-loading="loading" class="box">
|
||||
<StationData :table-data="overflowData" />
|
||||
</div>
|
||||
<div v-else v-loading="loading" class="box">
|
||||
<StationData :table-data="totalData" />
|
||||
</div>
|
||||
<el-dialog
|
||||
:append-to-body="true"
|
||||
title="日充放统计规则"
|
||||
:visible.sync="ruleShow"
|
||||
center
|
||||
width="30%"
|
||||
:close-on-click-modal="false"
|
||||
>
|
||||
<el-form :model="timeForm" label-width="120px">
|
||||
<el-form-item label="前一日" class="select-box">
|
||||
<el-select
|
||||
v-model="timeForm.beforeTime"
|
||||
style="width:100%"
|
||||
placeholder="请选择"
|
||||
@change="selectRuleTime"
|
||||
>
|
||||
<template slot="prefix">
|
||||
<span style="padding-left: 5px;">
|
||||
<i class="el-icon-time" />
|
||||
</span>
|
||||
</template>
|
||||
<el-option
|
||||
v-for="item in timeList"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="今日">
|
||||
<el-time-picker
|
||||
v-model="timeForm.nowDayTime"
|
||||
style="width:100%"
|
||||
:clearable="false"
|
||||
readonly
|
||||
placeholder="请选择时间"
|
||||
value-format="HH:mm:ss"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="cancelRule">取 消</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
:loading="timeSubmitLoading"
|
||||
@click="sureRule"
|
||||
>确 定</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</ItemBox>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { GetPcsStationData, addElecMeterConfig,
|
||||
updateElecMeterConfig } from '@/api/home-page/index'
|
||||
import { GetRAPcsTotalData } from '@/api/homePage-integrated/index'
|
||||
import { ToDegrees } from '@/utils/index'
|
||||
import disImg from '../../../../assets/station-data/total-discharge.png'
|
||||
export default {
|
||||
name: 'Index',
|
||||
props: {
|
||||
stationId: {
|
||||
type: Number,
|
||||
default: 0
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
currentIndex: 0,
|
||||
disImg,
|
||||
totalData: [{
|
||||
name: this.$t('dashboard.stationName'),
|
||||
id: 'name',
|
||||
picture: disImg,
|
||||
value: 0
|
||||
}, {
|
||||
name: this.$t('dashboard.stationType'),
|
||||
id: 'type',
|
||||
picture: disImg,
|
||||
value: 0
|
||||
}, {
|
||||
name: this.$t('dashboard.stationLocation'),
|
||||
id: 'address',
|
||||
picture: disImg,
|
||||
value: 0
|
||||
},
|
||||
{
|
||||
name: this.$t('dashboard.commTime'),
|
||||
id: 'createTime',
|
||||
picture: disImg,
|
||||
value: 0
|
||||
},
|
||||
{
|
||||
name: this.$t('dashboard.log'),
|
||||
id: 'longitude',
|
||||
picture: disImg,
|
||||
value: 0
|
||||
},
|
||||
{
|
||||
name: this.$t('dashboard.lat'),
|
||||
id: 'latitude',
|
||||
picture: disImg,
|
||||
value: 0
|
||||
}],
|
||||
overflowData: [{
|
||||
name: this.$t('dashboard.currentPower'),
|
||||
id: 'currentPower',
|
||||
picture: disImg,
|
||||
value: 0,
|
||||
unit: 'kW'
|
||||
}, {
|
||||
name: this.$t('dashboard.todayElectricityGeneration'),
|
||||
id: 'todayElecGeneration',
|
||||
picture: disImg,
|
||||
value: 0,
|
||||
unit: 'kWh'
|
||||
}, {
|
||||
name: this.$t('dashboard.totalPowerGeneration'),
|
||||
id: 'totalPowerGeneration',
|
||||
picture: disImg,
|
||||
value: 0,
|
||||
unit: 'kWh'
|
||||
},
|
||||
{
|
||||
name: this.$t('dashboard.totalRevenue'),
|
||||
id: 'totalRevenue',
|
||||
picture: disImg,
|
||||
value: 0,
|
||||
unit: 'kWh',
|
||||
click: true
|
||||
}, {
|
||||
name: this.$t('dashboard.ratedPowerofInverter'),
|
||||
id: 'ratedPowerofInverter',
|
||||
picture: disImg,
|
||||
value: 0,
|
||||
unit: 'kW'
|
||||
}],
|
||||
stationType: [],
|
||||
loading: false,
|
||||
ruleShow: false,
|
||||
timeForm: {
|
||||
beforeTime: undefined,
|
||||
nowDayTime: undefined
|
||||
},
|
||||
timeSubmitLoading: false,
|
||||
timeOperate: 1, // 1 新增 2 编辑
|
||||
timeList: []
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
stationTypeList() {
|
||||
return this.$store.getters.dicts['stationType'] || []
|
||||
},
|
||||
language() {
|
||||
return this.$store.getters.language || undefined
|
||||
}
|
||||
|
||||
},
|
||||
watch: {
|
||||
dailyTime: {
|
||||
handler(val) {
|
||||
if (val) {
|
||||
this.timeForm = val
|
||||
this.timeOperate = val.timeOperate
|
||||
this.GetPcsTotalData()
|
||||
}
|
||||
},
|
||||
deep: true,
|
||||
immediate: true
|
||||
},
|
||||
language: {
|
||||
handler() {
|
||||
this.totalData = [{
|
||||
name: this.$t('dashboard.stationName'),
|
||||
id: 'name',
|
||||
picture: disImg,
|
||||
value: 0
|
||||
}, {
|
||||
name: this.$t('dashboard.stationType'),
|
||||
id: 'type',
|
||||
picture: disImg,
|
||||
value: 0
|
||||
}, {
|
||||
name: this.$t('dashboard.stationLocation'),
|
||||
id: 'address',
|
||||
picture: disImg,
|
||||
value: 0
|
||||
},
|
||||
{
|
||||
name: this.$t('dashboard.commTime'),
|
||||
id: 'createTime',
|
||||
picture: disImg,
|
||||
value: 0
|
||||
},
|
||||
{
|
||||
name: this.$t('dashboard.log'),
|
||||
id: 'longitude',
|
||||
picture: disImg,
|
||||
value: 0
|
||||
},
|
||||
{
|
||||
name: this.$t('dashboard.lat'),
|
||||
id: 'latitude',
|
||||
picture: disImg,
|
||||
value: 0
|
||||
}]
|
||||
this.overflowData = [{
|
||||
name: this.$t('dashboard.safeDays'),
|
||||
id: 'operationDays',
|
||||
picture: disImg,
|
||||
value: 0,
|
||||
unit: this.$t('dashboard.day')
|
||||
}, {
|
||||
name: this.$t('dashboard.totalCapacity'),
|
||||
id: 'totalCapacity',
|
||||
picture: disImg,
|
||||
value: 0,
|
||||
unit: 'kWh'
|
||||
}, {
|
||||
name: this.$t('dashboard.systemConversionEfficiency'),
|
||||
id: 'systemEfficiency',
|
||||
picture: disImg,
|
||||
value: 0,
|
||||
unit: '%'
|
||||
}, {
|
||||
name: this.$t('dashboard.currentPower'),
|
||||
id: 'currentPower',
|
||||
picture: disImg,
|
||||
value: 0,
|
||||
unit: 'kW'
|
||||
}, {
|
||||
name: this.$t('dashboard.totalCharge'),
|
||||
id: 'totalChargeElec',
|
||||
picture: disImg,
|
||||
value: 0,
|
||||
unit: 'kWh'
|
||||
}, {
|
||||
name: this.stationId === 753 ? this.$t('dashboard.capacityIncrease') : this.$t('dashboard.totalDischarge'),
|
||||
id: 'totalDischargeElec',
|
||||
picture: disImg,
|
||||
value: 0,
|
||||
unit: 'kWh'
|
||||
},
|
||||
{
|
||||
name: this.$t('dashboard.dailyCharge'),
|
||||
id: 'dailyChargeElec',
|
||||
picture: disImg,
|
||||
value: 0,
|
||||
unit: 'kWh',
|
||||
click: true
|
||||
}, {
|
||||
name: this.stationId === 753 ? this.$t('dashboard.DailycapacityIncrease') : this.$t('dashboard.dailyDischarge'),
|
||||
id: 'dailyDischargeElec',
|
||||
picture: disImg,
|
||||
value: 0,
|
||||
unit: 'kWh'
|
||||
}]
|
||||
},
|
||||
deep: true
|
||||
}
|
||||
},
|
||||
created() {
|
||||
// console.log(this.stationTypeList)
|
||||
this.getTimeList()
|
||||
},
|
||||
mounted() { },
|
||||
methods: {
|
||||
getStationTypeName(item) {
|
||||
if (item && item !== '') {
|
||||
const typeIndex = this.stationTypeList.findIndex(t => Number(t.value) === Number(item))
|
||||
return this.stationTypeList[typeIndex].label
|
||||
}
|
||||
},
|
||||
changeType(val) {
|
||||
this.currentIndex = val
|
||||
},
|
||||
getData() {
|
||||
this.GetPcsStationData()
|
||||
this.GetPcsTotalData()
|
||||
},
|
||||
async GetPcsStationData() {
|
||||
this.loading = true
|
||||
const params = {
|
||||
stationId: this.stationId
|
||||
}
|
||||
try {
|
||||
const { data } = await GetPcsStationData(params)
|
||||
this.totalData.forEach((item) => {
|
||||
item.value = data[item.id]
|
||||
if (item.id === 'type') {
|
||||
item.value = this.getStationTypeName(item.value)
|
||||
}
|
||||
if (item.id === 'longitude') {
|
||||
item.value = ToDegrees(item.value, 1)
|
||||
}
|
||||
if (item.id === 'latitude') {
|
||||
item.value = ToDegrees(item.value, 2)
|
||||
}
|
||||
})
|
||||
} catch (error) {
|
||||
// console.log(error);
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
|
||||
async GetPcsTotalData() {
|
||||
this.loading = true
|
||||
const params = {
|
||||
stationId: this.stationId
|
||||
}
|
||||
try {
|
||||
const { data } = await GetRAPcsTotalData(params)
|
||||
this.overflowData.forEach((item) => {
|
||||
if (data[item.id]) {
|
||||
item.value = data[item.id]
|
||||
}
|
||||
if (item.id === 'systemEfficiency') {
|
||||
item.value = (item.value * 100).toFixed(2)
|
||||
}
|
||||
if (item.id === 'totalCapacity' && item.value >= 1E4) {
|
||||
item.unit = 'MWh'
|
||||
item.value = (Number(item.value) / 1E3).toFixed(2) + ''
|
||||
}
|
||||
if (item.id === 'totalChargeElec' && item.value >= 1E4) {
|
||||
item.unit = 'MWh'
|
||||
item.value = (Number(item.value) / 1E3).toFixed(2) + ''
|
||||
}
|
||||
if (item.id === 'totalDischargeElec' && item.value >= 1E4) {
|
||||
item.unit = 'MWh'
|
||||
item.value = (Number(item.value) / 1E3).toFixed(2) + ''
|
||||
}
|
||||
if (item.id === 'dailyDischargeElec' && item.value >= 1E4) {
|
||||
item.unit = 'MWh'
|
||||
item.value = (Number(item.value) / 1E3).toFixed(2) + ''
|
||||
}
|
||||
if (item.id === 'dailyChargeElec' && item.value >= 1E4) {
|
||||
item.unit = 'MWh'
|
||||
item.value = (Number(item.value) / 1E3).toFixed(2) + ''
|
||||
}
|
||||
if (item.id === 'currentPower' && item.value >= 1E4) {
|
||||
item.unit = 'MW'
|
||||
item.value = (Number(item.value) / 1E3).toFixed(2) + ''
|
||||
}
|
||||
})
|
||||
} catch (error) {
|
||||
// console.log(error);
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
getTimeList() {
|
||||
for (let i = 0; i < 24; i++) {
|
||||
this.timeList.push({
|
||||
label: `${i < 10 ? '0' + i : i}:00:00`,
|
||||
value: `${i < 10 ? '0' + i : i}:00:00`
|
||||
})
|
||||
}
|
||||
},
|
||||
setRule() {
|
||||
this.ruleShow = true
|
||||
},
|
||||
selectRuleTime(val) {
|
||||
this.timeForm.nowDayTime = this.getEightTime('2020-07-28 ' + val)
|
||||
},
|
||||
cancelRule() {
|
||||
this.ruleShow = false
|
||||
},
|
||||
sureRule() {
|
||||
if (this.timeOperate === 1) {
|
||||
// 新增
|
||||
this.timeSubmitLoading = true
|
||||
const param = {
|
||||
stationId: this.stationId,
|
||||
beginTime: this.timeForm.beforeTime,
|
||||
endTime: this.timeForm.nowDayTime
|
||||
}
|
||||
addElecMeterConfig(param)
|
||||
.then((res) => {
|
||||
this.$message.success('新增成功')
|
||||
this.ruleShow = false
|
||||
this.$emit('updateTime')
|
||||
})
|
||||
.finally(() => {
|
||||
this.timeSubmitLoading = false
|
||||
})
|
||||
} else {
|
||||
// 编辑
|
||||
this.timeSubmitLoading = true
|
||||
const param = {
|
||||
stationId: this.stationId,
|
||||
beginTime: this.timeForm.beforeTime,
|
||||
endTime: this.timeForm.nowDayTime,
|
||||
id: this.timeForm.id
|
||||
}
|
||||
updateElecMeterConfig(param)
|
||||
.then((res) => {
|
||||
this.$message.success('更新成功')
|
||||
this.ruleShow = false
|
||||
this.$emit('updateTime')
|
||||
})
|
||||
.finally(() => {
|
||||
this.timeSubmitLoading = false
|
||||
})
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 指定时间的多少小时或多少分钟之后的时间
|
||||
* @param {*} str 2020-07-28 15:00:00
|
||||
*/
|
||||
getEightTime(str) {
|
||||
const t = new Date(str).getTime() + 24 * 60 * 60 * 1000 - 1 // 24小时 * 60分钟 * 60秒 * 1000
|
||||
const d = new Date(t)
|
||||
let theMonth = d.getMonth() + 1
|
||||
let theDate = d.getDate()
|
||||
let theHours = d.getHours()
|
||||
let theMinutes = d.getMinutes()
|
||||
let theSecond = d.getSeconds()
|
||||
if (theMonth < 10) {
|
||||
theMonth = '0' + theMonth
|
||||
}
|
||||
if (theDate < 10) {
|
||||
theDate = '0' + theDate
|
||||
}
|
||||
if (theHours < 10) {
|
||||
theHours = '0' + theHours
|
||||
}
|
||||
if (theMinutes < 10) {
|
||||
theMinutes = '0' + theMinutes
|
||||
}
|
||||
if (theSecond < 10) {
|
||||
theSecond = '0' + theSecond
|
||||
}
|
||||
// let date = d.getFullYear() + '-' + theMonth + '-' + theDate
|
||||
const time = theHours + ':' + theMinutes + ':' + theSecond
|
||||
// let Spare = date + ' ' + time
|
||||
// console.log(date)
|
||||
// console.log(time)
|
||||
// console.log(Spare)
|
||||
return time
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
::v-deep .item-con{
|
||||
overflow:auto;
|
||||
}
|
||||
.top-left-box{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
.header-right-box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.header-title {
|
||||
white-space: nowrap;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
letter-spacing: 0em;
|
||||
color: rgba(206, 235, 255, 0.5);
|
||||
padding: 0 10px;
|
||||
cursor: pointer;
|
||||
font-family: Source Han Sans CN;
|
||||
|
||||
&.active{
|
||||
color: #ffffff;
|
||||
background: linear-gradient(90deg, rgba(0,148,255,0.00) 0%, rgba(0,148,255,0.43) 51%, rgba(0,148,255,0.00) 99%);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.box{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 10px;
|
||||
padding-bottom: 0;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
</style>
|
||||
540
src/views/dashboard-pv/components/top-left/zzhb.vue
Normal file
540
src/views/dashboard-pv/components/top-left/zzhb.vue
Normal file
@ -0,0 +1,540 @@
|
||||
<template>
|
||||
<div class="top-left-box">
|
||||
<ItemBox :title="$t('dashboard.stationData')">
|
||||
<div slot="header">
|
||||
<div class="header-right-box">
|
||||
<div class="header-title" :class="{'active':currentIndex === 0}" @click="changeType(0)">{{ $t('dashboard.dataOverView') }}</div>
|
||||
<div class="header-title" :class="{'active':currentIndex === 1}" @click="changeType(1)">{{ $t('dashboard.stationInfo') }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="currentIndex === 0" v-loading="loading" class="box">
|
||||
<StationData :table-data="overflowData" />
|
||||
</div>
|
||||
<div v-else v-loading="loading" class="box">
|
||||
<StationData :table-data="totalData" />
|
||||
</div>
|
||||
<el-dialog
|
||||
:append-to-body="true"
|
||||
title="日充放统计规则"
|
||||
:visible.sync="ruleShow"
|
||||
center
|
||||
width="30%"
|
||||
:close-on-click-modal="false"
|
||||
>
|
||||
<el-form :model="timeForm" label-width="120px">
|
||||
<el-form-item label="前一日" class="select-box">
|
||||
<el-select
|
||||
v-model="timeForm.beforeTime"
|
||||
style="width:100%"
|
||||
placeholder="请选择"
|
||||
@change="selectRuleTime"
|
||||
>
|
||||
<template slot="prefix">
|
||||
<span style="padding-left: 5px;">
|
||||
<i class="el-icon-time" />
|
||||
</span>
|
||||
</template>
|
||||
<el-option
|
||||
v-for="item in timeList"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="今日">
|
||||
<el-time-picker
|
||||
v-model="timeForm.nowDayTime"
|
||||
style="width:100%"
|
||||
:clearable="false"
|
||||
readonly
|
||||
placeholder="请选择时间"
|
||||
value-format="HH:mm:ss"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="cancelRule">取 消</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
:loading="timeSubmitLoading"
|
||||
@click="sureRule"
|
||||
>确 定</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</ItemBox>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { GetPcsStationData, addElecMeterConfig,
|
||||
updateElecMeterConfig } from '@/api/home-page/index'
|
||||
import { GetRAPcsTotalData, GetZZHBday } from '@/api/homePage-integrated/index'
|
||||
import { ToDegrees } from '@/utils/index'
|
||||
import disImg from '../../../../assets/station-data/total-discharge.png'
|
||||
export default {
|
||||
name: 'Index',
|
||||
props: {
|
||||
stationId: {
|
||||
type: Number,
|
||||
default: 0
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
disImg,
|
||||
currentIndex: 0,
|
||||
totalData: [{
|
||||
name: this.$t('dashboard.stationName'),
|
||||
id: 'name',
|
||||
picture: disImg,
|
||||
value: 0
|
||||
}, {
|
||||
name: this.$t('dashboard.stationType'),
|
||||
id: 'type',
|
||||
picture: disImg,
|
||||
value: 0
|
||||
}, {
|
||||
name: this.$t('dashboard.stationLocation'),
|
||||
id: 'address',
|
||||
picture: disImg,
|
||||
value: 0
|
||||
},
|
||||
{
|
||||
name: this.$t('dashboard.commTime'),
|
||||
id: 'createTime',
|
||||
picture: disImg,
|
||||
value: 0
|
||||
},
|
||||
{
|
||||
name: this.$t('dashboard.log'),
|
||||
id: 'longitude',
|
||||
picture: disImg,
|
||||
value: 0
|
||||
},
|
||||
{
|
||||
name: this.$t('dashboard.lat'),
|
||||
id: 'latitude',
|
||||
picture: disImg,
|
||||
value: 0
|
||||
}],
|
||||
overflowData: [{
|
||||
name: this.$t('dashboard.safeDays'),
|
||||
id: 'operationDays',
|
||||
picture: disImg,
|
||||
value: 0,
|
||||
unit: this.$t('dashboard.day')
|
||||
}, {
|
||||
name: this.$t('dashboard.totalCapacity'),
|
||||
id: 'totalCapacity',
|
||||
picture: disImg,
|
||||
value: 0,
|
||||
unit: 'kWh'
|
||||
}, {
|
||||
name: this.$t('dashboard.systemConversionEfficiency'),
|
||||
id: 'systemEfficiency',
|
||||
picture: disImg,
|
||||
value: 0,
|
||||
unit: '%'
|
||||
}, {
|
||||
name: this.$t('dashboard.currentPower'),
|
||||
id: 'currentPower',
|
||||
picture: disImg,
|
||||
value: 0,
|
||||
unit: 'kW'
|
||||
}, {
|
||||
name: this.$t('dashboard.totalCharge'),
|
||||
id: 'totalChargeElec',
|
||||
picture: disImg,
|
||||
value: 0,
|
||||
unit: 'kWh'
|
||||
}, {
|
||||
name: this.$t('dashboard.totalDischarge'),
|
||||
id: 'totalDischargeElec',
|
||||
picture: disImg,
|
||||
value: 0,
|
||||
unit: 'kWh'
|
||||
}, {
|
||||
name: this.$t('dashboard.dailyCharge'),
|
||||
id: 'dailyChargeElec',
|
||||
picture: disImg,
|
||||
value: 0,
|
||||
unit: 'kWh'
|
||||
}, {
|
||||
name: this.$t('dashboard.dailyDischarge'),
|
||||
id: 'dailyDischargeElec',
|
||||
picture: disImg,
|
||||
value: 0,
|
||||
unit: 'kWh'
|
||||
}, {
|
||||
name: this.$t('dashboard.dayPhotovoltaic'),
|
||||
id: 'cumulativePowerGeneration',
|
||||
picture: disImg,
|
||||
value: 0,
|
||||
unit: 'kWh'
|
||||
}],
|
||||
|
||||
stationType: [],
|
||||
loading: false,
|
||||
ruleShow: false,
|
||||
timeForm: {
|
||||
beforeTime: undefined,
|
||||
nowDayTime: undefined
|
||||
},
|
||||
timeSubmitLoading: false,
|
||||
timeOperate: 1, // 1 新增 2 编辑
|
||||
timeList: []
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
stationTypeList() {
|
||||
return this.$store.getters.dicts['stationType'] || []
|
||||
},
|
||||
language() {
|
||||
return this.$store.getters.language || undefined
|
||||
}
|
||||
|
||||
},
|
||||
watch: {
|
||||
dailyTime: {
|
||||
handler(val) {
|
||||
if (val) {
|
||||
this.timeForm = val
|
||||
this.timeOperate = val.timeOperate
|
||||
this.GetPcsTotalData()
|
||||
}
|
||||
},
|
||||
deep: true,
|
||||
immediate: true
|
||||
},
|
||||
language: {
|
||||
handler() {
|
||||
this.totalData = [{
|
||||
name: this.$t('dashboard.stationName'),
|
||||
id: 'name',
|
||||
picture: disImg,
|
||||
value: 0
|
||||
}, {
|
||||
name: this.$t('dashboard.stationType'),
|
||||
id: 'type',
|
||||
picture: disImg,
|
||||
value: 0
|
||||
}, {
|
||||
name: this.$t('dashboard.stationLocation'),
|
||||
id: 'address',
|
||||
picture: disImg,
|
||||
value: 0
|
||||
},
|
||||
{
|
||||
name: this.$t('dashboard.commTime'),
|
||||
id: 'createTime',
|
||||
picture: disImg,
|
||||
value: 0
|
||||
},
|
||||
{
|
||||
name: this.$t('dashboard.log'),
|
||||
id: 'longitude',
|
||||
picture: disImg,
|
||||
value: 0
|
||||
},
|
||||
{
|
||||
name: this.$t('dashboard.lat'),
|
||||
id: 'latitude',
|
||||
picture: disImg,
|
||||
value: 0
|
||||
}]
|
||||
this.overflowData = [{
|
||||
name: this.$t('dashboard.safeDays'),
|
||||
id: 'operationDays',
|
||||
picture: disImg,
|
||||
value: 0,
|
||||
unit: this.$t('dashboard.day')
|
||||
}, {
|
||||
name: this.$t('dashboard.totalCapacity'),
|
||||
id: 'totalCapacity',
|
||||
picture: disImg,
|
||||
value: 0,
|
||||
unit: 'kWh'
|
||||
}, {
|
||||
name: this.$t('dashboard.systemConversionEfficiency'),
|
||||
id: 'systemEfficiency',
|
||||
picture: disImg,
|
||||
value: 0,
|
||||
unit: '%'
|
||||
}, {
|
||||
name: this.$t('dashboard.currentPower'),
|
||||
id: 'currentPower',
|
||||
picture: disImg,
|
||||
value: 0,
|
||||
unit: 'kW'
|
||||
}, {
|
||||
name: this.$t('dashboard.totalCharge'),
|
||||
id: 'totalChargeElec',
|
||||
picture: disImg,
|
||||
value: 0,
|
||||
unit: 'kWh'
|
||||
}, {
|
||||
name: this.$t('dashboard.totalDischarge'),
|
||||
id: 'totalDischargeElec',
|
||||
picture: disImg,
|
||||
value: 0,
|
||||
unit: 'kWh'
|
||||
}, {
|
||||
name: this.$t('dashboard.dailyCharge'),
|
||||
id: 'dailyChargeElec',
|
||||
picture: disImg,
|
||||
value: 0,
|
||||
unit: 'kWh'
|
||||
}, {
|
||||
name: this.$t('dashboard.dailyDischarge'),
|
||||
id: 'dailyDischargeElec',
|
||||
picture: disImg,
|
||||
value: 0,
|
||||
unit: 'kWh'
|
||||
}, {
|
||||
name: this.$t('dashboard.dayPhotovoltaic'),
|
||||
id: 'cumulativePowerGeneration',
|
||||
picture: disImg,
|
||||
value: 0,
|
||||
unit: 'kWh'
|
||||
}]
|
||||
},
|
||||
deep: true
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getTimeList()
|
||||
},
|
||||
mounted() { },
|
||||
methods: {
|
||||
getStationTypeName(item) {
|
||||
const typeIndex = this.stationTypeList.findIndex(t => Number(t.value) === Number(item))
|
||||
return this.stationTypeList[typeIndex].label
|
||||
},
|
||||
changeType(val) {
|
||||
this.currentIndex = val
|
||||
},
|
||||
getData() {
|
||||
this.GetPcsStationData()
|
||||
this.GetPcsTotalData()
|
||||
this.GetZZHBdayInverter()
|
||||
},
|
||||
async GetZZHBdayInverter() {
|
||||
this.loading = true
|
||||
const params = {
|
||||
stationId: this.stationId
|
||||
}
|
||||
try {
|
||||
const { data } = await GetZZHBday(params)
|
||||
this.totalData = Object.assign(this.totalData, data)
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
async GetPcsStationData() {
|
||||
this.loading = true
|
||||
const params = {
|
||||
stationId: this.stationId
|
||||
}
|
||||
try {
|
||||
const { data } = await GetPcsStationData(params)
|
||||
this.totalData.forEach((item) => {
|
||||
item.value = data[item.id]
|
||||
if (item.id === 'type') {
|
||||
item.value = this.getStationTypeName(item.value)
|
||||
}
|
||||
if (item.id === 'longitude') {
|
||||
item.value = ToDegrees(item.value, 1)
|
||||
}
|
||||
if (item.id === 'latitude') {
|
||||
item.value = ToDegrees(item.value, 2)
|
||||
}
|
||||
})
|
||||
} catch (error) {
|
||||
// console.log(error);
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
|
||||
async GetPcsTotalData() {
|
||||
this.loading = true
|
||||
const params = {
|
||||
stationId: this.stationId
|
||||
}
|
||||
try {
|
||||
const { data } = await GetRAPcsTotalData(params)
|
||||
// this.totalData = Object.assign(this.totalData, data)
|
||||
this.overflowData.forEach((item) => {
|
||||
if (data[item.id]) {
|
||||
item.value = data[item.id]
|
||||
}
|
||||
if (item.id === 'systemEfficiency') {
|
||||
item.value = (item.value * 100).toFixed(2)
|
||||
}
|
||||
if (item.id === 'totalCapacity' && item.value >= 1E4) {
|
||||
item.unit = 'MWh'
|
||||
item.value = (Number(item.value) / 1E3).toFixed(2) + ''
|
||||
}
|
||||
if (item.id === 'totalChargeElec' && item.value >= 1E4) {
|
||||
item.unit = 'MWh'
|
||||
item.value = (Number(item.value) / 1E3).toFixed(2) + ''
|
||||
}
|
||||
if (item.id === 'totalDischargeElec' && item.value >= 1E4) {
|
||||
item.unit = 'MWh'
|
||||
item.value = (Number(item.value) / 1E3).toFixed(2) + ''
|
||||
}
|
||||
if (item.id === 'dailyDischargeElec' && item.value >= 1E4) {
|
||||
item.unit = 'MWh'
|
||||
item.value = (Number(item.value) / 1E3).toFixed(2) + ''
|
||||
}
|
||||
if (item.id === 'dailyChargeElec' && item.value >= 1E4) {
|
||||
item.unit = 'MWh'
|
||||
item.value = (Number(item.value) / 1E3).toFixed(2) + ''
|
||||
}
|
||||
if (item.id === 'currentPower' && item.value >= 1E4) {
|
||||
item.unit = 'MW'
|
||||
item.value = (Number(item.value) / 1E3).toFixed(2) + ''
|
||||
}
|
||||
if (item.id === 'cumulativePowerGeneration' && item.value >= 1E4) {
|
||||
item.unit = 'MW'
|
||||
item.value = (Number(item.value) / 1E3).toFixed(2) + ''
|
||||
}
|
||||
})
|
||||
} catch (error) {
|
||||
// console.log(error);
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
getTimeList() {
|
||||
for (let i = 0; i < 24; i++) {
|
||||
this.timeList.push({
|
||||
label: `${i < 10 ? '0' + i : i}:00:00`,
|
||||
value: `${i < 10 ? '0' + i : i}:00:00`
|
||||
})
|
||||
}
|
||||
},
|
||||
setRule() {
|
||||
this.ruleShow = true
|
||||
},
|
||||
selectRuleTime(val) {
|
||||
this.timeForm.nowDayTime = this.getEightTime('2020-07-28 ' + val)
|
||||
},
|
||||
cancelRule() {
|
||||
this.ruleShow = false
|
||||
},
|
||||
sureRule() {
|
||||
if (this.timeOperate === 1) {
|
||||
// 新增
|
||||
this.timeSubmitLoading = true
|
||||
const param = {
|
||||
stationId: this.stationId,
|
||||
beginTime: this.timeForm.beforeTime,
|
||||
endTime: this.timeForm.nowDayTime
|
||||
}
|
||||
addElecMeterConfig(param)
|
||||
.then((res) => {
|
||||
this.$message.success('新增成功')
|
||||
this.ruleShow = false
|
||||
this.$emit('updateTime')
|
||||
})
|
||||
.finally(() => {
|
||||
this.timeSubmitLoading = false
|
||||
})
|
||||
} else {
|
||||
// 编辑
|
||||
this.timeSubmitLoading = true
|
||||
const param = {
|
||||
stationId: this.stationId,
|
||||
beginTime: this.timeForm.beforeTime,
|
||||
endTime: this.timeForm.nowDayTime,
|
||||
id: this.timeForm.id
|
||||
}
|
||||
updateElecMeterConfig(param)
|
||||
.then((res) => {
|
||||
this.$message.success('更新成功')
|
||||
this.ruleShow = false
|
||||
this.$emit('updateTime')
|
||||
})
|
||||
.finally(() => {
|
||||
this.timeSubmitLoading = false
|
||||
})
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 指定时间的多少小时或多少分钟之后的时间
|
||||
* @param {*} str 2020-07-28 15:00:00
|
||||
*/
|
||||
getEightTime(str) {
|
||||
const t = new Date(str).getTime() + 24 * 60 * 60 * 1000 - 1 // 24小时 * 60分钟 * 60秒 * 1000
|
||||
const d = new Date(t)
|
||||
let theMonth = d.getMonth() + 1
|
||||
let theDate = d.getDate()
|
||||
let theHours = d.getHours()
|
||||
let theMinutes = d.getMinutes()
|
||||
let theSecond = d.getSeconds()
|
||||
if (theMonth < 10) {
|
||||
theMonth = '0' + theMonth
|
||||
}
|
||||
if (theDate < 10) {
|
||||
theDate = '0' + theDate
|
||||
}
|
||||
if (theHours < 10) {
|
||||
theHours = '0' + theHours
|
||||
}
|
||||
if (theMinutes < 10) {
|
||||
theMinutes = '0' + theMinutes
|
||||
}
|
||||
if (theSecond < 10) {
|
||||
theSecond = '0' + theSecond
|
||||
}
|
||||
// let date = d.getFullYear() + '-' + theMonth + '-' + theDate
|
||||
const time = theHours + ':' + theMinutes + ':' + theSecond
|
||||
// let Spare = date + ' ' + time
|
||||
// console.log(date)
|
||||
// console.log(time)
|
||||
// console.log(Spare)
|
||||
return time
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
::v-deep .item-con{
|
||||
overflow:auto;
|
||||
}
|
||||
.top-left-box{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
.header-right-box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.header-title {
|
||||
white-space: nowrap;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
letter-spacing: 0em;
|
||||
color: rgba(206, 235, 255, 0.5);
|
||||
padding: 0 10px;
|
||||
cursor: pointer;
|
||||
font-family: Source Han Sans CN;
|
||||
|
||||
&.active{
|
||||
color: #ffffff;
|
||||
background: linear-gradient(90deg, rgba(0,148,255,0.00) 0%, rgba(0,148,255,0.43) 51%, rgba(0,148,255,0.00) 99%);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.box{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 10px;
|
||||
padding-bottom: 0;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
</style>
|
||||
571
src/views/dashboard-pv/components/top-right/control.vue
Normal file
571
src/views/dashboard-pv/components/top-right/control.vue
Normal file
@ -0,0 +1,571 @@
|
||||
<template>
|
||||
<div>
|
||||
<ItemBox :title="$t('dashboard.oneControl')">
|
||||
|
||||
<div v-loading="loading" class="con-box">
|
||||
<!-- <div class="mode">
|
||||
<span class="mode-title">工作模式:</span>
|
||||
<template v-if="!currentWorkInfo.noWork">
|
||||
<span class="mode-title">{{ currentWorkInfo.label }}</span>
|
||||
<el-button style="margin-left: 10px" circle type="primary" icon="el-icon-edit" @click="sureMode" />
|
||||
</template>
|
||||
<span v-else class="noWork"> 请配置关联点</span>
|
||||
</div> -->
|
||||
<div class="control-box">
|
||||
<div v-for="(item, index) in controlList" :key="index" class="control-item-box" @click="handleOpen(item)">
|
||||
|
||||
<div class="control-item">
|
||||
<el-tooltip :content="item.controlName" placement="bottom" effect="dark">
|
||||
<div>{{ item.controlName }}</div>
|
||||
</el-tooltip>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ItemBox>
|
||||
<el-dialog
|
||||
:append-to-body="true"
|
||||
:show-close="false"
|
||||
center
|
||||
:close-on-click-modal="false"
|
||||
:title="controlInfo.controlName"
|
||||
:visible="controlShow"
|
||||
width="40%"
|
||||
>
|
||||
<div class="control-box">
|
||||
<el-steps :space="140" direction="vertical" :active="activeControlStatus">
|
||||
<el-step v-for="(item, index) in controlInfo.list" :key="index" :title="item.colName">
|
||||
<div slot="description">
|
||||
<div class="description-box">
|
||||
<div class="description-item">
|
||||
<span class="label">{{ $t('dashboard.col') }}:</span>
|
||||
<span class="value">{{ item.col }}</span>
|
||||
</div>
|
||||
<div class="description-item">
|
||||
<span class="label">{{ $t('dashboard.state') }}:</span>
|
||||
<span
|
||||
v-if="item.statusLabel === `${$t('dashboard.orderTimeOut')}` ||
|
||||
item.statusLabel === `${$t('dashboard.orderFail')}`
|
||||
"
|
||||
class="value"
|
||||
style="color: red"
|
||||
>{{ item.statusLabel }}</span>
|
||||
<span v-else class="value" style="color: #0bbd87">{{
|
||||
item.statusLabel
|
||||
}}</span>
|
||||
</div>
|
||||
<div class="description-item">
|
||||
<span class="label">{{ $t('dashboard.orderValue') }}:</span>
|
||||
<span class="value">{{ item.setValue }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-step>
|
||||
</el-steps>
|
||||
</div>
|
||||
<span slot="footer">
|
||||
<el-button type="primary" @click="closeControl">{{ $t('dashboard.close') }}</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
<el-dialog
|
||||
:append-to-body="true"
|
||||
:close-on-click-modal="false"
|
||||
:title="$t('dashboard.workingMode')"
|
||||
:visible="dispatchVisiable"
|
||||
width="40%"
|
||||
center
|
||||
@close="closeModel"
|
||||
>
|
||||
<div>
|
||||
<el-form ref="workInfo" :model="workInfo" :rules="workRules" label-width="210px" label-position="right">
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="24">
|
||||
<el-form-item :label="$t('dashboard.remoteControl')">
|
||||
<el-select v-model="workInfo.value" style="width: 100%" :placeholder="$t('dashboard.selectMode')" @change="changeWorkInfo">
|
||||
<el-option v-for="item in modeOptions" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col v-if="workInfo.value === 1" :span="24">
|
||||
<el-form-item :label="$t('dashboard.remoteControlActive') + (kW)" prop="p">
|
||||
<el-input-number
|
||||
v-model="workInfo.p"
|
||||
style="width: 100%"
|
||||
:controls="false"
|
||||
:placeholder="$t('dashboard.inputValue')"
|
||||
class="input-with-select"
|
||||
>
|
||||
|
||||
<template slot="append">kW</template>
|
||||
</el-input-number>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col v-if="workInfo.value === 1" :span="24">
|
||||
<el-form-item :label="$t('dashboard.remoteControlreActive') + (kVar)" prop="q">
|
||||
<el-input-number
|
||||
v-model="workInfo.q"
|
||||
style="width: 100%"
|
||||
:controls="false"
|
||||
:placeholder="$t('dashboard.inputValue')"
|
||||
class="input-with-select"
|
||||
>
|
||||
|
||||
<template slot="append">kVar</template>
|
||||
</el-input-number>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</div>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="closeModel">{{ $t('dashboard.back') }}</el-button>
|
||||
<el-button type="primary" :loading="issueLoading" @click="confirmIssue">{{ $t('dashboard.issused') }}</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
<el-dialog
|
||||
:append-to-body="true"
|
||||
:title=" $t('dashboard.tips')"
|
||||
:visible.sync="messageShow"
|
||||
width="20%"
|
||||
center
|
||||
@close="messageShow = false"
|
||||
>
|
||||
<span style="color: #fff;">{{ $t('dashboard.issusedMsg') }}</span>
|
||||
|
||||
<div class="dialog-footer">
|
||||
<el-button plain @click="messageShow = false"> {{ $t('dashboard.cancel') }} </el-button>
|
||||
<el-button v-preventReClick type="primary" @click="handleToOrder">
|
||||
{{ $t('dashboard.sure') }}
|
||||
</el-button>
|
||||
</div>
|
||||
|
||||
<!-- <span slot="footer">
|
||||
<el-button @click="messageShow = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleToOrder">确定</el-button>
|
||||
</span> -->
|
||||
</el-dialog>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
SendPlanControl,
|
||||
GetprogressBar
|
||||
} from '@/api/strategic-management/strategy.js'
|
||||
import { GetControlList } from '@/api/strategic-management/chronological-control'
|
||||
import {
|
||||
OneKeyControl, GetTabModel
|
||||
} from '@/api/strategic-management/policyOverview'
|
||||
export default {
|
||||
name: 'Index',
|
||||
props: {
|
||||
stationId: {
|
||||
type: Number,
|
||||
default: 0
|
||||
}
|
||||
},
|
||||
data() {
|
||||
const valueRule = (rule, value, callback) => {
|
||||
if (value === null || value === '' || value === undefined) {
|
||||
callback(new Error(this.$t('dashboard.inputValue')))
|
||||
} else {
|
||||
if (value > 65535 || value < -65535) {
|
||||
callback(new Error(this.$t('dashboard.dataRange') - '65535~65535'))
|
||||
} else {
|
||||
return callback()
|
||||
}
|
||||
}
|
||||
}
|
||||
return {
|
||||
workRules: {
|
||||
p: [{ validator: valueRule, required: true, trigger: 'blur' }],
|
||||
q: [{ validator: valueRule, required: true, trigger: 'blur' }]
|
||||
},
|
||||
currentWorkInfo: {
|
||||
id: undefined,
|
||||
value: '',
|
||||
p: undefined,
|
||||
q: undefined,
|
||||
noWork: false
|
||||
},
|
||||
workInfo: {
|
||||
id: undefined,
|
||||
value: '',
|
||||
p: undefined,
|
||||
q: undefined,
|
||||
noWork: false
|
||||
},
|
||||
controlList: [],
|
||||
loading: false,
|
||||
controlInfo: {
|
||||
controlName: '',
|
||||
list: []
|
||||
},
|
||||
modeOptions: [
|
||||
{ label: `${this.$t('dashboard.psvf')}`, value: 0 },
|
||||
{ label: `${this.$t('dashboard.reakSchedu')}`, value: 1 }
|
||||
],
|
||||
controlTimer: null,
|
||||
activeControlStatus: 0,
|
||||
activeIndex: 0, // 当前下发的index
|
||||
controlShow: false,
|
||||
dispatchVisiable: false,
|
||||
issueLoading: false,
|
||||
messageShow: false,
|
||||
orderItem: {}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
||||
},
|
||||
|
||||
created() {
|
||||
|
||||
},
|
||||
mounted() {
|
||||
|
||||
},
|
||||
methods: {
|
||||
|
||||
changeWorkInfo(val) {
|
||||
this.workInfo = {
|
||||
value: val,
|
||||
p: undefined,
|
||||
q: undefined
|
||||
}
|
||||
},
|
||||
|
||||
async confirmIssue() {
|
||||
this.$refs.workInfo.validate((valid) => {
|
||||
if (valid) {
|
||||
try {
|
||||
this.$confirm(
|
||||
this.$t('dashboard.sureDispatch'),
|
||||
this.$t('dashboard.tips'),
|
||||
{
|
||||
confirmButtonText: this.$t('dashboard.sure'),
|
||||
cancelButtonText: this.$t('dashboard.cancel'),
|
||||
type: 'warning',
|
||||
showClose: false,
|
||||
center: true
|
||||
}
|
||||
)
|
||||
.then(async() => {
|
||||
this.issueLoading = true
|
||||
const res = await SendPlanControl({
|
||||
...this.workInfo,
|
||||
stationId: this.stationId
|
||||
})
|
||||
this.getprogressBar(res.data)
|
||||
})
|
||||
.catch(() => { })
|
||||
} catch (err) {
|
||||
this.issueLoading = false
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
async getprogressBar(val) {
|
||||
this.issueLoading = true
|
||||
const timer = setInterval(async() => {
|
||||
const { data } = await GetprogressBar(val)
|
||||
if (data.isEnd === '1' || data.isEnd === 1) {
|
||||
this.$message.success(data.msg)
|
||||
clearInterval(timer)
|
||||
this.issueLoading = false
|
||||
this.getTabModel()
|
||||
}
|
||||
if (data.isEnd === '2' || data.isEnd === 2) {
|
||||
this.$message.warning(data.msg)
|
||||
clearInterval(timer)
|
||||
this.issueLoading = false
|
||||
}
|
||||
}, 1000)
|
||||
},
|
||||
async getTabModel() {
|
||||
const res = await GetTabModel({ stationId: this.stationId })
|
||||
if (
|
||||
res.data.planControlModel !== undefined &&
|
||||
res.data.planControlModel !== null
|
||||
) {
|
||||
this.currentWorkInfo.value = res.data.planControlModel
|
||||
this.currentWorkInfo.p = res.data?.planControlP
|
||||
this.currentWorkInfo.q = res.data?.planControlQ
|
||||
this.currentWorkInfo.label = this.modeOptions.find(
|
||||
(item) => item.value === res.data?.planControlModel
|
||||
)?.label
|
||||
this.currentWorkInfo.noWork = false
|
||||
this.workInfo.value = res.data.planControlModel
|
||||
this.workInfo.p = res.data?.planControlP
|
||||
this.workInfo.q = res.data?.planControlQ
|
||||
this.workInfo.label = this.modeOptions.find(
|
||||
(item) => item.value === res.data?.planControlModel
|
||||
)?.label
|
||||
this.workInfo.noWork = false
|
||||
} else {
|
||||
this.workInfo.noWork = true
|
||||
this.currentWorkInfo.noWork = true
|
||||
}
|
||||
},
|
||||
closeControl() {
|
||||
this.controlShow = false
|
||||
if (this.controlTimer) {
|
||||
clearInterval(this.controlTimer)
|
||||
}
|
||||
},
|
||||
sureMode() {
|
||||
this.dispatchVisiable = true
|
||||
},
|
||||
async getControlList() {
|
||||
const res = await GetControlList({
|
||||
stationId: this.stationId
|
||||
})
|
||||
this.controlList = res.data
|
||||
},
|
||||
getData() {
|
||||
this.loading = true
|
||||
Promise.all([this.getTabModel(), this.getControlList()]).finally(() => {
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
closeModel() {
|
||||
this.dispatchVisiable = false
|
||||
this.workInfo = JSON.parse(JSON.stringify(this.currentWorkInfo))
|
||||
},
|
||||
handleOpen(item) {
|
||||
this.orderItem = item
|
||||
this.messageShow = true
|
||||
},
|
||||
handleToOrder() {
|
||||
this.controlInfo = this.orderItem
|
||||
this.controlInfo.list = this.orderItem.list.map((i) => {
|
||||
i.statusLabel = '未下发'
|
||||
return i
|
||||
})
|
||||
this.activeIndex = 0
|
||||
this.activeControlStatus = 0
|
||||
this.toIssueByOrder()
|
||||
this.controlShow = true
|
||||
},
|
||||
toIssueByOrder() {
|
||||
this.messageShow = false
|
||||
if (this.activeIndex <= this.controlInfo.list.length - 1) {
|
||||
this.getGroupIssueProgress()
|
||||
this.controlTimer = setInterval(() => {
|
||||
this.getGroupIssueProgress()
|
||||
}, 1000)
|
||||
} else {
|
||||
clearInterval(this.controlTimer)
|
||||
}
|
||||
},
|
||||
async getGroupIssueProgress() {
|
||||
try {
|
||||
const res = await OneKeyControl([
|
||||
{
|
||||
...this.controlInfo.list[this.activeIndex],
|
||||
isLast:
|
||||
this.activeIndex === this.controlInfo.list.length - 1 ? 1 : 0
|
||||
}
|
||||
])
|
||||
if (
|
||||
res.data.isEnd === '1' ||
|
||||
res.data.isEnd === '2' ||
|
||||
res.data.isEnd === '3' ||
|
||||
res.data.isEnd === 1 ||
|
||||
res.data.isEnd === 2 ||
|
||||
res.data.isEnd === 3
|
||||
) {
|
||||
if (res.data.isEnd === '1' || res.data.isEnd === 1) {
|
||||
this.$set(this.controlInfo.list, this.activeIndex, {
|
||||
...this.controlInfo.list[this.activeIndex],
|
||||
statusLabel: this.$t('dashboard.orderSuccess')
|
||||
})
|
||||
this.activeIndex += 1
|
||||
this.activeControlStatus += 1
|
||||
if (this.controlTimer) {
|
||||
clearInterval(this.controlTimer)
|
||||
}
|
||||
this.toIssueByOrder()
|
||||
this.$message.success(`${this.$t('dashboard.orderSuccess')}`)
|
||||
}
|
||||
if (res.data.isEnd === '2' || res.data.isEnd === 2) {
|
||||
this.$set(this.controlInfo.list, this.activeIndex, {
|
||||
...this.controlInfo.list[this.activeIndex],
|
||||
statusLabel: this.$t('dashboard.orderFail')
|
||||
})
|
||||
if (this.controlTimer) {
|
||||
clearInterval(this.controlTimer)
|
||||
}
|
||||
}
|
||||
if (res.data.isEnd === '3' || res.data.isEnd === 3) {
|
||||
this.$set(this.controlInfo.list, this.activeIndex, {
|
||||
...this.controlInfo.list[this.activeIndex],
|
||||
statusLabel: this.$t('dashboard.orderTimeOut')
|
||||
})
|
||||
if (this.controlTimer) {
|
||||
clearInterval(this.controlTimer)
|
||||
}
|
||||
}
|
||||
} else if (res.data.isEnd === '0' || res.data.isEnd === 0) {
|
||||
this.$set(this.controlInfo.list, this.activeIndex, {
|
||||
...this.controlInfo.list[this.activeIndex],
|
||||
statusLabel: this.$t('dashboard.orderLoading')
|
||||
})
|
||||
} else if (res.data.isEnd === '') {
|
||||
if (this.controlTimer) {
|
||||
clearInterval(this.controlTimer)
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
if (this.controlTimer) {
|
||||
clearInterval(this.controlTimer)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.con-box {
|
||||
width: 100%;
|
||||
height: 169px;
|
||||
padding: 10px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
}
|
||||
|
||||
.mode {
|
||||
width: 100%;
|
||||
|
||||
.mode-title {
|
||||
padding-right: 10px;
|
||||
color: #fff;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
.control-box {
|
||||
flex: 1;
|
||||
width: 100%;
|
||||
overflow-y: auto;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-evenly;
|
||||
|
||||
.control-item-box {
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
.control-item {
|
||||
width: 190px;
|
||||
height: 40px;
|
||||
background-image: url("../../../../assets/images/controlbg.png");
|
||||
background-size: 100% 100%;
|
||||
background-repeat: no-repeat;
|
||||
box-sizing: border-box;
|
||||
font-size: 16px;
|
||||
color: #ffffff;
|
||||
text-align: center;
|
||||
line-height: 40px;
|
||||
|
||||
word-break: break-all;
|
||||
padding-left: 10px;
|
||||
cursor: pointer;
|
||||
|
||||
div {
|
||||
width: 150px;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.noWork {
|
||||
font-size: 14px;
|
||||
color: #bfc6ce;
|
||||
|
||||
}
|
||||
|
||||
.description-box {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.description-item {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
color: #fff !important;
|
||||
font-size: 14px;
|
||||
|
||||
.label {
|
||||
width: 60px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep .el-step__title.is-process {
|
||||
color: #ffffff !important;
|
||||
}
|
||||
|
||||
.case-progress {
|
||||
::v-deep .el-progress-bar__outer {
|
||||
background-color: #023b61;
|
||||
}
|
||||
}
|
||||
|
||||
// 默认当前激活步骤显示的是黑色,这里修改显示为蓝色
|
||||
::v-deep .el-step__head.is-process {
|
||||
color: #ffffff !important; // 圆圈中数字
|
||||
border-color: #0bbd87 !important; // 圆圈
|
||||
|
||||
.el-step__icon {
|
||||
background-color: #0bbd87 !important;
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep .el-step__title.is-process {
|
||||
color: #0bbd87 !important; // 圆圈下的标题文本
|
||||
}
|
||||
|
||||
::v-deep .el-step__head.is-finish {
|
||||
color: #ffffff !important; // 圆圈中数字
|
||||
border-color: #409eff !important; // 圆圈
|
||||
|
||||
.el-step__icon {
|
||||
background-color: #409eff !important;
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep .el-step__title.is-finish {
|
||||
color: #409eff !important; // 圆圈下的标题文本
|
||||
}
|
||||
|
||||
::v-deep .el-dialog {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin: 0 !important;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
max-height: calc(100% - 30px);
|
||||
max-width: calc(100% - 30px);
|
||||
}
|
||||
|
||||
::v-deep .el-dialog .el-dialog__body {
|
||||
flex: 1;
|
||||
overflow: auto;
|
||||
}
|
||||
.dialog-footer{
|
||||
text-align:center;
|
||||
margin-top:20px;
|
||||
}
|
||||
</style>
|
||||
331
src/views/dashboard-pv/components/top-right/index.vue
Normal file
331
src/views/dashboard-pv/components/top-right/index.vue
Normal file
@ -0,0 +1,331 @@
|
||||
<template>
|
||||
<div class="top-right-box">
|
||||
<ItemBox :title="$t('dashboard.realtimeAlarm')">
|
||||
<div v-loading="loading" class="box">
|
||||
<div class="alarm-list">
|
||||
<template v-if="listData.length">
|
||||
<div v-for="(item, index) in listData" :key="index" :class="index % 2 ? 'item1' : 'item'">
|
||||
<div class="alarm-title">
|
||||
<div class="dev">
|
||||
<span class="title">{{ $t('dashboard.device') }}:</span>
|
||||
<span class="value">{{ item.deviceName }}</span>
|
||||
</div>
|
||||
<div class="time-box">
|
||||
<div class="time">{{ item.createTime }}</div>
|
||||
</div>
|
||||
<div class="leve">
|
||||
<span :class="item.name === '异常' ? 'leve-value' : 'leve-value2'">{{ item.name }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bottom">
|
||||
<span class="content">{{ item.description }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<div v-else style="height:100%;text-align:center;font-size:14px;color:#999;display: flex;justify-content: center;align-items: center;">
|
||||
{{ $t('screen.runSuccess' ) }}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</ItemBox>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { GetAlarmList } from '@/api/alarm/realtime'
|
||||
export default {
|
||||
name: 'Index',
|
||||
props: {
|
||||
stationId: {
|
||||
type: Number,
|
||||
default: 0
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
config: {
|
||||
header: ['等级', '内容', '时间'],
|
||||
data: [],
|
||||
columnWidth: [80],
|
||||
align: ['center', 'center', 'center', 'center'],
|
||||
headerBGC: '#062b40',
|
||||
oddRowBGC: 'rgba(255, 255, 255, 0)',
|
||||
evenRowBGC: 'rgba(255, 255, 255, 0.05)'
|
||||
},
|
||||
pageflag: false,
|
||||
listData: [],
|
||||
loading: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
eventLevels() {
|
||||
return this.$store.getters.dicts['eventLevel'] || []
|
||||
},
|
||||
eventTypes() {
|
||||
return this.$store.getters.dicts['eventType'] || []
|
||||
}
|
||||
},
|
||||
watch: {},
|
||||
created() {
|
||||
// this.GetAlarmList()
|
||||
},
|
||||
mounted() {
|
||||
// this.getData()
|
||||
},
|
||||
methods: {
|
||||
oldsortData(data) {
|
||||
const result = data.sort(function(a, b) {
|
||||
return b.createTime - a.createTime
|
||||
})
|
||||
return result
|
||||
},
|
||||
async getData() {
|
||||
this.loading = true
|
||||
this.pageflag = false
|
||||
const params = {
|
||||
pageNum: 1,
|
||||
pageSize: 50,
|
||||
status: 0,
|
||||
stationIds: this.stationId ? [this.stationId] : [],
|
||||
deviceTypeList: [],
|
||||
description: '',
|
||||
eventLevels: ['1', '2', '3'],
|
||||
eventTypes: ['2', '3', '4', '5', '6']
|
||||
}
|
||||
this.config.data = []
|
||||
try {
|
||||
const res = await GetAlarmList(params)
|
||||
// const sortDataRes = this.oldsortData(res.data.list)
|
||||
const chartData = []
|
||||
res.data.list.forEach(item => {
|
||||
const eventLevel = this.getEventLevelsname(item.eventLevel)
|
||||
const lastIndex = item.timeStamp.lastIndexOf('.')
|
||||
const result = item.timeStamp.slice(0, lastIndex)
|
||||
item.timeStamp = result
|
||||
|
||||
const i = {
|
||||
name: eventLevel,
|
||||
deviceName: item.name,
|
||||
description: item.description,
|
||||
createTime: item.timeStamp
|
||||
}
|
||||
chartData.push(i)
|
||||
})
|
||||
// console.log(chartData)
|
||||
this.listData = chartData
|
||||
|
||||
this.pageflag = true
|
||||
} catch (error) {
|
||||
// console.log(error);
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
getEventLevelsname(item) {
|
||||
return (
|
||||
this.eventLevels.find(level => Number(level.value) === item).label || ''
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.top-right-box{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
.box {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 10px;
|
||||
padding-bottom: 0;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
font-family: Source Han Sans CN;
|
||||
|
||||
.top-box {
|
||||
width: 100%;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
}
|
||||
|
||||
.alarm-list {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 0 auto;
|
||||
overflow: auto;
|
||||
|
||||
.alarm-title {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
|
||||
.dev {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
|
||||
.title {
|
||||
display: inline-block;
|
||||
|
||||
font-family: Source Han Sans CN;
|
||||
font-size: 14px;
|
||||
font-weight: normal;
|
||||
text-align: center;
|
||||
letter-spacing: 0px;
|
||||
|
||||
color: rgba(206, 235, 255, 0.7);
|
||||
|
||||
}
|
||||
|
||||
.value {
|
||||
|
||||
font-family: Source Han Sans CN;
|
||||
font-size: 14px;
|
||||
font-weight: normal;
|
||||
letter-spacing: 0px;
|
||||
|
||||
color: rgba(206, 235, 255, 0.7);
|
||||
width: calc(100% - 45px);
|
||||
display: -webkit-box; //将盒子转换为弹性盒子
|
||||
-webkit-box-orient: vertical; //文本显示方式,默认水平
|
||||
-webkit-line-clamp: 1; //设置显示多少行
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.time {
|
||||
/* 12:33:17 */
|
||||
|
||||
opacity: 1;
|
||||
|
||||
font-family: Source Han Sans CN;
|
||||
font-size: 14px;
|
||||
font-weight: normal;
|
||||
letter-spacing: 0px;
|
||||
|
||||
color: #ffffff;
|
||||
|
||||
z-index: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.time-box {
|
||||
min-width: 117px;
|
||||
height: 100%;
|
||||
/* 设备:PCS */
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
margin-right: 5px;
|
||||
|
||||
.title {
|
||||
font-family: Source Han Sans CN;
|
||||
font-size: 14px;
|
||||
font-weight: normal;
|
||||
text-align: center;
|
||||
letter-spacing: 0px;
|
||||
flex-shrink: 0;
|
||||
|
||||
color: rgba(206, 235, 255, 0.7);
|
||||
}
|
||||
|
||||
.time {
|
||||
/* 12:33:17 */
|
||||
|
||||
opacity: 1;
|
||||
|
||||
font-family: Source Han Sans CN;
|
||||
font-size: 14px;
|
||||
font-weight: normal;
|
||||
letter-spacing: 0px;
|
||||
|
||||
color: rgba(206, 235, 255, 0.7);
|
||||
|
||||
z-index: 1;
|
||||
display: -webkit-box; //将盒子转换为弹性盒子
|
||||
-webkit-box-orient: vertical; //文本显示方式,默认水平
|
||||
-webkit-line-clamp: 1; //设置显示多少行
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
.leve {
|
||||
// width: 20%;
|
||||
margin-left: auto;
|
||||
|
||||
height: 100%;
|
||||
/* 异常 */
|
||||
text-align: center;
|
||||
opacity: 1;
|
||||
font-family: Source Han Sans CN;
|
||||
font-size: 14px;
|
||||
font-weight: normal;
|
||||
letter-spacing: 0em;
|
||||
color: #ffeeee;
|
||||
text-shadow: 0px 0px 5px 0px #ff0000, 0px 0px 5px 0px #ffb800;
|
||||
|
||||
.leve-value {
|
||||
display: inline-block;
|
||||
width: 40px;
|
||||
background: url(../../../../assets/images/alarm-error.png) no-repeat;
|
||||
background-size: 100% 100%;
|
||||
}
|
||||
|
||||
.leve-value2 {
|
||||
display: inline-block;
|
||||
width: 40px;
|
||||
background: url(../../../../assets/images/alarm-error-2.png) no-repeat;
|
||||
background-size: 100% 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bottom {
|
||||
width: 100%;
|
||||
margin-top: 10px;
|
||||
padding: 5px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background-image: url('../../../../assets/images/alarm-con-bg.png');
|
||||
background-size: 100% 100%;
|
||||
|
||||
.content {
|
||||
/* 这是内容这是内容这是内容这是内容这是内容这 */
|
||||
|
||||
opacity: 1;
|
||||
|
||||
font-family: Source Han Sans CN;
|
||||
font-size: 14px;
|
||||
font-weight: normal;
|
||||
letter-spacing: 0px;
|
||||
|
||||
color: rgba(255, 255, 255, 1);
|
||||
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
|
||||
.item {
|
||||
width: 100%;
|
||||
padding: 5px 10px;
|
||||
background-color: #0c3650;
|
||||
background-size: 100% 100%;
|
||||
margin-bottom: 10px;
|
||||
|
||||
}
|
||||
|
||||
.item1 {
|
||||
width: 100%;
|
||||
padding: 5px 10px;
|
||||
margin-bottom: 10px;
|
||||
background-color: transparent;
|
||||
background-size: 100% 100%;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
509
src/views/dashboard-pv/index.vue
Normal file
509
src/views/dashboard-pv/index.vue
Normal file
@ -0,0 +1,509 @@
|
||||
<template>
|
||||
<div class="home-container">
|
||||
<el-row class="top-box" :gutter="10">
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="6" :xl="6">
|
||||
<div class="component-wrapper">
|
||||
<component
|
||||
:is="topLeftComponent"
|
||||
ref="topLeft"
|
||||
:permission-id="permissionId"
|
||||
:station-id="stationId"
|
||||
:daily-time="timeForm"
|
||||
@handleSetting="handlePointSetting('stationData')"
|
||||
/>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col
|
||||
:xs="24"
|
||||
:sm="24"
|
||||
:md="24"
|
||||
:lg="11"
|
||||
:xl="11"
|
||||
class="hidden-md-only hidden-xs-only hidden-sm-only"
|
||||
>
|
||||
<div v-if="clientWidth >= 1200" class="tuopu-box">
|
||||
<component
|
||||
:is="topCenterComponent"
|
||||
ref="topCenter"
|
||||
:station-id="stationId"
|
||||
:station-type="stationType"
|
||||
@screenFull="screenFull"
|
||||
/>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="7" :xl="7">
|
||||
<div class="component-wrapper">
|
||||
<component
|
||||
:is="topRightComponent"
|
||||
ref="topRight"
|
||||
:station-id="stationId"
|
||||
/>
|
||||
<!-- <component
|
||||
:is="centerRightComponent"
|
||||
ref="centerRight"
|
||||
:station-id="stationId"
|
||||
:permission-id="permissionId"
|
||||
class="center-right"
|
||||
@handleSetting="handlePointSetting('airData')"
|
||||
/> -->
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col
|
||||
:xs="24"
|
||||
:sm="24"
|
||||
:md="24"
|
||||
:lg="11"
|
||||
:xl="11"
|
||||
class="hidden-xl-only hidden-lg-only"
|
||||
>
|
||||
<div v-if="clientWidth < 1200" class="tuopu-box">
|
||||
<component
|
||||
:is="topCenterComponent"
|
||||
ref="topCenter1"
|
||||
:station-id="stationId"
|
||||
:station-type="stationType"
|
||||
/>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row class="bottom-box" :gutter="10">
|
||||
<el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12">
|
||||
<div class="component-bottom">
|
||||
<!-- <div class="component-bottom" :style="{ height: bottomHeight }"> -->
|
||||
<component
|
||||
:is="bottomLeftComponent"
|
||||
ref="bottomLeft"
|
||||
:station-id="stationId"
|
||||
:daily-time="timeForm"
|
||||
@handleSetting="handlePointSetting('barLeftBottom')"
|
||||
/>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12">
|
||||
<div class="component-bottom">
|
||||
<!-- <div
|
||||
class="component-bottom"
|
||||
:style="{ height: bottomHeight }"
|
||||
@contextmenu.prevent="onContextmenu"
|
||||
> -->
|
||||
<component
|
||||
:is="bottomRightComponent"
|
||||
ref="bottomRight"
|
||||
:permission-id="permissionId"
|
||||
:station-id="stationId"
|
||||
@handleSetting="handleSetting('runChart')"
|
||||
/>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<!-- 配置曲线 -->
|
||||
<DispositionChartData :page-location="chartLocation" :disposition-show="show_dispostion" @getData="getDynamicData" @close="close" />
|
||||
<!-- 配置点 -->
|
||||
<DispositionPointData :page-location="pageLocation" :disposition-show="show_point_dispostion" @getData="getDynamicPointData" @close="closePoint" />
|
||||
<!-- 右键菜单 -->
|
||||
<!-- <rightMenu
|
||||
:class-index="0"
|
||||
:rightclick-info="rightclickInfo"
|
||||
@copy="copy"
|
||||
/> -->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import rightMenu from '@/components/RightMenu/index.vue'
|
||||
import commonTopLeft from './components/top-left/common.vue'
|
||||
import standard215TopLeft from './components/top-left/standard-215.vue'
|
||||
import zzhbTopLeft from './components/top-left/zzhb.vue'
|
||||
import commonMWhTopLeft from './components/top-left/common-mwh.vue'
|
||||
import dispositionTopLeft from './components/top-left/disposition.vue'
|
||||
|
||||
import leftBottom_215 from './components/bottom-left/standard-215.vue'
|
||||
|
||||
import topRight from './components/top-right/index.vue'
|
||||
import controlTopRight from './components/top-right/control.vue'
|
||||
|
||||
import pvCurve from './components/top-center/pv-operating-curve.vue'
|
||||
// import fourthTopCenter from './components/top-center/fourth.vue'
|
||||
|
||||
// import topCenter_215 from './components/top-center/standard-215.vue'
|
||||
// import triadTopCenter from './components/top-center/triad.vue'
|
||||
|
||||
// import secondTopCenter from './components/top-center/second.vue'
|
||||
|
||||
// import fifthTopCenter from './components/top-center/fifth.vue'
|
||||
// import sixthTopCenter from './components/top-center/sixth.vue'
|
||||
// import seventhTopCenter from './components/top-center/seventh.vue'
|
||||
// import eighthTopCenter from './components/top-center/eighth.vue'
|
||||
// import ninthTopCenter from './components/top-center/ninth.vue'
|
||||
|
||||
// import secondDispositionTopCenter from './components/top-center/second-disposition.vue'
|
||||
// import triadDispositionTopCenter from './components/top-center/triad-disposition.vue'
|
||||
// import fourthDispositionTopCenter from './components/top-center/fourth-disposition.vue'
|
||||
|
||||
// import tenthTopCenter from './components/top-center/ten.vue'
|
||||
|
||||
// import onceTopCenter from './components/top-center/once.vue'
|
||||
|
||||
import rightCenter_215 from './components/center-right/standard-215.vue'
|
||||
import commonRightCenter from './components/center-right/common.vue'
|
||||
import dispositionRightCenter from './components/center-right/disposition.vue'
|
||||
|
||||
import commonBottom from './components/bottom-right/common.vue'
|
||||
import bottom_215 from './components/bottom-right/standard-215.vue'
|
||||
|
||||
import dispositionBottomRight from './components/bottom-right/disposition.vue'
|
||||
import { getDashboard } from '@/api/station/maintain'
|
||||
import { queryElecMeterConfig } from '@/api/home-page/index'
|
||||
|
||||
// import pv1AndStorage_261 from './components/top-center/pv1storage261.vue'
|
||||
// import pv2AndStorage_261 from './components/top-center/pv2storage261.vue'
|
||||
|
||||
export default {
|
||||
name: 'Index',
|
||||
components: {
|
||||
commonMWhTopLeft,
|
||||
|
||||
zzhbTopLeft,
|
||||
leftBottom_215,
|
||||
commonRightCenter,
|
||||
commonTopLeft,
|
||||
standard215TopLeft,
|
||||
rightCenter_215,
|
||||
topRight,
|
||||
commonBottom,
|
||||
bottom_215,
|
||||
rightMenu,
|
||||
dispositionTopLeft,
|
||||
dispositionRightCenter,
|
||||
dispositionBottomRight,
|
||||
controlTopRight,
|
||||
pvCurve
|
||||
},
|
||||
props: {},
|
||||
data() {
|
||||
return {
|
||||
stationId: undefined,
|
||||
topLeftComponent: '',
|
||||
bottomLeftComponent: '',
|
||||
topCenterComponent: '',
|
||||
topRightComponent: '',
|
||||
centerRightComponent: '',
|
||||
bottomRightComponent: '',
|
||||
stationType: 0,
|
||||
chartKey: 0,
|
||||
bottomHeight: '230px',
|
||||
interval: null,
|
||||
timeForm: null,
|
||||
clientWidth: 1920,
|
||||
centerStatus: 1,
|
||||
cancalDebounce: undefined,
|
||||
rightclickInfo: {},
|
||||
show_dispostion: false,
|
||||
show_point_dispostion: false,
|
||||
pageLocation: null,
|
||||
chartLocation: 'runChart',
|
||||
permissionId: null
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
currentStation() {
|
||||
return this.$store.getters.currentStation || undefined
|
||||
},
|
||||
stationStatus() {
|
||||
return this.$store.getters.stationStatus || undefined
|
||||
},
|
||||
language() {
|
||||
return this.$store.getters.language || undefined
|
||||
}
|
||||
},
|
||||
|
||||
watch: {
|
||||
currentStation: {
|
||||
handler(val) {
|
||||
if (val && val.id) {
|
||||
const self = this
|
||||
if (self.interval) {
|
||||
clearInterval(self.interval)
|
||||
self.interval = null
|
||||
}
|
||||
this.stationId = val.id
|
||||
this.stationType = val.type
|
||||
this.$nextTick(() => {
|
||||
this.handleSite()
|
||||
|
||||
this.clientWidth = document.body.clientWidth
|
||||
this.centerStatus = this.clientWidth >= 1200 ? 1 : 0
|
||||
this.getCenterData()
|
||||
// this.getRangeTime()
|
||||
})
|
||||
this.init(this.stationId, this.permissionId)
|
||||
}
|
||||
},
|
||||
deep: true,
|
||||
immediate: true
|
||||
},
|
||||
language: {
|
||||
handler(val) {
|
||||
this.$refs.bottomLeft.getData()
|
||||
this.$refs.bottomRight.getData()
|
||||
},
|
||||
deep: true
|
||||
},
|
||||
permissionId: {
|
||||
handler(val) {
|
||||
if (val) {
|
||||
this.init(this.stationId, val)
|
||||
}
|
||||
},
|
||||
deep: true
|
||||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
const self = this
|
||||
const timer = setInterval(() => {
|
||||
if (self.$store.getters.menuList.length) {
|
||||
self.getPermissionId()
|
||||
clearInterval(timer)
|
||||
}
|
||||
}, 500)
|
||||
window.addEventListener('resize', this.handleResize)
|
||||
const getWindowInfo = () => {
|
||||
if (window.innerHeight > 1000) {
|
||||
this.bottomHeight = window.innerHeight - 620 + 'px'
|
||||
} else {
|
||||
this.bottomHeight = 230 + 'px'
|
||||
}
|
||||
}
|
||||
getWindowInfo()
|
||||
const debounce = (fn, delay) => {
|
||||
let timer
|
||||
return function() {
|
||||
if (timer) {
|
||||
clearTimeout(timer)
|
||||
}
|
||||
timer = setTimeout(() => {
|
||||
fn()
|
||||
}, delay)
|
||||
}
|
||||
}
|
||||
this.cancalDebounce = debounce(getWindowInfo, 100)
|
||||
|
||||
window.addEventListener('resize', this.cancalDebounce)
|
||||
},
|
||||
beforeDestroy() {
|
||||
clearInterval(this.interval)
|
||||
this.interval = null
|
||||
window.removeEventListener('resize', this.handleResize)
|
||||
window.removeEventListener('resize', this.cancalDebounce)
|
||||
},
|
||||
mounted() {
|
||||
|
||||
},
|
||||
methods: {
|
||||
getPermissionId() {
|
||||
this.permissionId = this.$store.getters.menuList.find(item => {
|
||||
return item.url === this.$route.path
|
||||
})?.id
|
||||
},
|
||||
init(stationId, permissionId) {
|
||||
if (stationId && permissionId) {
|
||||
setTimeout(() => {
|
||||
this.getAllData()
|
||||
}, 100)
|
||||
|
||||
if (this.stationId === 1069) {
|
||||
self.interval = setInterval(() => {
|
||||
this.getAllData()
|
||||
this.getCenterData()
|
||||
}, 10000)
|
||||
} else {
|
||||
self.interval = setInterval(() => {
|
||||
this.getAllData()
|
||||
this.getCenterData()
|
||||
}, 1000 * 60 * 2)
|
||||
}
|
||||
}
|
||||
},
|
||||
screenFull(val) {
|
||||
this.$nextTick(() => {
|
||||
setTimeout(() => {
|
||||
if (!val) {
|
||||
this.bottomHeight = window.innerHeight - 620 + 'px'
|
||||
} else {
|
||||
this.bottomHeight = window.innerHeight - 680 + 'px'
|
||||
}
|
||||
}, 200)
|
||||
})
|
||||
},
|
||||
getDynamicData() {
|
||||
this.$refs.bottomRight.getData()
|
||||
this.$refs.centerRight.getData()
|
||||
},
|
||||
getDynamicPointData() {
|
||||
this.$refs.bottomLeft.getData()
|
||||
this.$refs.topLeft.getData()
|
||||
this.$refs.centerRight.getData()
|
||||
},
|
||||
handleSetting(val) {
|
||||
this.chartLocation = val
|
||||
this.show_dispostion = true
|
||||
},
|
||||
handlePointSetting(val) {
|
||||
this.pageLocation = val
|
||||
this.show_point_dispostion = true
|
||||
},
|
||||
copy(params) {
|
||||
this.show_dispostion = true
|
||||
},
|
||||
close() {
|
||||
this.show_dispostion = false
|
||||
},
|
||||
closePoint() {
|
||||
this.show_point_dispostion = false
|
||||
},
|
||||
// 普通dom右键
|
||||
onContextmenu(e) {
|
||||
this.rightclickInfo = {
|
||||
position: {
|
||||
x: e.clientX,
|
||||
y: e.clientY
|
||||
},
|
||||
menulists: [
|
||||
{
|
||||
fnName: 'copy',
|
||||
params: '配置',
|
||||
icoName: 'el-icon-setting',
|
||||
btnName: '配置'
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
handleResize() {
|
||||
this.clientWidth = document.body.clientWidth
|
||||
this.getCenterData()
|
||||
},
|
||||
getCenterData() {
|
||||
if (this.clientWidth < 1200) {
|
||||
if (!this.centerStatus) {
|
||||
this.centerStatus = 1
|
||||
|
||||
setTimeout(() => {
|
||||
this.$refs.topCenter1?.getData()
|
||||
}, 800)
|
||||
}
|
||||
} else if (this.clientWidth >= 1200) {
|
||||
if (this.centerStatus) {
|
||||
this.centerStatus = 0
|
||||
|
||||
setTimeout(() => {
|
||||
this.$refs.topCenter?.getData()
|
||||
}, 800)
|
||||
}
|
||||
}
|
||||
},
|
||||
async handleSite() {
|
||||
const res = await getDashboard(this.stationId)
|
||||
this.topLeftComponent = res.data[0]?.topLeft
|
||||
? res.data[0].topLeft
|
||||
: 'standard215TopLeft'
|
||||
this.bottomLeftComponent = res.data[0]?.leftBottom
|
||||
? res.data[0].leftBottom
|
||||
: 'leftBottom_215'
|
||||
this.topCenterComponent = 'pvCurve'
|
||||
this.centerRightComponent = res.data[0]?.rightCenter
|
||||
? res.data[0].rightCenter
|
||||
: 'rightCenter_215'
|
||||
this.bottomRightComponent = res.data[0]?.bottom
|
||||
? res.data[0].bottom
|
||||
: 'bottom_215'
|
||||
this.topRightComponent = res.data[0]?.rightTop
|
||||
? res.data[0].rightTop
|
||||
: 'topRight'
|
||||
},
|
||||
updateTime() {
|
||||
this.getRangeTime()
|
||||
},
|
||||
getRangeTime() {
|
||||
const param = {
|
||||
stationId: this.stationId
|
||||
}
|
||||
queryElecMeterConfig(param).then((res) => {
|
||||
if (res.data.beginTime) {
|
||||
this.timeForm = {
|
||||
beforeTime: res.data.beginTime,
|
||||
nowDayTime: res.data.endTime,
|
||||
id: res.data.id,
|
||||
stationId: res.data.stationId,
|
||||
timeOperate: 2
|
||||
}
|
||||
} else {
|
||||
this.timeForm = {
|
||||
beforeTime: '22:00:00',
|
||||
nowDayTime: '21:59:59',
|
||||
timeOperate: 1
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
getAllData() {
|
||||
setTimeout(() => {
|
||||
this.getPermissionId()
|
||||
this.$refs.topLeft?.getData()
|
||||
this.$refs.bottomLeft?.getData()
|
||||
this.$refs.bottomRight?.getData()
|
||||
this.$refs.topCenter?.getData()
|
||||
this.$refs.centerRight?.getData()
|
||||
this.$refs.topRight?.getData()
|
||||
}, 800)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.home-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
.top-box{
|
||||
height: 60%;
|
||||
.el-col{
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
.bottom-box{
|
||||
height: 40%;
|
||||
.el-col{
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
.component-wrapper {
|
||||
width: 100%;
|
||||
height: calc(100% - 10px);
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.tuopu-box {
|
||||
width: 100%;
|
||||
height: calc(100% - 10px);
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.component-bottom {
|
||||
width: 100%;
|
||||
height: calc(100% - 10px);
|
||||
// min-height: 235px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
||||
::v-deep .icon-font{
|
||||
cursor: auto!important;
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -530,12 +530,10 @@
|
||||
<text x="730" y="460" fill="#FFB800" font-size="14">{{ pcsData_9.length > 1 ? pcsData_9[1].value : '' }}</text>
|
||||
<text x="730" y="480" fill="#FFB800" font-size="14">{{ pcsData_9.length > 2 ? pcsData_9[2].value : '' }}</text>
|
||||
<text x="730" y="500" fill="#FFB800" font-size="14">{{ pcsData_9.length > 3 ? pcsData_9[3].value : '' }}</text>
|
||||
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
<DispositionPointData :disposition-show="show_point_dispostion" :page-location="pageLocation" @close="closePoint" @getData="getDynamicPointData" />
|
||||
|
||||
</ItemBox>
|
||||
</template>
|
||||
|
||||
|
||||
@ -54,30 +54,6 @@
|
||||
stroke="#0094FF"
|
||||
stroke-dasharray="3 3"
|
||||
/>
|
||||
<!-- <rect
|
||||
x="154"
|
||||
y="78"
|
||||
width="231"
|
||||
height="4"
|
||||
:style="{ fill: 'rgba(100,100,100,0)', stroke: 'transparent',cursor: 'pointer' }"
|
||||
@click="lookDeviceDetail('line-top-left')"
|
||||
/> -->
|
||||
<!-- <polyline
|
||||
points="385,80 600,80"
|
||||
fill="none"
|
||||
class="g-rect-path"
|
||||
stroke="#0094FF"
|
||||
stroke-dasharray="3 3"
|
||||
/> -->
|
||||
<!-- <rect
|
||||
x="385"
|
||||
y="78"
|
||||
width="215"
|
||||
height="4"
|
||||
:style="{ fill: 'rgba(100,100,100,0)', stroke: 'transparent',cursor: 'pointer' }"
|
||||
@click="lookDeviceDetail('line-top-right')"
|
||||
/> -->
|
||||
|
||||
<!-- center -->
|
||||
<polyline
|
||||
points="385,50 385,417"
|
||||
@ -414,15 +390,12 @@
|
||||
popper-class="svg-tooltip"
|
||||
>
|
||||
<span style="font-size: 14px;font-family: sans-serif;color: #ffffff;max-width: 120px;white-space: nowrap;overflow: hidden;text-overflow: ellipsis">
|
||||
{{ truncateText(item.name, 100) }}
|
||||
{{ truncateText(item.name, 90) }}
|
||||
</span>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</foreignObject>
|
||||
<!-- <text x="200" :y="450 + ( 20 * index)" fill="#ffffff" font-size="14">
|
||||
{{ item.name }}
|
||||
</text> -->
|
||||
<text :x="calculateValueX(item.name, 185)" :y="450 + ( 20 * index)" fill="#FFB800" font-size="14">
|
||||
<text :x="calculateValueX(item.name, 205)" :y="450 + ( 20 * index)" fill="#FFB800" font-size="14">
|
||||
{{ item.value }}
|
||||
</text>
|
||||
</g>
|
||||
@ -445,7 +418,7 @@
|
||||
popper-class="svg-tooltip"
|
||||
>
|
||||
<span style="font-size: 14px;font-family: sans-serif;color: #ffffff;max-width: 120px;white-space: nowrap;overflow: hidden;text-overflow: ellipsis">
|
||||
{{ truncateText(item.name, 100) }}
|
||||
{{ truncateText(item.name, 90) }}
|
||||
</span>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
@ -453,7 +426,7 @@
|
||||
<!-- <text x="410" :y="450 + ( 20 * index)" fill="#ffffff" font-size="14">
|
||||
{{ item.name }}
|
||||
</text> -->
|
||||
<text :x="calculateValueX(item.name, 395)" :y="450 + ( 20 * index)" fill="#FFB800" font-size="14">
|
||||
<text :x="calculateValueX(item.name, 410)" :y="450 + ( 20 * index)" fill="#FFB800" font-size="14">
|
||||
{{ item.value }}
|
||||
</text>
|
||||
</g>
|
||||
@ -570,20 +543,35 @@ export default {
|
||||
},
|
||||
mounted() {},
|
||||
methods: {
|
||||
truncateText(text, maxWidth) {
|
||||
if (!text) return ''
|
||||
const width = this.measureTextWidth(text)
|
||||
if (width <= maxWidth) return text
|
||||
|
||||
let truncated = text
|
||||
while (this.measureTextWidth(truncated + '...') > maxWidth && truncated.length > 0) {
|
||||
truncated = truncated.slice(0, -1)
|
||||
}
|
||||
return truncated + (truncated.length < text.length ? '...' : '')
|
||||
isChineseDominant(text) {
|
||||
const chineseRegex = /[\u4e00-\u9fa5]/g
|
||||
const chineseCount = (text.match(chineseRegex) || []).length
|
||||
return chineseCount / text.length > 0.5
|
||||
},
|
||||
// 精确测量文本渲染宽度(像素)
|
||||
|
||||
// 修改截断逻辑:按字符类型统一视觉宽度
|
||||
truncateText(text, baseMaxWidth = 90) {
|
||||
if (!text) return ''
|
||||
|
||||
// 1. 按文本类型设置“最大可显示字符数”(视觉宽度相近)
|
||||
const isChinese = this.isChineseDominant(text)
|
||||
const maxChars = isChinese ? 8 : 15 // 中文8字 ≈ 英文15字母(14px sans-serif下)
|
||||
|
||||
// 2. 先按字符数截断(避免过长文本循环过多)
|
||||
const truncated = text.slice(0, maxChars)
|
||||
let finalText = truncated
|
||||
|
||||
// 3. 精确测量:如果截断后加...仍超宽,继续缩减
|
||||
while (this.measureTextWidth(finalText + '...') > baseMaxWidth && finalText.length > 0) {
|
||||
finalText = finalText.slice(0, -1)
|
||||
}
|
||||
|
||||
// 4. 补充...(如果有截断)
|
||||
return finalText + (finalText.length < text.length ? '...' : '')
|
||||
},
|
||||
|
||||
// 精确测量文本渲染宽度(像素)- 保持不变
|
||||
measureTextWidth(text, font = '14px sans-serif') {
|
||||
// 创建或复用一个 canvas(避免重复创建)
|
||||
if (!this._textMeasurementCanvas) {
|
||||
this._textMeasurementCanvas = document.createElement('canvas')
|
||||
}
|
||||
@ -592,11 +580,12 @@ export default {
|
||||
return ctx.measureText(text).width
|
||||
},
|
||||
|
||||
// 计算 value 的 x 坐标:baseX + name 的实际宽度 + 一点间距
|
||||
calculateValueX(name, baseX = 200) {
|
||||
const truncatedName = this.truncateText(name, 120) // 限制 name 最大宽度
|
||||
const width = this.measureTextWidth(truncatedName)
|
||||
return baseX + width + 6 // +6 是 name 和 value 之间的小空隙
|
||||
// 计算value的x坐标:基于统一后的截断文本宽度
|
||||
calculateValueX(name, baseX = 205) {
|
||||
const truncatedName = this.truncateText(name) // 无需传maxWidth,内部统一处理
|
||||
const nameWidth = this.measureTextWidth(truncatedName)
|
||||
const spacing = 6 // 固定间距(因截断文本视觉宽度一致,间距会统一)
|
||||
return baseX + nameWidth + spacing
|
||||
},
|
||||
countChineseAndEnglishCharacters(str, x) {
|
||||
var chineseCount = str.match(/[\u4e00-\u9fa5]/g) ? str.match(/[\u4e00-\u9fa5]/g).length : 0
|
||||
|
||||
265
src/views/new-screen-zz-pv/components/SwiperTable.vue
Normal file
265
src/views/new-screen-zz-pv/components/SwiperTable.vue
Normal file
@ -0,0 +1,265 @@
|
||||
<template>
|
||||
<div
|
||||
class="table-wrapper"
|
||||
:style="{
|
||||
width: 'calc(' + widths.reduce((i, j) => `${i} + ${j}`) + ` + ${(widths.length - 1) * 6}px)`,
|
||||
height: `calc(${contentHeight}px + 48px)`
|
||||
}"
|
||||
>
|
||||
<div v-if="showHeader" class="table-header">
|
||||
<span v-show="isSort" :style="{ width: '60px' }">序号</span>
|
||||
<span v-for="(it, i) in titles" :key="i" :style="{ width: widths[i] === 'auto' ? 'auto' : widths[i] + 'px' }" :class="{'span-auto': widths[i] === 'auto'}">{{ titles[i] }}</span>
|
||||
</div>
|
||||
<div
|
||||
class="table-content"
|
||||
:style="{height:contentHeight+'px'}"
|
||||
>
|
||||
<swiper v-if="data.length > 0" ref="myBotSwiper" class="swiper" :options="swiperOption">
|
||||
<swiper-slide v-for="(row, rowIndex) in data" :key="rowIndex">
|
||||
<div
|
||||
class="table-row"
|
||||
:class="{ stripe: rowIndex % 2 === 1}"
|
||||
:style="{ height: tabelHeight }"
|
||||
@click="handleRowClick(row, rowIndex)"
|
||||
>
|
||||
<span
|
||||
v-show="isSort"
|
||||
:style="{ width: '60px', height: tabelHeight }"
|
||||
>{{ rowIndex+1 }}</span>
|
||||
<span
|
||||
v-for="(column, columnIndex) in columns"
|
||||
:key="columnIndex"
|
||||
:title="row[columnIndex]"
|
||||
:style="{ width: widths[columnIndex] === 'auto' ? 'auto' : widths[columnIndex] + 'px', height: tabelHeight }"
|
||||
:class="{'span-auto': widths[columnIndex] === 'auto','color-blue':column === 'efficiencyValue'}"
|
||||
>{{ row[column] }}</span>
|
||||
</div>
|
||||
</swiper-slide>
|
||||
</swiper>
|
||||
<div v-if="data.length === 0" style="height:100%;text-align:center; margin-top:40px;font-size:14px;color:#999">
|
||||
暂无数据
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import 'swiper/dist/css/swiper.css'
|
||||
import { swiper, swiperSlide } from 'vue-awesome-swiper'
|
||||
export default {
|
||||
name: 'SwiperTable',
|
||||
components: {
|
||||
swiper,
|
||||
swiperSlide
|
||||
},
|
||||
props: {
|
||||
// 传入的表格数据
|
||||
data: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
// 传入的表格头
|
||||
titles: {
|
||||
type: Array,
|
||||
default: () => ['事件标题', '创建时间', '信息来源', '分类', '状态', '上报人']
|
||||
},
|
||||
// 表格的列宽
|
||||
widths: {
|
||||
type: Array,
|
||||
default: () => ['246px', '348px', '224px', '214px', '214px', '214px']
|
||||
},
|
||||
// 表格的高度
|
||||
contentHeight: {
|
||||
type: Number,
|
||||
default: 200
|
||||
},
|
||||
// 是否展示表格头
|
||||
showHeader: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
isSort: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
// 表格的行高
|
||||
tabelHeight: {
|
||||
type: String,
|
||||
default: '32px'
|
||||
},
|
||||
// 字段
|
||||
columns: {
|
||||
type: Array,
|
||||
default: () => ['title', 'createTime', 'info', 'type', 'status', 'upper']
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
currentActiveRow: 0,
|
||||
swiperOption: {
|
||||
autoHeight: true,
|
||||
direction: 'vertical',
|
||||
spaceBetween: 0,
|
||||
autoplay: {
|
||||
delay: 2500,
|
||||
disableOnInteraction: false,
|
||||
autoplayDisableOnInteraction: false
|
||||
},
|
||||
slidesPerView: 'auto',
|
||||
grabCursor: true,
|
||||
autoplayDisableOnInteraction: false,
|
||||
mousewheelControl: true
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
myBotSwiper() {
|
||||
return this.$refs.myBotSwiper.$swiper
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
data: {
|
||||
handler(val) {
|
||||
this.currentActiveRow = 0
|
||||
// if (val && val.length > 0) {
|
||||
// this.columns = []
|
||||
// for (const key in val[0]) {
|
||||
// this.columns.push(key)
|
||||
// }
|
||||
// // this.swiperStart()
|
||||
// }
|
||||
},
|
||||
deep: true,
|
||||
immediate: true
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleRowClick(it, i) {
|
||||
this.currentActiveRow = i
|
||||
const currentIt = this.data[i]
|
||||
this.$emit('change', currentIt)
|
||||
},
|
||||
// 控制表格停止滚动
|
||||
swiperStop() {
|
||||
this.myBotSwiper.autoplay.stop()
|
||||
},
|
||||
// 控制表格开始滚动
|
||||
swiperStart() {
|
||||
this.myBotSwiper.autoplay.start()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.table-wrapper {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
span {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.table-header {
|
||||
$height: 32px;
|
||||
width: 100%;
|
||||
height: $height;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background: transparent;
|
||||
span {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #9AD1FD;
|
||||
font-size: 14px;
|
||||
font-family: Microsoft YaHei-Regular, Microsoft YaHei;
|
||||
font-weight: 400;
|
||||
line-height: $height;
|
||||
&:nth-child(2) {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
}
|
||||
.span-auto {
|
||||
flex: 1;
|
||||
}
|
||||
span + span {
|
||||
margin-left: 2px;
|
||||
}
|
||||
}
|
||||
.table-content {
|
||||
width: 100%;
|
||||
margin-top: 2px;
|
||||
.swiper {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
.table-row {
|
||||
width: 100%;
|
||||
height: 36px;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
&.active {
|
||||
border: 2px solid rgba(0, 148, 255, 0.00);
|
||||
background: linear-gradient(90deg, rgba(0, 51, 81, 0.00) 0%, #003351 51.3%, rgba(0, 51, 81, 0.00) 100%);
|
||||
span {
|
||||
|
||||
color: #32AAFF;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
&.stripe span {
|
||||
background:#00131B;
|
||||
}
|
||||
span {
|
||||
font-size: 14px;
|
||||
font-family: PingFangSC-Regular, PingFang SC;
|
||||
font-weight: 400;
|
||||
color: #E6F4FE;
|
||||
line-height: 36px;
|
||||
}
|
||||
.span-auto {
|
||||
flex: 1;
|
||||
}
|
||||
// span + span {
|
||||
// margin-left: 2px;
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
span {
|
||||
height: 100%;
|
||||
line-height: 100%;
|
||||
display: inline-block;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
margin-bottom: 6px;
|
||||
&:nth-child(1) {
|
||||
width: 246px;
|
||||
}
|
||||
&:nth-child(2) {
|
||||
width: 348px;
|
||||
|
||||
padding-left: 13px;
|
||||
}
|
||||
&:nth-child(3) {
|
||||
text-align: center;
|
||||
|
||||
width: 214px;
|
||||
}
|
||||
&:nth-child(4) {
|
||||
text-align: center;
|
||||
|
||||
width: 214px;
|
||||
}
|
||||
&:nth-child(5) {
|
||||
width: 214px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.color-blue{
|
||||
color: #0089FB !important;
|
||||
}
|
||||
</style>
|
||||
292
src/views/new-screen-zz-pv/components/SwiperTableAlarm.vue
Normal file
292
src/views/new-screen-zz-pv/components/SwiperTableAlarm.vue
Normal file
@ -0,0 +1,292 @@
|
||||
<template>
|
||||
<div
|
||||
class="table-wrapper"
|
||||
:style="{
|
||||
width: 'calc(' + widths.reduce((i, j) => `${i} + ${j}`) + ` + ${(widths.length - 1) * 6}px)`,
|
||||
|
||||
}"
|
||||
>
|
||||
<div v-if="showHeader" class="table-header">
|
||||
<span v-show="isSort" :style="{ width: '60px' }">序号</span>
|
||||
<span v-for="(it, i) in titles" :key="i" :style="{ width: widths[i] === 'auto' ? 'auto' : widths[i] + 'px' }" :class="{'span-auto': widths[i] === 'auto'}">{{ titles[i] }}</span>
|
||||
</div>
|
||||
<div
|
||||
class="table-content"
|
||||
:style="{height:contentHeight+'px'}"
|
||||
>
|
||||
<swiper v-if="data.length > 0" ref="myBotSwiper" class="swiper" :options="swiperOption">
|
||||
<swiper-slide v-for="(row, rowIndex) in data" :key="rowIndex">
|
||||
<div
|
||||
class="table-row "
|
||||
:style="{ height: tabelHeight,'border-color':alarmList.find(i=>i.level === row.eventLevel)?alarmList.find(i=>i.level === row.eventLevel).color :'#fff'}"
|
||||
@click="handleRowClick(row, rowIndex)"
|
||||
>
|
||||
<div class="tip-box" :style="{color:alarmList.find(i=>i.level === row.eventLevel) ? alarmList.find(i=>i.level === row.eventLevel).color :'#fff'}">{{ alarmList.find(i=>i.level === row.eventLevel)? alarmList.find(i=>i.level === row.eventLevel).label :'' }}</div>
|
||||
<div
|
||||
v-for="(column, columnIndex) in columns"
|
||||
:key="columnIndex"
|
||||
:title="row[columnIndex]"
|
||||
:style="{ width: widths[columnIndex] === 'auto' ? 'auto' : widths[columnIndex] + 'px', height: tabelHeight }"
|
||||
:class="{'span-auto': widths[columnIndex] === 'auto'}"
|
||||
>{{ column === 'timeStamp' ?parseTime( row[column]) : row[column] }}</div>
|
||||
</div>
|
||||
</swiper-slide>
|
||||
</swiper>
|
||||
<div v-if="data.length === 0" style="height:100%;text-align:center; margin-top:40px;font-size:14px;color:#999">
|
||||
暂无数据
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import 'swiper/dist/css/swiper.css'
|
||||
import { parseTime } from '@/utils/index'
|
||||
import { swiper, swiperSlide } from 'vue-awesome-swiper'
|
||||
export default {
|
||||
name: 'SwiperTable',
|
||||
components: {
|
||||
swiper,
|
||||
swiperSlide
|
||||
},
|
||||
props: {
|
||||
// 传入的表格数据
|
||||
data: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
// 传入的表格头
|
||||
titles: {
|
||||
type: Array,
|
||||
default: () => ['事件标题', '创建时间', '信息来源', '分类', '状态', '上报人']
|
||||
},
|
||||
// 表格的列宽
|
||||
widths: {
|
||||
type: Array,
|
||||
default: () => ['246px', '348px', '224px', '214px', '214px', '214px']
|
||||
},
|
||||
// 表格的高度
|
||||
contentHeight: {
|
||||
type: Number,
|
||||
default: 200
|
||||
},
|
||||
// 是否展示表格头
|
||||
showHeader: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
isSort: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
// 表格的行高
|
||||
tabelHeight: {
|
||||
type: String,
|
||||
default: '40px'
|
||||
},
|
||||
// 字段
|
||||
columns: {
|
||||
type: Array,
|
||||
default: () => ['title', 'createTime', 'info', 'type', 'status', 'upper']
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
alarmList: [{
|
||||
level: 1,
|
||||
label: '事故',
|
||||
color: '#CF0000'
|
||||
},
|
||||
{
|
||||
level: 2,
|
||||
label: '故障',
|
||||
color: '#FDA934'
|
||||
|
||||
},
|
||||
{
|
||||
level: 3,
|
||||
label: '告警',
|
||||
color: '#0089FB'
|
||||
},
|
||||
{
|
||||
level: 4,
|
||||
label: '提示',
|
||||
color: '#0089FB'
|
||||
|
||||
},
|
||||
{
|
||||
level: 5,
|
||||
label: '告知',
|
||||
color: '#0089FB'
|
||||
|
||||
}
|
||||
],
|
||||
currentActiveRow: 0,
|
||||
swiperOption: {
|
||||
autoHeight: true,
|
||||
direction: 'vertical',
|
||||
spaceBetween: 0,
|
||||
autoplay: {
|
||||
delay: 2500,
|
||||
disableOnInteraction: false,
|
||||
autoplayDisableOnInteraction: false
|
||||
},
|
||||
slidesPerView: 'auto',
|
||||
grabCursor: true,
|
||||
autoplayDisableOnInteraction: false,
|
||||
mousewheelControl: true
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
myBotSwiper() {
|
||||
return this.$refs.myBotSwiper.$swiper
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
data: {
|
||||
handler(val) {
|
||||
this.currentActiveRow = 0
|
||||
// if (val && val.length > 0) {
|
||||
// this.columns = []
|
||||
// for (const key in val[0]) {
|
||||
// this.columns.push(key)
|
||||
// }
|
||||
// // this.swiperStart()
|
||||
// }
|
||||
},
|
||||
deep: true,
|
||||
immediate: true
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
parseTime,
|
||||
handleRowClick(it, i) {
|
||||
this.currentActiveRow = i
|
||||
const currentIt = this.data[i]
|
||||
this.$emit('change', currentIt)
|
||||
},
|
||||
// 控制表格停止滚动
|
||||
swiperStop() {
|
||||
this.myBotSwiper.autoplay.stop()
|
||||
},
|
||||
// 控制表格开始滚动
|
||||
swiperStart() {
|
||||
this.myBotSwiper.autoplay.start()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.table-wrapper {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
span {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.table-header {
|
||||
$height: 32px;
|
||||
width: 100%;
|
||||
height: $height;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background: transparent;
|
||||
span {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #9AD1FD;
|
||||
font-size: 14px;
|
||||
font-family: Microsoft YaHei-Regular, Microsoft YaHei;
|
||||
font-weight: 400;
|
||||
line-height: $height;
|
||||
&:nth-child(2) {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
}
|
||||
.span-auto {
|
||||
flex: 1;
|
||||
}
|
||||
span + span {
|
||||
margin-left: 2px;
|
||||
}
|
||||
}
|
||||
.table-content {
|
||||
width: 100%;
|
||||
margin-top: 2px;
|
||||
.swiper {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
.table-row {
|
||||
width: calc(100% - 2px);
|
||||
height: 40px;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
margin-bottom: 20px;
|
||||
padding: 0 10px;
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
box-sizing: border-box;
|
||||
div {
|
||||
font-size: 14px;
|
||||
font-family: PingFangSC-Regular, PingFang SC;
|
||||
font-weight: 400;
|
||||
color: #E6F4FE;
|
||||
line-height: 36px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.span-auto {
|
||||
flex: 1;
|
||||
}
|
||||
div + div {
|
||||
margin-left: 2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
span {
|
||||
height: 100%;
|
||||
line-height: 100%;
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
margin-bottom: 6px;
|
||||
&:nth-child(1) {
|
||||
width: 246px;
|
||||
}
|
||||
&:nth-child(2) {
|
||||
width: 348px;
|
||||
padding-left: 13px;
|
||||
}
|
||||
&:nth-child(3) {
|
||||
width: 214px;
|
||||
}
|
||||
&:nth-child(4) {
|
||||
width: 214px;
|
||||
}
|
||||
&:nth-child(5) {
|
||||
width: 214px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.tip-box{
|
||||
font-size: 12px !important;
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
line-height: 16px !important; /* 133.333% */
|
||||
letter-spacing: 0.6px;
|
||||
writing-mode: tb-rl !important;
|
||||
margin-right: 10px;
|
||||
|
||||
}
|
||||
|
||||
</style>
|
||||
296
src/views/new-screen-zz-pv/components/SwiperTableCenter.vue
Normal file
296
src/views/new-screen-zz-pv/components/SwiperTableCenter.vue
Normal file
@ -0,0 +1,296 @@
|
||||
<!-- eslint-disable vue/no-parsing-error -->
|
||||
<template>
|
||||
<div
|
||||
class="table-wrapper"
|
||||
:style="{
|
||||
width: 'calc(' + widths.reduce((i, j) => `${i} + ${j}`) + ` + ${(widths.length - 1) * 6}px)`,
|
||||
|
||||
}"
|
||||
>
|
||||
<div v-if="showHeader" class="table-header">
|
||||
<span v-show="isSort" :style="{ width: '60px' }">序号</span>
|
||||
<span v-for="(it, i) in titles" :key="i" :style="{ width: widths[i] === 'auto' ? 'auto' : widths[i] + 'px' }" :class="{'span-auto': widths[i] === 'auto'}">{{ titles[i] }}</span>
|
||||
</div>
|
||||
<div
|
||||
class="table-content"
|
||||
:style="{height:contentHeight+'px'}"
|
||||
>
|
||||
<swiper v-if="data.length > 0" ref="myBotSwiper" class="swiper" :options="swiperOption">
|
||||
<swiper-slide v-for="(row, rowIndex) in data" :key="rowIndex">
|
||||
<div
|
||||
class="table-row"
|
||||
:style="{ height: tabelHeight }"
|
||||
@click="handleRowClick(row, rowIndex)"
|
||||
>
|
||||
<img :src="screenRightCenterBg" class="row-bg">
|
||||
|
||||
<div
|
||||
v-show="isSort"
|
||||
class="sort-box"
|
||||
:style="{ width: '60px', height: tabelHeight,'margin-left':'20px' }"
|
||||
>
|
||||
<img v-if="rowIndex === 0" :src="one">
|
||||
<img v-else-if="rowIndex === 1" :src="two">
|
||||
<img v-else-if="rowIndex === 2" :src="three">
|
||||
|
||||
<div v-else class="sort-box" :style="{ width: '100%', height: tabelHeight }"> {{ rowIndex < 9 ?'0' :'' }}{{ rowIndex +1 }}</div>
|
||||
</div>
|
||||
<span
|
||||
v-for="(column, columnIndex) in columns"
|
||||
:key="columnIndex"
|
||||
:title="row[columnIndex]"
|
||||
:style="{ width: widths[columnIndex] === 'auto' ? 'auto' : widths[columnIndex] + 'px' }"
|
||||
:class="{'span-auto': widths[columnIndex] === 'auto'}"
|
||||
>{{ row[column] }}</span>
|
||||
</div>
|
||||
</swiper-slide>
|
||||
</swiper>
|
||||
<div v-if="data.length === 0" style="height:100%;text-align:center; margin-top:40px;font-size:14px;color:#999">
|
||||
暂无数据
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import 'swiper/dist/css/swiper.css'
|
||||
import one from '@/assets/new-screen/one.png'
|
||||
import two from '@/assets/new-screen/two.png'
|
||||
import three from '@/assets/new-screen/three.png'
|
||||
import { swiper, swiperSlide } from 'vue-awesome-swiper'
|
||||
import screenRightCenterBg from '@/assets/new-screen/screenRightCenterBg.png'
|
||||
export default {
|
||||
name: 'SwiperTable',
|
||||
components: {
|
||||
swiper,
|
||||
swiperSlide
|
||||
},
|
||||
props: {
|
||||
// 传入的表格数据
|
||||
data: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
// 传入的表格头
|
||||
titles: {
|
||||
type: Array,
|
||||
default: () => ['事件标题', '创建时间', '信息来源', '分类', '状态', '上报人']
|
||||
},
|
||||
// 表格的列宽
|
||||
widths: {
|
||||
type: Array,
|
||||
default: () => ['246px', '348px', '224px', '214px', '214px', '214px']
|
||||
},
|
||||
// 表格的高度
|
||||
contentHeight: {
|
||||
type: Number,
|
||||
default: 200
|
||||
},
|
||||
// 是否展示表格头
|
||||
showHeader: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
isSort: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
// 表格的行高
|
||||
tabelHeight: {
|
||||
type: String,
|
||||
default: '32px'
|
||||
},
|
||||
// 字段
|
||||
columns: {
|
||||
type: Array,
|
||||
default: () => ['title', 'createTime', 'info', 'type', 'status', 'upper']
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
one,
|
||||
two,
|
||||
three,
|
||||
screenRightCenterBg,
|
||||
currentActiveRow: 0,
|
||||
swiperOption: {
|
||||
autoHeight: true,
|
||||
direction: 'vertical',
|
||||
spaceBetween: 0,
|
||||
autoplay: {
|
||||
delay: 2500,
|
||||
disableOnInteraction: false,
|
||||
autoplayDisableOnInteraction: false
|
||||
},
|
||||
slidesPerView: 'auto',
|
||||
grabCursor: true,
|
||||
autoplayDisableOnInteraction: false,
|
||||
mousewheelControl: true
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
myBotSwiper() {
|
||||
return this.$refs.myBotSwiper.$swiper
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
data: {
|
||||
handler(val) {
|
||||
this.currentActiveRow = 0
|
||||
// if (val && val.length > 0) {
|
||||
// this.columns = []
|
||||
// for (const key in val[0]) {
|
||||
// this.columns.push(key)
|
||||
// }
|
||||
// // this.swiperStart()
|
||||
// }
|
||||
},
|
||||
deep: true,
|
||||
immediate: true
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleRowClick(it, i) {
|
||||
this.currentActiveRow = i
|
||||
const currentIt = this.data[i]
|
||||
this.$emit('change', currentIt)
|
||||
},
|
||||
// 控制表格停止滚动
|
||||
swiperStop() {
|
||||
this.myBotSwiper.autoplay.stop()
|
||||
},
|
||||
// 控制表格开始滚动
|
||||
swiperStart() {
|
||||
this.myBotSwiper.autoplay.start()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.table-wrapper {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
span {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.table-header {
|
||||
$height: 32px;
|
||||
width: 100%;
|
||||
height: $height;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background: transparent;
|
||||
span {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #fff;
|
||||
font-size: 14px;
|
||||
font-family: Microsoft YaHei-Regular, Microsoft YaHei;
|
||||
font-weight: 400;
|
||||
line-height: $height;
|
||||
&:nth-child(2) {
|
||||
// text-align: center;
|
||||
}
|
||||
|
||||
}
|
||||
.span-auto {
|
||||
flex: 1;
|
||||
}
|
||||
span + span {
|
||||
margin-left: 2px;
|
||||
}
|
||||
}
|
||||
.table-content {
|
||||
width: 100%;
|
||||
margin-top: 2px;
|
||||
.swiper {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
.table-row {
|
||||
width: 100%;
|
||||
height: 36px;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
.row-bg{
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
width: 386px;
|
||||
height: auto;
|
||||
}
|
||||
&.active {
|
||||
border: 2px solid rgba(0, 148, 255, 0.00);
|
||||
background: linear-gradient(90deg, rgba(0, 51, 81, 0.00) 0%, #003351 51.3%, rgba(0, 51, 81, 0.00) 100%);
|
||||
span {
|
||||
|
||||
color: #32AAFF;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
&.stripe span {
|
||||
background: rgba(2, 74, 123, 0.2);
|
||||
}
|
||||
span {
|
||||
font-size: 14px;
|
||||
font-family: PingFangSC-Regular, PingFang SC;
|
||||
font-weight: 400;
|
||||
color: #E6F4FE;
|
||||
line-height: 36px;
|
||||
}
|
||||
.span-auto {
|
||||
flex: 1;
|
||||
}
|
||||
// span + span {
|
||||
// margin-left: 2px;
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
span {
|
||||
display: inline-block;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-align: center;
|
||||
|
||||
text-overflow: ellipsis;
|
||||
margin-bottom: 6px;
|
||||
&:nth-child(1) {
|
||||
width: 246px;
|
||||
}
|
||||
&:nth-child(2) {
|
||||
width: 348px;
|
||||
padding-left: 13px;
|
||||
text-align: center;
|
||||
|
||||
}
|
||||
&:nth-child(3) {
|
||||
text-align: center;
|
||||
|
||||
width: 214px;
|
||||
}
|
||||
&:nth-child(4) {
|
||||
width: 214px;
|
||||
}
|
||||
&:nth-child(5) {
|
||||
width: 214px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.sort-box{
|
||||
color: #FAD733 !important;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
text-align: center;
|
||||
text-shadow: 0px 0px 1px #FAD733 !important;
|
||||
font-size: 16px !important;
|
||||
font-weight: 400;
|
||||
line-height: 36px;
|
||||
}
|
||||
</style>
|
||||
192
src/views/new-screen-zz-pv/components/center-bottom.vue
Normal file
192
src/views/new-screen-zz-pv/components/center-bottom.vue
Normal file
@ -0,0 +1,192 @@
|
||||
<template>
|
||||
<div class="center-bottom-warp">
|
||||
<item :title="$t('screen.dailyPowerGeneration')">
|
||||
<dv-loading v-if="Loading">Loading...</dv-loading>
|
||||
<Chart v-else :options="options" />
|
||||
</item>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import item from './item-warp.vue'
|
||||
import { GetChargeDailyChart } from '@/api/screen/zzScreen'
|
||||
import dayChargeIcon from '../../../assets/new-screen/dayCharge-icon.png'
|
||||
// import dayDischargeIcon from '../../../assets/new-screen/dayDischarge-icon.png'
|
||||
export default {
|
||||
components: { item },
|
||||
data() {
|
||||
return {
|
||||
options: {},
|
||||
Loading: true
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
lang() {
|
||||
return this.$store.getters.language
|
||||
}
|
||||
},
|
||||
created() {},
|
||||
mounted() {},
|
||||
methods: {
|
||||
async getData(deptId) {
|
||||
try {
|
||||
this.Loading = true
|
||||
const { data } = await GetChargeDailyChart({
|
||||
deptId: deptId
|
||||
})
|
||||
this.initChart(data)
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
} finally {
|
||||
this.Loading = false
|
||||
}
|
||||
|
||||
// data.splice(0, 3)
|
||||
},
|
||||
initChart(data) {
|
||||
if (data.length) {
|
||||
const x_data = []
|
||||
|
||||
const dayCharge = []
|
||||
data.forEach((el) => {
|
||||
x_data.push(el.time)
|
||||
dayCharge.push(el.dayCharge)
|
||||
})
|
||||
this.options = {
|
||||
tooltip: {
|
||||
trigger: 'axis'
|
||||
},
|
||||
legend: {
|
||||
orient: 'horizontal',
|
||||
right: 30,
|
||||
itemWidth: 14,
|
||||
data: [
|
||||
{
|
||||
icon: 'image://' + dayChargeIcon,
|
||||
name: this.$t('screen.powerGeneration')
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
grid: {
|
||||
left: '5%',
|
||||
top: '13%',
|
||||
right: '5%',
|
||||
bottom: '10%'
|
||||
},
|
||||
xAxis: [
|
||||
{
|
||||
data: x_data,
|
||||
axisLabel: {
|
||||
textStyle: {
|
||||
color: '#6E7174'
|
||||
},
|
||||
margin: 10 // 刻度标签与轴线之间的距离。
|
||||
},
|
||||
|
||||
axisLine: {
|
||||
show: false // 不显示x轴
|
||||
},
|
||||
axisTick: {
|
||||
show: false // 不显示刻度
|
||||
},
|
||||
boundaryGap: true,
|
||||
splitLine: {
|
||||
show: false,
|
||||
width: 0.08,
|
||||
lineStyle: {
|
||||
type: 'solid',
|
||||
color: '#03202E'
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
yAxis: [
|
||||
{
|
||||
name: 'kWh',
|
||||
nameTextStyle: {
|
||||
color: '#6E7174',
|
||||
fontSize: 12,
|
||||
padding: [0, 0, 0, -40]
|
||||
},
|
||||
splitLine: {
|
||||
show: false,
|
||||
lineStyle: {
|
||||
color: '#eee',
|
||||
type: 'solid'
|
||||
}
|
||||
},
|
||||
axisTick: {
|
||||
show: false
|
||||
},
|
||||
axisLine: {
|
||||
show: false
|
||||
},
|
||||
axisLabel: {
|
||||
textStyle: {
|
||||
color: '#6E7174'
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
series: [
|
||||
// 柱体
|
||||
{
|
||||
name: this.$t('screen.powerGeneration'),
|
||||
type: 'bar',
|
||||
|
||||
barGap: '20%',
|
||||
barCategoryGap: '50%' /* 多个并排柱子设置柱子之间的间距*/,
|
||||
itemStyle: {
|
||||
normal: {
|
||||
color: {
|
||||
x: 0,
|
||||
y: 0,
|
||||
x2: 0,
|
||||
y2: 1,
|
||||
type: 'linear',
|
||||
global: false,
|
||||
colorStops: [
|
||||
{
|
||||
// 第一节下面
|
||||
offset: 0,
|
||||
color: 'rgba(0, 243, 253, 1)'
|
||||
},
|
||||
{
|
||||
offset: 1,
|
||||
color: 'rgba(0, 243, 253, 0.2)'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
data: dayCharge
|
||||
}
|
||||
]
|
||||
}
|
||||
} else {
|
||||
this.options = {
|
||||
title: {
|
||||
text: this.$t('screen.noData'),
|
||||
x: 'center',
|
||||
y: 'center',
|
||||
textStyle: {
|
||||
fontSize: 14,
|
||||
color: 'rgb(153, 153, 153)',
|
||||
fontWeight: 'normal'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.center-bottom-warp {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
119
src/views/new-screen-zz-pv/components/center-top.vue
Normal file
119
src/views/new-screen-zz-pv/components/center-top.vue
Normal file
@ -0,0 +1,119 @@
|
||||
<template>
|
||||
<div class="center-top-warp">
|
||||
<div class="income">
|
||||
<div class="title">
|
||||
<span class="square" />
|
||||
<span>{{ $t('screen.todayEarning') }}</span>
|
||||
</div>
|
||||
<div class="value">
|
||||
<template v-for="(item,index) in info.yestProfit">
|
||||
<div :key="index" class="number">{{ item }}</div>
|
||||
</template>
|
||||
|
||||
<div class="unit">{{ $t('screen.mRMB') }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="income">
|
||||
<div class="title">
|
||||
<span class="square" />
|
||||
<span>{{ $t('screen.annualEarning') }}</span>
|
||||
</div>
|
||||
<div class="value">
|
||||
<template v-for="(item,index) in info.yearProfit">
|
||||
<div :key="index" class="number">{{ item }}</div>
|
||||
</template>
|
||||
|
||||
<div class="unit">{{ $t('screen.mRMB') }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="income">
|
||||
<div class="title">
|
||||
<span class="square" />
|
||||
<span>{{ $t('screen.totalEarning') }}</span>
|
||||
</div>
|
||||
<div class="value">
|
||||
<template v-for="(item,index) in info.totalProfit">
|
||||
<div :key="index" class="number">{{ item }}</div>
|
||||
</template>
|
||||
|
||||
<div class="unit">{{ $t('screen.mRMB') }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
info: {
|
||||
type: Object,
|
||||
default: () => null
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
number: '1234.5'
|
||||
}
|
||||
},
|
||||
created() {
|
||||
|
||||
},
|
||||
mounted() {
|
||||
this.getData()
|
||||
},
|
||||
methods: {
|
||||
getData() {}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.center-top-warp {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
|
||||
.income {
|
||||
height: 100%;
|
||||
padding-top: 15px;
|
||||
z-index: 99999;
|
||||
.title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.square {
|
||||
display: inline-block;
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-radius: 50%;
|
||||
background: rgba(0, 137, 251, 1);
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
.value {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.number {
|
||||
width: 36px;
|
||||
height: 44px;
|
||||
line-height: 44px;
|
||||
background: url(../../../assets/new-screen/num-bg.png);
|
||||
color: #fff;
|
||||
font-family: LCD;
|
||||
font-size: 32px;
|
||||
text-align: center;
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
margin-right: 5px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
.unit{
|
||||
margin-top: 10px;
|
||||
height: 44px;
|
||||
line-height: 77px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
51
src/views/new-screen-zz-pv/components/item-warp.vue
Normal file
51
src/views/new-screen-zz-pv/components/item-warp.vue
Normal file
@ -0,0 +1,51 @@
|
||||
<template>
|
||||
<div class="item-warp">
|
||||
<div class="item-bg">
|
||||
<div class="item-title">{{ title }}</div>
|
||||
</div>
|
||||
|
||||
<div class="item-content">
|
||||
<slot />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
default: '集团数据'
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.item-warp {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.item-bg {
|
||||
width: 385px;
|
||||
height: 40px;
|
||||
background: url(../../../assets/new-screen/item-bg.png) no-repeat;
|
||||
background-size: 100% 75%;
|
||||
background-position:0 10px;
|
||||
padding-left: 12px;
|
||||
.item-title{
|
||||
font-size: 16px;
|
||||
color: #CCE8FE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.item-content {
|
||||
width: 100%;
|
||||
height: calc(100% - 41px);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
136
src/views/new-screen-zz-pv/components/left-bottom.vue
Normal file
136
src/views/new-screen-zz-pv/components/left-bottom.vue
Normal file
@ -0,0 +1,136 @@
|
||||
<template>
|
||||
<div class="left-bottom-warp">
|
||||
<item :title="$t('screen.energySaving')">
|
||||
<dv-loading v-if="loading">Loading...</dv-loading>
|
||||
<div v-else class="top-all-box">
|
||||
<div class="top-con-box">
|
||||
<div class="top-item-box">
|
||||
<div class="data">{{ info.treePlanting }}<span class="unit">{{ $t('screen.tree') }}</span></div>
|
||||
<div class="title">{{ $t('screen.planted') }}</div>
|
||||
<img :src="screenItemBg" class="item-bg-img">
|
||||
</div>
|
||||
<div class="top-item-box">
|
||||
<div class="data">{{ info.reductionCO2 | kgFormat }}<span class="unit">{{ info.reductionCO2 | KgUnitFormat }}</span></div>
|
||||
<div class="title">{{ $t('screen.co2') }}</div>
|
||||
<img :src="screenItemBg" class="item-bg-img">
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="top-con-box">
|
||||
<div class="top-item-box">
|
||||
<div class="data">{{ info.equivalentCoal | kgFormat }}<span class="unit">{{ info.equivalentCoal | KgUnitFormat }}</span></div>
|
||||
<div class="title">{{ $t('screen.coal') }}</div>
|
||||
<img :src="screenItemBg" class="item-bg-img">
|
||||
</div>
|
||||
<div class="top-item-box">
|
||||
<div class="data">{{ info.income | moneyFormat }}<span class="unit">{{ info.income | moneyUnitFormat }}</span></div>
|
||||
<div class="title">{{ $t('screen.income') }}</div>
|
||||
<img :src="screenItemBg" class="item-bg-img">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</item>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import item from './item-warp.vue'
|
||||
import screenItemBg from '@/assets/new-screen/screen-item-bg.png'
|
||||
import { GetEnergySaving } from '@/api/screen/zzScreen'
|
||||
export default {
|
||||
components: { item },
|
||||
data() {
|
||||
return {
|
||||
screenItemBg,
|
||||
loading: true,
|
||||
info: {
|
||||
treePlanting: null,
|
||||
reductionCO2: null,
|
||||
equivalentCoal: null,
|
||||
income: null
|
||||
}
|
||||
|
||||
}
|
||||
},
|
||||
created() {
|
||||
},
|
||||
mounted() {
|
||||
},
|
||||
methods: {
|
||||
async getData(deptId) {
|
||||
try {
|
||||
this.loading = true
|
||||
const { data } = await GetEnergySaving({
|
||||
deptId: deptId
|
||||
})
|
||||
this.info = data
|
||||
} catch (error) {
|
||||
// console.log(error);
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.left-bottom-warp {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.top-all-box {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: space-around;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 10px 0;
|
||||
.top-con-box {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-around;
|
||||
width: 100%;
|
||||
|
||||
.top-item-box {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
min-height: 110px;
|
||||
|
||||
.data {
|
||||
color: #F5FAFF;
|
||||
font-family: DIN;
|
||||
font-size: 24px;
|
||||
font-weight: 500;
|
||||
line-height: normal;
|
||||
}
|
||||
|
||||
.unit {
|
||||
color: #F5FAFF;
|
||||
font-family: DIN;
|
||||
font-size: 12px;
|
||||
line-height: normal;
|
||||
}
|
||||
|
||||
.title {
|
||||
color: #B7C1C9;
|
||||
font-size: 14px;
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
line-height: normal;
|
||||
}
|
||||
|
||||
.item-bg-img {
|
||||
width: 90px;
|
||||
height: auto;
|
||||
position: absolute;
|
||||
top: 38px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}</style>
|
||||
202
src/views/new-screen-zz-pv/components/left-center.vue
Normal file
202
src/views/new-screen-zz-pv/components/left-center.vue
Normal file
@ -0,0 +1,202 @@
|
||||
<template>
|
||||
<div class="left-center-warp">
|
||||
|
||||
<item :title="$t('screen.regionStation')">
|
||||
<dv-loading v-if="loading">Loading...</dv-loading>
|
||||
<div v-else class="chart-box">
|
||||
<Chart :options="options" :class-name="'chart'" />
|
||||
</div></item>
|
||||
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import item from './item-warp.vue'
|
||||
import { GetRegionalDistribution } from '@/api/screen/zzScreen'
|
||||
|
||||
export default {
|
||||
components: { item },
|
||||
data() {
|
||||
return {
|
||||
options: {},
|
||||
loading: true
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async getData(deptId) {
|
||||
try {
|
||||
this.loading = true
|
||||
const res = await GetRegionalDistribution({
|
||||
deptId: deptId
|
||||
})
|
||||
this.initChart(res.data)
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
initChart(val) {
|
||||
if (val.length) {
|
||||
val.sort((a, b) => b.regionValue - a.regionValue)
|
||||
|
||||
var ydata = []
|
||||
var legend = []
|
||||
val.forEach(i => {
|
||||
const param = {
|
||||
name: i.addName,
|
||||
value: i.regionValue
|
||||
}
|
||||
legend.push(param.name)
|
||||
ydata.push(param)
|
||||
})
|
||||
const count = this.arrCount(ydata)
|
||||
this.options = {
|
||||
title: [{
|
||||
text: this.$t('screen.totalStation'),
|
||||
subtext: count,
|
||||
|
||||
subtextStyle: {
|
||||
color: '#fff',
|
||||
fontSize: 37,
|
||||
fontWeight: 500
|
||||
|
||||
},
|
||||
|
||||
left: '35%',
|
||||
top: '40%',
|
||||
padding: [0, 0],
|
||||
textStyle: {
|
||||
color: '#fff',
|
||||
fontSize: 18
|
||||
},
|
||||
textAlign: 'center'
|
||||
|
||||
}],
|
||||
tooltip: {},
|
||||
legend: {
|
||||
type: 'scroll',
|
||||
orient: 'vertical',
|
||||
right: 10,
|
||||
top: 20,
|
||||
bottom: 20,
|
||||
padding: [0, 10],
|
||||
data: legend,
|
||||
icon: 'circle',
|
||||
align: 'left',
|
||||
itemWidth: 8,
|
||||
itemHeight: 8,
|
||||
itemGap: 15,
|
||||
textStyle: {
|
||||
color: '#fff',
|
||||
rich: {
|
||||
name: {
|
||||
fontSize: 12,
|
||||
color: '#ffffff',
|
||||
padding: [0, 10, 0, 0]
|
||||
},
|
||||
num: {
|
||||
fontSize: 16,
|
||||
color: '#ffffff'
|
||||
},
|
||||
unit: {
|
||||
fontSize: 16,
|
||||
color: '#ffffff'
|
||||
}
|
||||
}
|
||||
},
|
||||
formatter: function(name) {
|
||||
const val = ydata.filter(item => {
|
||||
return item.name === name
|
||||
})
|
||||
const num = (((val[0].value / count)) * 100).toFixed(2)
|
||||
return [
|
||||
`{name|${name.length > 5 ? name.slice(0, 2) : name}}`,
|
||||
`{num|${num}}{unit|%}`
|
||||
].join(' ')
|
||||
}
|
||||
|
||||
},
|
||||
series: [{
|
||||
name: '电站个数',
|
||||
type: 'pie',
|
||||
clockwise: false, // 饼图的扇区是否是顺时针排布
|
||||
minAngle: 20, // 最小的扇区角度(0 ~ 360)
|
||||
radius: ['60%', '75%'],
|
||||
center: ['35%', '50%'],
|
||||
avoidLabelOverlap: false,
|
||||
itemStyle: { // 图形样式
|
||||
normal: {
|
||||
borderColor: '#070A0C',
|
||||
borderWidth: 5
|
||||
}
|
||||
},
|
||||
label: {
|
||||
normal: {
|
||||
show: false
|
||||
},
|
||||
emphasis: {
|
||||
show: false,
|
||||
position: 'outer',
|
||||
alignTo: 'edge',
|
||||
margin: 10,
|
||||
formatter: '{text|{b}}\n{value|{d}%}',
|
||||
rich: {
|
||||
text: {
|
||||
fontSize: 14,
|
||||
align: 'center',
|
||||
verticalAlign: 'middle',
|
||||
padding: 5
|
||||
},
|
||||
value: {
|
||||
fontSize: 24,
|
||||
align: 'center',
|
||||
verticalAlign: 'middle'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
data: ydata
|
||||
}]
|
||||
}
|
||||
} else {
|
||||
this.options = {
|
||||
title: {
|
||||
text: '暂无数据',
|
||||
x: 'center',
|
||||
y: 'center',
|
||||
textStyle: {
|
||||
fontSize: 14,
|
||||
color: 'rgb(153, 153, 153)',
|
||||
fontWeight: 'normal'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
arrCount(arr) {
|
||||
let count = 0
|
||||
arr.forEach(item => {
|
||||
count = count + item.value
|
||||
})
|
||||
return count
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.left-center-warp {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.chart-box {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
180
src/views/new-screen-zz-pv/components/left-top.vue
Normal file
180
src/views/new-screen-zz-pv/components/left-top.vue
Normal file
@ -0,0 +1,180 @@
|
||||
<template>
|
||||
<div class="left-top-warp">
|
||||
<item :title="$t('screen.groupData')">
|
||||
<dv-loading v-if="loading">Loading...</dv-loading>
|
||||
<div v-else class="top-all-box">
|
||||
<div class="value-box">
|
||||
<el-tooltip class="item" effect="dark" :content="$t('screen.capacity')" placement="top">
|
||||
<div class="title">{{ $t('screen.capacity') }}</div>
|
||||
</el-tooltip>
|
||||
<el-tooltip class="item" effect="dark" :content="info.capacity |kwhFormat" placement="top">
|
||||
<div class="value">{{ info.capacity |kwhFormat }}</div>
|
||||
</el-tooltip>
|
||||
<div class="unit">{{ info.capacity | kwhUnitFormat }}</div>
|
||||
</div>
|
||||
<div class="value-box">
|
||||
<el-tooltip class="item" effect="dark" :content="$t('screen.stationNum')" placement="top">
|
||||
<div class="title">{{ $t('screen.stationNum') }}</div>
|
||||
</el-tooltip>
|
||||
<el-tooltip class="item" effect="dark" :content="info.stationNumber" placement="top">
|
||||
<div class="value">{{ info.stationNumber }}</div>
|
||||
</el-tooltip>
|
||||
<div class="unit">{{ lang === 'zh'? '个':'' }}</div>
|
||||
</div>
|
||||
<div class="value-box" style="width:100%">
|
||||
<el-tooltip class="item" effect="dark" :content="$t('screen.dailyPowerGeneration')" placement="top">
|
||||
<div class="title" style="min-width:170px;max-width:170px;">{{ $t('screen.dailyPowerGeneration') }}</div>
|
||||
</el-tooltip>
|
||||
<el-tooltip class="item" effect="dark" :content="info.dayCharge |kwhFormat" placement="top">
|
||||
<div class="value" style="min-width:170px;max-width:170px;">{{ info.dayCharge |kwhFormat }}</div>
|
||||
</el-tooltip>
|
||||
<div class="unit">{{ info.dayCharge |kwhUnitFormat }}</div>
|
||||
</div>
|
||||
<div class="value-box" style="width:100%">
|
||||
<el-tooltip class="item" effect="dark" :content="$t('screen.yearlyPowerGeneration')" placement="top">
|
||||
<div class="title" style="min-width:170px;max-width:170px;">{{ $t('screen.yearlyPowerGeneration') }}</div>
|
||||
</el-tooltip>
|
||||
<el-tooltip class="item" effect="dark" :content="info.dayDischarge |kwhFormat" placement="top">
|
||||
<div class="value" style="min-width:170px;max-width:170px;">{{ info.dayDischarge |kwhFormat }}</div>
|
||||
</el-tooltip>
|
||||
<div class="unit">{{ info.dayDischarge |kwhUnitFormat }}</div>
|
||||
</div>
|
||||
<div class="value-box" style="width:100%">
|
||||
<el-tooltip class="item" effect="dark" :content="$t('screen.cumulativePowerGeneration')" placement="top">
|
||||
<div class="title" style="min-width:170px;max-width:170px;">{{ $t('screen.cumulativePowerGeneration') }}</div>
|
||||
</el-tooltip>
|
||||
<el-tooltip class="item" effect="dark" :content="info.yearCharge |kwhFormat" placement="top">
|
||||
<div class="value" style="min-width:170px;max-width:170px;">{{ info.yearCharge |kwhFormat }}</div>
|
||||
</el-tooltip>
|
||||
<div class="unit">{{ info.yearCharge |kwhUnitFormat }}</div>
|
||||
</div>
|
||||
<!-- <div class="value-box">
|
||||
<el-tooltip class="item" effect="dark" :content="$t('screen.yearDisCharge')" placement="top">
|
||||
<div class="title">{{ $t('screen.yearDisCharge') }}</div>
|
||||
</el-tooltip>
|
||||
<el-tooltip class="item" effect="dark" :content="info.yearDischarge |kwhFormat" placement="top">
|
||||
<div class="value">{{ info.yearDischarge |kwhFormat }}</div>
|
||||
</el-tooltip>
|
||||
<div class="unit">{{ info.yearDischarge |kwhUnitFormat }}</div>
|
||||
</div>
|
||||
<div class="value-box">
|
||||
<el-tooltip class="item" effect="dark" :content="$t('screen.totalCharge')" placement="top">
|
||||
<div class="title">{{ $t('screen.totalCharge') }}</div>
|
||||
</el-tooltip>
|
||||
<el-tooltip class="item" effect="dark" :content="info.totalCharge |kwhFormat" placement="top">
|
||||
<div class="value">{{ info.totalCharge |kwhFormat }}</div>
|
||||
</el-tooltip>
|
||||
<div class="unit">{{ info.totalCharge |kwhUnitFormat }}</div>
|
||||
</div>
|
||||
<div class="value-box">
|
||||
<el-tooltip class="item" effect="dark" :content="$t('screen.totalDisCharge')" placement="top">
|
||||
<div class="title">{{ $t('screen.totalDisCharge') }}</div>
|
||||
</el-tooltip>
|
||||
<el-tooltip class="item" effect="dark" :content="info.totalDischarge |kwhFormat" placement="top">
|
||||
<div class="value">{{ info.totalDischarge |kwhFormat }}</div>
|
||||
</el-tooltip>
|
||||
<div class="unit">{{ info.totalDischarge |kwhUnitFormat }}</div>
|
||||
</div> -->
|
||||
</div>
|
||||
</item>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import item from './item-warp.vue'
|
||||
|
||||
export default {
|
||||
components: { item },
|
||||
props: {
|
||||
info: {
|
||||
type: Object,
|
||||
default: () => null
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
loading: true
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
lang() {
|
||||
return this.$store.getters.language
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
info: {
|
||||
handler(val) {
|
||||
if (val) {
|
||||
this.loading = false
|
||||
} else {
|
||||
this.loading = true
|
||||
}
|
||||
},
|
||||
immediate: true,
|
||||
deep: true
|
||||
}
|
||||
},
|
||||
created() {
|
||||
},
|
||||
mounted() {
|
||||
this.getData()
|
||||
},
|
||||
|
||||
methods: {
|
||||
getData() {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.left-top-warp {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.top-all-box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-around;
|
||||
flex-wrap: wrap;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 10px 0;
|
||||
.value-box{
|
||||
width: 50%;
|
||||
height: 32px;
|
||||
background: url(../../../assets/new-screen/top-left-bg.png)no-repeat;
|
||||
background-size: 120% 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.title{
|
||||
color: rgba(179, 221, 253, 1);
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
min-width: 90px;
|
||||
max-width: 90px;
|
||||
padding-left: 16px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.value{
|
||||
color: rgba(255, 184, 0, 1);
|
||||
padding-left: 10px;
|
||||
min-width: 70px;
|
||||
max-width: 70px;
|
||||
text-align: right;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.unit{
|
||||
color: rgba(183, 193, 201, 1);
|
||||
padding-right: 20px;
|
||||
padding-left: 5px;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
394
src/views/new-screen-zz-pv/components/map-center.vue
Normal file
394
src/views/new-screen-zz-pv/components/map-center.vue
Normal file
@ -0,0 +1,394 @@
|
||||
<template>
|
||||
<div class="map-warp">
|
||||
<dv-loading v-if="loading">Loading...</dv-loading>
|
||||
<Chart v-else ref="chart" :options="options" @mapClick="mapClick" />
|
||||
<div class="map-left-box">
|
||||
<template v-for="(item,index) in tableData">
|
||||
<div :key="index" class="box-value">
|
||||
<span class="num">{{ index + 1 }}</span>
|
||||
<span class="name">{{ item.addName }}</span>
|
||||
<span class="value"><span style="min-width: 25px;display: inline-block;">{{ (item.stationCapacity / 1000).toFixed(2) }}</span>MWh</span>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
// import chinaMap from '@/assets/mapJson/chinaMap.json'
|
||||
import worldJson from 'echarts/map/json/world.json'
|
||||
// import { chinaMapOutline } from '@/assets/mapJson/chinaMapOut.js'
|
||||
import blue from '../../../assets/new-screen/map-blue.png'
|
||||
import { GetStationInfo, GetCapacity, GetRegionalDistribution } from '@/api/screen/zzScreen'
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
options: {},
|
||||
pointData: [],
|
||||
pointIndex: 0,
|
||||
timer: null,
|
||||
currentToolTip: {},
|
||||
loading: true,
|
||||
tableData: [],
|
||||
mapData: [],
|
||||
stationNum: []
|
||||
}
|
||||
},
|
||||
destroyed() {
|
||||
clearInterval(this.timer)
|
||||
this.timer = null
|
||||
},
|
||||
methods: {
|
||||
mapClick(params) {
|
||||
if (params.seriesType === 'effectScatter' || params.name === '四川') {
|
||||
const routeParams = {
|
||||
url: '/dashboard-test/dashboard-test',
|
||||
urlName: 'dashboard-test',
|
||||
data: {
|
||||
id: params.data.id
|
||||
}
|
||||
}
|
||||
this.$store.dispatch('user/menuChange', routeParams)
|
||||
}
|
||||
},
|
||||
async getStationNum(deptId) {
|
||||
const { data } = await GetRegionalDistribution({
|
||||
deptId: deptId
|
||||
})
|
||||
this.mapData = data
|
||||
this.mapData.map((el) => {
|
||||
el.name = el.addName
|
||||
el.value = el.regionValue
|
||||
this.stationNum.push(el.value)
|
||||
})
|
||||
},
|
||||
async getLeftData(deptId) {
|
||||
try {
|
||||
const { data } = await GetCapacity({
|
||||
deptId: deptId
|
||||
})
|
||||
this.tableData = data
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
},
|
||||
async getData(deptId) {
|
||||
this.loading = true
|
||||
try {
|
||||
const { data } = await GetStationInfo({
|
||||
deptId: deptId
|
||||
})
|
||||
console.log('GetStationInfo', data)
|
||||
const province = []
|
||||
if (data.length) {
|
||||
data.forEach((el) => {
|
||||
el.value = [el.longitude, el.latitude]
|
||||
el.symbol = 'image://' + blue
|
||||
el.cityCode = 1000
|
||||
province.push(el)
|
||||
})
|
||||
this.pointData = province
|
||||
} else {
|
||||
this.pointData = [{ symbol: 'image://' + blue, cityCode: 1000, value: [30.787045, 103.923008], name: 'Sichuan' }]
|
||||
}
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
this.getInitMap()
|
||||
},
|
||||
getInitMap() {
|
||||
this.$echarts.registerMap('world', worldJson)
|
||||
var series = [
|
||||
{
|
||||
name: '国家',
|
||||
map: 'world',
|
||||
type: 'map',
|
||||
roam: false,
|
||||
zoom: 1.1,
|
||||
label: {
|
||||
normal: {
|
||||
show: false,
|
||||
textStyle: {
|
||||
color: '#fff'
|
||||
}
|
||||
},
|
||||
emphasis: {
|
||||
textStyle: {
|
||||
color: '#fff'
|
||||
}
|
||||
}
|
||||
},
|
||||
top: '10%',
|
||||
tooltip: {
|
||||
show: false
|
||||
},
|
||||
itemStyle: {
|
||||
normal: {
|
||||
areaColor: 'transparent',
|
||||
borderColor: 'rgba(21,138,246,100%)',
|
||||
borderWidth: 1
|
||||
},
|
||||
emphasis: {
|
||||
areaColor: '#0B63B0',
|
||||
textStyle: {
|
||||
color: 'red'
|
||||
}
|
||||
}
|
||||
},
|
||||
data: this.mapData
|
||||
},
|
||||
|
||||
{
|
||||
name: '散点',
|
||||
type: 'effectScatter',
|
||||
coordinateSystem: 'geo',
|
||||
rippleEffect: {
|
||||
color: 'purple', // 涟漪颜色,默认为散点自身颜色
|
||||
brushType: 'fill', // 动画方式,全填充或只有线条,'stroke'
|
||||
period: 4, // 动画周期
|
||||
scale: '0.5' // 涟漪规模
|
||||
},
|
||||
itemStyle: {
|
||||
normal: {
|
||||
color: '#F4E925',
|
||||
shadowColor: '#333'
|
||||
}
|
||||
},
|
||||
symbolSize: 24,
|
||||
symbolOffset: [0, '-50%'], // 或 [0, -12] 更精确
|
||||
data: [this.pointData[this.pointIndex]],
|
||||
|
||||
showEffectOn: 'render' // 加载完毕显示特效
|
||||
}
|
||||
]
|
||||
|
||||
this.options = {
|
||||
visualMap: {
|
||||
min: 0,
|
||||
max: Math.max(...this.stationNum),
|
||||
right: 'right',
|
||||
top: 'bottom',
|
||||
text: [this.$t('screen.high') + '(' + this.$t('screen.stationNum') + ')', this.$t('screen.low') + '(' + this.$t('screen.stationNum') + ')'],
|
||||
calculable: true,
|
||||
inRange: {
|
||||
// color: ['#5edfd6', '#37d4cf', '#14c9c9', '#0da5aa', '#07828b']
|
||||
// color: ['#fcf26b', '#fbe842', '#fadc19', '#cfaf0f', '#a38408']
|
||||
color: ['#6aa1ff', '#4080ff', '#165dff', '#0e42d2', '#072ca6', '#031a79']
|
||||
// color: ['#8d4eda', '#722ed1', '#551db0', '#3c108f', '#27066e']
|
||||
// color: ['#e13edb', '#d91ad9', '#b010b6', '#8a0993', '#650370']
|
||||
// color: ['#23c343', '#00b42a', '#009a29', '#008026', '#006622']
|
||||
|
||||
},
|
||||
textStyle: {
|
||||
color: '#F5FAFF'
|
||||
},
|
||||
seriesIndex: [0]
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'item',
|
||||
alwaysShowContent: true,
|
||||
backgroundColor: 'transparent',
|
||||
position: 'bottom',
|
||||
triggerOn: 'click',
|
||||
enterable: true,
|
||||
formatter: params => {
|
||||
// 获取xAxis data中的数据
|
||||
let dataStr = `<div></div>`
|
||||
dataStr += `<div>
|
||||
<span style="padding-left:20px;font-weight:bold;margin-left:20px;margin-top:5px;font-size="14px">${params.name}</span>
|
||||
</div>`
|
||||
dataStr += `<div style="margin-top:15px">
|
||||
<span style="padding-left:10px;">${this.$t('screen.comTime')}</span>
|
||||
<span style="margin-left:5px;margin-right:10px;color:rgba(245, 221, 0, 1);font-family:DIN;">${params.data.createTime}</span>
|
||||
</div>`
|
||||
dataStr += `<div style="margin-top:2px;">
|
||||
<span style="padding-left:10px;">${this.$t('screen.capacity')}</span>
|
||||
<span style="margin-left:5px;margin-right:5px;color:rgba(245, 221, 0, 1);font-family:DIN;">${params.data.capacity}</span>
|
||||
<span style="color:rgba(245, 221, 0, 1);">kWh</span>
|
||||
</div>`
|
||||
const div = `<div style='height:85px;
|
||||
background-image:url(${require('../../../assets/new-screen/tooltip-bg.png')});background-repeat: no-repeat;background-size:100% 100%;' >${dataStr}</div>`
|
||||
return div
|
||||
}
|
||||
},
|
||||
color: ['#34c6bb'],
|
||||
geo: [
|
||||
{
|
||||
silent: true,
|
||||
map: 'world',
|
||||
zoom: 1.1,
|
||||
label: {
|
||||
normal: {
|
||||
show: false,
|
||||
textStyle: {
|
||||
color: '#fff'
|
||||
}
|
||||
},
|
||||
emphasis: {
|
||||
textStyle: {
|
||||
color: '#fff'
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
roam: false,
|
||||
itemStyle: {
|
||||
normal: {
|
||||
areaColor: 'rgba(3,56,100,50%)',
|
||||
borderColor: 'transparent',
|
||||
borderWidth: 1.5,
|
||||
shadowColor: 'transparent',
|
||||
shadowOffsetX: 0,
|
||||
shadowOffsetY: 4,
|
||||
shadowBlur: 10
|
||||
},
|
||||
emphasis: {
|
||||
areaColor: 'transparent', // 悬浮背景
|
||||
textStyle: {
|
||||
color: '#fff'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
{
|
||||
silent: true,
|
||||
map: 'chinaMapOutline',
|
||||
zoom: 1.2,
|
||||
top: '7%',
|
||||
label: {
|
||||
normal: {
|
||||
show: false,
|
||||
textStyle: {
|
||||
color: '#fff'
|
||||
}
|
||||
},
|
||||
emphasis: {
|
||||
textStyle: {
|
||||
color: '#fff'
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
roam: false,
|
||||
itemStyle: {
|
||||
normal: {
|
||||
areaColor: 'rgba(1,28,50,100%)',
|
||||
borderColor: '#0089FB',
|
||||
borderWidth: 1.5,
|
||||
shadowColor: '#0089FB',
|
||||
shadowOffsetX: 0,
|
||||
shadowOffsetY: 4,
|
||||
shadowBlur: 15
|
||||
},
|
||||
emphasis: {
|
||||
areaColor: 'transparent', // 悬浮背景
|
||||
textStyle: {
|
||||
color: '#fff'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}],
|
||||
series: series
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
this.$refs.chart?.chart.dispatchAction({
|
||||
type: 'showTip',
|
||||
seriesIndex: 1, // 针对series下第几个数据
|
||||
dataIndex: 0 // 第几个数据
|
||||
})
|
||||
}, 0)
|
||||
|
||||
if (!this.timer) {
|
||||
this.timer = setInterval(() => {
|
||||
this.pointIndex++
|
||||
if (this.pointIndex === this.pointData.length) {
|
||||
this.pointIndex = 0
|
||||
}
|
||||
this.getInitMap()
|
||||
}, 5000)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.map-warp {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
|
||||
.map-left-box{
|
||||
|
||||
width: 220px;
|
||||
height: 180px;
|
||||
// border: 1px solid;
|
||||
z-index: 9999999;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 10px;
|
||||
overflow: auto;
|
||||
margin-right: 10px;
|
||||
|
||||
.box-value{
|
||||
|
||||
width: 100%;
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
background-size: 100% 100%;
|
||||
background: url(../../../assets/new-screen/nomal-bg.png)no-repeat;
|
||||
background-size: 100% 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-top: 10px;
|
||||
.num{
|
||||
width: 20px;
|
||||
font-size: 12px;
|
||||
padding-left: 20px;
|
||||
font-family: DIN;
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
text-align: center;
|
||||
}
|
||||
.name{
|
||||
font-size: 12px;
|
||||
text-align: center;
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
}
|
||||
.value{
|
||||
font-size: 12px;
|
||||
width: 80px;
|
||||
line-height: 24px;
|
||||
height: 24px;
|
||||
background: url(../../../assets/new-screen/select-bg.png)no-repeat;
|
||||
background-size: 100% 100%;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
.map-right-box{
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
border: 1px solid;
|
||||
z-index: 9999999;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
}
|
||||
.box{
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
|
||||
}
|
||||
::v-deep *::-webkit-scrollbar{
|
||||
background-color: transparent!important;
|
||||
}
|
||||
::v-deep *::-webkit-scrollbar-thumb{
|
||||
background-color: transparent!important;
|
||||
}
|
||||
|
||||
</style>
|
||||
73
src/views/new-screen-zz-pv/components/right-bottom.vue
Normal file
73
src/views/new-screen-zz-pv/components/right-bottom.vue
Normal file
@ -0,0 +1,73 @@
|
||||
<template>
|
||||
<div class="left-bottom-warp">
|
||||
|
||||
<item :title="$t('screen.powerGenerationRanking')">
|
||||
<dv-loading v-if="tableLoading">Loading...</dv-loading>
|
||||
<div v-else class="con-box">
|
||||
<SwiperTable
|
||||
:titles="tableTitles"
|
||||
:widths="widths"
|
||||
:content-height="contentHeight"
|
||||
:data="tableData"
|
||||
:columns="tableColumns"
|
||||
:is-sort="false"
|
||||
/>
|
||||
</div>
|
||||
</item>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import SwiperTable from './SwiperTable.vue'
|
||||
import { GetEfficiencyDate } from '@/api/screen/zzScreen'
|
||||
import item from './item-warp.vue'
|
||||
export default {
|
||||
components: { item, SwiperTable },
|
||||
data() {
|
||||
return {
|
||||
tableLoading: false,
|
||||
tableTitles: [this.$t('screen.stationName'), this.$t('screen.cap')],
|
||||
tableData: [],
|
||||
widths: ['auto', 'auto', 'auto', 'auto'],
|
||||
contentHeight: 200,
|
||||
tableColumns: [
|
||||
'stationName',
|
||||
'stationCapacity',
|
||||
'efficiencyValue'
|
||||
]
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
},
|
||||
methods: {
|
||||
async getData(deptId) {
|
||||
try {
|
||||
this.tableLoading = true
|
||||
const res = await GetEfficiencyDate({
|
||||
deptId: deptId
|
||||
})
|
||||
this.tableData = res.data
|
||||
} finally {
|
||||
this.tableLoading = false
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.left-bottom-warp{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.con-box{
|
||||
width: 100%;
|
||||
padding-top: 10px;
|
||||
}
|
||||
}
|
||||
.class1{
|
||||
color: #F4E925;
|
||||
}
|
||||
</style>
|
||||
68
src/views/new-screen-zz-pv/components/right-center.vue
Normal file
68
src/views/new-screen-zz-pv/components/right-center.vue
Normal file
@ -0,0 +1,68 @@
|
||||
<template>
|
||||
<div class="right-top-warp">
|
||||
<item :title="$t('screen.powerGenerationEarningRanking')">
|
||||
<dv-loading v-if="tableLoading">Loading...</dv-loading>
|
||||
<div v-else class="con-box">
|
||||
<SwiperTableCenter
|
||||
:titles="tableTitles"
|
||||
:widths="widths"
|
||||
:content-height="contentHeight"
|
||||
:data="tableData"
|
||||
:columns="tableColumns"
|
||||
:show-header="false"
|
||||
tabel-height="53px"
|
||||
/>
|
||||
</div>
|
||||
</item>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import item from './item-warp.vue'
|
||||
import SwiperTableCenter from './SwiperTableCenter.vue'
|
||||
import { GetRegionalIncomeDate } from '@/api/screen/zzScreen'
|
||||
export default {
|
||||
components: { item, SwiperTableCenter },
|
||||
data() {
|
||||
return {
|
||||
tableLoading: false,
|
||||
tableTitles: ['电站名称', '容量'],
|
||||
tableData: [],
|
||||
widths: ['auto', 'auto', 'auto', 'auto'],
|
||||
contentHeight: 220,
|
||||
tableColumns: [
|
||||
'stationName',
|
||||
'incomeValue'
|
||||
]
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
},
|
||||
methods: {
|
||||
async getData(deptId) {
|
||||
try {
|
||||
this.tableLoading = true
|
||||
const res = await GetRegionalIncomeDate({
|
||||
deptId: deptId
|
||||
})
|
||||
this.tableData = res.data
|
||||
this.tableData.map((el) => {
|
||||
el.incomeValue = el.incomeValue + ' ' + this.$t('screen.mRMB')
|
||||
})
|
||||
} finally {
|
||||
this.tableLoading = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.right-top-warp {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
.con-box{
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
244
src/views/new-screen-zz-pv/components/right-top.vue
Normal file
244
src/views/new-screen-zz-pv/components/right-top.vue
Normal file
@ -0,0 +1,244 @@
|
||||
<template>
|
||||
<div class="right-top-warp">
|
||||
<item :title="$t('screen.groupEarning')">
|
||||
<div class="box">
|
||||
<div class="button-box">
|
||||
<el-tabs
|
||||
v-model="activeName"
|
||||
tab-position="top"
|
||||
@tab-click="handleClick"
|
||||
>
|
||||
<el-tab-pane :label="$t('screen.daily30')" name="day" />
|
||||
<el-tab-pane :label="$t('screen.monthly')" name="month" />
|
||||
<el-tab-pane :label="$t('screen.yearly')" name="year" />
|
||||
</el-tabs>
|
||||
</div>
|
||||
<div class="chart-box">
|
||||
<dv-loading v-if="loading">Loading...</dv-loading>
|
||||
<Chart v-else :options="options" />
|
||||
</div>
|
||||
</div>
|
||||
</item>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import item from './item-warp.vue'
|
||||
import { GetIncomeCurve } from '@/api/screen/zzScreen'
|
||||
export default {
|
||||
components: { item },
|
||||
props: {},
|
||||
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
options: {},
|
||||
deptId: null,
|
||||
type: 'day',
|
||||
activeName: 'day'
|
||||
}
|
||||
},
|
||||
|
||||
mounted() {
|
||||
// this.getData()
|
||||
},
|
||||
methods: {
|
||||
handleClick() {
|
||||
this.getData(this.deptId)
|
||||
},
|
||||
|
||||
async getData(deptId) {
|
||||
this.deptId = deptId
|
||||
try {
|
||||
this.loading = true
|
||||
const { data } = await GetIncomeCurve({ type: this.activeName, deptId: deptId })
|
||||
this.initChart(data)
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
initChart(val) {
|
||||
if (val.length) {
|
||||
const x_data = []
|
||||
const profit_data = []
|
||||
val.forEach((el) => {
|
||||
x_data.push(el.time)
|
||||
profit_data.push(el.profit)
|
||||
})
|
||||
this.options = {
|
||||
// backgroundColor: '#072685',
|
||||
grid: {
|
||||
left: '10%',
|
||||
top: '15%',
|
||||
right: '5%',
|
||||
bottom: '10%'
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis'
|
||||
},
|
||||
xAxis: [
|
||||
{
|
||||
data: x_data,
|
||||
axisLabel: {
|
||||
textStyle: {
|
||||
color: '#6E7174'
|
||||
},
|
||||
margin: 10 // 刻度标签与轴线之间的距离。
|
||||
},
|
||||
|
||||
axisLine: {
|
||||
show: false // 不显示x轴
|
||||
},
|
||||
axisTick: {
|
||||
show: false // 不显示刻度
|
||||
},
|
||||
boundaryGap: true,
|
||||
splitLine: {
|
||||
show: false,
|
||||
width: 0.08,
|
||||
lineStyle: {
|
||||
type: 'solid',
|
||||
color: '#03202E'
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
yAxis: [
|
||||
{
|
||||
type: 'value',
|
||||
name: this.$t('screen.mRMB'),
|
||||
nameTextStyle: {
|
||||
color: '#6E7174',
|
||||
fontSize: 12,
|
||||
padding: [0, 0, 0, -40]
|
||||
},
|
||||
|
||||
splitLine: {
|
||||
show: false,
|
||||
lineStyle: {
|
||||
color: '#eee',
|
||||
type: 'solid'
|
||||
}
|
||||
},
|
||||
axisTick: {
|
||||
show: false
|
||||
},
|
||||
axisLine: {
|
||||
show: false
|
||||
},
|
||||
axisLabel: {
|
||||
textStyle: {
|
||||
color: '#6E7174'
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
series: [
|
||||
{
|
||||
name: this.$t('screen.earning'),
|
||||
type: 'line',
|
||||
data: profit_data,
|
||||
smooth: true,
|
||||
symbolSize: 5,
|
||||
symbol: 'circle',
|
||||
itemStyle: {
|
||||
normal: {
|
||||
color: 'rgba(245, 209, 164, 1)' // 折线点的颜色
|
||||
}
|
||||
},
|
||||
lineStyle: {
|
||||
color: {
|
||||
type: 'linear',
|
||||
x: 0,
|
||||
y: 0,
|
||||
x2: 0,
|
||||
y2: 1,
|
||||
colorStops: [
|
||||
{
|
||||
offset: 0,
|
||||
color: 'rgba(245, 209, 164, 1)' // 0% 处的颜色
|
||||
},
|
||||
{
|
||||
offset: 1,
|
||||
color: 'rgba(236, 168, 80, 1)' // 100% 处的颜色
|
||||
}
|
||||
],
|
||||
global: false // 缺省为 false
|
||||
},
|
||||
// shadowColor: 'rgba(255, 120, 0,1)',
|
||||
shadowBlur: 8
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
} else {
|
||||
this.options = {
|
||||
title: {
|
||||
text: this.$t('screen.noData'),
|
||||
x: 'center',
|
||||
y: 'center',
|
||||
textStyle: {
|
||||
fontSize: 14,
|
||||
color: 'rgb(153, 153, 153)',
|
||||
fontWeight: 'normal'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.right-top-warp {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
.box {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
.button-box {
|
||||
width: 100%;
|
||||
height: 25px;
|
||||
padding-top: 5px;
|
||||
text-align: right;
|
||||
}
|
||||
.chart-box {
|
||||
height: calc(100% - 25px);
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
::v-deep .el-tabs {
|
||||
height: 100% !important;
|
||||
}
|
||||
::v-deep .el-tabs__header {
|
||||
height: 100% !important;
|
||||
}
|
||||
::v-deep .el-tabs__nav-wrap {
|
||||
height: 100% !important;
|
||||
}
|
||||
::v-deep .el-tabs__nav-scroll {
|
||||
height: 100% !important;
|
||||
display: flex;
|
||||
justify-content: right;
|
||||
}
|
||||
::v-deep .el-tabs__nav {
|
||||
transform: translate(0, -12px) !important;
|
||||
}
|
||||
::v-deep .el-tabs__active-bar {
|
||||
bottom: -15px !important;
|
||||
height: 6px !important;
|
||||
transform: skewX(-45deg);
|
||||
}
|
||||
::v-deep .el-tabs__nav-wrap::after {
|
||||
display: none;
|
||||
}
|
||||
::v-deep .el-tabs__item {
|
||||
padding: 0 10px !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
389
src/views/new-screen-zz-pv/index.vue
Normal file
389
src/views/new-screen-zz-pv/index.vue
Normal file
@ -0,0 +1,389 @@
|
||||
<template>
|
||||
<ScaleScreen :width="1920" :height="1080" class="scale-wrap" :self-adaption="true">
|
||||
<div class="bg">
|
||||
<!-- <dv-loading v-show="loading">Loading...</dv-loading> -->
|
||||
<div class="host-body">
|
||||
<!-- 头部 s -->
|
||||
<div class="title_wrap">
|
||||
<div class="title">
|
||||
<span :class="lang === 'zh'? 'left-title' : 'left-title-en'" />
|
||||
<span :class="lang === 'zh'? 'title-text' : 'en-eitle-text'">{{ $t('screen.pvScreenTitle') }}</span>
|
||||
<div class="right-title">
|
||||
<span>{{ time }}</span>
|
||||
<!-- <span class="weather">{{ weatherInfo ? weatherInfo.skyCon : '' }} {{ weatherInfo? weatherInfo.minTemperature :'' }}℃ ~ {{ weatherInfo ? weatherInfo.maxTemperature : '' }}℃</span> -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box">
|
||||
<div class="left">
|
||||
<div class="left-top">
|
||||
<LeftTop ref="LeftTopRef" :info="leftTopInfo" />
|
||||
</div>
|
||||
<div class="left-center">
|
||||
<LeftCenter ref="LeftCenterRef" />
|
||||
</div>
|
||||
<div class="left-bottom">
|
||||
<LeftBottom ref="LeftBottomRef" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="center">
|
||||
<div class="center-top">
|
||||
<CenterTop ref="CenterTopRef" :info="centerTopInfo" />
|
||||
</div>
|
||||
<div class="center-map">
|
||||
<MapCenter ref="MapCenterRef" />
|
||||
</div>
|
||||
|
||||
<div class="center-bottom">
|
||||
<CenterBottom ref="CenterBottomRef" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="right">
|
||||
<div class="right-top">
|
||||
<RightTop ref="RightTopRef" />
|
||||
</div>
|
||||
<div class="right-center">
|
||||
<RightCenter ref="RightCenterRef" />
|
||||
</div>
|
||||
<div class="right-bottom">
|
||||
<RightRight ref="RightRightRef" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</ScaleScreen>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import ScaleScreen from '@/components/scale-screen/scale-screen.vue'
|
||||
import MapCenter from './components/map-center.vue'
|
||||
import LeftTop from './components/left-top.vue'
|
||||
import LeftCenter from './components/left-center.vue'
|
||||
import LeftBottom from './components/left-bottom.vue'
|
||||
import RightTop from './components/right-top.vue'
|
||||
import RightCenter from './components/right-center.vue'
|
||||
import RightRight from './components/right-bottom.vue'
|
||||
import CenterBottom from './components/center-bottom.vue'
|
||||
import CenterTop from './components/center-top.vue'
|
||||
import { GetOverviewData, GetNewWeather, GetDeptIdByStationId } from '@/api/screen/zzScreen'
|
||||
export default {
|
||||
components: {
|
||||
// MapCenter, CenterTop,
|
||||
ScaleScreen, MapCenter, LeftTop, LeftCenter, LeftBottom, RightTop, RightCenter, RightRight, CenterBottom, CenterTop
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
time: '',
|
||||
leftTopInfo: null,
|
||||
leftBottomInfo: null,
|
||||
deptId: null,
|
||||
interval: null,
|
||||
centerTopInfo: {
|
||||
totalProfit: 0,
|
||||
yearProfit: 0,
|
||||
yestProfit: 0
|
||||
},
|
||||
weatherInfo: {
|
||||
skyCon: '',
|
||||
minTemperature: '',
|
||||
maxTemperature: ''
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
lang() {
|
||||
return this.$store.getters.language
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.changeFavicon(`./zhongzi.ico`)
|
||||
setInterval(() => {
|
||||
this.time = this.getCurrentFormattedTime()
|
||||
}, 1000)
|
||||
},
|
||||
mounted() {
|
||||
this.getDeptIdByStationId()
|
||||
},
|
||||
destroyed() {
|
||||
clearInterval(this.interval)
|
||||
this.interval = null
|
||||
},
|
||||
methods: {
|
||||
// 修改Favicon的方法
|
||||
changeFavicon(link) {
|
||||
let $favicon = document.querySelector('link[rel="icon"]')
|
||||
if ($favicon !== null) {
|
||||
$favicon.href = link
|
||||
} else {
|
||||
$favicon = document.createElement('link')
|
||||
$favicon.rel = 'icon'
|
||||
$favicon.href = link
|
||||
document.head.appendChild($favicon)
|
||||
}
|
||||
},
|
||||
getCurrentFormattedTime() {
|
||||
const now = new Date()
|
||||
const year = now.getFullYear().toString().padStart(4, '0')
|
||||
const month = (now.getMonth() + 1).toString().padStart(2, '0')
|
||||
const day = now.getDate().toString().padStart(2, '0')
|
||||
const hours = now.getHours().toString().padStart(2, '0')
|
||||
const minutes = now.getMinutes().toString().padStart(2, '0')
|
||||
const seconds = now.getSeconds().toString().padStart(2, '0')
|
||||
|
||||
const formattedTime = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
|
||||
return formattedTime
|
||||
},
|
||||
async getData() {
|
||||
try {
|
||||
this.$refs.LeftCenterRef.getData(this.deptId)
|
||||
this.$refs.LeftBottomRef.getData(this.deptId)
|
||||
this.$refs.RightTopRef.getData(this.deptId)
|
||||
this.$refs.RightCenterRef.getData(this.deptId)
|
||||
this.$refs.RightRightRef.getData(this.deptId)
|
||||
// this.getWeatherInfo() 国外大屏不展示天气
|
||||
this.$refs.MapCenterRef.getStationNum(this.deptId)
|
||||
this.$refs.MapCenterRef.getData(this.deptId)
|
||||
this.$refs.MapCenterRef.getLeftData(this.deptId)
|
||||
|
||||
this.$refs.CenterBottomRef.getData(this.deptId)
|
||||
const res = await GetOverviewData({
|
||||
deptId: this.deptId
|
||||
})
|
||||
this.leftTopInfo = {
|
||||
capacity: res.data.capacity,
|
||||
stationNumber: res.data.stationNumber,
|
||||
yearCharge: res.data.yearCharge,
|
||||
yearDischarge: res.data.yearDischarge,
|
||||
totalCharge: res.data.totalCharge,
|
||||
totalDischarge: res.data.totalDischarge,
|
||||
dayCharge: res.data.dayCharge,
|
||||
dayDischarge: res.data.dayDischarge
|
||||
}
|
||||
|
||||
this.centerTopInfo = {
|
||||
totalProfit: (Number(res.data.totalProfit) / 1E4).toFixed(2),
|
||||
yearProfit: (Number(res.data.yearProfit) / 1E4).toFixed(2),
|
||||
yestProfit: (Number(res.data.yestProfit) / 1E4).toFixed(2)
|
||||
}
|
||||
} catch (err) {
|
||||
this.leftTopInfo = {
|
||||
capacity: 0,
|
||||
stationNumber: 0,
|
||||
yearCharge: 0,
|
||||
yearDischarge: 0,
|
||||
totalCharge: 0,
|
||||
totalDischarge: 0,
|
||||
dayCharge: 0,
|
||||
dayDischarge: 0
|
||||
}
|
||||
this.centerTopInfo = {
|
||||
totalProfit: 0,
|
||||
yearProfit: 0,
|
||||
yestProfit: 0
|
||||
}
|
||||
}
|
||||
},
|
||||
getWeatherInfo() {
|
||||
GetNewWeather().then(res => {
|
||||
this.weatherInfo = res.data
|
||||
})
|
||||
},
|
||||
getDeptIdByStationId() {
|
||||
GetDeptIdByStationId({
|
||||
stationId: null
|
||||
}).then(res => {
|
||||
this.deptId = res.data?.deptId
|
||||
this.getData()
|
||||
this.interval = setInterval(() => {
|
||||
this.getData()
|
||||
}, 600000)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
// 左右两侧图表宽度
|
||||
$lrWidth: 385px;
|
||||
$cTopHeight: 85px;
|
||||
$lTopHeight: 313px;
|
||||
$lBottomHeight: 300px;
|
||||
$rTopHeight: 313px;
|
||||
$rBottomHeight: 300px;
|
||||
$margin: 16px;
|
||||
.scale-wrap {
|
||||
color: #d3d6dd;
|
||||
width: 1920px;
|
||||
height: 1080px;
|
||||
overflow: hidden;
|
||||
|
||||
.bg {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
background-color: #000c18;
|
||||
.box{
|
||||
height: 100%;
|
||||
display: flex;
|
||||
.left {
|
||||
width: $lrWidth;
|
||||
height: calc(100% - 100px);
|
||||
display: flex;
|
||||
margin-left: $margin;
|
||||
flex-direction: column;
|
||||
|
||||
.left-top {
|
||||
width: 100%;
|
||||
height: $lTopHeight;
|
||||
margin-bottom: $margin;
|
||||
}
|
||||
|
||||
.left-center {
|
||||
width: 100%;
|
||||
flex: 1;
|
||||
margin-bottom: $margin;
|
||||
|
||||
}
|
||||
|
||||
.left-bottom {
|
||||
width: 100%;
|
||||
margin-bottom: $margin;
|
||||
height: $lBottomHeight;
|
||||
|
||||
}
|
||||
}
|
||||
.center{
|
||||
flex: 1;
|
||||
height: calc(100% - 100px);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin: 0 $margin 0 $margin;
|
||||
.center-top{
|
||||
height: 80px;
|
||||
|
||||
}
|
||||
.center-map{
|
||||
flex: 1;
|
||||
margin-bottom: $margin;
|
||||
}
|
||||
.center-bottom{
|
||||
height: $lBottomHeight;
|
||||
margin-bottom: $margin;
|
||||
}
|
||||
}
|
||||
.right {
|
||||
width: $lrWidth;
|
||||
height: calc(100% - 100px);
|
||||
display: flex;
|
||||
margin-right: $margin;
|
||||
flex-direction: column;
|
||||
|
||||
.right-top {
|
||||
width: 100%;
|
||||
height: $rTopHeight;
|
||||
margin-bottom: $margin;
|
||||
}
|
||||
|
||||
.right-center {
|
||||
width: 100%;
|
||||
margin-bottom: $margin;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.right-bottom {
|
||||
width: 100%;
|
||||
margin-bottom: $margin;
|
||||
height: $rBottomHeight;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
.host-body {
|
||||
height: 100%;
|
||||
background-color: #070A0C;
|
||||
background-size: 100% 100%;
|
||||
|
||||
.title_wrap {
|
||||
height: 100px;
|
||||
background-image: url("../../assets/new-screen/top-bg.png");
|
||||
background-size: cover;
|
||||
background-position: center center;
|
||||
position: relative;
|
||||
margin-bottom: 4px;
|
||||
|
||||
}
|
||||
|
||||
.title {
|
||||
position: relative;
|
||||
text-align: center;
|
||||
background-size: cover;
|
||||
color: transparent;
|
||||
height: 127px;
|
||||
line-height: 100px;
|
||||
|
||||
.left-title {
|
||||
width: 200px;
|
||||
height: 52px;
|
||||
background: url(../../assets/new-screen/zhongzi.png) no-repeat;
|
||||
background-size: 100% 100%;
|
||||
color: #fff;
|
||||
font-size: 16px;
|
||||
position: absolute;
|
||||
left: $margin;
|
||||
top: 30px;
|
||||
}
|
||||
.left-title-en {
|
||||
width: 200px;
|
||||
height: 52px;
|
||||
background: url(../../assets/new-screen/zhongzien.png) no-repeat;
|
||||
background-size: 100% 100%;
|
||||
color: #fff;
|
||||
font-size: 16px;
|
||||
position: absolute;
|
||||
left: $margin;
|
||||
top: 30px;
|
||||
}
|
||||
.right-title {
|
||||
font-family: LCD;
|
||||
color: #fff;
|
||||
position: absolute;
|
||||
right: $margin;
|
||||
top: 10px;
|
||||
font-size: 22px;
|
||||
.weather{
|
||||
margin-left: 16px;
|
||||
}
|
||||
}
|
||||
.en-eitle-text{
|
||||
font-size: 18px;
|
||||
letter-spacing: 1px;
|
||||
font-weight: 900;
|
||||
width: 100%;
|
||||
background: linear-gradient(92deg, #fff, #fff 48.85254%, #fff);
|
||||
font-family: PangMenNumber;
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
}
|
||||
.title-text {
|
||||
font-size: 38px;
|
||||
font-weight: 900;
|
||||
letter-spacing: 6px;
|
||||
width: 100%;
|
||||
background: linear-gradient(92deg,
|
||||
#fff 0%,
|
||||
#fff 48.8525390625%,
|
||||
#fff 100%);
|
||||
font-family: PangMenNumber;
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}</style>
|
||||
@ -0,0 +1,89 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="loader">
|
||||
<div id="ld4">
|
||||
<div />
|
||||
<div />
|
||||
<div />
|
||||
<div />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'Loading',
|
||||
components: {},
|
||||
props: {},
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
computed: {},
|
||||
watch: {},
|
||||
created() {},
|
||||
mounted() {},
|
||||
methods: {}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.loader {
|
||||
width: 60px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin: 0 10px;
|
||||
}
|
||||
|
||||
#ld4 {
|
||||
position: relative;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
justify-content: space-between;
|
||||
}
|
||||
#ld4 div {
|
||||
height: 8px;
|
||||
width: 8px;
|
||||
border-radius: 50%;
|
||||
background: #409eff;
|
||||
}
|
||||
#ld4 div:nth-child(1) {
|
||||
animation: ld4 3s linear infinite 0s;
|
||||
}
|
||||
#ld4 div:nth-child(2) {
|
||||
animation: ld4 3s linear infinite 0.15s;
|
||||
}
|
||||
#ld4 div:nth-child(3) {
|
||||
animation: ld4 3s linear infinite 0.3s;
|
||||
}
|
||||
#ld4 div:nth-child(4) {
|
||||
animation: ld4 3s linear infinite 0.45s;
|
||||
}
|
||||
|
||||
@keyframes ld4 {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: scale(0.3);
|
||||
// background: #409eff;
|
||||
}
|
||||
25% {
|
||||
opacity: 1;
|
||||
transform: scale(1.8);
|
||||
// background: #0072bb;
|
||||
}
|
||||
50% {
|
||||
opacity: 0;
|
||||
transform: scale(0.3);
|
||||
// background: #fe4a49;
|
||||
}
|
||||
75% {
|
||||
opacity: 1;
|
||||
transform: scale(1.8);
|
||||
// background: #fed766;
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
988
src/views/revenue-management/pv-earnings-statement/index.vue
Normal file
988
src/views/revenue-management/pv-earnings-statement/index.vue
Normal file
@ -0,0 +1,988 @@
|
||||
<template>
|
||||
<div class="earnings-warp">
|
||||
<el-form id="searchForm">
|
||||
<el-row :gutter="5" class="search-row">
|
||||
<el-col :xs="24" :sm="24" :md="7" :lg="7" :xl="7">
|
||||
<el-form-item :label="$t('state.month') + ':'" label-width="90px">
|
||||
<el-date-picker
|
||||
v-model="month"
|
||||
type="month"
|
||||
value-format="yyyy-MM"
|
||||
:placeholder="$t('state.selectMonth')"
|
||||
:clearable="false"
|
||||
@change="changeTime"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col
|
||||
:xs="24"
|
||||
:sm="24"
|
||||
:md="17"
|
||||
:lg="17"
|
||||
:xl="17"
|
||||
style="text-align: right"
|
||||
>
|
||||
<el-button
|
||||
v-permission="['business:earningsCalculate:oneKeyComputation']"
|
||||
style="margin-left: auto"
|
||||
type="primary"
|
||||
class="reset-btn"
|
||||
@click="handleComputeReport"
|
||||
>{{ $t("state.onButtonComputed") }}</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
class="reset-btn"
|
||||
:loading="downLoadingReport"
|
||||
@click="handleExportReport"
|
||||
>{{ $t("state.exportBill") }}</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
class="reset-btn"
|
||||
:loading="downLoading"
|
||||
@click="handleExportTempData"
|
||||
>{{ $t("state.exportReport") }}</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
|
||||
<el-row class="top-search">
|
||||
<el-col :span="24" class="report-title">{{
|
||||
totalData.stationName
|
||||
}}</el-col>
|
||||
</el-row>
|
||||
|
||||
<div class="top">
|
||||
<ItemBox :title="$t('state.powerGenerationStatus')">
|
||||
<div class="box">
|
||||
<div class="value-box">
|
||||
<div class="top-box">
|
||||
<span class="d" />
|
||||
<el-tooltip
|
||||
:content="$t('state.totalStringCapacity')"
|
||||
placement="top"
|
||||
effect="dark"
|
||||
>
|
||||
<span class="title">{{ $t("state.totalStringCapacity") }}</span>
|
||||
</el-tooltip>
|
||||
|
||||
<span class="d" />
|
||||
</div>
|
||||
<div class="center-line" />
|
||||
<div class="bottom-value">
|
||||
{{ totalData.capacity }}
|
||||
<span class="unit">kWp</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="value-box">
|
||||
<div class="top-box">
|
||||
<span class="d" />
|
||||
<el-tooltip
|
||||
:content="$t('state.currentMonthlyPowerGeneration')"
|
||||
placement="top"
|
||||
effect="dark"
|
||||
>
|
||||
<span class="title">{{
|
||||
$t("state.currentMonthlyPowerGeneration")
|
||||
}}</span>
|
||||
</el-tooltip>
|
||||
<span class="d" />
|
||||
</div>
|
||||
<div class="center-line" />
|
||||
<div class="bottom-value">
|
||||
203{{ totalData.totalChargeElec }}.55
|
||||
<span class="unit">kWh</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="value-box">
|
||||
<div class="top-box">
|
||||
<span class="d" />
|
||||
<el-tooltip
|
||||
:content="$t('state.cumulativePowerGeneration')"
|
||||
placement="top"
|
||||
effect="dark"
|
||||
>
|
||||
<span class="title">{{
|
||||
$t("state.cumulativePowerGeneration")
|
||||
}}</span>
|
||||
</el-tooltip>
|
||||
<span class="d" />
|
||||
</div>
|
||||
<div class="center-line" />
|
||||
<div class="bottom-value">
|
||||
237{{ totalData.totalCharge }}.12
|
||||
<span class="unit">kWh</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="value-box">
|
||||
<div class="top-box">
|
||||
<span class="d" />
|
||||
<el-tooltip
|
||||
:content="$t('state.equivalentPowerGenerationTime')"
|
||||
placement="top"
|
||||
effect="dark"
|
||||
>
|
||||
<span class="title">{{
|
||||
$t("state.equivalentPowerGenerationTime")
|
||||
}}</span>
|
||||
</el-tooltip>
|
||||
<span class="d" />
|
||||
</div>
|
||||
<div class="center-line" />
|
||||
<div class="bottom-value">
|
||||
9.{{ totalData.totalDischargeElec }}6
|
||||
<span class="unit">kWh/kWp</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="value-box">
|
||||
<div class="top-box">
|
||||
<span class="d" />
|
||||
<el-tooltip
|
||||
:content="$t('state.peakACpower')"
|
||||
placement="top"
|
||||
effect="dark"
|
||||
>
|
||||
<span class="title">{{ $t("state.peakACpower") }}</span>
|
||||
</el-tooltip>
|
||||
<span class="d" />
|
||||
</div>
|
||||
<div class="center-line" />
|
||||
<div class="bottom-value">
|
||||
6{{ totalData.totalDischarge }}.87
|
||||
<span class="unit">kW</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="value-box">
|
||||
<div class="top-box">
|
||||
<span class="d" />
|
||||
<el-tooltip
|
||||
:content="$t('state.gridConnectedDuration')"
|
||||
placement="top"
|
||||
effect="dark"
|
||||
>
|
||||
<span class="title">{{
|
||||
$t("state.gridConnectedDuration")
|
||||
}}</span>
|
||||
</el-tooltip>
|
||||
<span class="d" />
|
||||
</div>
|
||||
<div class="center-line" />
|
||||
<div class="bottom-value">
|
||||
0
|
||||
<span class="unit">h</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ItemBox>
|
||||
</div>
|
||||
|
||||
<div class="center">
|
||||
<ItemBox :title="$t('state.monthlyPowerGeneration')">
|
||||
<div v-loading="loading" class="charts-box">
|
||||
<Chart
|
||||
ref="chart"
|
||||
:key="key"
|
||||
:options="powerOptions"
|
||||
:class-name="'chart'"
|
||||
/>
|
||||
</div>
|
||||
</ItemBox>
|
||||
<!-- <el-row :gutter="10" style="width: 100%">
|
||||
<el-col
|
||||
:xs="24"
|
||||
:sm="12"
|
||||
:md="12"
|
||||
:lg="12"
|
||||
:xl="12"
|
||||
class="center-left"
|
||||
>
|
||||
<ItemBox :title="$t('state.charge')">
|
||||
<el-table
|
||||
v-loading="load_data"
|
||||
:header-cell-style="{
|
||||
color: '#CEEBFF',
|
||||
textAlign: 'center',
|
||||
}"
|
||||
:data="chargeArr"
|
||||
style="width: 100%"
|
||||
:row-style="{ height: '40px' }"
|
||||
height="175"
|
||||
>
|
||||
<el-table-column
|
||||
align="center"
|
||||
prop="rateType"
|
||||
:label="$t('state.time')"
|
||||
/>
|
||||
<el-table-column
|
||||
align="center"
|
||||
prop="elec"
|
||||
:label="$t('state.ele')"
|
||||
/>
|
||||
<el-table-column
|
||||
align="center"
|
||||
prop="digital"
|
||||
:label="$t('state.expend')"
|
||||
/>
|
||||
</el-table>
|
||||
</ItemBox>
|
||||
</el-col>
|
||||
<el-col
|
||||
:xs="24"
|
||||
:sm="12"
|
||||
:md="12"
|
||||
:lg="12"
|
||||
:xl="12"
|
||||
class="center-right"
|
||||
>
|
||||
<ItemBox :title="$t('state.disCharge')">
|
||||
<div class="box">
|
||||
<el-table
|
||||
v-loading="load_data"
|
||||
:header-cell-style="{
|
||||
color: '#CEEBFF',
|
||||
textAlign: 'center',
|
||||
}"
|
||||
:data="dischargeArr"
|
||||
style="width: 100%"
|
||||
:row-style="{ height: '40px' }"
|
||||
height="175"
|
||||
>
|
||||
<el-table-column
|
||||
align="center"
|
||||
prop="rateType"
|
||||
:label="$t('state.time')"
|
||||
/>
|
||||
<el-table-column
|
||||
align="center"
|
||||
prop="elec"
|
||||
:label="$t('state.ele')"
|
||||
/>
|
||||
<el-table-column
|
||||
align="center"
|
||||
prop="digital"
|
||||
:label="$t('state.earnings') + `(${$t('state.rmb')})`"
|
||||
/>
|
||||
</el-table>
|
||||
</div>
|
||||
</ItemBox>
|
||||
</el-col>
|
||||
</el-row> -->
|
||||
</div>
|
||||
|
||||
<div class="bottom">
|
||||
<ItemBox :title="$t('state.projectRevenue')">
|
||||
<div class="box">
|
||||
<div class="value-box">
|
||||
<div class="title">{{ $t("state.monthlyPVpowerGeneration") }}</div>
|
||||
<div class="bottom-value">
|
||||
<div class="value">
|
||||
2031.{{ totalData.totalChargePrice }}7
|
||||
<span class="unit">kWh</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="value-box">
|
||||
<div class="title">
|
||||
{{ $t("state.monthlyInverterPowerGeneration") }}
|
||||
</div>
|
||||
<div class="bottom-value">
|
||||
<div class="value">
|
||||
237{{ totalData.totalDisChargePrice }}.53
|
||||
<span class="unit">kWh</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="value-box">
|
||||
<div class="title">{{ $t("state.monthlyIncome") }}</div>
|
||||
<div class="bottom-value">
|
||||
<div class="value">
|
||||
45{{ totalData.income }}8.3
|
||||
<span class="unit">{{ $t("state.rmb") }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ItemBox>
|
||||
</div>
|
||||
|
||||
<el-dialog
|
||||
:append-to-body="false"
|
||||
:title="$t('state.earningsRecalculation')"
|
||||
center
|
||||
:close-on-click-modal="false"
|
||||
:visible.sync="computedShow"
|
||||
width="30%"
|
||||
@close="closeComputed"
|
||||
>
|
||||
<template v-if="!conformLoading">
|
||||
<el-form :model="filter">
|
||||
<el-row class="search-row">
|
||||
<el-col v-if="timeShow" :span="24">
|
||||
<el-form-item
|
||||
:label="$t('state.computedTime') + ':'"
|
||||
label-width="120px"
|
||||
>
|
||||
<el-date-picker
|
||||
v-model="filter.time"
|
||||
style="width: 90%"
|
||||
type="daterange"
|
||||
value-format="yyyy-MM-dd"
|
||||
range-separator="~"
|
||||
:start-placeholder="$t('state.startTime')"
|
||||
:end-placeholder="$t('state.endTime')"
|
||||
:disabled="progressShow"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col v-if="progressShow" :span="24">
|
||||
<el-form-item
|
||||
:label="$t('state.conputedProgress') + ':'"
|
||||
label-width="150px"
|
||||
>
|
||||
<el-progress
|
||||
:text-inside="true"
|
||||
:stroke-width="20"
|
||||
style="margin-top: 8px"
|
||||
:percentage="percentage"
|
||||
:format="progressFormat"
|
||||
class="case-progress"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="closeComputed">{{ $t("state.close") }}</el-button>
|
||||
<el-button v-if="sureShow" type="primary" @click="sureComputed">{{
|
||||
$t("state.sure")
|
||||
}}</el-button>
|
||||
</span>
|
||||
</template>
|
||||
<loading v-show="conformLoading" />
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as echarts from 'echarts'
|
||||
import {
|
||||
GetTotal,
|
||||
OneKeyComputation,
|
||||
SureOneKeyComputation
|
||||
} from '@/api/revenue-management/earnings-statement'
|
||||
import loading from './components/loading'
|
||||
import { handleDownExcel } from '@/utils'
|
||||
export default {
|
||||
components: { loading },
|
||||
data() {
|
||||
return {
|
||||
month: '',
|
||||
downLoadingReport: false,
|
||||
downLoading: false,
|
||||
totalData: {},
|
||||
load_data: false,
|
||||
chargeArr: [],
|
||||
dischargeArr: [],
|
||||
computedTime: [],
|
||||
computedShow: false,
|
||||
computedLoading: false,
|
||||
filter: {
|
||||
time: []
|
||||
},
|
||||
percentage: 0,
|
||||
finish: '',
|
||||
timeShow: true,
|
||||
progressShow: false,
|
||||
sureShow: true,
|
||||
timer: undefined,
|
||||
confirmTimer: undefined,
|
||||
conformLoading: false,
|
||||
|
||||
powerOptions: undefined,
|
||||
currentType: 'day',
|
||||
color: ['#4197FF'],
|
||||
key: 0,
|
||||
dontClick: true
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
currentStation() {
|
||||
return this.$store.getters.currentStation || undefined
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
currentStation: {
|
||||
handler(val) {
|
||||
if (val && val.id) {
|
||||
const now = new Date()
|
||||
const year = now.getFullYear()
|
||||
const month = String(now.getMonth() + 1).padStart(2, '0') // 月份从0开始,所以要加1,然后用padStart确保是两位数
|
||||
this.month = `${year}-${month}`
|
||||
this.stationId = val.id
|
||||
this.get_table_data()
|
||||
}
|
||||
},
|
||||
deep: true,
|
||||
immediate: true
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
const currentData = []
|
||||
for (let i = 1; i < 32; i++) {
|
||||
currentData.push({
|
||||
date: i,
|
||||
chargeElec: Number((Math.random() * 50 + 30).toFixed(2))
|
||||
})
|
||||
}
|
||||
this.initCharts(currentData, 1)
|
||||
},
|
||||
methods: {
|
||||
closeComputed() {
|
||||
if (this.dontClick) {
|
||||
return
|
||||
}
|
||||
this.computedShow = false
|
||||
if (this.timer) {
|
||||
clearInterval(this.timer)
|
||||
}
|
||||
if (this.confirmTimer) {
|
||||
clearInterval(this.confirmTimer)
|
||||
}
|
||||
setTimeout(() => {
|
||||
this.filter.time = []
|
||||
this.sureShow = true
|
||||
}, 500)
|
||||
},
|
||||
getProgress() {
|
||||
const that = this
|
||||
const params = {
|
||||
stationId: this.stationId
|
||||
}
|
||||
this.conformLoading = true
|
||||
this.timer = setInterval(async() => {
|
||||
try {
|
||||
const res = await SureOneKeyComputation(params)
|
||||
|
||||
if (res.data?.finish === 1) {
|
||||
// 计算完成
|
||||
that.sureShow = false
|
||||
this.percentage = +res.data.progress
|
||||
clearInterval(this.timer)
|
||||
}
|
||||
if (res.data?.finish === '') {
|
||||
// 未计算
|
||||
that.progressShow = false
|
||||
that.timeShow = true
|
||||
that.sureShow = true
|
||||
clearInterval(this.timer)
|
||||
}
|
||||
if (res.data?.finish !== 1 && res.data?.finish !== '') {
|
||||
// 计算中
|
||||
that.progressShow = true
|
||||
that.timeShow = false
|
||||
that.sureShow = false
|
||||
this.percentage = +res.data.progress
|
||||
}
|
||||
this.conformLoading = false
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
clearInterval(this.timer)
|
||||
this.$message.warning(this.$t('state.computedFail'))
|
||||
this.conformLoading = false
|
||||
}
|
||||
}, 1000)
|
||||
},
|
||||
progressFormat(percentage) {
|
||||
return percentage === 100 ? this.$t('state.finish') : `${percentage}%`
|
||||
},
|
||||
async sureComputed() {
|
||||
if (this.dontClick) {
|
||||
return
|
||||
}
|
||||
const that = this
|
||||
if (this.filter.time.length === 0) {
|
||||
this.$message.warning(this.$t('state.selectComputedTime'))
|
||||
return
|
||||
}
|
||||
this.computedLoading = true
|
||||
const params = {
|
||||
stationId: this.stationId,
|
||||
startTime: this.filter.time[0],
|
||||
endTime: this.filter.time[1]
|
||||
}
|
||||
let res = await OneKeyComputation(params)
|
||||
this.sureShow = false
|
||||
this.confirmTimer = setInterval(async() => {
|
||||
try {
|
||||
res = await SureOneKeyComputation(params)
|
||||
// that.sureShow = false
|
||||
this.timeShow = true
|
||||
this.progressShow = true
|
||||
this.percentage = +res.data.progress
|
||||
if (res.data.finish === 1) {
|
||||
// 计算完成
|
||||
// this.sureShow = true
|
||||
that.computedLoading = false
|
||||
this.percentage = +res.data.progress
|
||||
clearInterval(this.confirmTimer)
|
||||
}
|
||||
if (res.data?.finish === '') {
|
||||
// 未计算
|
||||
that.computedLoading = false
|
||||
// res = await OneKeyComputation(params)
|
||||
clearInterval(this.confirmTimer)
|
||||
}
|
||||
if (res.data.finish !== 1 && res.data.finish !== '') {
|
||||
// 计算中
|
||||
this.percentage = +res.data.progress
|
||||
}
|
||||
} catch (error) {
|
||||
clearInterval(this.confirmTimer)
|
||||
this.$message.warning(this.$t('state.computedFail'))
|
||||
}
|
||||
}, 3000)
|
||||
},
|
||||
changeTime() {
|
||||
this.get_table_data()
|
||||
},
|
||||
async get_table_data() {
|
||||
this.load_data = true
|
||||
const params = {
|
||||
stationId: this.stationId,
|
||||
time: this.month
|
||||
}
|
||||
try {
|
||||
const res = await GetTotal(params)
|
||||
this.totalData = res.data
|
||||
this.chargeArr = []
|
||||
this.dischargeArr = []
|
||||
if (res.data.finish === 0) {
|
||||
this.$message.warning(
|
||||
`${this.$t('state.computeding')}${res.data.progress}${this.$t(
|
||||
'state.laterQuery'
|
||||
)}`
|
||||
)
|
||||
}
|
||||
if (res.data.list.length) {
|
||||
res.data.list.forEach((el) => {
|
||||
if (+el.type === 0) {
|
||||
this.chargeArr.push(el)
|
||||
}
|
||||
if (+el.type === 1) {
|
||||
this.dischargeArr.push(el)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
this.chargeArr = []
|
||||
this.dischargeArr = []
|
||||
}
|
||||
} catch (error) {
|
||||
// console.log(error);
|
||||
} finally {
|
||||
this.load_data = false
|
||||
}
|
||||
},
|
||||
handleExportReport() {
|
||||
if (this.dontClick) {
|
||||
return
|
||||
}
|
||||
this.downLoadingReport = true
|
||||
const params = {
|
||||
title: this.$t('state.bill'),
|
||||
stationId: this.stationId,
|
||||
time: this.month
|
||||
}
|
||||
handleDownExcel(
|
||||
'/business/earningsCalculate/exportReport',
|
||||
params,
|
||||
(callback) => {
|
||||
console.log(callback)
|
||||
this.downLoadingReport = false
|
||||
}
|
||||
)
|
||||
},
|
||||
handleExportTempData() {
|
||||
if (this.dontClick) {
|
||||
return
|
||||
}
|
||||
this.downLoading = true
|
||||
const params = {
|
||||
title: this.$t('state.earningReport'),
|
||||
stationId: this.stationId,
|
||||
time: this.month
|
||||
}
|
||||
handleDownExcel(
|
||||
'/business/earningsCalculate/export',
|
||||
params,
|
||||
(callback) => {
|
||||
console.log(callback)
|
||||
this.downLoading = false
|
||||
}
|
||||
)
|
||||
},
|
||||
handleComputeReport() {
|
||||
if (this.dontClick) {
|
||||
return
|
||||
}
|
||||
this.computedShow = true
|
||||
this.getProgress()
|
||||
},
|
||||
|
||||
// 新增代码
|
||||
|
||||
initCharts(val, type) {
|
||||
const x_data = []
|
||||
const charge_data = []
|
||||
// const discharge_data = []
|
||||
// let benefit_data = [0, 0, 0, 0, 0, 0, 0]
|
||||
if (val && val.length > 0) {
|
||||
val.forEach((item) => {
|
||||
x_data.push(item.date)
|
||||
charge_data.push(item.chargeElec)
|
||||
// discharge_data.push(item.dischargeElec)
|
||||
})
|
||||
}
|
||||
this.powerOptions = {
|
||||
grid: {
|
||||
top: '25%',
|
||||
left: '5%',
|
||||
right: '5%',
|
||||
bottom: '5%',
|
||||
containLabel: true
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
backgroundColor: 'rgba(0,0,0,0,)',
|
||||
borderColor: 'rgba(0,0,0,0,);',
|
||||
borderWidth: 0,
|
||||
textStyle: {
|
||||
width: 160,
|
||||
height: 250,
|
||||
lineHeight: 24,
|
||||
color: '#ffffff',
|
||||
fontSize: '14',
|
||||
fontFamily: 'SourceHanSansCN-Normal'
|
||||
},
|
||||
formatter: (params) => {
|
||||
// 获取xAxis data中的数据
|
||||
let dataStr = `<div><p style="font-weight:bold;margin:0 8px 15px;">${this.month}-${params[0].name}</p></div>`
|
||||
params.forEach((item) => {
|
||||
dataStr += `<div>
|
||||
<div style="margin: 0 8px;">
|
||||
<span style="display:inline-block;margin-right:5px;width:10px;height:10px;background-color:${this.color[0]};"></span>
|
||||
<span>${item.seriesName}</span>
|
||||
<span style="float:right;color:#00C8FF;margin-left:20px;">${item.data}</span>
|
||||
</div>
|
||||
</div>`
|
||||
})
|
||||
const div = `<div style='border: 1px solid ;
|
||||
border-image: linear-gradient(130deg, #FFFFFF 0%, rgba(201,255,243,0.00) 22%, rgba(201,255,243,0.00) 75%, rgba(201,255,243,0.00) 80%, #FFFFFF 99%, #FFFFFF 99%) 1;
|
||||
box-shadow: inset 0px 2px 16px 0px rgba(0, 148, 255, 0.4);' >${dataStr}</div>`
|
||||
return div
|
||||
}
|
||||
},
|
||||
xAxis: [
|
||||
{
|
||||
type: 'category',
|
||||
data: x_data,
|
||||
axisLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: '#90e9d8'
|
||||
}
|
||||
},
|
||||
axisLabel: {
|
||||
show: true,
|
||||
color: '#CEEBFF'
|
||||
},
|
||||
|
||||
axisTick: {
|
||||
show: false
|
||||
}
|
||||
}
|
||||
],
|
||||
yAxis: [
|
||||
{
|
||||
type: 'value',
|
||||
name: `kWh`,
|
||||
nameTextStyle: {
|
||||
color: ' rgba(255, 255, 255, 0.5)'
|
||||
},
|
||||
axisLine: {
|
||||
show: false,
|
||||
lineStyle: {
|
||||
color: '#90e9d8'
|
||||
}
|
||||
},
|
||||
axisLabel: {
|
||||
show: true,
|
||||
color: '#CEEBFF'
|
||||
},
|
||||
axisTick: {
|
||||
show: false
|
||||
},
|
||||
splitLine: {
|
||||
show: true, // 强制显示分割线(默认已开启,确保不被隐藏)
|
||||
lineStyle: {
|
||||
type: 'dashed', // 线型设为虚线
|
||||
color: 'rgba(255,255,255,0.2)', // 虚线颜色(可自定义,如 #999、rgba(0,0,0,0.1))
|
||||
width: 1, // 虚线宽度
|
||||
dashOffset: 5 // 虚线偏移量(可选,调整虚线起始位置)
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
series: [
|
||||
{
|
||||
name: `${this.$t('state.powerGeneration')}`,
|
||||
type: 'bar',
|
||||
data: charge_data,
|
||||
barWidth: 14, // 柱状图的宽度
|
||||
color: '#00C8FF',
|
||||
itemStyle: {
|
||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||
{ offset: 0, color: 'rgba(0,200,255,0.90)' },
|
||||
{ offset: 1, color: 'rgba(0, 200, 255, 0.0)' }
|
||||
])
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.earnings-warp {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: var(--table-bg);
|
||||
padding: 10px;
|
||||
|
||||
overflow: auto;
|
||||
box-shadow: inset 0px 2px 16px 0px rgba(0, 148, 255, 0.15);
|
||||
|
||||
.top {
|
||||
// height: 180px;
|
||||
width: 100%;
|
||||
|
||||
.box {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
padding: 20px;
|
||||
|
||||
.value-box {
|
||||
background: url(../../../assets/images/yxsj.png) no-repeat;
|
||||
background-size: 100% 100%;
|
||||
width: 190px;
|
||||
height: 80px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-around;
|
||||
|
||||
.top-box {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 30px;
|
||||
justify-content: space-around;
|
||||
|
||||
.d {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
display: inline-block;
|
||||
width: 4px;
|
||||
height: 4px;
|
||||
background: #ffb800;
|
||||
border-radius: 1px;
|
||||
margin-left: 10px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.title {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
color: #ceebff;
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.center-line {
|
||||
width: 80%;
|
||||
|
||||
text-align: center;
|
||||
background: url(../../../assets/images/xt.png) no-repeat;
|
||||
height: 5px;
|
||||
margin-left: 10%;
|
||||
background-size: 100% 100%;
|
||||
}
|
||||
|
||||
.bottom-value {
|
||||
height: 30px;
|
||||
width: 100%;
|
||||
color: #fff;
|
||||
font-size: 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.unit {
|
||||
margin-left: 2px;
|
||||
height: 28px;
|
||||
line-height: 30px;
|
||||
color: #fff;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.center {
|
||||
width: 100%;
|
||||
// height: 220px;
|
||||
display: flex;
|
||||
margin-top: 10px;
|
||||
justify-content: space-between;
|
||||
|
||||
.box {
|
||||
width: 100%;
|
||||
height: 175px;
|
||||
}
|
||||
}
|
||||
|
||||
.bottom {
|
||||
margin-top: 10px;
|
||||
width: 100%;
|
||||
height: calc(100% - 220px - 300px);
|
||||
|
||||
.box {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
|
||||
.value-box {
|
||||
background: url(../../../assets/images/report-bottom.png) no-repeat;
|
||||
background-size: 100% 100%;
|
||||
width: 240px;
|
||||
height: 212px;
|
||||
|
||||
.title {
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
font-size: 20px;
|
||||
font-family: Microsoft YaHei-Regular, Microsoft YaHei;
|
||||
font-weight: 400;
|
||||
color: #ffffff;
|
||||
letter-spacing: 1px;
|
||||
background: linear-gradient(180deg, #ffffff 37%, #5bbaf2 88%);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
}
|
||||
|
||||
.bottom-value {
|
||||
height: calc(212px - 40px);
|
||||
padding-top: 22px;
|
||||
display: flex;
|
||||
|
||||
.value {
|
||||
width: 100%;
|
||||
height: 49px;
|
||||
font-size: 40px;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
color: #e3e9f5;
|
||||
line-height: 47px;
|
||||
// text-shadow: 0px 6px 6px rgba(206, 235, 255, 0.2);
|
||||
color: #e3e9f5;
|
||||
|
||||
text-align: center;
|
||||
text-shadow: 0px 6.400000095367432px 6.400000095367432px
|
||||
rgba(206, 235, 255, 0.2);
|
||||
font-family: DIN;
|
||||
font-size: 40px;
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
line-height: normal;
|
||||
|
||||
.unit {
|
||||
color: #e3e9f5;
|
||||
font-family: DIN;
|
||||
font-size: 14px;
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
line-height: normal;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.top-search {
|
||||
width: 100%;
|
||||
height: 50px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
padding: 0 10px;
|
||||
|
||||
.report-title {
|
||||
text-align: center;
|
||||
font-size: 24px;
|
||||
white-space: nowrap;
|
||||
color: #fff;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.serach-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: $text-color;
|
||||
|
||||
.input-box {
|
||||
width: 60%;
|
||||
}
|
||||
}
|
||||
|
||||
.btns-box {
|
||||
text-align: right;
|
||||
|
||||
.upload-btn {
|
||||
background: $tiffany;
|
||||
}
|
||||
|
||||
.download-btn {
|
||||
background: $green;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/deep/ .el-table__header-wrapper {
|
||||
background-color: #025086 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.case-progress {
|
||||
::v-deep .el-progress-bar__outer {
|
||||
background-color: #023b61;
|
||||
}
|
||||
}
|
||||
|
||||
.charts-box {
|
||||
width: 100%;
|
||||
height: 175px;
|
||||
}
|
||||
</style>
|
||||
@ -0,0 +1,255 @@
|
||||
<template>
|
||||
<div class="left-bottom-wrap">
|
||||
<ItemBox :title="$t('pcs.powerGenerationCapacity')">
|
||||
<div slot="title-right">
|
||||
<div class="title-right">
|
||||
<div class="title-content">
|
||||
{{ $t("pcs.timeGranula") }}:
|
||||
<el-select
|
||||
v-model="timeLidu"
|
||||
style="width: 120px"
|
||||
@change="changTime"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in times"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-loading="loading" class="top-bottom-container">
|
||||
<Chart :options="options" :class-name="'chart'" />
|
||||
</div>
|
||||
</ItemBox>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import { GetPcsCurve } from '@/api/surveillance/pcs'
|
||||
import ItemBox from '../../item-kuang.vue'
|
||||
export default {
|
||||
name: 'Index',
|
||||
components: { ItemBox },
|
||||
data() {
|
||||
return {
|
||||
timeLidu: 1,
|
||||
times: [
|
||||
{ label: 1 + this.$t('pcs.min'), value: 1 },
|
||||
{ label: 5 + this.$t('pcs.min'), value: 5 },
|
||||
{ label: 10 + this.$t('pcs.min'), value: 10 },
|
||||
{ label: 15 + this.$t('pcs.min'), value: 15 },
|
||||
{ label: 20 + this.$t('pcs.min'), value: 20 },
|
||||
{ label: 30 + this.$t('pcs.min'), value: 30 }
|
||||
],
|
||||
options: {
|
||||
title: {
|
||||
text: this.$t('pcs.noData'),
|
||||
x: 'center',
|
||||
y: 'center',
|
||||
textStyle: {
|
||||
fontSize: 14,
|
||||
fontWeight: 'normal'
|
||||
}
|
||||
}
|
||||
},
|
||||
stationId: '',
|
||||
srcId: '',
|
||||
loading: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
language() {
|
||||
return this.$store.getters.language || undefined
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
language: {
|
||||
handler(val) {
|
||||
if (this.stationId) {
|
||||
this.times = [
|
||||
{ label: 1 + this.$t('pcs.min'), value: 1 },
|
||||
{ label: 5 + this.$t('pcs.min'), value: 5 },
|
||||
{ label: 10 + this.$t('pcs.min'), value: 10 },
|
||||
{ label: 15 + this.$t('pcs.min'), value: 15 },
|
||||
{ label: 20 + this.$t('pcs.min'), value: 20 },
|
||||
{ label: 30 + this.$t('pcs.min'), value: 30 }
|
||||
]
|
||||
this.getData(this.stationId, this.srcId)
|
||||
}
|
||||
},
|
||||
deep: true
|
||||
}
|
||||
},
|
||||
created() {
|
||||
// this.getChatData()
|
||||
},
|
||||
mounted() {},
|
||||
methods: {
|
||||
changTime() {
|
||||
this.getData(this.stationId, this.srcId)
|
||||
},
|
||||
async getData(stationId, srcId) {
|
||||
this.loading = true
|
||||
this.stationId = stationId
|
||||
this.srcId = srcId
|
||||
const params = {
|
||||
sampleTime: this.timeLidu,
|
||||
stationId: stationId,
|
||||
srcId: srcId
|
||||
}
|
||||
try {
|
||||
const res = await GetPcsCurve(params)
|
||||
this.getChatData(res.data)
|
||||
} catch (error) {
|
||||
// console.log(error);
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
getChatData(val) {
|
||||
const gonglv = []
|
||||
const xAxis = []
|
||||
val.forEach((v) => {
|
||||
xAxis.push(v.data)
|
||||
gonglv.push(Number((Math.random() * 50 + 100).toFixed(2)))
|
||||
})
|
||||
this.options = {
|
||||
color: ['#00C8FF', '#FBBB11'],
|
||||
legend: {},
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
backgroundColor: 'rgba(0,0,0,0,)',
|
||||
borderColor: 'rgba(0,0,0,0,);',
|
||||
borderWidth: 0,
|
||||
textStyle: {
|
||||
width: 160,
|
||||
height: 250,
|
||||
lineHeight: 24,
|
||||
color: '#ffffff',
|
||||
fontSize: '14',
|
||||
fontFamily: 'SourceHanSansCN-Normal'
|
||||
},
|
||||
|
||||
formatter: (params) => {
|
||||
// 获取xAxis data中的数据
|
||||
let dataStr = `<div><p style="font-weight:bold;margin:0 8px 15px;">${params[0].name}</p></div>`
|
||||
params.forEach((item) => {
|
||||
dataStr += `<div>
|
||||
<div style="margin: 0 8px;">
|
||||
<span style="display:inline-block;margin-right:5px;width:10px;height:10px;background-color:${item.color};"></span>
|
||||
<span>${item.seriesName}</span>
|
||||
<span style="float:right;color:#00C8FF;margin-left:20px;">${item.data}</span>
|
||||
</div>
|
||||
</div>`
|
||||
})
|
||||
const div = `<div style='border: 1px solid ;
|
||||
border-image: linear-gradient(130deg, #FFFFFF 0%, rgba(201,255,243,0.00) 22%, rgba(201,255,243,0.00) 75%, rgba(201,255,243,0.00) 80%, #FFFFFF 99%, #FFFFFF 99%) 1;
|
||||
box-shadow: inset 0px 2px 16px 0px rgba(0, 148, 255, 0.4);' >${dataStr}</div>`
|
||||
return div
|
||||
}
|
||||
},
|
||||
grid: {
|
||||
top: '15%',
|
||||
left: '5%',
|
||||
right: '5%',
|
||||
bottom: '15%',
|
||||
containLabel: true
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: xAxis,
|
||||
splitLine: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
yAxis: [
|
||||
{
|
||||
type: 'value',
|
||||
axisLabel: {
|
||||
color: '#00C8FF'
|
||||
},
|
||||
nameTextStyle: {
|
||||
color: '#00C8FF'
|
||||
}
|
||||
// min: function(value) {
|
||||
// return Math.floor(
|
||||
// (Math.abs(value.min) < value.max
|
||||
// ? value.max
|
||||
// : value.min
|
||||
// ).toFixed(2)
|
||||
// )
|
||||
// },
|
||||
// max: function(value) {
|
||||
// return Math.ceil(
|
||||
// (Math.abs(value.min) < value.max
|
||||
// ? value.max
|
||||
// : value.min
|
||||
// ).toFixed(2)
|
||||
// )
|
||||
// }
|
||||
}
|
||||
],
|
||||
dataZoom: [
|
||||
{
|
||||
type: 'inside',
|
||||
start: 0,
|
||||
end: 100
|
||||
},
|
||||
{
|
||||
start: 0,
|
||||
height: 20,
|
||||
bottom: 10,
|
||||
end: 100
|
||||
}
|
||||
],
|
||||
series: [
|
||||
{
|
||||
name: this.$t('pcs.powerGenerationCapacity') + '(kW)',
|
||||
type: 'line',
|
||||
symbol: 'none',
|
||||
lineStyle: {
|
||||
color: '#00A0E9'
|
||||
},
|
||||
data: gonglv
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.left-bottom-wrap {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
.title-right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.title-content {
|
||||
white-space: nowrap;
|
||||
padding: 0 10px;
|
||||
font-size: 16px;
|
||||
letter-spacing: 0.2em;
|
||||
color: #ceebff;
|
||||
font-family: Source Han Sans CN;
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
|
||||
.top-bottom-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
.chat {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
// color: rgb(0, 200, 255)
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -0,0 +1,950 @@
|
||||
<template>
|
||||
<div class="center-top-wrap">
|
||||
<ItemBox :title="$t('pcs.pcstopo')">
|
||||
<div slot="title-right">
|
||||
<div class="title-right">
|
||||
<div class="title-content">
|
||||
<!-- <el-select v-model="value" placeholder="请选择" style="width:200px">
|
||||
<el-option
|
||||
v-for="item in times"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select> -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="center-top-container">
|
||||
<div class="left">
|
||||
<div v-loading="left_top_loading" class="left-first">
|
||||
<div
|
||||
v-for="item in pcsLeftTopData"
|
||||
:key="item.label"
|
||||
class="box-title"
|
||||
>
|
||||
<span v-if="language === 'en'" class="title">{{ item.englabel }}:</span>
|
||||
<span v-else class="title">{{ item.label }}:</span>
|
||||
<span class="value">{{ item.value }}</span>
|
||||
<span class="unit">{{ item.unit }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-loading="left_bottom_loading"
|
||||
class="left-first"
|
||||
style="margin-top: 10%"
|
||||
>
|
||||
<div
|
||||
v-for="item in pcsLeftBottomData"
|
||||
:key="item.label"
|
||||
class="box-title"
|
||||
>
|
||||
<span v-if="language === 'en'" class="title">{{ item.englabel }}:</span>
|
||||
<span v-else class="title">{{ item.label }}:</span>
|
||||
<span class="value">{{ item.value }}</span>
|
||||
<span class="unit">{{ item.unit }}</span>
|
||||
</div>
|
||||
<!-- <div class="box-title">
|
||||
<span class="title">Idc:</span><span class="value">0.00</span><span class="unit">A</span>
|
||||
</div>
|
||||
<div class="box-title">
|
||||
<span class="title">Pdc:</span><span class="value">0.00</span><span class="unit">kW</span>
|
||||
</div> -->
|
||||
</div>
|
||||
</div>
|
||||
<div class="svg-box">
|
||||
<svg
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xml:space="preserve"
|
||||
class="circle-load-rect-svg"
|
||||
viewBox="0 0 400 450"
|
||||
>
|
||||
<defs>
|
||||
<defs>
|
||||
<radialGradient id="RadialGradient1">
|
||||
<stop offset="0%" stop-color="#fff" />
|
||||
<stop offset="30%" stop-color="#0171c1" />
|
||||
<stop offset="50%" stop-color="#035088" />
|
||||
<stop offset="100%" stop-color="#02395a" />
|
||||
</radialGradient>
|
||||
</defs>
|
||||
<marker
|
||||
id="markerCircle"
|
||||
markerWidth="15"
|
||||
markerHeight="15"
|
||||
refX="5"
|
||||
refY="5"
|
||||
>
|
||||
<circle
|
||||
cx="5"
|
||||
cy="5"
|
||||
r="5"
|
||||
style="stroke: none; fill: url(#RadialGradient1)"
|
||||
/>
|
||||
</marker>
|
||||
|
||||
<marker
|
||||
id="markerArrow"
|
||||
markerWidth="13"
|
||||
markerHeight="13"
|
||||
refX="2"
|
||||
refY="6"
|
||||
orient="auto"
|
||||
>
|
||||
<path d="M2,2 L2,11 L10,6 L2,2" style="fill: black" />
|
||||
</marker>
|
||||
</defs>
|
||||
<polyline
|
||||
:points="line.top"
|
||||
fill="none"
|
||||
class="g-rect-path"
|
||||
stroke="#01b4e7"
|
||||
/>
|
||||
<!-- 直线 -->
|
||||
<polyline
|
||||
:points="line.center"
|
||||
fill="none"
|
||||
class="g-rect-path"
|
||||
stroke="#01b4e7"
|
||||
/>
|
||||
<polyline
|
||||
v-if="
|
||||
newPcsCenterDataStatus.stateCharging ||
|
||||
newPcsCenterDataStatus.stateDischarging
|
||||
"
|
||||
:points="line.center"
|
||||
fill="none"
|
||||
class="g-rect-fill-two"
|
||||
stroke="#00e9f9"
|
||||
/>
|
||||
<polyline
|
||||
v-if="
|
||||
newPcsCenterDataStatus.stateCharging ||
|
||||
newPcsCenterDataStatus.stateDischarging
|
||||
"
|
||||
:points="line.center"
|
||||
fill="none"
|
||||
class="g-rect-fill-two-delay-1"
|
||||
stroke="#00e9f9"
|
||||
/>
|
||||
<polyline
|
||||
v-if="
|
||||
newPcsCenterDataStatus.stateCharging ||
|
||||
newPcsCenterDataStatus.stateDischarging
|
||||
"
|
||||
:points="line.center"
|
||||
fill="none"
|
||||
class="g-rect-fill-two-delay-2"
|
||||
stroke="#00e9f9"
|
||||
/>
|
||||
<polyline
|
||||
v-if="
|
||||
newPcsCenterDataStatus.stateCharging ||
|
||||
newPcsCenterDataStatus.stateDischarging
|
||||
"
|
||||
:points="line.center"
|
||||
fill="none"
|
||||
class="g-rect-fill-two-delay-3"
|
||||
stroke="#00e9f9"
|
||||
/>
|
||||
|
||||
<!-- <text x="100" y="320" fill="#ffffff" style="font-size: 16px">
|
||||
{{ $t('pcs.dcbreaker' ) }}
|
||||
</text> -->
|
||||
<!-- <rect
|
||||
x="190"
|
||||
y="300"
|
||||
width="20"
|
||||
height="30"
|
||||
style="fill: #ff3232"
|
||||
/> -->
|
||||
|
||||
<!-- <rect v-if="newPcsCenterDataStatus.dcBreaker" x="190" y="300" width="20" height="30" style="fill:#ff3232;" />
|
||||
<rect v-else x="190" y="300" width="20" height="30" style="fill:rgba(4, 48, 80, 0.6);stroke:#fff" /> -->
|
||||
<image
|
||||
:xlink:href="frameImg"
|
||||
x="160"
|
||||
y="300"
|
||||
width="100"
|
||||
height="100"
|
||||
style="cursor: pointer;"
|
||||
@click="lookDeviceDetail('triad-pcs-left')"
|
||||
/>
|
||||
<rect
|
||||
x="160"
|
||||
y="160"
|
||||
width="80"
|
||||
height="80"
|
||||
style="stroke: #ceebff; fill: #4d91da"
|
||||
/>
|
||||
<polyline
|
||||
:points="line.rect"
|
||||
fill="none"
|
||||
class="g-rect-path"
|
||||
stroke="#CEEBFF"
|
||||
/>
|
||||
<text x="180" y="190" fill="#ffffff" style="font-size: 18px">
|
||||
DC
|
||||
</text>
|
||||
<text x="200" y="220" fill="#ffffff" style="font-size: 18px">
|
||||
DC
|
||||
</text>
|
||||
</svg>
|
||||
|
||||
<!-- <div class="battary-box">
|
||||
<div class="container">
|
||||
<div class="header" />
|
||||
<div class="battery" />
|
||||
<div class="battery-copy">
|
||||
<div
|
||||
class="g-wave"
|
||||
:style="{
|
||||
bottom: newPcsCenterDataStatus.soc
|
||||
? `${(newPcsCenterDataStatus.soc / 100) * 55}px`
|
||||
: '0px',
|
||||
}"
|
||||
/>
|
||||
<div
|
||||
class="g-wave"
|
||||
:style="{
|
||||
bottom: newPcsCenterDataStatus.soc
|
||||
? `${(newPcsCenterDataStatus.soc / 100) * 55}px`
|
||||
: '0px',
|
||||
}"
|
||||
/>
|
||||
<div
|
||||
class="g-wave"
|
||||
:style="{
|
||||
bottom: newPcsCenterDataStatus.soc
|
||||
? `${(newPcsCenterDataStatus.soc / 100) * 55}px`
|
||||
: '0px',
|
||||
}"
|
||||
/>
|
||||
</div>
|
||||
<div class="battery-num">
|
||||
{{
|
||||
newPcsCenterDataStatus.soc ? newPcsCenterDataStatus.soc : 0
|
||||
}}%
|
||||
</div>
|
||||
</div>
|
||||
<div class="soc">SOC</div>
|
||||
</div> -->
|
||||
</div>
|
||||
<div v-loading="right_loding" class="right">
|
||||
<div class="left-first">
|
||||
<div class="box-title">
|
||||
<span class="title">{{ $t('pcs.runState') }}:</span><span class="value">{{
|
||||
workStatus(newPcsCenterDataStatus.runState)
|
||||
}}</span>
|
||||
</div>
|
||||
<div
|
||||
v-if="newPcsCenterDataStatus.remoteInPlace === 0"
|
||||
class="box-title"
|
||||
>
|
||||
<span class="title">{{ $t('pcs.rsState') }}:</span><span class="value">{{ $t('pcs.local') }}</span>
|
||||
</div>
|
||||
<div
|
||||
v-else-if="newPcsCenterDataStatus.remoteInPlace === 1"
|
||||
class="box-title"
|
||||
>
|
||||
<span class="title">{{ $t('pcs.rsState') }}:</span><span class="value">{{ $t('pcs.distance') }}</span>
|
||||
</div>
|
||||
<!-- <div v-if="newPcsCenterDataStatus.onGrid" class="box-title">
|
||||
<span class="title">{{ $t('pcs.gridMode') }}:</span><span class="value">{{ $t('pcs.grid') }}</span>
|
||||
</div>
|
||||
<div v-else class="box-title">
|
||||
<span class="title">{{ $t('pcs.gridMode') }}:</span><span class="value">{{ $t('pcs.offGrid') }}</span>
|
||||
</div> -->
|
||||
<div class="box-title-radio">
|
||||
<div class="title-radio">{{ $t('pcs.deviceState') }}:</div>
|
||||
<div class="radio">
|
||||
<div class="radio-box">
|
||||
<div class="radio-value">
|
||||
<span :class=" newPcsCenterDataStatus.deviceStateStand? 'sq': 'sq-transparent'" />
|
||||
<span class="sq-value">{{ $t('pcs.standby') }}</span>
|
||||
</div>
|
||||
<div class="radio-value">
|
||||
<span :class=" newPcsCenterDataStatus.deviceStateFault? 'sq': 'sq-transparent'" />
|
||||
<span class="sq-value">{{ $t('pcs.fault') }}</span>
|
||||
</div>
|
||||
<template v-if="!hnStationId.includes(stationId)">
|
||||
<!-- <div class="radio-value">
|
||||
<span :class="isChongdian ? 'sq' : 'sq-transparent'" />
|
||||
<span class="sq-value">{{ $t('pcs.charge') }}</span>
|
||||
</div> -->
|
||||
<div class="radio-value">
|
||||
<span :class="isFangdian ? 'sq' : 'sq-transparent'" />
|
||||
<span class="sq-value">{{ $t('pcs.powerGeneration') }}</span>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<div class="radio-value">
|
||||
<span
|
||||
:class="
|
||||
newPcsCenterDataStatus.stateCharging
|
||||
? 'sq'
|
||||
: 'sq-transparent'
|
||||
"
|
||||
/>
|
||||
<span class="sq-value">{{ $t('pcs.charge') }}</span>
|
||||
</div>
|
||||
<div class="radio-value">
|
||||
<span
|
||||
:class="
|
||||
newPcsCenterDataStatus.stateDischarging
|
||||
? 'sq'
|
||||
: 'sq-transparent'
|
||||
"
|
||||
/>
|
||||
<span class="sq-value">{{ $t('pcs.discharge') }}</span>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ItemBox>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import frameImg from '@/assets/images/wxjd/frame.png'
|
||||
import {
|
||||
pcsLeftTopData,
|
||||
pcsCenterDataStatus,
|
||||
pcsLeftBottomData1,
|
||||
pcsLeftBottomData2
|
||||
} from '../config/config'
|
||||
import { GetNewValue } from '@/api/surveillance/pcs/index'
|
||||
import ItemBox from '../../item-kuang.vue'
|
||||
export default {
|
||||
name: 'Index',
|
||||
components: { ItemBox },
|
||||
props: {},
|
||||
data() {
|
||||
return {
|
||||
frameImg,
|
||||
value: 'XX直流舱',
|
||||
times: [
|
||||
{ label: 'XX直流舱', value: 'XX直流舱' },
|
||||
{ label: 'XX1直流舱', value: 'XX1直流舱' },
|
||||
{ label: 'XX2直流舱', value: 'XX2直流舱' },
|
||||
{ label: 'XX3直流舱', value: 'XX3直流舱' }
|
||||
],
|
||||
config: {
|
||||
header: ['告警'],
|
||||
data: [],
|
||||
columnWidth: [],
|
||||
align: ['center', 'center', 'center', 'center'],
|
||||
headerBGC: '#062b40',
|
||||
oddRowBGC: 'rgba(255, 255, 255, 0)',
|
||||
evenRowBGC: 'rgba(255, 255, 255, 0.05)'
|
||||
},
|
||||
pageflag: false,
|
||||
isChongdian: false,
|
||||
isFangdian: false,
|
||||
line: {
|
||||
top: '50,20,350,20',
|
||||
center: '200,20 200,320',
|
||||
rect: '161,239 239,161'
|
||||
},
|
||||
radio: 3,
|
||||
pcsLeftTopData: pcsLeftTopData,
|
||||
pcsCenterDataStatus: pcsCenterDataStatus,
|
||||
pcsLeftBottomData: [],
|
||||
pcsLeftBottomData1: pcsLeftBottomData1,
|
||||
pcsLeftBottomData2: pcsLeftBottomData2,
|
||||
newPcsCenterDataStatus: {},
|
||||
left_top_loading: false,
|
||||
left_bottom_loading: false,
|
||||
right_loding: false,
|
||||
stationId: null,
|
||||
// 对海南4个电站处理和
|
||||
hnStationId: [417, 398, 416, 415, 405, 485],
|
||||
ksStationId: [526],
|
||||
jlShow: [417, 398, 416, 415, 405, 485, 526, 528, 514, 527, 529]// 控制交流断路器的显示
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
language() {
|
||||
return this.$store.getters.language || undefined
|
||||
}
|
||||
},
|
||||
watch: {},
|
||||
created() {
|
||||
// this.getChatData()
|
||||
},
|
||||
mounted() {},
|
||||
methods: {
|
||||
workStatus(val) {
|
||||
if (val === 0) {
|
||||
return this.$t('pcs.shutdown')
|
||||
} else if (val === 1) {
|
||||
return this.$t('pcs.run')
|
||||
} else if (val === 2) {
|
||||
return this.$t('pcs.standby')
|
||||
}
|
||||
},
|
||||
async getData(stationId, srcId) {
|
||||
this.stationId = stationId
|
||||
this.getLeftTop(stationId, srcId)
|
||||
this.getLeftBottom(stationId, srcId)
|
||||
this.getCeterTop(stationId, srcId)
|
||||
},
|
||||
async getLeftTop(stationId, srcId) {
|
||||
const self = this
|
||||
this.left_top_loading = true
|
||||
const colArr = []
|
||||
this.pcsLeftTopData.forEach((el) => {
|
||||
colArr.push(el.field)
|
||||
})
|
||||
const params = {
|
||||
stationId,
|
||||
srcId,
|
||||
colList: colArr
|
||||
}
|
||||
try {
|
||||
const res = await GetNewValue(params)
|
||||
|
||||
this.pcsLeftTopData.forEach((el) => {
|
||||
if (Object.keys(res.data).length !== 0) {
|
||||
el.value = res.data[el.field].value
|
||||
if (!self.hnStationId.includes(this.stationId)) {
|
||||
if (el.field === 'outputPower') {
|
||||
if (res.data.flowDirection === 2) {
|
||||
// if (+val > +1) {
|
||||
// return '放电'
|
||||
// }
|
||||
|
||||
if (+el.value > 1) {
|
||||
self.isFangdian = true
|
||||
self.isChongdian = false
|
||||
} else if (+el.value < -1) {
|
||||
self.isChongdian = true
|
||||
self.isFangdian = false
|
||||
} else {
|
||||
self.isChongdian = false
|
||||
self.isFangdian = false
|
||||
}
|
||||
} else {
|
||||
if (+el.value > 1) {
|
||||
self.isFangdian = false
|
||||
self.isChongdian = true
|
||||
} else if (+el.value < -1) {
|
||||
self.isChongdian = false
|
||||
self.isFangdian = true
|
||||
} else {
|
||||
self.isChongdian = false
|
||||
self.isFangdian = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
} catch (error) {
|
||||
// console.log(error)
|
||||
} finally {
|
||||
this.left_top_loading = false
|
||||
}
|
||||
},
|
||||
async getLeftBottom(stationId, srcId) {
|
||||
this.left_bottom_loading = true
|
||||
const colArr = []
|
||||
if (stationId === 719 || stationId === 728) {
|
||||
this.pcsLeftBottomData = pcsLeftBottomData2
|
||||
} else {
|
||||
this.pcsLeftBottomData = pcsLeftBottomData1
|
||||
}
|
||||
this.pcsLeftBottomData.forEach((el) => {
|
||||
colArr.push(el.field)
|
||||
})
|
||||
|
||||
const params = {
|
||||
stationId,
|
||||
srcId,
|
||||
colList: colArr
|
||||
}
|
||||
try {
|
||||
const res = await GetNewValue(params)
|
||||
this.pcsLeftBottomData.forEach((el) => {
|
||||
if (Object.keys(res.data).length !== 0) {
|
||||
el.value = res.data[el.field].value
|
||||
}
|
||||
})
|
||||
} catch (error) {
|
||||
// console.log(error)
|
||||
} finally {
|
||||
this.left_bottom_loading = false
|
||||
}
|
||||
},
|
||||
async getCeterTop(stationId, srcId) {
|
||||
this.right_loding = true
|
||||
const colArr = []
|
||||
this.pcsCenterDataStatus.forEach((el) => {
|
||||
colArr.push(el.field)
|
||||
})
|
||||
const params = {
|
||||
stationId,
|
||||
srcId,
|
||||
colList: colArr
|
||||
}
|
||||
try {
|
||||
const res = await GetNewValue(params)
|
||||
this.pcsCenterDataStatus.forEach((el) => {
|
||||
if (Object.keys(res.data).length !== 0) {
|
||||
el.value = res.data[el.field]?.value
|
||||
this.newPcsCenterDataStatus[el.field] = res.data[el.field]?.value
|
||||
}
|
||||
})
|
||||
|
||||
// if (this.hnStationId.includes(this.stationId)) {
|
||||
// 充电拓扑图流向
|
||||
if (this.newPcsCenterDataStatus.stateCharging) {
|
||||
this.line = {
|
||||
top: '50,20,350,20',
|
||||
center: '200,400,200,20',
|
||||
rect: '161,239 239,161'
|
||||
}
|
||||
}
|
||||
// 放电拓扑图流向
|
||||
if (this.newPcsCenterDataStatus.stateDischarging) {
|
||||
this.line = {
|
||||
top: '50,20,350,20',
|
||||
center: '200,20 200,400',
|
||||
rect: '161,239 239,161'
|
||||
}
|
||||
}
|
||||
// }
|
||||
} catch (error) {
|
||||
// console.log(error)
|
||||
} finally {
|
||||
this.$forceUpdate()
|
||||
this.right_loding = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.center-top-wrap {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.title-right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.title-content {
|
||||
padding: 0 10px;
|
||||
font-size: 16px;
|
||||
letter-spacing: 0.2em;
|
||||
color: #ceebff;
|
||||
font-family: Source Han Sans CN;
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
|
||||
.center-top-container {
|
||||
width: 100%;
|
||||
min-width: 700px;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-around;
|
||||
|
||||
.left {
|
||||
width: 25%;
|
||||
padding-top: 10%;
|
||||
padding-left: 3%;
|
||||
align-self: flex-start;
|
||||
|
||||
.left-first {
|
||||
width: 210px;
|
||||
// width: 80%;
|
||||
padding: 10px;
|
||||
padding-bottom: 0;
|
||||
background: url(../../../../../../assets/images/item-border.png)
|
||||
no-repeat;
|
||||
background-size: 100% 100%;
|
||||
|
||||
.box-title {
|
||||
padding-bottom: 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.title {
|
||||
// width: 100px;
|
||||
text-align: left;
|
||||
white-space: nowrap;
|
||||
font-family: Source Han Sans CN;
|
||||
color: #fff;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.value {
|
||||
flex: 1;
|
||||
text-align: right;
|
||||
font-family: DIN;
|
||||
color: #ffb800;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.unit {
|
||||
width: 40px;
|
||||
padding-left: 5px;
|
||||
color: #ffff;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.right {
|
||||
width: 30%;
|
||||
padding-top: 10%;
|
||||
padding-right: 1%;
|
||||
align-self: flex-start;
|
||||
|
||||
.left-first {
|
||||
min-width: 217px;
|
||||
padding: 10px;
|
||||
padding-bottom: 0;
|
||||
background: url(../../../../../../assets/images/item-border.png)
|
||||
no-repeat;
|
||||
background-size: 100% 100%;
|
||||
|
||||
.box-title {
|
||||
padding-bottom: 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-around;
|
||||
|
||||
.title {
|
||||
width: 160px;
|
||||
text-align: left;
|
||||
color: #fff;
|
||||
font-size: 14px;
|
||||
font-family: Source Han Sans CN;
|
||||
}
|
||||
|
||||
.value {
|
||||
flex: 1;
|
||||
color: #ffb800;
|
||||
font-size: 14px;
|
||||
font-family: DIN;
|
||||
}
|
||||
|
||||
.unit {
|
||||
width: 40px;
|
||||
text-align: right;
|
||||
padding-left: 5px;
|
||||
color: #ffff;
|
||||
font-size: 14px;
|
||||
font-family: DIN;
|
||||
}
|
||||
}
|
||||
|
||||
.box-title-radio {
|
||||
display: flex;
|
||||
padding-bottom: 10px;
|
||||
width: 100%;
|
||||
|
||||
.title-radio {
|
||||
width: 140px;
|
||||
text-align: left;
|
||||
color: #fff;
|
||||
font-size: 14px;
|
||||
font-family: Source Han Sans CN;
|
||||
}
|
||||
|
||||
.radio {
|
||||
// border: 1px solid;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
width: 100%;
|
||||
|
||||
.radio-box {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
.radio-value {
|
||||
width: 45%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-right: 5px;
|
||||
margin-bottom: 5px;
|
||||
|
||||
.sq {
|
||||
display: inline-block;
|
||||
min-width: 14px;
|
||||
height: 14px;
|
||||
background-color: #32aaff;
|
||||
border-radius: 50%;
|
||||
border: 1px solid #6d93ac;
|
||||
}
|
||||
|
||||
.sq-transparent {
|
||||
display: inline-block;
|
||||
min-width: 14px;
|
||||
height: 14px;
|
||||
background-color: transparent;
|
||||
border-radius: 50%;
|
||||
border: 1px solid #6d93ac;
|
||||
}
|
||||
|
||||
.sq-value {
|
||||
font-family: Source Han Sans CN;
|
||||
padding-left: 3px;
|
||||
display: flex;
|
||||
font-size: 14px;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// /deep/.el-radio{
|
||||
// width: 45%;
|
||||
// margin: 0;
|
||||
// // margin-right: 8px;
|
||||
|
||||
// }
|
||||
// /deep/.el-radio-group{
|
||||
// display: flex;
|
||||
// flex-wrap: wrap;
|
||||
// }
|
||||
// /deep/ .el-radio__label{
|
||||
// padding-left: 0;
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.svg-box {
|
||||
width: 400px;
|
||||
height: 450px;
|
||||
position: relative;
|
||||
|
||||
svg {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.circle-load-rect-svg {
|
||||
width: 100%;
|
||||
height: 450px;
|
||||
// margin: 10px;
|
||||
}
|
||||
|
||||
.g-rect-path {
|
||||
fill: none;
|
||||
stroke-width: 3;
|
||||
stroke-linejoin: round;
|
||||
stroke-linecap: round;
|
||||
}
|
||||
|
||||
/*
|
||||
$color: 圆点背景颜色
|
||||
$path: 圆点行走路径
|
||||
$duration跑完需要多久时间
|
||||
$delay延迟多久开始跑
|
||||
*/
|
||||
@mixin move-round($duration, $delay) {
|
||||
fill: none;
|
||||
stroke-width: 5;
|
||||
stroke-linejoin: round;
|
||||
stroke-linecap: round;
|
||||
stroke-dasharray: 3, 900;
|
||||
stroke-dashoffset: 0;
|
||||
animation: lineMove $duration $delay cubic-bezier(0, 0, 0.74, 0.74)
|
||||
infinite;
|
||||
}
|
||||
|
||||
@keyframes lineMove {
|
||||
0% {
|
||||
stroke-dashoffset: -850;
|
||||
}
|
||||
|
||||
100% {
|
||||
stroke-dashoffset: -0;
|
||||
}
|
||||
}
|
||||
|
||||
.g-rect-fill-two {
|
||||
@include move-round(3.5s, 1s);
|
||||
}
|
||||
|
||||
.g-rect-fill-two-delay-1 {
|
||||
@include move-round(3.5s, 1.5s);
|
||||
}
|
||||
|
||||
.g-rect-fill-two-delay-2 {
|
||||
@include move-round(3.5s, 2s);
|
||||
}
|
||||
|
||||
.g-rect-fill-two-delay-3 {
|
||||
@include move-round(3.5s, 2.5s);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.jl-box {
|
||||
border: 1px solid;
|
||||
color: #fff;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.zl-box {
|
||||
position: absolute;
|
||||
top: 90px;
|
||||
left: 100px;
|
||||
border: 1px solid;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.battary-box {
|
||||
position: absolute;
|
||||
bottom: 10px;
|
||||
left: 45%;
|
||||
|
||||
.soc {
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
right: -40px;
|
||||
font-size: 16px;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
.container {
|
||||
position: relative;
|
||||
width: 40px;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.battery-num {
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
top: 30px;
|
||||
-webkit-z-index: 666;
|
||||
-moz-z-index: 666;
|
||||
-ms-z-index: 666;
|
||||
-o-z-index: 666;
|
||||
z-index: 666;
|
||||
font-size: 14px;
|
||||
color: #ffb800;
|
||||
}
|
||||
|
||||
.shandianImg {
|
||||
position: absolute;
|
||||
left: 7px;
|
||||
top: 10px;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.header {
|
||||
position: absolute;
|
||||
width: 16px;
|
||||
height: 5px;
|
||||
left: 50%;
|
||||
top: 0;
|
||||
transform: translate(-50%, -5px);
|
||||
border-radius: 5px 5px 0 0;
|
||||
background: rgba(255, 255, 255, 0.88);
|
||||
}
|
||||
|
||||
.battery-copy {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 60px;
|
||||
width: 40px;
|
||||
border-radius: 10px 10px 5px 5px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.battery {
|
||||
position: relative;
|
||||
height: 60px;
|
||||
box-sizing: border-box;
|
||||
border-radius: 15px 15px 5px 5px;
|
||||
box-shadow: 0 0 5px 2px rgba(255, 255, 255, 0.22);
|
||||
background: #fff;
|
||||
z-index: 1;
|
||||
|
||||
&::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
top: 5px;
|
||||
background: linear-gradient(to bottom, #877925 0%, #877925 100%);
|
||||
border-radius: 0px 0px 5px 5px;
|
||||
box-shadow: 0 14px 28px rgba(33, 150, 243, 0),
|
||||
0 10px 10px rgba(9, 188, 215, 0.08);
|
||||
// animation: charging 10s linear infinite;
|
||||
// filter: hue-rotate(90deg);
|
||||
}
|
||||
}
|
||||
|
||||
.g-wave {
|
||||
position: absolute;
|
||||
width: 300px;
|
||||
height: 300px;
|
||||
background: rgba(255, 255, 255, 0.8);
|
||||
border-radius: 45% 47% 44% 42%;
|
||||
bottom: 55px;
|
||||
left: 50%;
|
||||
transform: translate(-50%, 0);
|
||||
z-index: 1;
|
||||
animation: move 10s linear infinite;
|
||||
}
|
||||
|
||||
// .g-wave:nth-child(2) {
|
||||
// border-radius: 38% 46% 43% 47%;
|
||||
// transform: translate(-50%, 0) rotate(-135deg);
|
||||
// }
|
||||
|
||||
// .g-wave:nth-child(3) {
|
||||
// border-radius: 42% 46% 37% 40%;
|
||||
// transform: translate(-50%, 0) rotate(135deg);
|
||||
// }
|
||||
|
||||
@keyframes charging {
|
||||
50% {
|
||||
box-shadow: 0 14px 28px rgba(0, 150, 136, 0.83),
|
||||
0px 4px 10px rgba(9, 188, 215, 0.4);
|
||||
}
|
||||
|
||||
95% {
|
||||
top: 5%;
|
||||
filter: hue-rotate(0deg);
|
||||
border-radius: 0 0 5px 5px;
|
||||
box-shadow: 0 14px 28px rgba(4, 188, 213, 0.2),
|
||||
0 10px 10px rgba(9, 188, 215, 0.08);
|
||||
}
|
||||
|
||||
100% {
|
||||
top: 0%;
|
||||
filter: hue-rotate(0deg);
|
||||
border-radius: 15px 15px 5px 5px;
|
||||
box-shadow: 0 14px 28px rgba(4, 188, 213, 0),
|
||||
0 10px 10px rgba(9, 188, 215, 0.4);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes move {
|
||||
100% {
|
||||
transform: translate(-50%, 0px) rotate(720deg);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -0,0 +1,106 @@
|
||||
<template>
|
||||
<div class="right-wrap">
|
||||
<div class="left-top-wrap">
|
||||
<ItemBox :title="$t('pcs.faultSign')">
|
||||
<div slot="title-right" />
|
||||
<ColListData v-loading="loading" :col-list-data="pcsRightData" :label-key="language === 'en' ? 'englabel' : 'label'" />
|
||||
</ItemBox>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { pcsRightData } from '../config/config'
|
||||
import { GetPCSAlarm } from '@/api/surveillance/pcs/index'
|
||||
import ItemBox from '../../item-kuang.vue'
|
||||
export default {
|
||||
name: 'Index',
|
||||
components: { ItemBox },
|
||||
props: {
|
||||
stationId: {
|
||||
type: Number,
|
||||
default: 0
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
currentIndex: 0,
|
||||
totalData: {
|
||||
operationDays: '',
|
||||
ratePower: '',
|
||||
totalChargeElec: '',
|
||||
totalDischargeElec: '',
|
||||
dailyChargeElec: '',
|
||||
dailyDischargeElec: '',
|
||||
currentPower: ''
|
||||
},
|
||||
stationData: {
|
||||
name: '1',
|
||||
type: '1',
|
||||
address: '1',
|
||||
createTime: '1',
|
||||
longitude: '1',
|
||||
latitude: '1'
|
||||
},
|
||||
stationType: [],
|
||||
pcsRightData: pcsRightData,
|
||||
loading: false
|
||||
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
language() {
|
||||
return this.$store.getters.language || undefined
|
||||
}
|
||||
},
|
||||
created() {
|
||||
|
||||
},
|
||||
mounted() {
|
||||
|
||||
},
|
||||
methods: {
|
||||
async getData(stationId, srcId) {
|
||||
this.loading = true
|
||||
const colArr = []
|
||||
this.pcsRightData.forEach((el) => {
|
||||
colArr.push(el.field)
|
||||
})
|
||||
try {
|
||||
const params = {
|
||||
stationId, srcId, colList: colArr
|
||||
}
|
||||
const res = await GetPCSAlarm(params)
|
||||
this.pcsRightData.forEach((el) => {
|
||||
if (Object.keys(res.data).length !== 0) {
|
||||
el.value = res.data[el.field].value
|
||||
}
|
||||
})
|
||||
} catch (error) {
|
||||
// console.log(error)
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.left-top-wrap {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.title-right {
|
||||
.setting-title {
|
||||
cursor: pointer;
|
||||
margin-top: 5px;
|
||||
background: url(../../../../../../assets/images/setting.png) no-repeat;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
background-size: cover;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
@ -0,0 +1,439 @@
|
||||
export const pcsRightData = [
|
||||
{
|
||||
label: '总报警状态',
|
||||
englabel: 'PCS Total Alarm Status',
|
||||
field: 'YX0012',
|
||||
value: ''
|
||||
},
|
||||
|
||||
{
|
||||
label: '单元直压故障',
|
||||
englabel: 'Unit direct pressure failure',
|
||||
field: 'YX0007',
|
||||
value: ''
|
||||
},
|
||||
{
|
||||
label: '开关电源欠压',
|
||||
englabel: 'Switching power supply is undervoltaged',
|
||||
field: 'YX0010',
|
||||
value: ''
|
||||
},
|
||||
{
|
||||
label: '过温故障',
|
||||
englabel: 'Overtemperature failure',
|
||||
field: 'YX0015',
|
||||
value: ''
|
||||
},
|
||||
{
|
||||
label: '系统相序错误',
|
||||
englabel: 'The system phase sequence is incorrect',
|
||||
field: 'YX0031',
|
||||
value: ''
|
||||
},
|
||||
{
|
||||
label: '直流极性反接',
|
||||
englabel: 'DC polarity reversed',
|
||||
field: 'YX0032',
|
||||
value: ''
|
||||
},
|
||||
{
|
||||
label: '直流母线软件过压',
|
||||
englabel: 'DC bus software overvoltage',
|
||||
field: 'YX0033',
|
||||
value: ''
|
||||
},
|
||||
{
|
||||
label: '直流母线软件欠压',
|
||||
englabel: 'DC bus software undervoltage',
|
||||
field: 'YX0034',
|
||||
value: ''
|
||||
},
|
||||
{
|
||||
label: '系统过频率',
|
||||
englabel: 'The frequency of the system is over-frequent',
|
||||
field: 'YX0035',
|
||||
value: ''
|
||||
},
|
||||
{
|
||||
label: '系统欠频率',
|
||||
englabel: 'System underfrequency',
|
||||
field: 'YX0036',
|
||||
value: ''
|
||||
},
|
||||
{
|
||||
label: '直流充电过流',
|
||||
englabel: 'DC charging overcurrent',
|
||||
field: 'YX0037',
|
||||
value: ''
|
||||
},
|
||||
{
|
||||
label: '直流放电过流',
|
||||
englabel: 'DC discharge overcurrent',
|
||||
field: 'YX0038',
|
||||
value: ''
|
||||
},
|
||||
{
|
||||
label: '孤岛保护',
|
||||
englabel: 'Island protection',
|
||||
field: 'YX0039',
|
||||
value: ''
|
||||
},
|
||||
{
|
||||
label: '直流主接合闸故障',
|
||||
englabel: 'DC main connection and closing fault',
|
||||
field: 'YX0045',
|
||||
value: ''
|
||||
},
|
||||
{
|
||||
label: '直流主接分闸故障',
|
||||
englabel: 'DC main connection opening fault',
|
||||
field: 'YX0046',
|
||||
value: ''
|
||||
},
|
||||
{
|
||||
label: '直流软启合闸故障',
|
||||
englabel: 'DC soft start and close fault',
|
||||
field: 'YX0047',
|
||||
value: ''
|
||||
},
|
||||
{
|
||||
label: '直流软启分闸故障',
|
||||
englabel: 'DC soft start opening fault',
|
||||
field: 'YX0048',
|
||||
value: ''
|
||||
},
|
||||
{
|
||||
label: '直流软起失败',
|
||||
englabel: 'DC soft start failed',
|
||||
field: 'YX0050',
|
||||
value: ''
|
||||
},
|
||||
{
|
||||
label: '起机条件不满足',
|
||||
englabel: 'The starting conditions are not met',
|
||||
field: 'YX0053',
|
||||
value: ''
|
||||
},
|
||||
{
|
||||
label: '运行中开关故障',
|
||||
englabel: 'Faulty switch during operation',
|
||||
field: 'YX0054',
|
||||
value: ''
|
||||
},
|
||||
{
|
||||
label: '逆变启动超时',
|
||||
englabel: 'The inverter startup timed out',
|
||||
field: 'YX0055',
|
||||
value: ''
|
||||
},
|
||||
{
|
||||
label: '参数下发设置错误',
|
||||
englabel: 'The parameter delivery setting is incorrect',
|
||||
field: 'YX0056',
|
||||
value: ''
|
||||
},
|
||||
{
|
||||
label: '通讯故障',
|
||||
englabel: 'Communication failures',
|
||||
field: 'YX0057',
|
||||
value: ''
|
||||
},
|
||||
{
|
||||
label: '温度异常',
|
||||
englabel: 'Abnormal temperature',
|
||||
field: 'YX0058',
|
||||
value: ''
|
||||
},
|
||||
{
|
||||
label: '跳机',
|
||||
englabel: 'Jump',
|
||||
field: 'YX0059',
|
||||
value: ''
|
||||
},
|
||||
{
|
||||
label: 'DCDC通讯故障',
|
||||
englabel: 'DCDC communication failure',
|
||||
field: 'YX0061',
|
||||
value: ''
|
||||
},
|
||||
{
|
||||
label: 'EMS通讯故障',
|
||||
englabel: 'EMS communication failure',
|
||||
field: 'YX0062',
|
||||
value: ''
|
||||
},
|
||||
{
|
||||
label: '急停故障',
|
||||
englabel: 'Emergency stop or melt core failure',
|
||||
field: 'YX0063',
|
||||
value: ''
|
||||
},
|
||||
{
|
||||
label: '母线不平衡异常',
|
||||
englabel: 'The bus bar is unbalanced and abnormal',
|
||||
field: 'YX0068',
|
||||
value: ''
|
||||
},
|
||||
{
|
||||
label: '母线半直压过压',
|
||||
englabel: 'The bus bar is semi-directly pressed and overpressed',
|
||||
field: 'YX0069',
|
||||
value: ''
|
||||
},
|
||||
{
|
||||
label: '启动超时',
|
||||
englabel: 'Startup timed out',
|
||||
field: 'YX0070',
|
||||
value: ''
|
||||
}
|
||||
|
||||
]
|
||||
|
||||
export const pcsLeftTopData = [
|
||||
{
|
||||
label: 'BAT电压',
|
||||
englabel: 'BAT voltage',
|
||||
field: 'outputPower',
|
||||
value: '0',
|
||||
unit: 'V'
|
||||
},
|
||||
{
|
||||
label: 'BAT电流',
|
||||
field: 'reactivePowerPCS',
|
||||
englabel: 'BAT current',
|
||||
value: '0',
|
||||
unit: 'A'
|
||||
},
|
||||
{
|
||||
label: 'BUS电压',
|
||||
englabel: 'BUS voltage',
|
||||
field: 'grid',
|
||||
value: '0',
|
||||
unit: 'V'
|
||||
},
|
||||
|
||||
{
|
||||
label: 'BUS电流',
|
||||
englabel: 'BUS current',
|
||||
field: 'volA',
|
||||
value: '0',
|
||||
unit: 'A'
|
||||
}
|
||||
|
||||
]
|
||||
// export const pcsLeftTopData = [
|
||||
// {
|
||||
// label: 'Pac',
|
||||
// field: 'outputPower',
|
||||
// value: '0',
|
||||
// unit: 'kW'
|
||||
// },
|
||||
// {
|
||||
// label: 'Qac',
|
||||
// field: 'reactivePowerPCS',
|
||||
// value: '0',
|
||||
// unit: 'kVar'
|
||||
// },
|
||||
// {
|
||||
// label: 'Freq',
|
||||
// field: 'grid',
|
||||
// value: '0',
|
||||
// unit: 'Hz'
|
||||
// },
|
||||
|
||||
// {
|
||||
// label: 'Uab',
|
||||
// field: 'volA',
|
||||
// value: '0',
|
||||
// unit: 'V'
|
||||
// },
|
||||
// {
|
||||
// label: 'Ubc',
|
||||
// field: 'volB',
|
||||
// value: '0',
|
||||
// unit: 'V'
|
||||
// },
|
||||
// {
|
||||
// label: 'Uca',
|
||||
// field: 'volC',
|
||||
// value: '0',
|
||||
// unit: 'V'
|
||||
// },
|
||||
// {
|
||||
// label: 'Ia',
|
||||
// field: 'currentA',
|
||||
// value: '0',
|
||||
// unit: 'A'
|
||||
// },
|
||||
// {
|
||||
// label: 'Ib',
|
||||
// field: 'currentB',
|
||||
// value: '0',
|
||||
// unit: 'A'
|
||||
// },
|
||||
// {
|
||||
// label: 'Ic',
|
||||
// field: 'currentC',
|
||||
// value: '0',
|
||||
// unit: 'A'
|
||||
// }
|
||||
|
||||
// ]
|
||||
|
||||
// export const pcsLeftBottomData = [
|
||||
// {
|
||||
// label: 'Udc',
|
||||
// field: 'dcPower',
|
||||
// value: '0',
|
||||
// unit: 'kW'
|
||||
// },
|
||||
// {
|
||||
// label: 'Idc',
|
||||
// field: 'dcCurrent',
|
||||
// value: '0',
|
||||
// unit: 'A'
|
||||
// },
|
||||
// {
|
||||
// label: 'Pdc',
|
||||
// field: 'dcInputVol',
|
||||
// value: '0',
|
||||
// unit: 'V'
|
||||
// }
|
||||
|
||||
// ]
|
||||
export const pcsLeftBottomData1 = [
|
||||
{
|
||||
label: '运行功率',
|
||||
englabel: 'operating power',
|
||||
field: 'dcPower',
|
||||
value: '0',
|
||||
unit: 'kW'
|
||||
},
|
||||
{
|
||||
label: '直流电压',
|
||||
englabel: 'DC voltage',
|
||||
field: 'dcInputVol',
|
||||
value: '0',
|
||||
unit: 'V'
|
||||
},
|
||||
{
|
||||
label: '直流电流',
|
||||
englabel: 'DC current',
|
||||
field: 'dcCurrent',
|
||||
value: '0',
|
||||
unit: 'A'
|
||||
}
|
||||
|
||||
]
|
||||
|
||||
export const pcsLeftBottomData2 = [
|
||||
{
|
||||
label: '直流功率',
|
||||
englabel: 'DC power',
|
||||
field: 'dcPower',
|
||||
value: '0',
|
||||
unit: 'kW'
|
||||
},
|
||||
{
|
||||
label: '直流电压',
|
||||
englabel: 'DC voltage',
|
||||
field: 'dcInputVol',
|
||||
value: '0',
|
||||
unit: 'V'
|
||||
},
|
||||
{
|
||||
label: '直流电流',
|
||||
englabel: 'DC current',
|
||||
field: 'dcCurrent',
|
||||
value: '0',
|
||||
unit: 'A'
|
||||
},
|
||||
{
|
||||
label: 'pcs模块温度',
|
||||
englabel: 'PCS module temperature',
|
||||
field: 'radiatorTemperature',
|
||||
value: '0',
|
||||
unit: '℃'
|
||||
}
|
||||
|
||||
]
|
||||
|
||||
export const pcsCenterDataStatus = [
|
||||
{
|
||||
label: '运行状态',
|
||||
englabel: 'Run state',
|
||||
field: 'runState',
|
||||
value: ''
|
||||
},
|
||||
{
|
||||
label: '远方/就地状态',
|
||||
englabel: 'Distance/Local State',
|
||||
field: 'remoteInPlace',
|
||||
value: ''
|
||||
},
|
||||
{
|
||||
label: '并网',
|
||||
englabel: 'Grid',
|
||||
field: 'onGrid',
|
||||
value: ''
|
||||
},
|
||||
{
|
||||
label: '离网',
|
||||
englabel: 'Off-grid',
|
||||
field: 'offGrid',
|
||||
value: ''
|
||||
},
|
||||
|
||||
{
|
||||
label: '充电状态',
|
||||
englabel: 'Charge state',
|
||||
field: 'stateCharging',
|
||||
value: ''
|
||||
},
|
||||
{
|
||||
label: '放电状态',
|
||||
englabel: 'Discharge state',
|
||||
field: 'stateDischarging',
|
||||
value: ''
|
||||
}, {
|
||||
label: '待机',
|
||||
englabel: 'Standby',
|
||||
field: 'deviceStateStand',
|
||||
value: ''
|
||||
}, {
|
||||
label: '故障',
|
||||
englabel: 'Fault',
|
||||
field: 'deviceStateFault',
|
||||
value: ''
|
||||
},
|
||||
{
|
||||
label: '充满',
|
||||
englabel: 'Full',
|
||||
field: 'deviceStateFull',
|
||||
value: ''
|
||||
},
|
||||
{
|
||||
label: '放空',
|
||||
englabel: 'Empty',
|
||||
field: 'deviceStateEmpty',
|
||||
value: ''
|
||||
},
|
||||
{
|
||||
label: '直流断路器',
|
||||
englabel: 'DC breaker',
|
||||
field: 'dcBreaker',
|
||||
value: ''
|
||||
},
|
||||
{
|
||||
label: '紧急停机',
|
||||
englabel: 'Emergent shutdown',
|
||||
field: 'eStop',
|
||||
value: ''
|
||||
},
|
||||
{
|
||||
label: 'SOC',
|
||||
field: 'soc',
|
||||
value: ''
|
||||
}
|
||||
|
||||
]
|
||||
@ -0,0 +1,121 @@
|
||||
<template>
|
||||
<div class="pcs-wrap">
|
||||
<div class="center-wrap">
|
||||
<div class="center-top">
|
||||
<PCSCenterTop ref="PCScenterTop" />
|
||||
</div>
|
||||
<div class="center-bottom">
|
||||
<PCSCenterBottom ref="PCScenterBottom" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="right-wrap">
|
||||
<PCSRight ref="PCSright" class="right-wrap" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// PCS
|
||||
|
||||
import PCSCenterTop from './components/center-top.vue'
|
||||
import PCSCenterBottom from './components/center-bottom.vue'
|
||||
import PCSRight from './components/right.vue'
|
||||
export default {
|
||||
components: { PCSCenterTop, PCSCenterBottom, PCSRight },
|
||||
props: {},
|
||||
data() {
|
||||
return {
|
||||
stationId: undefined
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
currentStation() {
|
||||
return this.$store.getters.currentStation || undefined
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
currentStation: {
|
||||
handler(val) {
|
||||
if (val && val.id) {
|
||||
this.stationId = val.id
|
||||
// this.$nextTick(() => {
|
||||
// this.$refs.left.getTreeData(this.stationId)
|
||||
// this.$refs.left.expandedKeys = []
|
||||
// })
|
||||
}
|
||||
},
|
||||
deep: true,
|
||||
immediate: true
|
||||
}
|
||||
},
|
||||
created() { },
|
||||
mounted() {
|
||||
// this.getData()
|
||||
},
|
||||
methods: {
|
||||
getData(srcId) {
|
||||
this.$refs.PCScenterTop.getData(this.stationId, srcId)
|
||||
this.$refs.PCScenterBottom.getData(this.stationId, srcId)
|
||||
this.$refs.PCSright.getData(this.stationId, srcId)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.pcs-wrap {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
|
||||
.center-wrap {
|
||||
flex: 2.5;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
.center-top {
|
||||
width: 100%;
|
||||
flex: 2;
|
||||
padding: 0 20px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.center-bottom {
|
||||
width: 100%;
|
||||
flex: 1;
|
||||
padding: 0 20px;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.right-wrap {
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
min-width: 300px;
|
||||
flex-direction: column;
|
||||
|
||||
.right-top {
|
||||
width: 100%;
|
||||
flex: 2;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.right-top-top {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.right-top-bottom {
|
||||
width: 100%;
|
||||
flex: 1;
|
||||
margin-top: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.right-bottom {
|
||||
width: 100%;
|
||||
flex: 1;
|
||||
margin-top: 20px;
|
||||
}
|
||||
}</style>
|
||||
@ -18,6 +18,7 @@
|
||||
// 电池堆
|
||||
import Left from './components/left.vue'
|
||||
import PCS from './components/pcs/index.vue'
|
||||
import DCDCMPPT from './components/dcdcmppt/index.vue'
|
||||
|
||||
import RingMainUnit from './components/ring-main-unit/index.vue'
|
||||
import CLUSTER from './components/cluster/index.vue'
|
||||
@ -33,7 +34,7 @@ import OPTICALSTORAGE from './components/optical-storage/index.vue'
|
||||
import DIESELGENERATORS from './components/diesel-generators/index.vue'
|
||||
import NABATTERY from './components/na-battery/index.vue'
|
||||
export default {
|
||||
components: { Left, PCS, LIQUIDCLUSTER, DIESELGENERATORS, RingMainUnit, CLUSTER, STACK, AIRCONDITION, STORAGEFIRE, ElectricityMeter, GROUP, LIQUID, FIRE, OPTICALSTORAGE, NABATTERY },
|
||||
components: { Left, PCS, DCDCMPPT, LIQUIDCLUSTER, DIESELGENERATORS, RingMainUnit, CLUSTER, STACK, AIRCONDITION, STORAGEFIRE, ElectricityMeter, GROUP, LIQUID, FIRE, OPTICALSTORAGE, NABATTERY },
|
||||
props: {},
|
||||
data() {
|
||||
return {
|
||||
@ -85,12 +86,19 @@ export default {
|
||||
methods: {
|
||||
getDeviceNode(node) {
|
||||
const self = this
|
||||
console.log(node.deviceType)
|
||||
|
||||
if (node.deviceType) {
|
||||
if (node.deviceType.includes('pcs') && !this.isBoShi(node.stationId)) {
|
||||
this.currentComponent = 'PCS'
|
||||
self.$nextTick(() => {
|
||||
self.$refs[self.currentComponent].getData(node.srcId)
|
||||
})
|
||||
} else if (node.deviceType.includes('mttp') || node.deviceType.includes('mppt')) {
|
||||
this.currentComponent = 'DCDCMPPT'
|
||||
self.$nextTick(() => {
|
||||
self.$refs[self.currentComponent].getData(node.srcId)
|
||||
})
|
||||
} else if (node.deviceType.includes('emu')) {
|
||||
this.currentComponent = 'RingMainUnit'
|
||||
self.$nextTick(() => {
|
||||
|
||||
@ -6,7 +6,7 @@ function resolve(dir) {
|
||||
return path.join(__dirname, dir)
|
||||
}
|
||||
|
||||
const name = defaultSettings.title || '中自新能源' // page title
|
||||
const name = defaultSettings.title || '中自能源' // page title
|
||||
|
||||
// If your port is set to 80,
|
||||
// use administrator privileges to execute the command line.
|
||||
|
||||
Reference in New Issue
Block a user