<template>
|
<view class="container">
|
|
<cu-custom bgColor="bg-gradual-blue" :isBack="true">
|
<block slot="content">1#智能干燥机</block>
|
</cu-custom>
|
<view class="uni-padding-wrap">
|
<view class="page-section swiper">
|
<view class="page-section-spacing">
|
<swiper class="swiper" style="height: 450rpx;" circular="true" indicator-dots="true" autoplay="true"
|
interval="3500" duration="600">
|
<swiper-item class="swiper-list" v-for="(item, index) in bannerList" :key="index">
|
<view class="swiper-item uni-bg-red">
|
<image class="swiper-img" :src="item.imageUrl" mode="aspectFit"></image>
|
</view>
|
</swiper-item>
|
</swiper>
|
</view>
|
</view>
|
</view>
|
|
<!-- 可通过设置bar-animate-mode="worm"开启毛毛虫模式-->
|
<z-tabs ref="tabs" :current="swiperCurrent" :list="swiperList" @change="tabsChange"></z-tabs>
|
<swiper class="custom-swiper" :current="swiperCurrent" @transition="swiperTransition"
|
@animationfinish="swiperAnimationfinish">
|
<swiper-item :key="0">
|
<view class="swiper-item-view">
|
<uni-section title="设备信息" type="line">
|
<text class="text-bold text-black"></text>
|
<view class="h-table">
|
<view class="h-tr h-tr-2 h-thead">
|
<view class="h-td">设备状态</view>
|
<view class="h-td">运行状态</view>
|
<view class="h-td">开机时间</view>
|
<view class="h-td">报警信息</view>
|
|
</view>
|
<view class="h-tr h-tr-2">
|
<view class="h-td">
|
<u-tag v-if="connected" size="mini" text="在线" type="success" plain
|
plainFill></u-tag>
|
<u-tag v-else size="mini" text="离线" type="error" plain plainFill></u-tag>
|
</view>
|
<view class="h-td">
|
<template v-if="runStatu">
|
<u-tag size="mini" text="正在干燥" type="success" plain plainFill></u-tag>
|
</template>
|
<template v-else>
|
<u-tag size="mini" text="待机" type="error" plain plainFill></u-tag>
|
</template>
|
</view>
|
<view class="h-td">{{$lget(model,'windTemp')}}</view>
|
<view class="h-td">{{$lget(model,'windTemp')}}</view>
|
</view>
|
</view>
|
<view class="h-table">
|
<view class="h-tr h-tr-2 h-thead">
|
<view class="h-td">热风</view>
|
<view class="h-td">温度</view>
|
<view class="h-td">电能</view>
|
<view class="h-td">蒸汽</view>
|
|
</view>
|
<view class="h-tr h-tr-2">
|
<view class="h-td">开</view>
|
<view class="h-td">70℃</view>
|
<view class="h-td">2.1kW·h</view>
|
<view class="h-td">10m³</view>
|
</view>
|
</view>
|
</uni-section>
|
|
<uni-section title="药材信息" type="line" class="margin-top-sm">
|
<text class="text-bold text-black"></text>
|
<view class="h-table">
|
<view class="h-tr h-tr-2 h-thead">
|
<view class="h-td">物料</view>
|
<view class="h-td">投料量</view>
|
<view class="h-td">初始重量</view>
|
<view class="h-td">过程重量</view>
|
|
</view>
|
<view class="h-tr h-tr-2">
|
<view class="h-td">{{$lget(model,'herbName')}}</view>
|
<view class="h-td">{{$lget(model,'envTemp') == "" ? "--" : $lget(model,'envTemp')}}m³
|
</view>
|
<view class="h-td">{{$lget(model,'envHum') == "" ? "--" :$lget(model,'envHum') }}kg
|
</view>
|
<view class="h-td">{{$lget(model,'windTemp')}}kg</view>
|
</view>
|
</view>
|
<view class="h-table">
|
<view class="h-tr h-tr-2 h-thead">
|
<view class="h-td"> </view>
|
<view class="h-td">初始含水率</view>
|
<view class="h-td">当前含水率</view>
|
<view class="h-td">目标含水率</view>
|
|
</view>
|
<view class="h-tr h-tr-2">
|
<view class="h-td"> </view>
|
<view class="h-td">{{$lget(model,'envTemp') == "" ? "--" : $lget(model,'envTemp')}}%
|
</view>
|
<view class="h-td">{{$lget(model,'envHum') == "" ? "--" :$lget(model,'envHum') }}%
|
</view>
|
<view class="h-td">{{$lget(model,'windTemp')}}%</view>
|
</view>
|
</view>
|
</uni-section>
|
|
|
|
<uni-section title="进度信息" type="line" class="margin-top-sm">
|
<text class="text-bold text-black"></text>
|
<view class="h-table">
|
<view class="h-tr h-tr-2 h-thead">
|
<view class="h-td">开始时间</view>
|
<view class="h-td">加热时间</view>
|
<view class="h-td">运行时间</view>
|
</view>
|
<view class="h-tr h-tr-2">
|
<view class="h-td">10:10:10</view>
|
<view class="h-td">10min</view>
|
<view class="h-td">120min</view>
|
</view>
|
</view>
|
<view class="h-table">
|
<view class="h-tr h-tr-2 h-thead">
|
<view class="h-td">当前阶段</view>
|
<view class="h-td">阶段时间</view>
|
<view class="h-td">预计时间</view>
|
</view>
|
<view class="h-tr h-tr-2">
|
<view class="h-td">3</view>
|
<view class="h-td">10min</view>
|
<view class="h-td">120min</view>
|
</view>
|
</view>
|
</uni-section>
|
</view>
|
</swiper-item>
|
<swiper-item :key="1">
|
<uni-section title="指令" type="line">
|
<view class="flex justify-center padding-lg bg-white">
|
<view class="margin-right-sm">
|
<u-button :disabled="connected" text="开机" type="success"
|
@click="$u.throttle(showModal(1), 500)"></u-button>
|
</view>
|
<view class="margin-left-sm">
|
<u-button :disabled="!connected" text="关机" type="error"
|
@click="$u.throttle(showModal(2), 500)"></u-button>
|
</view>
|
|
|
</view>
|
</uni-section>
|
|
|
<uni-section title="控制台" type="line" class="margin-top-sm ">
|
<view class="padding-left-sm padding-right-sm padding-bottom-sm">
|
<view class="text-sm text-gray" :class="{'margin-top-sm':index>0}" v-for="(log,index) in logList">{{log}}</view>
|
<!-- <view class="text-sm text-gray margin-top-sm">12:00:10: 发送<开机>指令</view> -->
|
</view>
|
|
</uni-section>
|
|
|
|
</swiper-item>
|
</swiper>
|
|
|
<u-modal :show="show" @confirm="confirm" :showCancelButton="true" @cancel="show=false" ref="uModal"
|
:asyncClose="true">
|
|
<slot>
|
<view style="width: 100%;height:100%;">
|
<view style="color:red">
|
远程控制操作可能存在安全风险,请谨慎操作
|
</view>
|
<u--input style="width: 100%;" placeholder="请输入二级安全密码" border="surround" password
|
clearable></u--input>
|
</view>
|
</slot>
|
</u-modal>
|
</view>
|
</template>
|
|
<script>
|
import get from 'lodash.get'
|
// 图表
|
import uCharts from "@/components/u-charts/u-charts.js";
|
var _self;
|
var canvaArea = null;
|
export default {
|
data() {
|
return {
|
//上个页面传递过来的数据
|
option: {},
|
//操作指令log
|
logList: [],
|
//当前设备连接状态
|
connected: false,
|
//开关机指令 1-开机 2-关机
|
cmd: -1,
|
show: false,
|
swiperList: ["监测", "控制"],
|
swiperCurrent: 0,
|
chartData: {},
|
opts: {
|
color: ["#1890FF", "#91CB74", "#FAC858", "#EE6666", "#73C0DE", "#3CA272", "#FC8452", "#9A60B4",
|
"#ea7ccc"
|
],
|
padding: [15, 10, 0, 15],
|
dataLabel: false,
|
dataPointShape: false,
|
enableScroll: false,
|
legend: {},
|
update: true,
|
xAxis: {
|
disableGrid: true,
|
labelCount: 6
|
},
|
yAxis: {
|
gridType: "dash",
|
dashLength: 2,
|
},
|
extra: {
|
line: {
|
type: "curve",
|
width: 2,
|
activeType: "hollow",
|
linearType: "custom"
|
}
|
}
|
},
|
notice: "2023-03-1812:00:001号机台低温报警",
|
model: {},
|
queryParam: {
|
machineid: "",
|
tenantid: null
|
},
|
bannerList: [{
|
imageUrl: '../../static/image/zcy_gzj1.png'
|
}]
|
|
|
}
|
},
|
onShow() {
|
console.info("onShow")
|
this.startTimer()
|
|
},
|
|
onLoad(option) {
|
const userinfo = uni.getStorageSync('userinfo');
|
this.option = option
|
this.option.tenantid = userinfo.loginTenantId
|
this.option.username = userinfo.username
|
|
|
//初始化查询参数
|
this.queryParam.machineid = option.code
|
this.queryParam.tenantid = userinfo.loginTenantId
|
|
},
|
onBackPress() {
|
this.stopTimer()
|
},
|
onHide() {
|
this.stopTimer()
|
|
},
|
onUnload() {
|
|
},
|
mounted() {
|
|
},
|
onReady() {
|
//this.getServerData()
|
// this.$mqttTool.message().then(res => {
|
// console.error("解析数据")
|
// if (res.topic == this.$constant.SERVICE_RES_EQU_STATU) {
|
// const msgstr = res.message.toString();
|
// const message = JSON.parse(msgstr);
|
// console.error(message)
|
// console.error(message.success)
|
// }
|
// })
|
let _this = this
|
this.$mqttTool.client.on('message', function(topic, message, buffer) {
|
|
const msg = JSON.parse(message);
|
if (topic == _this.$constant.SERVICE_RES_EQU_STATU.replace('equ', _this.deviceId)) {
|
if (msg.success) {
|
_this.connected = msg.connected
|
} else {
|
_this.connected = false
|
}
|
} else if (topic == _this.$constant.SERVICE_RES_EQU_CMD.replace('equ', _this.deviceId)) {
|
//发送指令收到响应
|
//添加log
|
let log = this.getCurrentTime() +'返回:' + + '指令' ;
|
this.logList.push(log)
|
|
setTimeout(() => {
|
// 3秒后自动关闭
|
uni.showToast({
|
title: msg.msg,
|
icon: 'none',
|
mask: true
|
});
|
_this.show = false;
|
}, 1000)
|
}
|
})
|
|
this.queryEquStatu()
|
|
},
|
methods: {
|
//MQTT
|
queryEquStatu() {
|
|
//1.查询设备实时状态
|
const message = {
|
clientId: this.option.clientId,
|
timestamp: new Date(),
|
req: this.deviceId
|
}
|
let opts = {
|
topic: this.$constant.MOBILE_QUERY_EQU_STATU,
|
message: JSON.stringify(message),
|
}
|
|
this.$mqttTool.publish(opts).then(res => {
|
console.error(res)
|
})
|
|
},
|
|
sendEquCmd() {
|
//添加log
|
let log = this.getCurrentTime() +'发送' + (this.cmd == 1 ? ":《开机》" : ":《关机》") + '指令' ;
|
this.logList.push(log)
|
|
//1.发送开关机指令 1-开机 2-关机
|
const message = {
|
clientId: this.option.clientId,
|
cmd: this.cmd,
|
timestamp: new Date(),
|
req: this.deviceId
|
}
|
let opts = {
|
topic: this.$constant.MOBILE_REQ_EQU_CMD,
|
message: JSON.stringify(message),
|
}
|
|
this.$mqttTool.publish(opts).then(res => {
|
console.error(res)
|
})
|
|
},
|
|
showModal(cmd) {
|
this.show = true;
|
this.cmd = cmd;
|
},
|
confirm() {
|
this.sendEquCmd()
|
// setTimeout(() => {
|
// // 3秒后自动关闭
|
// uni.showToast({
|
// title: '操作成功~',
|
// icon: 'none',
|
// mask: true
|
// });
|
// this.show = false;
|
// }, 3000)
|
|
|
|
|
},
|
startTimer() {
|
console.info("监控页面显示")
|
this.getRealData()
|
//不间断查询待操作干燥机的状态,实时更新
|
//this.queryEquStatu()
|
if (!this.$monitorTimer) {
|
this.$monitorTimer = setInterval(() => {
|
console.info("定时器工作")
|
console.info(this.$monitorTimer)
|
this.getRealData()
|
|
/**
|
* TODO 使用last_will代替轮询
|
*/
|
//不间断查询待操作干燥机的状态,实时更新
|
//this.queryEquStatu()
|
|
}, 1000 * 12)
|
}
|
|
},
|
stopTimer() {
|
clearInterval(this.$monitorTimer)
|
this.$monitorTimer = null
|
console.info("监控页面隐藏")
|
console.info("定时器停止")
|
console.info(this.$monitorTimer)
|
},
|
//tabs通知swiper切换
|
tabsChange(index) {
|
this.swiperCurrent = index;
|
},
|
//swiper滑动中
|
swiperTransition(e) {
|
this.$refs.tabs.setDx(e.detail.dx);
|
},
|
//swiper滑动结束
|
swiperAnimationfinish(e) {
|
this.swiperCurrent = e.detail.current;
|
console.log(e.detail.current)
|
this.$refs.tabs.unlockDx();
|
},
|
getCurrentTime() {
|
// 获取当前时间
|
let now = new Date();
|
// 格式化时间
|
let year = now.getFullYear();
|
let month = (now.getMonth() + 1).toString().padStart(2, '0');
|
let day = now.getDate().toString().padStart(2, '0');
|
let hours = now.getHours().toString().padStart(2, '0');
|
let minutes = now.getMinutes().toString().padStart(2, '0');
|
let seconds = now.getSeconds().toString().padStart(2, '0');
|
|
// 返回结果
|
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
|
},
|
getServerData() {
|
//模拟从服务器获取数据时的延时
|
setTimeout(() => {
|
let res = {
|
categories: ["2018", "2019", "2020", "2021", "2022", "2023"],
|
series: [{
|
name: "成交量A",
|
data: [35, 8, null, 37, 4, 20]
|
},
|
{
|
name: "成交量B",
|
connectNulls: true,
|
data: [70, 40, null, 100, 44, 68]
|
},
|
{
|
name: "成交量C",
|
data: [100, 80, null, 150, 112, 132]
|
}
|
]
|
};
|
this.chartData = JSON.parse(JSON.stringify(res));
|
}, 500);
|
},
|
|
/**
|
* 组建数据
|
*/
|
createData() {
|
//温度数据 10s一次
|
let bellowsTemp = this.$lget(this.model, 'bellowsTemp');
|
//称重数据 (重量、含水率)
|
let detailList = this.$lget(this.model, 'detailList');
|
if (!bellowsTemp) return;
|
let wmap = {} //取出所有重量数据
|
let mmap = {} //取出所有温度数据
|
let minW = null; //第一个重量数据
|
let minM = null; //第一个温度数据
|
let maxW = null; //最后一个重量数据
|
let maxM = null; //最后一个温度数据
|
//取出重量和含水率数据
|
if (detailList && detailList.length > 0) {
|
for (var i = 0; i < detailList.length; i++) {
|
let item = detailList[i]
|
//每个时间节点重量数据
|
wmap[item.totalTime] = item.weight
|
mmap[item.totalTime] = item.moisture
|
if (i == 0) {
|
minW = item.weight
|
minM = item.moisture
|
}
|
if (i == (detailList.length - 1)) {
|
maxW = item.weight
|
maxM = item.moisture
|
}
|
}
|
}
|
let tList = [] //温度
|
let wList = [] //重量
|
let mList = [] //含水率
|
let xList = [] //xAxis
|
//根据温度数据长度,生成x轴、重量和含水率数组等
|
for (let key in bellowsTemp) {
|
//console.log(key + '---' + bellowsTemp[key])
|
tList.push(bellowsTemp[key])
|
wList.push(wmap[key] || null)
|
mList.push(mmap[key] || null)
|
xList.push(key)
|
}
|
//填充测试数据 TODO 删除
|
// for(let i = 1 ; i <= 10 ; i++){
|
// tList.push(i*2)
|
// wList.push(i*100)
|
// mList.push(i*10)
|
// xList.push(i)
|
// }
|
|
//第一个数据为空 设置为第一次称重数据(没有称重数据则设置为0)
|
if (!wList[0]) {
|
wList[0] = minW || 0
|
}
|
|
|
if (!mList[0]) {
|
mList[0] = minM || 0
|
}
|
|
//最后一个数据为空 设置为最后一次称重数据
|
if (!wList[wList.length - 1]) {
|
wList[wList.length - 1] = maxW
|
}
|
|
if (!mList[mList.length - 1]) {
|
mList[mList.length - 1] = maxM
|
}
|
// let weightList = detailList.map(item => {
|
// return {type: item.weight, data: []}
|
// })
|
|
let series = [{
|
name: '重量',
|
data: wList,
|
connectNulls: true,
|
color: '#facc14'
|
}, {
|
name: '含水',
|
data: mList,
|
connectNulls: true,
|
color: '#2fc25b'
|
}, {
|
name: '温度',
|
data: tList,
|
color: '#1890ff'
|
}]
|
|
// console.error(wmap)
|
// console.error(mmap)
|
// console.error("============")
|
// console.error(wList)
|
// console.error(mList)
|
// console.error(tList)
|
let res = {
|
categories: xList,
|
series: series
|
}
|
this.chartData = JSON.parse(JSON.stringify(res));
|
},
|
/**
|
* 获取实时数据
|
*/
|
getRealData() {
|
this.$api.getRealTimeData(this.queryParam).then((res) => {
|
if (res.success) {
|
this.model = res.result
|
//创建图表数据
|
this.createData()
|
}
|
}).catch((err) => {
|
console.log('request fail', err);
|
})
|
},
|
|
goBack() {
|
uni.navigateBack({
|
delta: 1
|
})
|
}
|
},
|
computed: {
|
deviceId() {
|
return uni.getStorageSync(this.$constant.DEVICE_ID);
|
},
|
//运行状态
|
runStatu() {
|
let stop = this.$lget(this.model, 'stop');
|
return !stop
|
|
},
|
//报警状态 TODO 暂时不用
|
warmStatu() {
|
if (this.runStatu) {
|
if (this.model.envTemp < 50) {
|
return true
|
} else {
|
return false
|
}
|
} else {
|
return false
|
}
|
|
|
},
|
//配方名称
|
formulaName() {
|
let name = this.$lget(this.model, 'herbName')
|
let code = this.$lget(this.model, 'code')
|
let formula = ""
|
if (name) {
|
formula = name;
|
}
|
if (code) {
|
formula = formula + code
|
}
|
return formula
|
},
|
//干燥开始时间
|
startTime() {
|
let detailList = this.$lget(this.model, 'detailList')
|
if (detailList) {
|
if (detailList.length > 0) {
|
return detailList[0].tim
|
}
|
}
|
return ""
|
},
|
|
}
|
}
|
</script>
|
|
<style lang="scss" scoped>
|
@import "components/table/helang-table";
|
|
.swiper-box {
|
flex: 1;
|
}
|
|
.swiper-item {
|
height: 100%;
|
}
|
|
.custom-swiper {
|
min-height: 1100rpx;
|
}
|
|
.swiper-item-view {}
|
</style>
|