Files
emsapp/pages/work/dtdc/index.vue

519 lines
12 KiB
Vue
Raw Normal View History

2025-07-29 23:05:58 +08:00
<template>
<view class="container">
2025-07-31 14:24:05 +08:00
<view class="search-icon" @click="openSearch">
2026-01-15 17:51:09 +08:00
<uni-icons type="search" size="25" color="#fff"></uni-icons>
2025-07-29 23:05:58 +08:00
</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}}
2026-01-15 17:51:09 +08:00
<button type="primary" size="mini" class="charts-btn" @click="toDetail(item)">图表</button>
2025-07-29 23:05:58 +08:00
</view>
</template>
<template v-slot:body>
<view class="list-body">
<uni-row>
<uni-col :span="8">
<view>簇号</view>
</uni-col>
2026-01-15 17:51:09 +08:00
<uni-col :span="16">
<view class="right">{{item.clusterDeviceId || '-'}}</view>
2025-07-29 23:05:58 +08:00
</uni-col>
</uni-row>
<uni-row>
<uni-col :span="8">
<view>电压V</view>
</uni-col>
2026-01-15 17:51:09 +08:00
<uni-col :span="16">
<view class="right color">
<text @click="toDetail(item,'voltage')">{{item.voltage | formatNumber}}</text>
2025-07-29 23:05:58 +08:00
</view>
</uni-col>
</uni-row>
<uni-row>
<uni-col :span="8">
<view>温度</view>
</uni-col>
2026-01-15 17:51:09 +08:00
<uni-col :span="16">
<view class="right color">
<text
@click="toDetail(item,'temperature')">{{item.temperature | formatNumber}}</text>
2025-07-29 23:05:58 +08:00
</view>
</uni-col>
</uni-row>
<uni-row>
<uni-col :span="8">
<view>SOC%</view>
</uni-col>
2026-01-15 17:51:09 +08:00
<uni-col :span="16">
<view class="right color">
<text @click="toDetail(item,'soc')">{{item.soc | formatNumber}}</text>
</view>
2025-07-29 23:05:58 +08:00
</uni-col>
</uni-row>
<uni-row>
<uni-col :span="8">
<view>SOH%</view>
</uni-col>
2026-01-15 17:51:09 +08:00
<uni-col :span="16">
<view class="right color">
<text @click="toDetail(item,'soh')">{{item.soh | formatNumber}}</text>
</view>
2025-07-29 23:05:58 +08:00
</uni-col>
</uni-row>
</view>
</template>
</uni-list-item>
</uni-list>
</view>
2025-08-17 01:13:04 +08:00
<uni-popup ref="popup" type="center" :animation="false" :mask-click="false" :is-mask-click="false"
@maskClick="maskClick">
<view class="chart-popup" v-if="showChart">
2025-10-15 18:16:56 +08:00
<date-range-select ref="chartDateRangeSelect" @updateDate="updateChartDate"
2025-08-17 01:13:04 +08:00
style="margin-bottom: 10px;" />
<view class="chart-container">
2026-01-16 17:54:42 +08:00
<qiun-data-charts type="area" :reload="showChart" :optsWatch='false' :opts="options"
2025-08-17 01:13:04 +08:00
:chartData="chartsData" :ontouch="true" :inScrollView="true" :pageScrollTop="pageScrollTop" />
</view>
</view>
</uni-popup>
2025-07-31 14:24:05 +08:00
<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>
2025-08-15 17:41:26 +08:00
<uni-forms-item label="编号">
<uni-easyinput type="text" v-model="search.batteryId" placeholder="请输入编号" />
</uni-forms-item>
2025-07-31 14:24:05 +08:00
</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>
2025-07-29 23:05:58 +08:00
</view>
</template>
<script>
2025-10-15 18:16:56 +08:00
import DateRangeSelect from './../DateRangeSelect.vue'
2025-07-29 23:05:58 +08:00
import {
getStackNameList,
getClusterNameList,
getClusterDataInfoList,
2025-08-17 01:13:04 +08:00
getSingleBatteryData
2025-07-29 23:05:58 +08:00
} from '@/api/ems/site.js'
import {
mapState
} from 'vuex'
export default {
2025-10-15 18:16:56 +08:00
components: {
DateRangeSelect
},
2025-07-29 23:05:58 +08:00
data() {
return {
pageNum: 1,
pageSize: 20,
total: 0,
stackOptions: [],
clusterOptions: [],
search: {
stackId: '',
2025-08-15 17:41:26 +08:00
clusterId: '',
batteryId: ''
2025-07-29 23:05:58 +08:00
},
list: [],
siteId: '',
2025-07-30 22:56:25 +08:00
pageScrollTop: 0,
2025-08-17 01:13:04 +08:00
// ucharts数据
showChart: false,
chartSearchData: {
},
options: {
2026-01-16 17:54:42 +08:00
padding: [10, 5, 0, 10],
2025-08-17 01:13:04 +08:00
duration: 0,
animation: false,
dataLabel: false,
enableScroll: true,
xAxis: {
scrollShow: true,
itemCount: 3,
disableGrid: true
},
2026-01-16 17:54:42 +08:00
extra: {
area: {
type: "curve",
opacity: 0.2,
addLine: true,
width: 2,
gradient: true,
activeType: "hollow"
}
}
2025-08-17 01:13:04 +08:00
},
range: [],
end: Date.now(),
loading: false,
chartsData: {},
// ucharts数据结束
2025-07-29 23:05:58 +08:00
}
},
2025-07-30 22:56:25 +08:00
onPageScroll(e) {
this.pageScrollTop = e.scrollTop
},
2025-08-05 17:26:18 +08:00
onReachBottom() {
if (this.list.length >= this.total) {
return console.log('数据已经加载完成')
}
this.pageNum += 1 //每次搜索从1开始搜索
this.getTableData()
},
2025-07-29 23:05:58 +08:00
methods: {
2025-08-17 01:13:04 +08:00
//ucharts方法
maskClick() {
this.showChart = false
this.$refs.popup.close()
},
chartOpen({
siteId,
clusterDeviceId,
deviceId
}, dataType) {
this.loading = false
this.chartSearchData = {
clusterDeviceId,
deviceId,
dataType
}
this.$refs.popup.open()
setTimeout(() => {
this.showChart = true
2025-10-15 18:16:56 +08:00
this.$nextTick(() => {
this.$refs.chartDateRangeSelect.init()
})
}, 500)
2025-08-17 01:13:04 +08:00
},
2025-10-15 18:16:56 +08:00
updateChartDate(data) {
this.range = data || []
2025-08-17 01:13:04 +08:00
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方法结束
2025-07-31 14:24:05 +08:00
openSearch() {
this.$refs.searchPopup.open()
},
closeSearch() {
this.$refs.searchPopup.close()
},
2025-07-30 22:56:25 +08:00
toDetail(item, dataType) {
const {
clusterDeviceId,
deviceId
} = item, {
siteId
} = this
2025-08-17 01:13:04 +08:00
// this.$refs.chart.open({
this.chartOpen({
2025-07-30 22:56:25 +08:00
siteId,
clusterDeviceId,
deviceId
}, dataType)
},
2025-07-29 23:05:58 +08:00
// 搜索
onSearch() {
this.pageNum = 1 //每次搜索从1开始搜索
this.getTableData(true)
2025-07-31 14:24:05 +08:00
this.closeSearch()
2025-07-29 23:05:58 +08:00
},
// 重置
// 清空搜索栏选中数据
// 清空电池簇列表,保留电池堆列表
onReset() {
this.search = {
stackId: '',
2025-08-15 17:41:26 +08:00
clusterId: '',
batteryId: ''
2025-07-29 23:05:58 +08:00
}
this.clusterOptions = []
this.pageNum = 1
this.getTableData(true)
2025-07-31 14:24:05 +08:00
this.closeSearch()
2025-07-29 23:05:58 +08:00
},
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,
2025-08-15 17:41:26 +08:00
clusterId: clusterDeviceId,
batteryId
2025-07-29 23:05:58 +08:00
} = this.search
const {
siteId,
pageNum,
pageSize
} = this
getClusterDataInfoList({
stackDeviceId,
clusterDeviceId,
2025-08-15 17:41:26 +08:00
batteryId,
2025-07-29 23:05:58 +08:00
siteId,
pageNum,
pageSize
}).then(response => {
2025-08-15 17:41:26 +08:00
this.list = this.list.concat(response?.rows?.[0]?.batteryList || []);
2025-07-29 23:05:58 +08:00
this.total = response?.total || 0
}).finally(() => {
uni.hideLoading()
})
},
},
2026-01-19 17:30:03 +08:00
onLoad(options) {
2025-07-29 23:05:58 +08:00
// uni.showLoading()
2026-01-19 17:30:03 +08:00
this.siteId = options.siteId || ''
2025-07-29 23:05:58 +08:00
this.getStackList()
this.getTableData(true)
}
}
</script>
<style lang="scss" scoped>
.container {
position: relative;
2026-01-15 17:51:09 +08:00
background: #f5f5f5;
2025-07-31 14:24:05 +08:00
.search-icon {
position: fixed;
2026-01-15 17:51:09 +08:00
bottom: 40rpx;
right: 40rpx;
2025-07-31 14:24:05 +08:00
z-index: 1;
2026-01-15 17:51:09 +08:00
height: 60rpx;
width: 60rpx;
2025-07-31 14:24:05 +08:00
background-color: #007aff;
border-radius: 100%;
2026-01-15 17:51:09 +08:00
line-height: 60rpx;
2025-07-31 14:24:05 +08:00
text-align: center;
}
2025-07-29 23:05:58 +08:00
.search-container {
background: #ffffff;
2025-07-31 14:24:05 +08:00
width: 360px;
padding: 15px 20px;
2025-07-29 23:05:58 +08:00
}
.list-container {
2026-01-15 17:51:09 +08:00
padding-top: 40rpx;
padding-bottom: 100rpx;
background: transparent;
2025-07-29 23:05:58 +08:00
::v-deep {
2026-01-15 17:51:09 +08:00
.uni-list {
background: transparent;
}
2025-08-05 17:44:20 +08:00
.uni-list-item {
2026-01-15 17:51:09 +08:00
padding: 10rpx 30rpx;
background-color: transparent !important;
2025-08-05 17:44:20 +08:00
}
2025-07-29 23:05:58 +08:00
.uni-list-item__container {
2026-01-15 17:51:09 +08:00
background-color: #ffffff;
2025-08-05 17:44:20 +08:00
padding: 0;
2025-07-29 23:05:58 +08:00
display: block;
2026-01-15 17:51:09 +08:00
border-radius: 10rpx;
box-shadow: 0 1px 16rpx 1px rgba($color: #a5a5a5, $alpha: 0.2);
2025-07-29 23:05:58 +08:00
}
.uni-list--border-top,
.uni-list--border-bottom,
.uni-list--border::after {
background-color: transparent;
}
}
.list-header {
2026-01-15 17:51:09 +08:00
border-radius: 14rpx 14rpx 0 0;
border-bottom: 1px solid #eee;
padding: 20rpx 30rpx;
font-weight: 700;
2026-01-19 17:30:03 +08:00
font-size: 28rpx;
2025-07-29 23:05:58 +08:00
position: relative;
2026-01-15 17:51:09 +08:00
color: #333;
2025-07-29 23:05:58 +08:00
2026-01-15 17:51:09 +08:00
.charts-btn {
2025-07-29 23:05:58 +08:00
position: absolute;
top: 50%;
2026-01-15 17:51:09 +08:00
right: 20rpx;
2026-01-19 17:30:03 +08:00
font-size: 26rpx;
2025-07-29 23:05:58 +08:00
transform: translateY(-50%);
2026-01-15 17:51:09 +08:00
background-color: #4c7af3;
2025-07-29 23:05:58 +08:00
}
}
.list-body {
2026-01-15 17:51:09 +08:00
padding: 10rpx 0;
2025-07-29 23:05:58 +08:00
2026-01-15 17:51:09 +08:00
>.uni-row {
font-size: 26rpx;
line-height: 36rpx;
2025-07-29 23:05:58 +08:00
color: #000;
2026-01-15 17:51:09 +08:00
padding: 12rpx 30rpx;
2025-07-29 23:05:58 +08:00
2026-01-15 17:51:09 +08:00
.left {
color: #333;
text-align: left;
}
2025-07-29 23:05:58 +08:00
2026-01-15 17:51:09 +08:00
.right {
text-align: right;
2025-07-29 23:05:58 +08:00
2026-01-15 17:51:09 +08:00
&.color {
color: #4c7af3;
font-weight: 700;
}
2025-07-29 23:05:58 +08:00
}
}
2026-01-15 17:51:09 +08:00
2025-07-29 23:05:58 +08:00
}
}
2025-08-17 01:13:04 +08:00
.chart-popup {
2026-01-15 17:51:09 +08:00
width: 720rpx;
2025-08-17 01:13:04 +08:00
background-color: #fff;
2026-01-15 17:51:09 +08:00
padding: 20rpx 30rpx;
2025-08-17 01:13:04 +08:00
.chart-container {
width: 100%;
2026-01-15 17:51:09 +08:00
height: 500rpx;
margin-top: 40rpx;
2025-08-17 01:13:04 +08:00
}
::v-deep {
uni-canvas {
2026-01-15 17:51:09 +08:00
height: 500rpx;
2025-08-17 01:13:04 +08:00
width: 100%;
}
}
}
2025-07-29 23:05:58 +08:00
}
</style>