congming_huose-apk/common/mixins/deviceUserWs.js

194 lines
6.2 KiB
JavaScript
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.

/**
* 设备详情页:仅监听全局长连接推送并合入展示;不在此页 subscribe / unsubscribe。
* 列表侧DeviceTab在设备 Tab 内保持订阅,从列表进详情不会触发列表退订。
*/
import { connectIfLoggedIn } from '@/common/utils/appUserWs.js'
function normalizeMac(m) {
if (m === undefined || m === null) return ''
return String(m).replace(/:/g, '').trim().toUpperCase()
}
function pickDeviceRecord(vm) {
if (vm.xqobj && typeof vm.xqobj === 'object' && Object.keys(vm.xqobj).length) {
return vm.xqobj
}
if (vm.sbobj && typeof vm.sbobj === 'object' && Object.keys(vm.sbobj).length) {
return vm.sbobj
}
return null
}
function mergeIotDataPoint(ov, nv) {
if (nv === null) return null
if (typeof nv !== 'object' || Array.isArray(nv)) {
return nv
}
if (!ov || typeof ov !== 'object' || Array.isArray(ov)) {
return { ...nv }
}
const merged = { ...ov, ...nv }
// 长连接 patch 里若带 value: undefined 或缺省,不要冲掉 HTTP 里已有 value/desc
if (Object.prototype.hasOwnProperty.call(nv, 'value') && nv.value === undefined) {
if (Object.prototype.hasOwnProperty.call(ov, 'value') && ov.value !== undefined) {
merged.value = ov.value
}
}
if (!Object.prototype.hasOwnProperty.call(nv, 'desc') || nv.desc === undefined || nv.desc === '') {
if (Object.prototype.hasOwnProperty.call(ov, 'desc') && ov.desc !== undefined && ov.desc !== '') {
merged.desc = ov.desc
}
}
return merged
}
export default {
data() {
return {
deviceUserWsPageActive: false,
_deviceWsIotPartials: {},
}
},
onLoad() {
this._deviceWsIotPartials = {}
},
computed: {
_deviceMacForWs() {
const r = pickDeviceRecord(this)
const m = r && r.mac
return m ? String(m).trim() : ''
},
},
onShow() {
this.deviceUserWsPageActive = true
connectIfLoggedIn()
uni.$off('appWs:deviceData', this._onAppWsDeviceData)
uni.$off('appWs:deviceOnlineStatus', this._onAppWsDeviceOnlineStatus)
uni.$on('appWs:deviceData', this._onAppWsDeviceData)
uni.$on('appWs:deviceOnlineStatus', this._onAppWsDeviceOnlineStatus)
},
onHide() {
uni.$off('appWs:deviceData', this._onAppWsDeviceData)
uni.$off('appWs:deviceOnlineStatus', this._onAppWsDeviceOnlineStatus)
this._leaveDeviceUserWs()
},
onUnload() {
uni.$off('appWs:deviceData', this._onAppWsDeviceData)
uni.$off('appWs:deviceOnlineStatus', this._onAppWsDeviceOnlineStatus)
this._leaveDeviceUserWs()
},
onBeforeUnmount() {
uni.$off('appWs:deviceData', this._onAppWsDeviceData)
uni.$off('appWs:deviceOnlineStatus', this._onAppWsDeviceOnlineStatus)
this._leaveDeviceUserWs()
},
methods: {
_onAppWsDeviceData(msg) {
if (!this.deviceUserWsPageActive) return
if (!msg || msg.event !== 'device_data') return
const outer = msg.data
if (!outer || typeof outer !== 'object') return
const myMac = normalizeMac(this._deviceMacForWs)
if (!myMac) return
const inner = outer.data
if (!inner || typeof inner !== 'object') return
const payloadMac = normalizeMac(inner.mac != null ? inner.mac : outer.mac)
if (payloadMac && payloadMac !== myMac) return
const patch = inner.data !== undefined ? inner.data : inner
if (!patch || typeof patch !== 'object') return
this._applyDeviceDataPatch(patch)
},
_onAppWsDeviceOnlineStatus(msg) {
if (!this.deviceUserWsPageActive) return
if (!msg || msg.event !== 'device_online_status') return
const outer = msg.data
if (!outer || typeof outer !== 'object') return
const myMac = normalizeMac(this._deviceMacForWs)
if (!myMac) return
const inner = outer.data
if (!inner || typeof inner !== 'object') return
const payloadMac = normalizeMac(inner.mac != null ? inner.mac : outer.mac)
if (payloadMac && payloadMac !== myMac) return
const statusPayload =
inner.data !== undefined && typeof inner.data === 'object' ? inner.data : inner
this._applyDeviceOnlinePatch(statusPayload)
},
_applyDeviceDataPatch(patch) {
const rec = pickDeviceRecord(this)
if (!rec) return
if (!rec.iotData) {
this.$set(rec, 'iotData', {})
}
const keys = Object.keys(patch).filter((k) => k !== 'mac')
let any = false
for (const k of keys) {
const nv = patch[k]
const ov = rec.iotData[k]
const prevP = this._deviceWsIotPartials[k]
const pMerged =
typeof nv === 'object' && nv !== null && !Array.isArray(nv)
? mergeIotDataPoint(prevP || null, nv)
: mergeIotDataPoint(prevP || null, { value: nv })
this.$set(this._deviceWsIotPartials, k, pMerged)
const nextVal =
nv !== null && typeof nv === 'object' && !Array.isArray(nv)
? mergeIotDataPoint(ov, nv)
: nv
if (JSON.stringify(ov) === JSON.stringify(nextVal)) continue
this.$set(rec.iotData, k, nextVal)
any = true
}
if (any && typeof this._afterDeviceUserWsData === 'function') {
this._afterDeviceUserWsData()
}
},
_applyDeviceOnlinePatch(inner) {
const rec = pickDeviceRecord(this)
if (!rec) return
const os = inner.onlineStatus
const lot = inner.lastOnlineTime
let changed = false
if (os !== undefined && os !== null && os !== '') {
const n = Number(os)
if (!Number.isNaN(n) && rec.onlineStatus !== n) {
this.$set(rec, 'onlineStatus', n)
changed = true
}
}
if (lot !== undefined && lot !== null && rec.lastOnlineTime !== lot) {
this.$set(rec, 'lastOnlineTime', lot)
changed = true
}
if (!rec.iotOnlineData) {
this.$set(rec, 'iotOnlineData', {})
}
if (os !== undefined && os !== null && os !== '') {
const s = String(os)
if (rec.iotOnlineData.onlineStatus !== s) {
this.$set(rec.iotOnlineData, 'onlineStatus', s)
changed = true
}
}
if (changed && typeof this._afterDeviceUserWsData === 'function') {
this._afterDeviceUserWsData()
}
},
_leaveDeviceUserWs() {
this.deviceUserWsPageActive = false
},
reapplyDeviceWsIotToHttpIotData() {
const rec = pickDeviceRecord(this)
if (!rec || !this._deviceWsIotPartials) return
const pkeys = Object.keys(this._deviceWsIotPartials)
if (!pkeys.length) return
if (!rec.iotData) this.$set(rec, 'iotData', {})
for (const k of pkeys) {
const p = this._deviceWsIotPartials[k]
if (p === null || p === undefined) continue
const base = rec.iotData[k]
this.$set(rec.iotData, k, mergeIotDataPoint(base, p))
}
},
},
}