Files
zgty-mas-m/components/sample/auncel-select-popup.vue
2025-10-10 10:45:25 +08:00

277 lines
6.3 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<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.code }}
<view style="text-align: center">{{ auncel.controlRealName }}</view>
</view>
<view class="weight">
<view
:class="
auncel.weightStable === 0
? 'weight-data-yellow'
: auncel.weightStable === 1
? 'weight-data'
: 'weight-data-warning'
"
>
{{ auncel.weightData }}
</view>
<view 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({
deviceType: 'auncel',
pageNo: 0,
pageSize: -1,
status: '1',
isEnable: '1'
})
.then(res => {
const dataList = res.records.map(item => ({
...item,
weightData: '',
weightUnit: '',
isConnected: 0,
weightStable: 0,
temperature: 0,
humidity: 0,
controlRealName: ''
}))
auncelList.value = dataList
})
}
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.code,
deviceName: currentAuncel.name,
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 !== 'auncel') return
auncelList.value.forEach(item => {
if (item.id === res.deviceId) {
item.weightData = res.weightData ?? ''
item.weightUnit = res.weightUnit ?? ''
item.weightStable = res.weightStable ?? 0
item.isConnected = 1
item.controlRealName = res.controlRealName ?? ''
}
})
}
const handleDeviceStatus = res => {
auncelList.value.forEach(item => {
if (item.id === res.deviceId) {
item.isConnected = res.connected ?? 0
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()
})
</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;
display: flex;
flex-direction: row;
font-size: 32px;
letter-spacing: 2px;
padding-top: 10px;
}
.weight-data {
flex: 1;
color: #4cd964;
text-align: right;
font-family: zzjc-lcd;
}
.weight-data-yellow {
flex: 1;
color: #ffff00;
text-align: center;
font-family: zzjc-lcd;
}
.weight-data-warning {
color: #ff3333;
text-align: right;
font-family: zzjc-lcd;
}
.weight-unit {
color: #ffffff;
font-size: 24px;
padding: 0 10px;
}
@media (max-width: 700px) {
.auncel-item {
height: 150px;
width: 150px;
}
.auncel-name {
padding-top: 10px;
}
}
</style>