507 lines
11 KiB
Vue
507 lines
11 KiB
Vue
|
<route lang="json5" type="page">
|
|||
|
{
|
|||
|
layout: 'default',
|
|||
|
style: {
|
|||
|
navigationStyle: 'custom',
|
|||
|
navigationBarTitleText: '历史数据图表',
|
|||
|
},
|
|||
|
}
|
|||
|
</route>
|
|||
|
|
|||
|
<template>
|
|||
|
<PageLayout navTitle="历史数据图表" backRouteName="index" routeMethod="pushTab">
|
|||
|
<view class="chart-container">
|
|||
|
<view class="chart-header">
|
|||
|
<view class="chart-title-container">
|
|||
|
<text class="chart-title">{{ chartTitle }}</text>
|
|||
|
</view>
|
|||
|
|
|||
|
<view class="filter-section">
|
|||
|
<view class="date-picker">
|
|||
|
<uni-datetime-picker type="datetimerange" v-model="lssjTimeRang" @change="getTime"
|
|||
|
:placeholder="['开始时间', '结束时间']" />
|
|||
|
</view>
|
|||
|
|
|||
|
<view class="checkbox-container">
|
|||
|
<label class="checkbox">
|
|||
|
<checkbox :checked="tableVisibled" @change="onChangeTable" />
|
|||
|
<text>{{ checkBoxText }}</text>
|
|||
|
</label>
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
|
|||
|
<!-- 图表容器 -->
|
|||
|
<view id="myCharts" class="chart"></view>
|
|||
|
|
|||
|
<!-- 数据表格 -->
|
|||
|
<view v-if="tableVisibled" class="table-container">
|
|||
|
<uni-table border stripe emptyText="暂无数据" :loading="loading">
|
|||
|
<uni-tr>
|
|||
|
<uni-th width="60" align="center">序号</uni-th>
|
|||
|
<uni-th align="center">日期时间</uni-th>
|
|||
|
<uni-th align="center">温度(℃)</uni-th>
|
|||
|
<uni-th align="center">压力(MPa)</uni-th>
|
|||
|
<uni-th align="center">压差(kPa)</uni-th>
|
|||
|
<uni-th align="center">瞬时量(Nm³/d)</uni-th>
|
|||
|
<uni-th align="center">今日量(m³)</uni-th>
|
|||
|
<uni-th align="center">今日时间(分)</uni-th>
|
|||
|
<uni-th align="center">仪表状态</uni-th>
|
|||
|
</uni-tr>
|
|||
|
<uni-tr v-for="(item, index) in dataSource" :key="index">
|
|||
|
<uni-td align="center">{{ index + 1 }}</uni-td>
|
|||
|
<uni-td align="center">{{ formatTableTime(item.createTime) }}</uni-td>
|
|||
|
<uni-td align="center">{{ item.wd }}</uni-td>
|
|||
|
<uni-td align="center">{{ item.yl }}</uni-td>
|
|||
|
<uni-td align="center">{{ item.yc }}</uni-td>
|
|||
|
<uni-td align="center">{{ item.ssll }}</uni-td>
|
|||
|
<uni-td align="center">{{ item.jrl }}</uni-td>
|
|||
|
<uni-td align="center">{{ item.jrsj }}</uni-td>
|
|||
|
<uni-td align="center">{{ item.zt }}</uni-td>
|
|||
|
</uni-tr>
|
|||
|
</uni-table>
|
|||
|
|
|||
|
<view class="pagination">
|
|||
|
<uni-pagination :current="ipagination.current" :pageSize="ipagination.pageSize"
|
|||
|
:total="ipagination.total" @change="handlePageChange" showTotal />
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
</PageLayout>
|
|||
|
</template>
|
|||
|
|
|||
|
<script setup>
|
|||
|
import {
|
|||
|
ref,
|
|||
|
onMounted,
|
|||
|
onUnmounted,
|
|||
|
watch,
|
|||
|
nextTick
|
|||
|
} from 'vue'
|
|||
|
import {
|
|||
|
onLoad
|
|||
|
} from '@dcloudio/uni-app'
|
|||
|
import {
|
|||
|
formatDate
|
|||
|
} from '@/utils/dateTime.ts'
|
|||
|
|
|||
|
// 定义props
|
|||
|
const props = defineProps({
|
|||
|
lineData: {
|
|||
|
type: Object,
|
|||
|
default: () => ({})
|
|||
|
}
|
|||
|
})
|
|||
|
|
|||
|
// 数据声明
|
|||
|
const urljlByJldID = ref('https://szcx.zyyt.sinopec.com/Gyk/jldls/cxcSssjLssjJldls/getLssjByJldId')
|
|||
|
|
|||
|
|
|||
|
const colorData = [{
|
|||
|
color: '#000000'
|
|||
|
},
|
|||
|
{
|
|||
|
color: '#00007f'
|
|||
|
},
|
|||
|
{
|
|||
|
color: '#ff0000'
|
|||
|
},
|
|||
|
{
|
|||
|
color: '#005500'
|
|||
|
},
|
|||
|
{
|
|||
|
color: '#55007f'
|
|||
|
},
|
|||
|
{
|
|||
|
color: '#ffff00'
|
|||
|
}
|
|||
|
]
|
|||
|
|
|||
|
const option = ref({})
|
|||
|
const legendData = ref([])
|
|||
|
const xData = ref([])
|
|||
|
const yaxis = ref({
|
|||
|
type: 'value',
|
|||
|
name: '',
|
|||
|
min: 0,
|
|||
|
max: 500,
|
|||
|
position: 'left',
|
|||
|
axisLabel: {
|
|||
|
formatter: '{value}'
|
|||
|
},
|
|||
|
axisLine: {
|
|||
|
lineStyle: {
|
|||
|
color: '#61A0A8'
|
|||
|
}
|
|||
|
}
|
|||
|
})
|
|||
|
|
|||
|
const yAxis = ref([])
|
|||
|
const series = ref([])
|
|||
|
const serie = ref({
|
|||
|
field: '',
|
|||
|
name: '',
|
|||
|
showSymbol: false,
|
|||
|
type: 'line',
|
|||
|
data: [],
|
|||
|
yAxisIndex: 1,
|
|||
|
lineStyle: {
|
|||
|
color: '#61A0A8',
|
|||
|
width: 1
|
|||
|
},
|
|||
|
connectNulls: false
|
|||
|
})
|
|||
|
|
|||
|
const tableVisibled = ref(false)
|
|||
|
const checkBoxText = ref('显示历史报表')
|
|||
|
const dataSource = ref([])
|
|||
|
const loading = ref(false)
|
|||
|
const ipagination = ref({
|
|||
|
current: 1,
|
|||
|
pageSize: 10,
|
|||
|
total: 0
|
|||
|
})
|
|||
|
|
|||
|
const jldID = ref('')
|
|||
|
const jldName = ref('')
|
|||
|
const chartTitle = ref('')
|
|||
|
const lineName = ref([])
|
|||
|
const startTime = ref('')
|
|||
|
const endTime = ref('')
|
|||
|
const lssjTimeRang = ref([])
|
|||
|
const myCharts = ref(null)
|
|||
|
|
|||
|
// 获取当前日期时间范围
|
|||
|
const getDefaultTimeRange = () => {
|
|||
|
const now = new Date()
|
|||
|
const start = new Date(now)
|
|||
|
start.setHours(8, 0, 0, 0)
|
|||
|
|
|||
|
const end = new Date(now)
|
|||
|
end.setDate(end.getDate() + 1)
|
|||
|
end.setHours(7, 59, 59, 0)
|
|||
|
|
|||
|
return [start.getTime(), end.getTime()]
|
|||
|
}
|
|||
|
|
|||
|
// 初始化图表
|
|||
|
const initChart = () => {
|
|||
|
series.value = []
|
|||
|
yAxis.value = []
|
|||
|
xData.value = []
|
|||
|
let positionIndex = 0
|
|||
|
|
|||
|
for (let i = 0; i < lineName.value.length; i++) {
|
|||
|
const yaxisTemp = JSON.parse(JSON.stringify(yaxis.value))
|
|||
|
legendData.value.push(`${lineName.value[i].name}(${lineName.value[i].unit})`)
|
|||
|
|
|||
|
if (lineName.value[i].field === 'ssll') {
|
|||
|
yaxisTemp.position = 'left'
|
|||
|
} else {
|
|||
|
yaxisTemp.position = 'right'
|
|||
|
yaxisTemp.offset = lineName.value[i].field === 'jrl' ? 60 * positionIndex : 55 * positionIndex
|
|||
|
positionIndex += 1
|
|||
|
}
|
|||
|
|
|||
|
yaxisTemp.name = `${lineName.value[i].name}(${lineName.value[i].unit})`
|
|||
|
yaxisTemp.min = lineName.value[i].min
|
|||
|
yaxisTemp.max = lineName.value[i].max
|
|||
|
yaxisTemp.axisLine.lineStyle.color = colorData[i].color
|
|||
|
yAxis.value.push(yaxisTemp)
|
|||
|
|
|||
|
const serieTemp = JSON.parse(JSON.stringify(serie.value))
|
|||
|
serieTemp.name = `${lineName.value[i].name}(${lineName.value[i].unit})`
|
|||
|
serieTemp.field = lineName.value[i].field
|
|||
|
serieTemp.lineStyle.color = colorData[i].color
|
|||
|
serieTemp.yAxisIndex = i
|
|||
|
series.value.push(serieTemp)
|
|||
|
}
|
|||
|
|
|||
|
option.value = {
|
|||
|
color: ['#000000', '#00007f', '#ff0000', '#005500', '#55007f', '#ffff00'],
|
|||
|
tooltip: {
|
|||
|
trigger: 'axis',
|
|||
|
axisPointer: {
|
|||
|
type: 'shadow'
|
|||
|
}
|
|||
|
},
|
|||
|
dataZoom: [{
|
|||
|
connectNulls: false,
|
|||
|
id: 'dataZoomX',
|
|||
|
type: "inside",
|
|||
|
roam: false,
|
|||
|
show: true,
|
|||
|
xAxisIndex: [0],
|
|||
|
filterMode: 'empty',
|
|||
|
throttle: 50,
|
|||
|
zoomOnMouseWheel: true,
|
|||
|
moveOnMouseMove: true
|
|||
|
}, {
|
|||
|
id: 'dataZoomY',
|
|||
|
type: 'inside',
|
|||
|
filterMode: 'empty',
|
|||
|
zoomLock: false,
|
|||
|
throttle: 50,
|
|||
|
zoomOnMouseWheel: true,
|
|||
|
moveOnMouseMove: true
|
|||
|
}],
|
|||
|
toolbox: {
|
|||
|
feature: {
|
|||
|
dataView: {
|
|||
|
show: false,
|
|||
|
readOnly: false
|
|||
|
},
|
|||
|
restore: {
|
|||
|
show: false
|
|||
|
},
|
|||
|
saveAsImage: {
|
|||
|
show: false
|
|||
|
}
|
|||
|
}
|
|||
|
},
|
|||
|
legend: {
|
|||
|
data: legendData.value
|
|||
|
},
|
|||
|
grid: {
|
|||
|
top: '10%',
|
|||
|
left: '3%',
|
|||
|
right: '10%',
|
|||
|
bottom: '3%',
|
|||
|
containLabel: true
|
|||
|
},
|
|||
|
xAxis: {
|
|||
|
type: 'category',
|
|||
|
axisTick: {
|
|||
|
alignWithLabel: true
|
|||
|
},
|
|||
|
data: xData.value
|
|||
|
},
|
|||
|
yAxis: yAxis.value,
|
|||
|
series: series.value
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// 时间选择变化
|
|||
|
const getTime = (e) => {
|
|||
|
if (e && e.length === 2) {
|
|||
|
startTime.value = formatDate(e[0], 'yyyy-MM-dd hh:mm:ss')
|
|||
|
endTime.value = formatDate(e[1], 'yyyy-MM-dd hh:mm:ss')
|
|||
|
updateChart()
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// 切换表格显示
|
|||
|
const onChangeTable = (e) => {
|
|||
|
tableVisibled.value = !tableVisibled.value
|
|||
|
checkBoxText.value = tableVisibled.value ? '显示历史趋势' : '显示历史报表'
|
|||
|
}
|
|||
|
|
|||
|
// 分页变化
|
|||
|
const handlePageChange = (e) => {
|
|||
|
ipagination.value.current = e.current
|
|||
|
ipagination.value.pageSize = e.pageSize
|
|||
|
}
|
|||
|
|
|||
|
// 格式化表格时间显示
|
|||
|
const formatTableTime = (time) => {
|
|||
|
if (!time) return ''
|
|||
|
return formatDate(time, 'yyyy-MM-dd hh:mm:ss')
|
|||
|
}
|
|||
|
|
|||
|
// 获取数组最大值
|
|||
|
const maxArrValue = (data) => {
|
|||
|
if (!data || data.length === 0) return 0
|
|||
|
|
|||
|
const list = []
|
|||
|
for (let i in data) {
|
|||
|
if (data[i] !== null) {
|
|||
|
list.push(parseInt(data[i]))
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (list.length === 0) return 0
|
|||
|
|
|||
|
list.sort((num1, num2) => num1 - num2)
|
|||
|
return list[list.length - 1]
|
|||
|
}
|
|||
|
|
|||
|
// 更新图表数据
|
|||
|
const updateChart = () => {
|
|||
|
dataSource.value = []
|
|||
|
xData.value = []
|
|||
|
|
|||
|
for (let j = 0; j < series.value.length; j++) {
|
|||
|
series.value[j].data = []
|
|||
|
}
|
|||
|
|
|||
|
loading.value = true
|
|||
|
|
|||
|
getAction(url.list, {
|
|||
|
jldId: jldID.value,
|
|||
|
startTime: startTime.value,
|
|||
|
endTime: endTime.value
|
|||
|
}).then(res => {
|
|||
|
loading.value = false
|
|||
|
|
|||
|
if (res.success) {
|
|||
|
const ssData = JSON.parse(res.result)
|
|||
|
dataSource.value = ssData
|
|||
|
ipagination.value.total = ssData.length
|
|||
|
|
|||
|
for (let i = 0; i < ssData.length; i++) {
|
|||
|
const ctime = formatDate(ssData[i].createTime, 'yyyy-MM-dd hh:mm:ss')
|
|||
|
xData.value.push(ctime)
|
|||
|
|
|||
|
for (let j = 0; j < series.value.length; j++) {
|
|||
|
let tempValue = ssData[i][lineName.value[j].field]
|
|||
|
tempValue = tempValue === 0 ? null : tempValue
|
|||
|
series.value[j].data.push(tempValue)
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
for (let mm = 0; mm < series.value.length; mm++) {
|
|||
|
const maxVal = maxArrValue(series.value[mm].data)
|
|||
|
yAxis.value[mm].max = Math.round(maxVal * 1.2)
|
|||
|
}
|
|||
|
|
|||
|
option.value.xAxis.data = xData.value
|
|||
|
|
|||
|
if (myCharts.value) {
|
|||
|
myCharts.value.setOption(option.value)
|
|||
|
}
|
|||
|
}
|
|||
|
}).catch(() => {
|
|||
|
loading.value = false
|
|||
|
})
|
|||
|
}
|
|||
|
|
|||
|
// 初始化ECharts
|
|||
|
const initECharts = () => {
|
|||
|
nextTick(() => {
|
|||
|
// 在Uniapp中,需要使用uni.createCanvasContext或使用ucharts等替代方案
|
|||
|
// 这里简化处理,实际使用时需要根据Uniapp的图表方案调整
|
|||
|
const canvas = document.getElementById('myCharts')
|
|||
|
if (canvas) {
|
|||
|
// 初始化ECharts实例
|
|||
|
myCharts.value = echarts.init(canvas)
|
|||
|
myCharts.value.setOption(option.value)
|
|||
|
}
|
|||
|
})
|
|||
|
}
|
|||
|
|
|||
|
// 监听lineData变化
|
|||
|
watch(() => props.lineData, (val) => {
|
|||
|
jldID.value = val.jldID
|
|||
|
jldName.value = val.jldName
|
|||
|
chartTitle.value = `${val.jldName}历史趋势`
|
|||
|
lineName.value = JSON.parse(JSON.stringify(val.lineName))
|
|||
|
startTime.value = val.startTime
|
|||
|
endTime.value = val.endTime
|
|||
|
|
|||
|
try {
|
|||
|
if (val.startTime && val.endTime) {
|
|||
|
const sDt = new Date(val.startTime)
|
|||
|
const eDt = new Date(val.endTime)
|
|||
|
lssjTimeRang.value = [sDt.getTime(), eDt.getTime()]
|
|||
|
} else {
|
|||
|
lssjTimeRang.value = getDefaultTimeRange()
|
|||
|
}
|
|||
|
} catch (e) {
|
|||
|
console.error('时间格式错误', e)
|
|||
|
lssjTimeRang.value = getDefaultTimeRange()
|
|||
|
}
|
|||
|
|
|||
|
initChart()
|
|||
|
updateChart()
|
|||
|
}, {
|
|||
|
deep: true,
|
|||
|
immediate: true
|
|||
|
})
|
|||
|
|
|||
|
// 页面加载
|
|||
|
onLoad(() => {
|
|||
|
// 设置默认时间范围
|
|||
|
lssjTimeRang.value = getDefaultTimeRange()
|
|||
|
|
|||
|
// 在Uniapp中需要动态导入echarts或使用其他图表库
|
|||
|
setTimeout(() => {
|
|||
|
initECharts()
|
|||
|
}, 500)
|
|||
|
})
|
|||
|
|
|||
|
// 页面卸载
|
|||
|
onUnmounted(() => {
|
|||
|
if (myCharts.value) {
|
|||
|
myCharts.value.dispose()
|
|||
|
}
|
|||
|
})
|
|||
|
</script>
|
|||
|
|
|||
|
<style scoped>
|
|||
|
.chart-container {
|
|||
|
width: 100%;
|
|||
|
height: 100%;
|
|||
|
padding: 20rpx;
|
|||
|
box-sizing: border-box;
|
|||
|
display: flex;
|
|||
|
flex-direction: column;
|
|||
|
}
|
|||
|
|
|||
|
.chart-header {
|
|||
|
margin-bottom: 20rpx;
|
|||
|
}
|
|||
|
|
|||
|
.chart-title-container {
|
|||
|
width: 100%;
|
|||
|
text-align: center;
|
|||
|
margin-bottom: 20rpx;
|
|||
|
}
|
|||
|
|
|||
|
.chart-title {
|
|||
|
font-size: 36rpx;
|
|||
|
font-weight: bold;
|
|||
|
color: #333;
|
|||
|
}
|
|||
|
|
|||
|
.filter-section {
|
|||
|
display: flex;
|
|||
|
flex-direction: column;
|
|||
|
gap: 20rpx;
|
|||
|
margin-bottom: 20rpx;
|
|||
|
}
|
|||
|
|
|||
|
.date-picker {
|
|||
|
width: 100%;
|
|||
|
}
|
|||
|
|
|||
|
.checkbox-container {
|
|||
|
display: flex;
|
|||
|
align-items: center;
|
|||
|
}
|
|||
|
|
|||
|
.checkbox {
|
|||
|
display: flex;
|
|||
|
align-items: center;
|
|||
|
font-size: 28rpx;
|
|||
|
}
|
|||
|
|
|||
|
.chart {
|
|||
|
width: 100%;
|
|||
|
height: 600rpx;
|
|||
|
background-color: #fff;
|
|||
|
border-radius: 10rpx;
|
|||
|
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.1);
|
|||
|
margin-bottom: 20rpx;
|
|||
|
}
|
|||
|
|
|||
|
.table-container {
|
|||
|
width: 100%;
|
|||
|
overflow-x: auto;
|
|||
|
}
|
|||
|
|
|||
|
.pagination {
|
|||
|
margin-top: 20rpx;
|
|||
|
display: flex;
|
|||
|
justify-content: center;
|
|||
|
}
|
|||
|
</style>
|