502 lines
11 KiB
Vue
502 lines
11 KiB
Vue
<template>
|
||
<view class="container">
|
||
<view class="search-icon" @click="openSearch">
|
||
<uni-icons type="search" size="40" color="#fff"></uni-icons>
|
||
</view>
|
||
<view class="list-container">
|
||
<view class="no-data" v-if="list.length === 0">暂无数据</view>
|
||
<uni-list v-else>
|
||
<uni-list-item v-for="(item,index) in list" :key="index+'dtdc'">
|
||
<template v-slot:header>
|
||
<view class="list-header">
|
||
单体编号:{{item.deviceId}}
|
||
<button type="primary" size="mini" class="charts" @click="toDetail(item)">图表</button>
|
||
</view>
|
||
</template>
|
||
<template v-slot:body>
|
||
<view class="list-body">
|
||
<uni-row>
|
||
<uni-col :span="8">
|
||
<view>簇号</view>
|
||
</uni-col>
|
||
<uni-col :span="14">
|
||
<view class="right">{{item.clusterDeviceId}}</view>
|
||
</uni-col>
|
||
</uni-row>
|
||
<uni-row>
|
||
<uni-col :span="8">
|
||
<view>电压(V)</view>
|
||
</uni-col>
|
||
<uni-col :span="14">
|
||
<view class="right color" @click="toDetail(item,'voltage')">{{item.voltage}}
|
||
</view>
|
||
</uni-col>
|
||
</uni-row>
|
||
<uni-row>
|
||
<uni-col :span="8">
|
||
<view>温度(℃)</view>
|
||
</uni-col>
|
||
<uni-col :span="14">
|
||
<view class="right color" @click="toDetail(item,'temperature')">
|
||
{{item.temperature}}
|
||
</view>
|
||
</uni-col>
|
||
</uni-row>
|
||
<uni-row>
|
||
<uni-col :span="8">
|
||
<view>SOC(%)</view>
|
||
</uni-col>
|
||
<uni-col :span="14">
|
||
<view class="right color" @click="toDetail(item,'soc')">{{item.soc}}</view>
|
||
</uni-col>
|
||
</uni-row>
|
||
<uni-row>
|
||
<uni-col :span="8">
|
||
<view>SOH(%)</view>
|
||
</uni-col>
|
||
<uni-col :span="14">
|
||
<view class="right color" @click="toDetail(item,'soh')">{{item.soh}}</view>
|
||
</uni-col>
|
||
</uni-row>
|
||
</view>
|
||
</template>
|
||
</uni-list-item>
|
||
</uni-list>
|
||
</view>
|
||
<uni-popup ref="popup" type="center" :animation="false" :mask-click="false" :is-mask-click="false"
|
||
@maskClick="maskClick">
|
||
<view class="chart-popup" v-if="showChart">
|
||
<uni-datetime-picker v-model="range" type="daterange" :end="end" rangeSeparator="至" @change="changeTime"
|
||
style="margin-bottom: 10px;" />
|
||
<view class="chart-container">
|
||
<qiun-data-charts type="line" :reload="showChart" :optsWatch='false' :opts="options"
|
||
:chartData="chartsData" :ontouch="true" :inScrollView="true" :pageScrollTop="pageScrollTop" />
|
||
</view>
|
||
</view>
|
||
</uni-popup>
|
||
<uni-popup ref="searchPopup" type="center">
|
||
<view class="uni-pa-5 search-container">
|
||
<uni-forms ref="form">
|
||
<uni-forms-item label="电池堆">
|
||
<uni-data-select :clear="false" v-model="search.stackId" :localdata="stackOptions"
|
||
@change="changeStackId"></uni-data-select>
|
||
</uni-forms-item>
|
||
<uni-forms-item label="电池簇">
|
||
<uni-data-select :clear="false" v-model="search.clusterId"
|
||
:localdata="clusterOptions"></uni-data-select>
|
||
</uni-forms-item>
|
||
<uni-forms-item label="编号">
|
||
<uni-easyinput type="text" v-model="search.batteryId" placeholder="请输入编号" />
|
||
</uni-forms-item>
|
||
</uni-forms>
|
||
<view class="button-group" style="text-align: center;">
|
||
<button type="default" size="mini" @click="onReset">重置</button>
|
||
<button type="primary" size="mini" @click="onSearch" style="margin-left: 20px;">搜索</button>
|
||
</view>
|
||
</view>
|
||
</uni-popup>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
// import Chart from './Chart.vue'
|
||
import {
|
||
getStackNameList,
|
||
getClusterNameList,
|
||
getClusterDataInfoList,
|
||
getSingleBatteryData
|
||
} from '@/api/ems/site.js'
|
||
import {
|
||
mapState
|
||
} from 'vuex'
|
||
export default {
|
||
components: {
|
||
// Chart
|
||
},
|
||
computed: {
|
||
...mapState({
|
||
workStatusOptions: (state) =>
|
||
state.ems.workStatusOptions,
|
||
communicationStatusOptions: (state) =>
|
||
state.ems.communicationStatusOptions,
|
||
})
|
||
},
|
||
data() {
|
||
return {
|
||
pageNum: 1,
|
||
pageSize: 20,
|
||
total: 0,
|
||
stackOptions: [],
|
||
clusterOptions: [],
|
||
search: {
|
||
stackId: '',
|
||
clusterId: '',
|
||
batteryId: ''
|
||
},
|
||
list: [],
|
||
siteId: '',
|
||
pageScrollTop: 0,
|
||
// ucharts数据
|
||
showChart: false,
|
||
chartSearchData: {
|
||
|
||
},
|
||
options: {
|
||
duration: 0,
|
||
animation: false,
|
||
dataLabel: false,
|
||
enableScroll: true,
|
||
xAxis: {
|
||
scrollShow: true,
|
||
itemCount: 3,
|
||
disableGrid: true
|
||
},
|
||
},
|
||
range: [],
|
||
end: Date.now(),
|
||
loading: false,
|
||
chartsData: {},
|
||
// ucharts数据结束
|
||
|
||
}
|
||
},
|
||
onPageScroll(e) {
|
||
this.pageScrollTop = e.scrollTop
|
||
},
|
||
onReachBottom() {
|
||
if (this.list.length >= this.total) {
|
||
return console.log('数据已经加载完成')
|
||
}
|
||
this.pageNum += 1 //每次搜索从1开始搜索
|
||
this.getTableData()
|
||
},
|
||
methods: {
|
||
//ucharts方法
|
||
maskClick() {
|
||
this.showChart = false
|
||
this.$refs.popup.close()
|
||
},
|
||
chartOpen({
|
||
siteId,
|
||
clusterDeviceId,
|
||
deviceId
|
||
}, dataType) {
|
||
this.loading = false
|
||
this.range = []
|
||
this.chartSearchData = {
|
||
clusterDeviceId,
|
||
deviceId,
|
||
dataType
|
||
}
|
||
this.$refs.popup.open()
|
||
setTimeout(() => {
|
||
this.showChart = true
|
||
this.getChartData()
|
||
}, 100)
|
||
},
|
||
changeTime(val) {
|
||
this.range = val || []
|
||
this.getChartData()
|
||
},
|
||
getChartData() {
|
||
if (this.loading) return
|
||
this.loading = true;
|
||
const {
|
||
siteId,
|
||
chartSearchData: {
|
||
deviceId,
|
||
clusterDeviceId
|
||
},
|
||
range: [startDate = '', endDate = '']
|
||
} = this;
|
||
this.chartsData = {}
|
||
return getSingleBatteryData({
|
||
siteId,
|
||
deviceId,
|
||
clusterDeviceId,
|
||
startDate,
|
||
endDate
|
||
}).then(response => {
|
||
this.handledata(response?.data || [])
|
||
}).finally(() => {
|
||
this.loading = false;
|
||
})
|
||
},
|
||
handledata(data) {
|
||
let obj = {
|
||
voltage: '电压',
|
||
temperature: '温度',
|
||
soc: 'SOC',
|
||
soh: 'SOH',
|
||
},
|
||
categories = [],
|
||
dataTypeList = [],
|
||
{
|
||
dataType
|
||
} = this.chartSearchData
|
||
if (dataType) {
|
||
dataTypeList = [{
|
||
attr: dataType,
|
||
title: obj[dataType],
|
||
data: []
|
||
}]
|
||
} else {
|
||
dataTypeList = Object.entries(obj).map(([key, value]) => {
|
||
return {
|
||
attr: key,
|
||
title: value,
|
||
data: []
|
||
}
|
||
})
|
||
|
||
}
|
||
data.forEach(item => {
|
||
categories.push(item.dataTimestamp)
|
||
dataTypeList.forEach(i => {
|
||
i.data.push(item[i.attr] || undefined)
|
||
})
|
||
})
|
||
const series = dataTypeList.map(item => {
|
||
return {
|
||
"name": item.title,
|
||
"data": item.data
|
||
}
|
||
})
|
||
this.chartsData = JSON.parse(JSON.stringify({
|
||
categories,
|
||
series
|
||
}))
|
||
console.log('this.chartsData', this.chartsData)
|
||
},
|
||
//ucharts方法结束
|
||
|
||
|
||
|
||
openSearch() {
|
||
this.$refs.searchPopup.open()
|
||
},
|
||
closeSearch() {
|
||
this.$refs.searchPopup.close()
|
||
},
|
||
toDetail(item, dataType) {
|
||
const {
|
||
clusterDeviceId,
|
||
deviceId
|
||
} = item, {
|
||
siteId
|
||
} = this
|
||
// this.$refs.chart.open({
|
||
this.chartOpen({
|
||
siteId,
|
||
clusterDeviceId,
|
||
deviceId
|
||
}, dataType)
|
||
},
|
||
// 搜索
|
||
onSearch() {
|
||
this.pageNum = 1 //每次搜索从1开始搜索
|
||
this.getTableData(true)
|
||
this.closeSearch()
|
||
},
|
||
// 重置
|
||
// 清空搜索栏选中数据
|
||
// 清空电池簇列表,保留电池堆列表
|
||
onReset() {
|
||
this.search = {
|
||
stackId: '',
|
||
clusterId: '',
|
||
batteryId: ''
|
||
}
|
||
this.clusterOptions = []
|
||
this.pageNum = 1
|
||
this.getTableData(true)
|
||
this.closeSearch()
|
||
},
|
||
changeStackId(val) {
|
||
if (val) {
|
||
console.log('选择了电池堆,需要获取对应的电池簇', val, this.search.stackId)
|
||
this.search.clusterId = ''
|
||
this.getClusterList()
|
||
}
|
||
},
|
||
getStackList() {
|
||
getStackNameList({
|
||
siteId: this.siteId
|
||
}).then(response => {
|
||
this.stackOptions = JSON.parse(JSON.stringify(response?.data || [])).map(item => {
|
||
return {
|
||
text: item.deviceName,
|
||
value: item.id
|
||
}
|
||
})
|
||
})
|
||
},
|
||
getClusterList() {
|
||
getClusterNameList({
|
||
stackDeviceId: this.search.stackId,
|
||
siteId: this.siteId
|
||
}).then(response => {
|
||
this.clusterOptions = JSON.parse(JSON.stringify(response?.data || [])).map(item => {
|
||
return {
|
||
text: item.deviceName,
|
||
value: item.id
|
||
}
|
||
})
|
||
}).finally(() => {})
|
||
},
|
||
//表格数据
|
||
getTableData(reset = false) {
|
||
if (!reset && this.list.length === this.total) return
|
||
uni.showLoading()
|
||
if (reset) {
|
||
this.list = []
|
||
this.total = 0
|
||
}
|
||
const {
|
||
stackId: stackDeviceId,
|
||
clusterId: clusterDeviceId,
|
||
batteryId
|
||
} = this.search
|
||
const {
|
||
siteId,
|
||
pageNum,
|
||
pageSize
|
||
} = this
|
||
getClusterDataInfoList({
|
||
stackDeviceId,
|
||
clusterDeviceId,
|
||
batteryId,
|
||
siteId,
|
||
pageNum,
|
||
pageSize
|
||
}).then(response => {
|
||
this.list = this.list.concat(response?.rows?.[0]?.batteryList || []);
|
||
this.total = response?.total || 0
|
||
}).finally(() => {
|
||
uni.hideLoading()
|
||
})
|
||
},
|
||
},
|
||
mounted() {
|
||
// uni.showLoading()
|
||
this.siteId = this.$route.query.siteId || ''
|
||
this.getStackList()
|
||
this.getTableData(true)
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.container {
|
||
position: relative;
|
||
|
||
// position: fixed;
|
||
// width: 100%;
|
||
// height: 100%;
|
||
// overflow-y: auto;
|
||
.search-icon {
|
||
position: fixed;
|
||
bottom: 20px;
|
||
right: 20px;
|
||
z-index: 1;
|
||
height: 50px;
|
||
width: 50px;
|
||
background-color: #007aff;
|
||
border-radius: 100%;
|
||
line-height: 50px;
|
||
text-align: center;
|
||
}
|
||
|
||
.search-container {
|
||
background: #ffffff;
|
||
width: 360px;
|
||
padding: 15px 20px;
|
||
}
|
||
|
||
.list-container {
|
||
// z-index: 10;
|
||
padding-top: 20px;
|
||
padding-bottom: 50px;
|
||
background: #ffffff;
|
||
|
||
::v-deep {
|
||
.uni-list-item {
|
||
padding: 12px 15px;
|
||
}
|
||
|
||
.uni-list-item__container {
|
||
padding: 0;
|
||
display: block;
|
||
box-shadow: 0 1px 8px 1px rgba($color: #a5a5a5, $alpha: 0.2);
|
||
}
|
||
|
||
.uni-list--border-top,
|
||
.uni-list--border-bottom,
|
||
.uni-list--border::after {
|
||
background-color: transparent;
|
||
}
|
||
}
|
||
|
||
.list-header {
|
||
background-color: #05AEA3;
|
||
color: #fff;
|
||
padding: 10px 15px;
|
||
border-radius: 5px 5px 0 0;
|
||
position: relative;
|
||
|
||
.charts {
|
||
position: absolute;
|
||
top: 50%;
|
||
right: 15px;
|
||
transform: translateY(-50%);
|
||
// background-color: #ff7300;
|
||
}
|
||
}
|
||
|
||
.list-body {
|
||
padding: 10px 15px;
|
||
border: 1px solid #eee;
|
||
border-top: none;
|
||
border-radius: 0 0 5px 5px;
|
||
font-size: 14px;
|
||
color: #666;
|
||
|
||
.right {
|
||
color: #000;
|
||
}
|
||
|
||
.color {
|
||
color: #007aff;
|
||
}
|
||
|
||
.uni-row {
|
||
margin-bottom: 10px;
|
||
|
||
&:last-child {
|
||
margin-bottom: 0;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.chart-popup {
|
||
width: 360px;
|
||
background-color: #fff;
|
||
padding: 10px 15px;
|
||
|
||
.chart-container {
|
||
width: 100%;
|
||
height: 250px;
|
||
margin-top: 20px;
|
||
}
|
||
|
||
::v-deep {
|
||
uni-canvas {
|
||
height: 250px;
|
||
width: 100%;
|
||
}
|
||
}
|
||
}
|
||
|
||
}
|
||
</style> |