288 lines
6.5 KiB
Vue
288 lines
6.5 KiB
Vue
<template>
|
||
<view>
|
||
<u-popup :show="showAuncelSelector" closeable @close="close" @open="open" mode="right">
|
||
<view class="p10">天平选择</view>
|
||
<scroll-view scroll-y="true" class="content">
|
||
<u-grid border :col="3" @click="doSelect">
|
||
<u-grid-item v-for="(auncel, index) in auncelList" :index="index" :key="index">
|
||
<view class="auncel-item">
|
||
<view class="auncel-name">
|
||
{{ auncel.deviceCode }}
|
||
<view style="text-align: center">{{ auncel.controlRealName }}</view>
|
||
</view>
|
||
|
||
<view class="weight">
|
||
<view :class="getWeightClass(auncel)" :style="getWeightStyle(auncel)">
|
||
{{ getWeightText(auncel) }}
|
||
</view>
|
||
<view v-if="auncel.isConnected === 1" class="weight-unit">{{ auncel.weightUnit }}</view>
|
||
</view>
|
||
</view>
|
||
</u-grid-item>
|
||
</u-grid>
|
||
</scroll-view>
|
||
</u-popup>
|
||
</view>
|
||
</template>
|
||
|
||
<script setup>
|
||
import { ref, computed, onMounted, onUnmounted } from 'vue'
|
||
import nx from '@/nx' // 假设你的全局状态/工具挂载在 nx
|
||
|
||
// Props & Emits
|
||
const props = defineProps({
|
||
showAuncelSelector: {
|
||
type: Boolean,
|
||
default: false
|
||
},
|
||
previousAuncelId: {
|
||
type: String,
|
||
default: ''
|
||
}
|
||
})
|
||
|
||
const emit = defineEmits(['update:showAuncelSelector', 'doSelect'])
|
||
|
||
// 响应式数据
|
||
const auncelList = ref([])
|
||
|
||
// 计算属性:获取用户信息
|
||
const userInfo = computed(() => nx.$store('user').userInfo)
|
||
|
||
// 方法
|
||
const open = () => {
|
||
getPageData()
|
||
listenDeviceData()
|
||
}
|
||
|
||
const close = () => {
|
||
auncelList.value = []
|
||
closeDeviceListener()
|
||
emit('update:showAuncelSelector', false)
|
||
}
|
||
|
||
const getPageData = () => {
|
||
nx.$api.laboratory
|
||
.getDeviceLaboratoryListBy({
|
||
pageNo: 1,
|
||
pageSize: 999,
|
||
collectDeviceType: 'balance',
|
||
deviceStatus: '0',
|
||
isEnable: '1'
|
||
})
|
||
.then(res => {
|
||
auncelList.value = res.list
|
||
})
|
||
}
|
||
|
||
const doSelect = index => {
|
||
const currentAuncel = auncelList.value[index]
|
||
if (currentAuncel.isConnected !== 1) {
|
||
uni.showToast({ title: '天平设备尚未连接!', icon: 'none' })
|
||
return
|
||
}
|
||
|
||
if (currentAuncel.controlRealName && currentAuncel.controlRealName !== userInfo.value.nickname) {
|
||
uni.showToast({
|
||
title: `当前天平正被“${currentAuncel.controlRealName}”使用,请选择其他天平!`,
|
||
icon: 'none'
|
||
})
|
||
return
|
||
}
|
||
|
||
let delayFlag = false
|
||
if (props.previousAuncelId && props.previousAuncelId !== '' && props.previousAuncelId !== currentAuncel.id) {
|
||
releaseDeviceControl(props.previousAuncelId)
|
||
delayFlag = true
|
||
}
|
||
|
||
const controlDevice = {
|
||
msgId: currentAuncel.id,
|
||
cmd: 'controlDevice',
|
||
clientType: 'caaClient',
|
||
data: {
|
||
deviceId: currentAuncel.id,
|
||
deviceCode: currentAuncel.deviceCode,
|
||
deviceName: currentAuncel.productName,
|
||
isControl: true,
|
||
controlRealName: userInfo.value.nickname
|
||
}
|
||
}
|
||
|
||
const sendControl = () => {
|
||
const controlData = JSON.stringify(controlDevice)
|
||
nx.$measure.send(controlData)
|
||
emit('update:showAuncelSelector', false)
|
||
emit('doSelect', controlDevice)
|
||
}
|
||
|
||
if (delayFlag) {
|
||
setTimeout(sendControl, 300)
|
||
} else {
|
||
sendControl()
|
||
}
|
||
}
|
||
|
||
const releaseDeviceControl = deviceId => {
|
||
if (!deviceId) return
|
||
const controlDevice = {
|
||
msgId: deviceId,
|
||
cmd: 'controlDevice',
|
||
clientType: 'caaClient',
|
||
data: {
|
||
deviceId,
|
||
isControl: false,
|
||
controlRealName: userInfo.value.nickname
|
||
}
|
||
}
|
||
nx.$measure.send(JSON.stringify(controlDevice))
|
||
}
|
||
|
||
const listenDeviceData = () => {
|
||
uni.$on('deviceData', handleDeviceData)
|
||
uni.$on('deviceStatus', handleDeviceStatus)
|
||
uni.$on('connClose', handleConnClose)
|
||
}
|
||
|
||
const handleDeviceData = res => {
|
||
if (res.deviceType === 'balance') {
|
||
auncelList.value.forEach(item => {
|
||
if (item.id === res.deviceId) {
|
||
item.weightData = res.weightData
|
||
item.weightUnit = res.weightUnit
|
||
item.weightStable = res.weightStable
|
||
item.isConnected = 1
|
||
item.controlRealName = res.controlRealName
|
||
}
|
||
})
|
||
}
|
||
}
|
||
|
||
const handleDeviceStatus = res => {
|
||
if (res.deviceType === 'balance') {
|
||
auncelList.value.forEach(item => {
|
||
if (item.id === res.deviceId) {
|
||
item.isConnected = res.connected
|
||
if (res.connected == 0) {
|
||
item.weightData = '天平断开'
|
||
item.weightUnit = ''
|
||
item.weightStable = 0
|
||
}
|
||
}
|
||
})
|
||
}
|
||
}
|
||
|
||
const handleConnClose = () => {
|
||
auncelList.value.forEach(item => {
|
||
item.weightData = ''
|
||
item.weightUnit = ''
|
||
item.weightStable = 0
|
||
item.controlRealName = ''
|
||
item.isConnected = 0
|
||
})
|
||
}
|
||
|
||
const closeDeviceListener = () => {
|
||
uni.$off('deviceData', handleDeviceData)
|
||
uni.$off('deviceStatus', handleDeviceStatus)
|
||
uni.$off('connClose', handleConnClose)
|
||
}
|
||
|
||
// 生命周期
|
||
onMounted(() => {
|
||
// 如果组件在 mounted 时已打开,可考虑自动加载(但通常由父组件控制 show)
|
||
})
|
||
|
||
onUnmounted(() => {
|
||
closeDeviceListener()
|
||
})
|
||
function getWeightText(auncel) {
|
||
if (auncel.isConnected !== 1) {
|
||
return '天平断开'
|
||
}
|
||
return auncel.weightData || ''
|
||
}
|
||
|
||
function getWeightClass(auncel) {
|
||
if (auncel.weightStable === 0) return 'weight-data-yellow'
|
||
if (auncel.weightStable === 1) return 'weight-data'
|
||
if (auncel.weightStable === 2) return 'weight-data-warning'
|
||
return 'weight-data-yellow'
|
||
}
|
||
|
||
function getWeightStyle(auncel) {
|
||
if (auncel.isConnected !== 1) {
|
||
return {
|
||
textAlign: 'center',
|
||
fontSize: '28px'
|
||
}
|
||
}
|
||
return {
|
||
textAlign: 'right',
|
||
fontSize: '32px'
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style scoped lang="scss">
|
||
.content {
|
||
width: 80vw;
|
||
height: 90vh;
|
||
}
|
||
.auncel-item {
|
||
height: 180px;
|
||
width: 180px;
|
||
background-image: url(/static/images/auncel.png);
|
||
background-repeat: no-repeat;
|
||
background-size: 100%;
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
.auncel-name {
|
||
flex: 1;
|
||
text-align: center;
|
||
padding-top: 20px;
|
||
}
|
||
.weight {
|
||
flex: 1;
|
||
font-size: 28px;
|
||
padding-top: 10px;
|
||
padding: 10px 30px 0 30px;
|
||
position: relative;
|
||
}
|
||
.weight-data,
|
||
.weight-data-yellow,
|
||
.weight-data-warning {
|
||
font-family: zzjc-lcd;
|
||
}
|
||
|
||
.weight-data {
|
||
color: #4cd964;
|
||
}
|
||
|
||
.weight-data-yellow {
|
||
color: #ffff00;
|
||
}
|
||
|
||
.weight-data-warning {
|
||
color: #ff3333;
|
||
}
|
||
.weight-unit {
|
||
position: absolute;
|
||
right: 10px;
|
||
top: 10px;
|
||
color: #ffffff;
|
||
font-size: 20px;
|
||
}
|
||
@media (max-width: 700px) {
|
||
.auncel-item {
|
||
height: 150px;
|
||
width: 150px;
|
||
}
|
||
.auncel-name {
|
||
padding-top: 10px;
|
||
}
|
||
}
|
||
</style>
|