You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

864 lines
24 KiB

This file contains invisible Unicode characters!

This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<view>
<uni-nav-bar left-icon="left" fixed="true" title="子阵视图" @clickLeft="handleClickLeft"></uni-nav-bar>
<view class="station-box">
<view class="station-search-box">
<uni-section title="选择电站" type="line" padding="10px" >
<uni-data-picker placeholder="请选择电站"
popup-title=""
:localdata="stationData"
:clear-icon="false"
v-model="selectStations"
:map="{text:'stationName',value:'id', children: 'children'}"
@change="onchange"
>
</uni-data-picker>
</uni-section>
<uni-section title="设备状态" type="line" padding="" >
<div class="report-status">
<div class="report-status-item">
<div class="flex flex-row-center ">
<div>设备:</div>
<div class="flex">
<div class="item flex flex-center">
<i class="bg s1"></i>
<span class="text">正常</span>
</div>
<div class="item flex flex-center ">
<i class="bg s2"></i>
<span class="text">停机</span>
</div>
<div class="item flex flex-center ">
<i class="bg s3"></i>
<span class="text">故障</span>
</div>
<div class="item flex flex-center ">
<i class="bg s4"></i>
<span class="text">不在线</span>
</div>
</div>
</div>
</div>
<div class="report-status-item" v-show="showSecond">
<div class="flex flex-column-start">
<div>组串:</div>
<div>
<div class="flex">
<div class="item flex flex-center">
<i class="bg z1"></i>
<span class="text">正常</span>
</div>
<div class="item flex flex-center">
<i class="bg z2"></i>
<span class="text">有警告</span>
</div>
<div class="item flex flex-center">
<i class="bg z3"></i>
<span class="text">未接入</span>
</div>
</div>
<div class="flex">
<div class="item flex flex-center">
<i class="bg z4"></i>
<span class="text">未关联或电流为0或关联错误</span>
</div>
</div>
</div>
</div>
</div>
</div>
</uni-section>
<uni-section title="环境监测仪" type="line" >
<u-collapse accordion class="first-class">
<u-collapse-item
name="index"
:title="envData.environmentName"
>
<view class="flex flex-center">
<table border="1" class="env-table" >
<tr>
<td>辐照强度</td>
<td >{{ envData.irradiationStrength }} W/㎡</td>
</tr>
<tr>
<td>日辐射累计</td>
<td>{{ envData.dayIrradiation }} MJ/㎡</td>
</tr>
<tr>
<td>大气温度</td>
<td>{{ envData.atmosphericTemperature }}°C</td>
</tr>
<tr>
<td>贴片温度</td>
<td>{{ envData.patchTemperature }}°C</td>
</tr>
<tr>
<td>湿度</td>
<td>{{ envData.humidity }} %RH</td>
</tr>
<tr>
<td>累计峰值日照数</td>
<td>{{ envData.sunshineTop }} h</td>
</tr>
<tr>
<td>风向</td>
<td>{{ envData.windDirection }}゜</td>
</tr>
<tr>
<td>风速</td>
<td>{{ envData.windSpeed }} m/s</td>
</tr>
</table>
</view>
</u-collapse-item>
</u-collapse>
</uni-section>
</view>
<view class="station-content">
<uni-section title="采集器" type="line">
<template v-slot:right >
<view class="second-status" :class="allOffLineState ? 'z4' : 'z1'" v-show="showSecond" @click="handleGetStatus">
{{ secondData.collectorName }}
</view>
</template>
<block v-if="type==='second'">
<u-collapse :value="['1']" class="second-class">
<u-collapse-item title="数据" name="1">
<view class="content-box">
<div class="report-item1 c3">
<div class="item flex" :class="itemStateClass(item.state).clas" v-for="item in secondList" :key="item.id">
<div class="item-img">
<div class="img-list flex flex-wrap base-item"
:class="item.list.length === 12 ? 'base-item' :
item.list.length === 16 ? 'sixteen-item' :
'eight-item'"
>
<div :class="['img-it'
, itemClass(it.electricQuantity)
]" v-for="(it,ind) in item.list" :key="ind">
{{ it.electricQuantity | itemNum }}
</div>
</div>
<div class="img-text">
{{ item.equipmentName }}
</div>
</div>
<div class="item-info flex" @click="handleGetDetail(item)">
<div class="info-img">
<img :src="`/static/station/${item.state === '1' ? 'zc1' : 'zc2'}.png`" alt="">
</div>
<div :class="['info-text text-state', itemStateClass(item.state).clas]">
<div>
{{ item.totalHavePower }}
</div>
<div>{{ item.dayEnergy }}</div>
<div>{{ item.temperature }}</div>
<div>{{ item.totalEnergy }}</div>
</div>
</div>
</div>
</div>
</view>
</u-collapse-item>
</u-collapse>
</block>
<block v-if="type==='first'">
<u-collapse accordion class="first-class">
<u-collapse-item
:name="index"
:title="item.key"
v-for="(item, index) in firstList"
:key="item.key"
>
<view class="content-box">
<div class="info-box-list flex flex-center" v-for="it in item.arr" :key="it.id">
<div class="info-img flex flex-column flex-center" @click="handleGetDetail(it)">
<img :src="`/static/station/${it.state === '1' ? 'b2' : 'b1'}.png`" alt="">
<div class="info-text">{{ it._sName }}</div>
<td :class="['text text-state flex flex-center jc-center', itemStateClass(it.state).clas]">
<div>{{ itemStateClass(it.state).text }}</div>
</td>
</div>
<table border="2" class="info-detail">
<tr class="row flex">
<td class="name flex">
<div>直流电压/流</div>
</td>
<td :class="['text text-state flex flex-center jc-center', itemStateClass(it.state).clas]">
<div>{{ it.dcVoltage || '#' }} / {{ it.dcCurrent || '#'}}</div>
</td>
</tr>
<tr class="row flex">
<td class="name flex "><div>总有功功率</div></td>
<td :class="['text text-state flex flex-center jc-center', itemStateClass(it.state).clas]">
<!-- <div>#V</div>-->
<!-- <div class="text2">#A</div>-->
<div>{{ it.totalHavePower || '#' }}</div>
</td>
</tr>
<tr class="row flex">
<td class="name flex">
<div>日发电量</div>
</td>
<td :class="['text text-state flex flex-center jc-center', itemStateClass(it.state).clas]">
<div>{{ it.dayEnergy || '#'}}</div>
</td>
</tr>
<tr class="row flex">
<td class="name flex">
<div>总发电量</div>
</td>
<td :class="['text text-state flex flex-center jc-center', itemStateClass(it.state).clas]">
<div>{{ it.totalEnergy || '#'}}</div>
</td>
</tr>
</table>
</div>
</view>
</u-collapse-item>
</u-collapse>
</block>
</uni-section>
</view>
</view>
<u-action-sheet
:show="show4"
@close="show4 = false"
title=""
:round="10"
>
<view>
<div class="report-pos-info item2-total-info" :class="allOffLineState ? 'z4' : 'z1'">
<div class="item2 flex flex-center flex-column">
<img src="/static/station/B0.jpg" alt="">
<div class="text">{{ secondData.collectorName }} 采集器</div>
</div>
<div class="item3 flex flex-center" v-show="showItemDetail">
<table border="3">
<tr>
<td>接入设备总数</td>
<td >{{ secondData.equipmentQuantity }}</td>
</tr>
<tr>
<td>故障设备总数</td>
<td>{{ secondData.faultEquipmentQuantity }}</td>
</tr>
<tr>
<td>温度</td>
<td>{{ secondData.temperature }}</td>
</tr>
<tr>
<td>湿度</td>
<td>{{ secondData.humidity }}</td>
</tr>
<tr>
<td>总有功功率</td>
<td>{{ secondData.totalActivePower }}</td>
</tr>
<tr>
<td>今日发电</td>
<td>{{ secondData.dayEnergy }}</td>
</tr>
<tr>
<td>累计发电</td>
<td>{{ secondData.totalEnergy }}</td>
</tr>
</table>
</div>
</div>
</view>
<u-status-bar></u-status-bar>
</u-action-sheet>
<u-status-bar></u-status-bar>
</view>
</template>
<script>
import { scrollSmoothTo } from '@/common/util/index.js'
import _mixin from './mixin.js'
import { AREA_SECOND_STATIONS, FIRST_STATIONS, UN_SHOW_STATIONS, END_NUM } from './config'
import { getBigScreenPowerInverterInfo, getBigScreenPowerInverterInfo2 } from '@/api/modules/station.js'
export default {
data() {
return {
modalName: null,
index: 0,
selectStations: uni.getStorageSync('_pro_selectStation') || [],
accordionVal:'1',
station: {},
envData: {},
type: 'first',
firstList: [],
secondList: [],
secondData: {},
show4: false,
allOffLineState: false
}
},
mixins: [_mixin],
created() {
this.initData()
},
filters: {
itemNum(data) {
if (!data) return ''
return data <= 0 || data === END_NUM ? '' : data
},
itemName(data) {
if (!data) return ''
return data.split(' ')[1]
},
},
computed: {
showItemDetail() {
return this.selectStations.length ? !UN_SHOW_STATIONS.includes(this.selectStations[1]) : false
},
showSecond(){
return this.type === 'second'
},
},
methods: {
handleGetDetail(item) {
uni.removeStorageSync('_pro_selectStation')
this.$router.push({
name: 'stationListItem2',
query: {
id: this.selectStations[0],
sd: this.selectStations[1],
ud: item.id
}
})
},
handleClickLeft() {
uni.removeStorageSync('_pro_selectStation')
this.$router.replace('/pages/station/list')
},
initData() {
console.log(this.stationData)
const hasLocalData = this.selectStations.length
const stationId = hasLocalData ? this.selectStations[0] : this.$route.query.id
const station = this.stationData.filter(v => {
return v.id === stationId
})
const data = hasLocalData ? this.selectStations :
station.length ?
[station[0].id, station[0].children[0].id]
:[this.stationData[0].id, this.stationData[0].children[0].id]
this.selectStations = data
this.station = this.stationData.filter(v => {
return v.id === data[0]
})[0]
this.type = AREA_SECOND_STATIONS.includes(data[1]) ? 'second' : FIRST_STATIONS.includes(data[0]) ? 'first' : 'second'
// this.type = FIRST_STATIONS.includes(data[0]) ? 'first' : 'second'
this.getDataInfo(this.type)
},
getDataInfo(type = 'first') {
const data = {
stationId: this.selectStations[0],
powerStationPartitionId: this.selectStations[1]
}
const METHOD = {
'first': getBigScreenPowerInverterInfo,
'second': getBigScreenPowerInverterInfo2
}
METHOD[type](data).then(res => {
if (type === 'first') {
const _data = res.data.data.map(v => {
v._tip = v.equipmentName.split(' ')[1].split('-')[0]
return v
})
this.firstList = this.handleFilterArray(_data)
this.envData = _data.length > 0 ? _data[0] : {}
} else {
this.secondData = this.handleFilterSecondArr(res.data.data)
this.envData = this.secondData
}
})
},
handleFilterSecondArr(arr) {
const item = arr[0]
let maxNum = 1
let itemNum = 1
for (let i = 1; i<= 50; i++) {
if (!item['dayEnergy' + i]) {
maxNum = i-1
break
}
}
for (let i = 25; i> 0; i--) {
if (item['electricQuantity1_' + i]) {
itemNum = i
break
}
}
// this.itemNum = eightNumArr.includes(this.selectStations[0]) ? 8 : sixteenNumArr.includes(this.selectStations[1]) ? 16 : 12
this.itemNum = itemNum
const SELF_ARR = ['35', '36']
const B9Arr = ['1052758018', '31']
const isB9 = B9Arr[0] === this.selectStations[0] && B9Arr[1]=== this.selectStations[1]
const isB15OrB17 = SELF_ARR.includes(this.selectStations[1])
// 伟创B9 3,6,9 设置为655。35 未接入
this.secondList = Array.from(Array(maxNum)).map((v, inde) => {
const index = inde + 1
const cList = Array.from(Array(this.itemNum)).map((cv, cIndex) => {
const _cIndex = cIndex + 1
let text = item[`electricQuantity${index}_${_cIndex}`]
text = text.split('A')[0] || 0
const isOffLine = +text <= 0.4
let num = isB9 && [3, 6, 9].includes(_cIndex) && isOffLine ? '655.35' : text
num = isB15OrB17 && [1,5,9,13].includes(_cIndex) && isOffLine ? '655.35' : num
// 如果是0.0 替换为655.35
// num = (+num) === 0 ? '655.35' : num
const reg = /^65/g
const is65535 = reg.test(num)
const _num = is65535 ? num.split('.').join('') : +num
// console.log(num)
return {
id: '',
electricQuantity: parseFloat(_num),
}
})
return {
list: cList,
dayEnergy: item[`dayEnergy${index}`],
equipmentName: item[`equipmentName${index}`] ? item[`equipmentName${index}`].split(' ')[1] : '-',
id: item[`inverterInfoId${index}`],
state: item[`state${index}`],
totalHavePower: item[`totalHavePower${index}`],
temperature: item[`temperature${index}`],
totalEnergy: item[`totalEnergy${index}`],
offLineState: cList.every(v => v.electricQuantity <= 0 || v.electricQuantity === END_NUM )
}
}).sort((a, b) => a.equipmentName.localeCompare(b.equipmentName, 'zh-CN'))
this.allOffLineState = this.secondList.every(v => v.offLineState)
return item
},
handleFilterArray(arr) {
const data = arr.reduce((c, v) => {
c[v._tip] = c[v._tip] || []
c[v._tip].push(v)
return c
}, {})
const data1 = Object.keys(data).map(v => {
const mat = v.match(/(\d)+/g)
const arr = data[v].map(v => {
v._sName = v.equipmentName.split(' ')[1]
return v
}).sort((a, b) => a._sName.localeCompare(b._sName, 'zh-CN'))
const num = mat && mat.length ? mat[0] : 0
return {
key: v,
num,
arr
}
}).sort((a, b) => a.num- b.num)
this.firstListMaxLength = data1.reduce((c, v) => {
c = c >= v.arr.length ? c : v.arr.length
return c
}, 1)
return data1
},
handleGetStatus() {
this.show4 = true
},
itemClass(_data) {
const offLineArr = ['1052758027'] // 健堂口 数值为0和未接入的都是黑色
const id = this.selectStations[0]
let str = ''
if (offLineArr.includes(id)) {
str = _data <= 0 || _data === END_NUM ? 'z3' : 'z1'
} else {
str = _data <= 0 ? 'z4' : _data === END_NUM ? 'z3' : 'z1'
}
return str
},
onnodeclick(e) {
console.log(e);
},
onchange(e) {
this.selectStations = e.detail.value.map(v => v.value)
uni.setStorageSync('_pro_selectStation', this.selectStations)
this.initData()
scrollSmoothTo(0);
},
handlerChangeStation(e) {
// this.station = this.stationData[this.index]
},
change(e) {
console.log(e);
}
}
}
</script>
<style lang="scss">
:root {
--c-green: #00d40e;
//--c-z1: #1d49a8;
--c-z1: #0c4ad1;
--c-z2: #ff0000;
--c-z3: #000;
--c-z4: #808080;
--c-z5: #fc6;
}
/deep/ .selected-list{
align-items: center;
}
/deep/ .u-collapse-item__content__text {
background-color: rgba(0,0,0, 1);
}
/deep/ .second-class .u-collapse-item__content {
height: auto !important;
}
/deep/ .first-class .u-collapse-item{
&:nth-child(2) .u-collapse-item__content {
// height: 514.656px !important;
}
}
/deep/ .u-action-sheet {
background: #000;
}
/deep/ .u-action-sheet__header__title {
color: #000;
}
html, body {
scroll-behavior:smooth;
}
.second-status {
&.z1 {
color:#00d40e;
}
&.z4 {
color: #808080;
}
}
.report-status {
// position: absolute;
// left: 68%;
// top: 2px;
color: #555;
transform: scale(0.85);
margin-left: -50upx;
.report-status-item {
margin-top: 4upx;
}
.item {
margin-right: 10upx;
.bg {
display: block;
width: 50upx;
height: 30upx;
margin-right: 2px;
border: 1px solid #ccc;
&.s1 {
background: #00a403;
}
&.s2 {
background: #ff0000;
}
&.s3 {
background: #fc6;
}
&.s4 {
background: #808080;
}
&.z1 {
background: #0c4ad1;
}
&.z2 {
background: #ff0000;
}
&.z3 {
background: #000;
}
&.z4 {
background: #808080;
}
}
}
}
.report-pos-info {
z-index: 1;
padding-bottom: 20upx;
color: #f5f5f5;
background-color: #000;
&.item2-total-info {
&.z1 {
table {
td:nth-child(2) {
color: #00d40e;
}
}
.text {
color:#00d40e;
}
}
&.z4 {
td:nth-child(2) {
color: #808080;
}
.text {
color: #808080;
}
}
}
.item1,.item2,.item3 {
margin-top: 10upx;
img {
width: 240upx;
}
.text {
margin-top:5upx;
}
table {
font-size: 28upx;
td {
padding: 4upx 10upx;
//padding-left: 20px;
//width: 180px;
}
}
}
.item2 {
img {
width: 100upx;
}
}
}
.station-box {
// padding: 0 10px 10px 10px;
padding-top: 10px;
padding-bottom: 10px;
font-size: 24upx;
.station-content {
margin-top: 5px;
padding: 5px 0;
.content-box {
margin: 5px auto;
padding: 0 10px;
}
.report-item1 {
color: #f6f6f6;
display: grid;
// height:100%;
grid-row-gap: 5upx;
grid-column-gap: 20upx;
grid-template-columns: 100%;
grid-template-rows:repeat(auto-fill,150upx);
place-items: center center;
.item {
//width: 100%;
//height: 100%;
&.z1 {
color: #00d40e;
}
&.z2 {
color: #ff0000;
}
&.z3 {
color: #fc6;
}
&.z4 {
color: #808080;
}
.item-img {
//width: 60%;
.img-list {
width: 450upx;
border: 1px solid #f5f5f5;
padding: 2upx;
justify-content: space-around;
&.eight-item {
width: 300upx;
}
&.sixteen-item {
width: 450upx;
.img-it {
width: 52upx;
}
}
.img-it {
width: 70upx;
height: 40upx;
border: 1px solid #fff;
transform: scale(0.85);
background-size: 4upx 4upx;
text-align: center;
line-height: 40upx;
font-size: 24upx;
color: #fff;
&.z1 {
background-color: #0c4ad1;
}
&.z2 {
background-color: #ff0000;
}
&.z3 {
background-color: #000;
}
&.z4 {
background-color: #808080;
}
}
}
.img-text {
text-align: right;
margin-right: -20upx;
margin-top: 4upx;
font-size: 14upx;
}
}
.item-info {
margin-left: 10upx;
&.z1 {
.info-text {
color: #00d40e;
}
}
&.z2 {
.info-text {
color: #ff0000;
}
}
&.z3 {
.info-text {
color: #fc6;
}
}
.info-img {
width: 80upx;
image, img {
width: 100%;
}
}
.info-text {
font-size: 26upx;
line-height: 1;
}
}
}
}
}
.station-search-box {
position: sticky;
top: 88upx;
width: 100%;
z-index: 2;
}
.info-box-list {
// margin-left: 5upx;
//width: 25%;
//flex-shrink: 0;
color: #fff;
padding: 10upx 0;
// background-color: rgba(0,0,0, 0.6);
&:not(:first-child) {
margin-top: 6upx;
}
&.base {
.text {
color: #fff;
}
}
&.nor {
.text-c, .info-text1 {
color: #00d40e;
}
}
.text-state {
font-size: 18upx;
&.z1 {
color: #00d40e;
}
&.z2 {
color: #ff0000;
}
&.z3 {
color: #fc6;
}
&.z4 {
color: #808080;
}
}
.info-detail {
font-size: 14upx;
margin-left: 10upx;
.row {
td {
padding: 8upx;
}
.name {
width: 140upx;
}
.text {
width: 180upx;
.text2 {
margin-left: 20upx;
}
}
}
}
.info-img {
width: 220upx;
font-size: 28upx;
transform: scale(0.86);
img {
width: 100%;
}
.info-text1 {
margin-top: 10upx;
font-size: 24upx;
}
}
}
}
.env-table {
border-color: #888;
color: #ccc;
td {
padding: 0 8upx;
}
}
</style>