From 220e4fab27b7f419b3e89e2f2d28ae789aac09d7 Mon Sep 17 00:00:00 2001
From: wangzhibo <wangzhibo@shsening.com>
Date: 星期四, 08 十月 2026 16:29:55 +0800
Subject: [PATCH] 5种场景模式家长端ok
---
xiaozhi-esp32-server/main/manager-mobile/src/pages/index/index.vue | 223 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 221 insertions(+), 2 deletions(-)
diff --git a/xiaozhi-esp32-server/main/manager-mobile/src/pages/index/index.vue b/xiaozhi-esp32-server/main/manager-mobile/src/pages/index/index.vue
index 4d73a15..55c5e70 100644
--- a/xiaozhi-esp32-server/main/manager-mobile/src/pages/index/index.vue
+++ b/xiaozhi-esp32-server/main/manager-mobile/src/pages/index/index.vue
@@ -11,12 +11,13 @@
</route>
<script lang="ts" setup>
-import type { Agent } from '@/api/agent/types'
+import type { Agent, AgentDevice } from '@/api/agent/types'
+import { onShow } from '@dcloudio/uni-app'
import { computed, onMounted, ref } from 'vue'
-// 鍦ㄧ粍浠舵寕杞藉悗璁剧疆瀵艰埅鏍忔爣棰�
import { useMessage } from 'wot-design-uni/components/wd-message-box'
import useZPaging from 'z-paging/components/z-paging/js/hooks/useZPaging.js'
import { createAgent, deleteAgent, getAgentList } from '@/api/agent/agent'
+import { getBindDevices } from '@/api/device'
import { t } from '@/i18n'
import { toast } from '@/utils/toast'
@@ -68,6 +69,7 @@
console.log('z-paging鑾峰彇鏅鸿兘浣撳垪琛�')
const response = await getAgentList()
+ await attachDevices(response)
// 鏇存柊鏈湴鍒楄〃
agentList.value = response
@@ -144,6 +146,73 @@
finally {
deleteAgentLoading.value = false
}
+}
+
+async function attachDevices(agents: Agent[]) {
+ await Promise.all((agents || []).map(async (agent) => {
+ if (Array.isArray(agent.devices))
+ return
+ try {
+ const list = await getBindDevices(agent.id)
+ agent.devices = (list || []).map(device => ({
+ macAddress: device.macAddress,
+ alias: device.alias,
+ online: device.online,
+ }))
+ agent.onlineDeviceCount = (agent.devices || []).filter(item => item.online === true).length
+ agent.deviceCount = agent.devices?.length || 0
+ }
+ catch (error) {
+ console.error('load home device status failed', error)
+ agent.devices = []
+ }
+ }))
+}
+
+function agentPresence(agent: Agent): 'online' | 'offline' | 'none' | 'unknown' {
+ const devices = agent.devices
+ if (!Array.isArray(devices))
+ return 'unknown'
+ if (devices.length === 0)
+ return 'none'
+ if (devices.some(item => item.online === true))
+ return 'online'
+ if (devices.every(item => item.online === false))
+ return 'offline'
+ return 'unknown'
+}
+
+function agentPresenceTitle(agent: Agent) {
+ const state = agentPresence(agent)
+ if (state === 'online') {
+ const devices = agent.devices || []
+ const online = devices.filter(item => item.online === true).length
+ if (devices.length > 1)
+ return t('home.onlineCount', { online, total: devices.length })
+ return t('device.online')
+ }
+ if (state === 'offline')
+ return t('device.offline')
+ if (state === 'none')
+ return t('home.noBoundDevice')
+ return t('device.checkingOnline')
+}
+
+function devicePresence(device: AgentDevice): 'online' | 'offline' | 'unknown' {
+ if (device.online === true)
+ return 'online'
+ if (device.online === false)
+ return 'offline'
+ return 'unknown'
+}
+
+function devicePresenceText(device: AgentDevice) {
+ const state = devicePresence(device)
+ if (state === 'online')
+ return t('device.online')
+ if (state === 'offline')
+ return t('device.offline')
+ return t('device.checkingOnline')
}
// 杩涘叆缂栬緫椤甸潰
@@ -260,6 +329,28 @@
<text class="agent-name">
{{ agent.agentName }}
</text>
+ <view class="presence-chip" :class="agentPresence(agent)">
+ <view class="presence-chip-dot" :class="agentPresence(agent)" />
+ <text class="presence-chip-text" :class="agentPresence(agent)">
+ {{ agentPresenceTitle(agent) }}
+ </text>
+ </view>
+ </view>
+
+ <view v-if="agent.devices && agent.devices.length" class="device-presence-list">
+ <view
+ v-for="device in agent.devices"
+ :key="device.macAddress"
+ class="device-presence-row"
+ >
+ <view class="device-presence-dot" :class="devicePresence(device)" />
+ <text class="device-presence-name">
+ {{ device.macAddress }}
+ </text>
+ <text class="device-presence-state" :class="devicePresence(device)">
+ {{ devicePresenceText(device) }}
+ </text>
+ </view>
</view>
<view class="model-info">
@@ -557,15 +648,143 @@
display: flex;
align-items: center;
justify-content: space-between;
+ gap: 12rpx;
margin-bottom: 12rpx;
.agent-name {
+ flex: 1;
+ min-width: 0;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
font-size: 32rpx;
font-weight: 600;
color: #1a1a1a;
}
}
+ .presence-chip {
+ display: flex;
+ align-items: center;
+ gap: 8rpx;
+ flex-shrink: 0;
+ padding: 6rpx 14rpx;
+ border-radius: 24rpx;
+
+ &.online {
+ background: #e8f8ef;
+ }
+
+ &.offline {
+ background: #fff1f0;
+ }
+
+ &.none,
+ &.unknown {
+ background: #f5f7fb;
+ }
+ }
+
+ .presence-chip-dot {
+ width: 12rpx;
+ height: 12rpx;
+ flex-shrink: 0;
+ border-radius: 50%;
+
+ &.online {
+ background: #1aa34a;
+ }
+
+ &.offline {
+ background: #d4380d;
+ }
+
+ &.none,
+ &.unknown {
+ background: #c0c4cc;
+ }
+ }
+
+ .presence-chip-text {
+ font-size: 22rpx;
+ font-weight: 600;
+ line-height: 1.4;
+
+ &.online {
+ color: #146c36;
+ }
+
+ &.offline {
+ color: #d4380d;
+ }
+
+ &.none,
+ &.unknown {
+ color: #65686f;
+ }
+ }
+
+ .device-presence-list {
+ display: flex;
+ flex-direction: column;
+ gap: 8rpx;
+ margin-bottom: 16rpx;
+ }
+
+ .device-presence-row {
+ display: flex;
+ align-items: center;
+ gap: 10rpx;
+ padding: 8rpx 4rpx;
+ }
+
+ .device-presence-dot {
+ width: 12rpx;
+ height: 12rpx;
+ flex-shrink: 0;
+ border-radius: 50%;
+
+ &.online {
+ background: #1aa34a;
+ }
+
+ &.offline {
+ background: #d4380d;
+ }
+
+ &.unknown {
+ background: #c0c4cc;
+ }
+ }
+
+ .device-presence-name {
+ flex: 1;
+ min-width: 0;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ font-size: 24rpx;
+ color: #232338;
+ }
+
+ .device-presence-state {
+ flex-shrink: 0;
+ font-size: 22rpx;
+ font-weight: 600;
+
+ &.online {
+ color: #146c36;
+ }
+
+ &.offline {
+ color: #d4380d;
+ }
+
+ &.unknown {
+ color: #65686f;
+ }
+ }
+
.model-info {
margin-bottom: 16rpx;
--
Gitblit v1.9.1