feasure-livedata
lld 2026-03-25 01:21:40 +08:00
parent c054822545
commit 6d228f20f8
6 changed files with 395 additions and 295 deletions

236
pages/data/data.vue Normal file
View File

@ -0,0 +1,236 @@
<template>
<view class="data-view">
<view class="select-box">
<uni-row >
<uni-col :span="8">
<uni-data-select :clear="false" v-model="imei" :localdata="agriList" @change="changeAgri"></uni-data-select>
</uni-col>
<uni-col :span="16">
<uni-datetime-picker v-model="dateRange" type="datetimerange" :end="end" @change="changeDate"/>
</uni-col>
</uni-row>
</view>
<view class="charts-box">
<qiun-data-charts
type="line"
:opts="opts"
background="#ffffff"
:chartData="chartData"
:canvas2d="true"
canvasId="nMPkeQGNEosMwoWKKNRBZBIEhguMoMWp"
:ontouch="true"
:disableScroll="true"
:onmovetip="true"
tooltipFormat="tooltipDemo"
/>
</view>
<view class="uni-padding-wrap uni-common-mt tag-row">
<button @click.stop="jumpDate(-1)" style="margin-right: 20rpx;" type="primary" size="mini">前一天</button>
<button :disabled="isTodayDate(dateRange[0]) || isTodayDate(dateRange[1]) || dateRange.length===0" @click.stop="jumpDate(1)" style="margin-right: 20rpx;" type="default" size="mini">后一天</button>
<button @click.stop="jumpDate(0)" type="warn" size="mini">回到当天</button>
</view>
<!-- 暂无数据 -->
</view>
</template>
<script>
import { getHistoryData} from "../../api/system/data";
import {listAgri} from "../../api/system/assets/agri";
import {parseTime, isIntervalMoreThanNDays, getExactDiffDays, isTodayDate} from "../../utils/agri";
export default {
data: function () {
return {
chartData: {},
// opts type="line" config-ucharts.js ['line'] opts
opts: {
legend: {
},
xAxis: {
rotateAngle: 75,
format: "xAxisDemo"
},
yAxis: {
gridType: "dash",
dashLength: 2,
disabled: false,
disableGrid: false,
splitNumber: 5,
gridColor: "#CCCCCC",
padding: 10,
showTitle: true,
data: [
{
type: "value",
position: "left",
disabled: false,
axisLine: true,
axisLineColor: "#CCCCCC",
calibration: true,
fontColor: "#666666",
fontSize: 13,
textAlign: "left",
title: "温度(℃)",
titleFontSize: 14,
titleOffsetY: -10,
titleOffsetX: 5,
titleFontColor: "#333333",
min: 0,
max: 50,
tofix: 1,
unit: "",
format: ""
},
{
type: "value",
position: "right",
disabled: false,
axisLine: true,
axisLineColor: "#CCCCCC",
calibration: true,
fontColor: "#666666",
fontSize: 13,
textAlign: "right",
title: "湿度(%RH",
titleFontSize: 14,
titleOffsetY: -10,
titleOffsetX: 0,
titleFontColor: "#333333",
min: 0,
max: 100,
tofix: 1,
unit: "",
format: ""
}
]
}
},
dateRange:[],
end:Date.now(),
agriList:[],
imei:null
};
},
mounted() {
// this.getAgriList();
},
methods: {
isTodayDate,
getServerData() {
const param = {
imei: this.imei,
startTime: this.dateRange[0],
endTime: this.dateRange[1]
}
//
getHistoryData(param).then(response => {
if (response.code === 200 && response.data) {
var data = response.data;
this.chartData = JSON.parse(JSON.stringify(data));
}
})
},
getAgriList() {
listAgri().then(response => {
if (response.code === 200) {
this.agriList = response.rows.map(item => ({
agriId: item.id,
text: item.agriName,
value: item.imei //
}));
this.imei = this.agriList[0].value;
this.getServerData();
}
})
},
changeAgri(imei) {
if (imei) {
this.getServerData();
}
},
changeDate(date) {
// date[0]-date[1]
if (isIntervalMoreThanNDays(date[0],date[1],7)) {
this.$modal.alert('时间范围暂不支持查询超过7天以上的数据');
return;
}
if (date[0] === date[1]) {
this.dateRange[0] = parseTime(date[0], '{y}-{m}-{d} 00:00:00')
}
if (this.imei) {
this.getServerData();
}
},
jumpDate(days) {
// ||
// days: (-1) (1) (0)
let targetDate;
if (this.dateRange.length === 0 || getExactDiffDays(this.dateRange[0],this.dateRange[1])>1) {
this.dateRange[0] = new Date();
}
if (days === 0) {
//
targetDate = new Date();
} else {
//
const currentStartDate = new Date(this.dateRange[0]);
targetDate = new Date(currentStartDate);
targetDate.setDate(targetDate.getDate() + days);
}
// 00:00:00
const startDate = new Date(targetDate);
startDate.setHours(0, 0, 0, 0);
//
let endDate;
if (days === 0) {
//
endDate = new Date();
} else {
// 23:59:59
endDate = new Date(targetDate);
endDate.setHours(23, 59, 59, 999);
}
// dateRange
this.dateRange = [
parseTime(startDate ),
parseTime(endDate)
];
setTimeout(() => {
this.$nextTick(() => {
//
if (this.imei) {
this.getServerData();
}
})
}, 500)
}
}
};
</script>
<style scoped>
.data-view {
background: #ffffff;
}
.select-box {
margin-top: 10rpx;
}
.charts-box {
width: 100%;
height: 500px;
}
/deep/ .uni-select, /deep/ .uni-date-editor--x {
background: #fff !important;
height: 68rpx;
}
.tag-row {
text-align: center;
padding-bottom: 20rpx;
}
</style>

View File

@ -1,236 +1,31 @@
<template>
<view class="data-view">
<view class="select-box">
<uni-row >
<uni-col :span="8">
<uni-data-select :clear="false" v-model="imei" :localdata="agriList" @change="changeAgri"></uni-data-select>
</uni-col>
<uni-col :span="16">
<uni-datetime-picker v-model="dateRange" type="datetimerange" :end="end" @change="changeDate"/>
</uni-col>
</uni-row>
</view>
<view class="charts-box">
<qiun-data-charts
type="line"
:opts="opts"
background="#ffffff"
:chartData="chartData"
:canvas2d="true"
canvasId="nMPkeQGNEosMwoWKKNRBZBIEhguMoMWp"
:ontouch="true"
:disableScroll="true"
:onmovetip="true"
tooltipFormat="tooltipDemo"
/>
</view>
<view class="uni-padding-wrap uni-common-mt tag-row">
<button @click.stop="jumpDate(-1)" style="margin-right: 20rpx;" type="primary" size="mini">前一天</button>
<button :disabled="isTodayDate(dateRange[0]) || isTodayDate(dateRange[1])" @click.stop="jumpDate(1)" style="margin-right: 20rpx;" type="default" size="mini">后一天</button>
<button @click.stop="jumpDate(0)" type="warn" size="mini">回到当天</button>
</view>
<!-- 暂无数据 -->
<view>
<HistoryData ref="historyData" />
</view>
</template>
<script>
import { getHistoryData} from "../../api/system/data";
import {listAgri} from "../../api/system/assets/agri";
import {parseTime, isIntervalMoreThanNDays, getExactDiffDays, isTodayDate} from "../../utils/agri";
import HistoryData from './data.vue'
export default {
data: function () {
return {
chartData: {},
// opts type="line" config-ucharts.js ['line'] opts
opts: {
legend: {
},
xAxis: {
rotateAngle: 75,
format: "xAxisDemo"
},
yAxis: {
gridType: "dash",
dashLength: 2,
disabled: false,
disableGrid: false,
splitNumber: 5,
gridColor: "#CCCCCC",
padding: 10,
showTitle: true,
data: [
{
type: "value",
position: "left",
disabled: false,
axisLine: true,
axisLineColor: "#CCCCCC",
calibration: true,
fontColor: "#666666",
fontSize: 13,
textAlign: "left",
title: "温度(℃)",
titleFontSize: 14,
titleOffsetY: -10,
titleOffsetX: 5,
titleFontColor: "#333333",
min: 0,
max: 50,
tofix: 1,
unit: "",
format: ""
},
{
type: "value",
position: "right",
disabled: false,
axisLine: true,
axisLineColor: "#CCCCCC",
calibration: true,
fontColor: "#666666",
fontSize: 13,
textAlign: "right",
title: "湿度(%RH",
titleFontSize: 14,
titleOffsetY: -10,
titleOffsetX: 0,
titleFontColor: "#333333",
min: 0,
max: 100,
tofix: 1,
unit: "",
format: ""
}
]
}
},
dateRange:[],
end:Date.now(),
agriList:[],
imei:null
};
},
components: {
HistoryData
},
onShow() {
this.getAgriList();
this.$nextTick(() => {
this.$refs.historyData.getAgriList();
})
},
methods: {
isTodayDate,
getServerData() {
const param = {
imei: this.imei,
startTime: this.dateRange[0],
endTime: this.dateRange[1]
}
//
getHistoryData(param).then(response => {
if (response.code === 200 && response.data) {
var data = response.data;
this.chartData = JSON.parse(JSON.stringify(data));
}
})
},
getAgriList() {
listAgri().then(response => {
if (response.code === 200) {
this.agriList = response.rows.map(item => ({
agriId: item.id,
text: item.agriName,
value: item.imei //
}));
this.imei = this.agriList[0].value;
this.getServerData();
}
})
},
changeAgri(imei) {
if (imei) {
this.getServerData();
}
},
changeDate(date) {
// date[0]-date[1]
if (isIntervalMoreThanNDays(date[0],date[1],7)) {
this.$modal.alert('时间范围暂不支持查询超过7天以上的数据');
return;
}
if (date[0] === date[1]) {
this.dateRange[0] = parseTime(date[0], '{y}-{m}-{d} 00:00:00')
}
if (this.imei) {
this.getServerData();
}
},
jumpDate(days) {
// ||
// days: (-1) (1) (0)
let targetDate;
if (this.dateRange.length === 0 || getExactDiffDays(this.dateRange[0],this.dateRange[1])>1) {
this.dateRange[0] = new Date();
}
if (days === 0) {
//
targetDate = new Date();
} else {
//
const currentStartDate = new Date(this.dateRange[0]);
targetDate = new Date(currentStartDate);
targetDate.setDate(targetDate.getDate() + days);
}
// 00:00:00
const startDate = new Date(targetDate);
startDate.setHours(0, 0, 0, 0);
//
let endDate;
if (days === 0) {
//
endDate = new Date();
} else {
// 23:59:59
endDate = new Date(targetDate);
endDate.setHours(23, 59, 59, 999);
}
// dateRange
this.dateRange = [
parseTime(startDate ),
parseTime(endDate)
];
setTimeout(() => {
this.$nextTick(() => {
//
if (this.imei) {
this.getServerData();
}
})
}, 500)
}
}
};
</script>
<style scoped>
.data-view {
background: #ffffff;
}
.select-box {
margin-top: 10rpx;
}
.charts-box {
width: 100%;
height: 500px;
}
/deep/ .uni-select, /deep/ .uni-date-editor--x {
background: #fff !important;
height: 68rpx;
}
.tag-row {
text-align: center;
padding-bottom: 20rpx;
}
</style>

View File

@ -1,79 +1,121 @@
<template>
<view style="height: 750rpx">
<view style="width:100%; height: 1000rpx; background:#FFFFFF;">
<view style="width:100%; height: 800rpx;">
<l-echart ref="chart"></l-echart>
</view>
</view>
</template>
<script>
import * as echarts from 'echarts';
import LEchart from "../../uni_modules/lime-echart/components/l-echart/l-echart.vue";
export default {
components: {LEchart},
components: { LEchart },
data() {
return {
option: {
title: {
text: 'Stacked Line' // todo
text: 'Stacked Line',
x: 'center',
textStyle: {
fontSize: 16,
color: '#333'
},
padding: [10, 0, 10, 0] //
},
tooltip: {
trigger: 'axis'
},
legend: {
data: ['邮件营销', '联盟广告', '视频广告', '直接访问', '搜索引擎']
data: ['价格', '数量'],
orient: 'horizontal',
bottom: '10%',
padding: [10, 20, 20, 20],
itemGap: 20,
textStyle: {
fontSize: 24,
color: '#333'
}
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
top: '15%',
bottom: '30%', //
containLabel: true
},
xAxis: {
type: 'category',
boundaryGap: false,
data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日']
data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日'],
axisLabel: {
fontSize: 12
}
},
yAxis: {
type: 'value'
yAxis: [
{
type: 'value',
name: '价格',
position: 'left',
alignTicks: true,
axisLine: {
lineStyle: {
color: '#c23531'
}
},
axisLabel: {
formatter: '{value} 元',
fontSize: 12
}
},
{
type: 'value',
name: '数量',
position: 'right',
alignTicks: true,
axisLine: {
lineStyle: {
color: '#2f4554'
}
},
axisLabel: {
formatter: '{value} 件',
fontSize: 12
}
}
],
dataZoom: [{}],
series: [
{
name: '邮件营销',
name: '价格',
type: 'line',
stack: '总量',
data: [120, 132, 101, 134, 90, 230, 210]
data: [820, 932, 901, 934, 1290, 1330, 1320],
yAxisIndex: 0,
smooth: true,
symbolSize: 6,
itemStyle: { color: '#c23531' },
lineStyle: { width: 2 }
},
{
name: '联盟广告',
name: '数量',
type: 'line',
stack: '总量',
data: [220, 182, 191, 234, 290, 330, 310]
},
{
name: '视频广告',
type: 'line',
stack: '总量',
data: [150, 232, 201, 154, 190, 330, 410]
},
{
name: '直接访问',
type: 'line',
stack: '总量',
data: [320, 332, 301, 334, 390, 330, 320]
},
{
name: '搜索引擎',
type: 'line',
stack: '总量',
data: [820, 932, 901, 934, 1290, 1330, 1320]
}
]
data: [120, 132, 101, 134, 90, 230, 210],
yAxisIndex: 1,
smooth: true,
symbolSize: 6,
itemStyle: { color: '#2f4554' },
lineStyle: { width: 2 }
}
],
color: ['#c23531', '#2f4554']
}
};
},
mounted() {
this.$refs.chart.init(echarts, chart=> {
this.$refs.chart.init(echarts, chart => {
chart.setOption(this.option);
});
}
}
};
</script>

View File

@ -280,6 +280,26 @@
:maskCloseable="false"
@click="showTips"
/>
<tn-fab
:btnList="content"
left="auto"
right="40"
bottom="100"
width="88"
height="88"
iconSize="64"
backgroundColor="#01BEFF"
fontColor="#FFFFFF"
icon="plusempty"
animationType="up"
@click="showData"
/>
<uni-popup ref="showHistoryData" type="dialog" mode="center">
<view class="modal-container popup">
<history-data ref="historyDataRef"></history-data>
</view>
</uni-popup>
</view>
</template>
@ -295,6 +315,7 @@ import UniSection from "../../../components/uni-section/uni-section.vue";
import UniFormsItem from "../../../uni_modules/uni-forms/components/uni-forms-item/uni-forms-item.vue";
import { checkTimeConflict } from "../../../utils/agri"
import {getAgriTerm, saveAgriTerm} from "../../../api/control/autoTerm";
import HistoryData from "../../data/data.vue";
export default {
options: {
@ -390,6 +411,7 @@ export default {
components: {
UniFormsItem,
UniSection,
HistoryData,
UniPopup //
},
mounted() {
@ -550,7 +572,20 @@ export default {
reservedLen: null,
ventTotalLen: null
},
showTip:false
showTip:false,
pattern: {
color: '#7A7E83',
backgroundColor: '#fff',
selectedColor: '#007AFF',
buttonColor: '#007AFF',
iconColor: '#fff'
},
content: [{
iconPath: '/static/image.png',
selectedIconPath: '/static/image-active.png',
text: '温度',
active: false
}]
};
},
@ -1104,6 +1139,12 @@ export default {
if (event.index===1) {
this.saveAgriTerm();
}
},
showData() {
this.$refs.showHistoryData.open();
this.$nextTick(() => {
this.$refs.historyDataRef.getAgriList()
})
}
}
@ -1206,12 +1247,15 @@ export default {
}
/* 新增:弹窗样式 */
.modal-container, .modal-container_ {
.modal-container_ {
width: 600rpx;
background: #fff;
border-radius: 16rpx;
padding: 30rpx 20rpx;
}
.popup {
width: 700rpx;
}
.modal-container_{
padding: 30rpx 40rpx;
.uni-forms-item:nth-child(1) {
@ -1222,40 +1266,7 @@ export default {
gap: 30rpx;
}
}
.modal-title {
font-size: 30rpx;
font-weight: 500;
text-align: center;
margin-bottom: 40rpx;
color: #333;
}
.modal-input-wrap {
display: flex;
align-items: center;
margin-bottom: 35rpx;
font-size: 26rpx;
margin-left: 20rpx;
}
.modal-label {
width: 180rpx;
color: #666;
}
.modal-current {
margin-left: 14rpx;
color: #333;
}
.modal-input {
height: 60rpx;
border: 1px solid #eee;
border-radius: 8rpx;
padding: 0 15rpx;
font-size: 26rpx;
width: 80rpx;
}
/* 核心样式:让子元素水平排列 */
.modal-slider {
display: flex;
@ -1466,5 +1477,6 @@ export default {
/deep/ .uni-swipe_button {
height: 140rpx;
border-radius: 10rpx;
box-shadow: 8rpx 5rpx 10rpx #D9D9D9 !important
}
</style>

View File

@ -594,10 +594,13 @@ page {
// #ifdef H5
height: 192rpx !important;
// #endif
margin-right: 10rpx;
border-radius: 12rpx;
box-shadow: 8rpx 5rpx 10rpx #999;
}
/deep/ .uni-swipe_button:nth-child(even) {
margin-right: 10rpx
}
.list-item,/deep/.tn-swipe-action-item {
height: 190rpx !important;
/* 移除border-bottom改为margin-top并且把列表项背景设为半透明白色 */

View File

@ -97,7 +97,12 @@
@tap.stop="fabClick"
>
<slot>
<view class="tn-fab__item__btn__icon" :class="[`tn-icon-${icon}`]" :style="{fontSize: $tn.string.getLengthUnitValue(iconSize || 64)}"></view>
<view class="tn-fab__item__btn__icon" :style="{fontSize: $tn.string.getLengthUnitValue(iconSize || 64)}">
<uni-icons :type="icon" :color="color" size="30" v-if="icon!='open'"/>
<view style="font-size: 30rpx" v-else>
{{ text }}
</view>
</view>
</slot>
</view>
</view>
@ -165,6 +170,14 @@
type: String,
default: 'open'
},
color: {
type: String,
default: '#fff'
},
text: {
type: String,
default: ''
},
//
radius: {
type: [String, Number],
@ -347,7 +360,6 @@
}, 10)
return
}
console.log(btnRectInfo);
this.systemInfo = {
width: systemInfo.windowWidth,
height: systemInfo.windowHeight