feat(device): 设备卡片图标替换为型号产品图

- 新增 ED713/ED719/EB15 产品图资源,设备列表卡片图标按型号映射展示
  (subDeviceType 优先、deviceModel 兜底,EB15 为 EP832 网关子设备)
- 未匹配型号回落原字符图标并打印型号字段日志便于核对后端值
This commit is contained in:
ozh 2026-09-21 15:58:44 +08:00
parent a4b2e13a8e
commit 9f3ea3d82b
5 changed files with 39 additions and 2 deletions

BIN
src/assets/device/eb15.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

BIN
src/assets/device/ed713.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

BIN
src/assets/device/ed719.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

View File

@ -165,12 +165,14 @@
.icon { .icon {
width: 108px; width: 108px;
height: 108px; height: 108px;
padding: 14px;
border-radius: $radius-circle; border-radius: $radius-circle;
background: $color-primary-grad; background: $color-primary-grad;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
margin-bottom: 20px; margin-bottom: 20px;
box-sizing: border-box;
} }
.iconOffline { background: $color-bg-disabled; } .iconOffline { background: $color-bg-disabled; }
@ -182,6 +184,13 @@
.iconOffline .iconText { color: $color-text-tertiary; } .iconOffline .iconText { color: $color-text-tertiary; }
.iconImg {
width: 80px;
height: 80px;
}
.iconOffline .iconImg { opacity: 0.5; }
.name { .name {
max-width: 100%; max-width: 100%;
font-size: 28px; font-size: 28px;

View File

@ -1,7 +1,7 @@
import { useState, useCallback } from 'react' import { useState, useCallback } from 'react'
import { useDidShow } from '@tarojs/taro' import { useDidShow } from '@tarojs/taro'
import Taro from '@tarojs/taro' import Taro from '@tarojs/taro'
import { View, Text } from '@tarojs/components' import { View, Text, Image } from '@tarojs/components'
import { Navbar } from '@/components/navbar' import { Navbar } from '@/components/navbar'
import { Loading } from '@/components/loading' import { Loading } from '@/components/loading'
import { StateView } from '@/components/state-view' import { StateView } from '@/components/state-view'
@ -12,10 +12,31 @@ import { getHomeList, type HomeInfo } from '@/api/home'
import { resolveCurrentHome, setCurrentHomeId } from '@/store/currentHome' import { resolveCurrentHome, setCurrentHomeId } from '@/store/currentHome'
import { ROUTES } from '@/constants/routes' import { ROUTES } from '@/constants/routes'
import { navigateTo } from '@/utils/navigation' import { navigateTo } from '@/utils/navigation'
import ed713Icon from '@/assets/device/ed713.png'
import ed719Icon from '@/assets/device/ed719.png'
import eb15Icon from '@/assets/device/eb15.jpg'
import styles from './index.module.scss' import styles from './index.module.scss'
const FALLBACK_ICON = '⌂' const FALLBACK_ICON = '⌂'
// 设备型号 → 产品图:sub-device 优先(EB15 是 EP832 网关下的子设备,
// 在 deviceModel 中没有对应值,需要走 subDeviceType 分支)。后端有时把型号
// 放在 deviceModel、有时放 subDeviceType,所以两个字段都查一遍
const pickDeviceIcon = (device: HomeDevice): string | null => {
const model = device.subDeviceType ?? device.deviceModel
if (model === 'EB15') return eb15Icon
if (model === 'ED713') return ed713Icon
if (model === 'ED719') return ed719Icon
// 调试:未匹配时打印设备型号字段,方便核对后端实际值(确认后移除)
console.log('[ICON] no match', {
installId: device.installId,
deviceModel: device.deviceModel,
subDeviceType: device.subDeviceType,
name: device.name
})
return null
}
// 设备显示名:优先 name,未命名回落序列号 // 设备显示名:优先 name,未命名回落序列号
const deviceLabel = (device: HomeDevice): string => device.name || device.deviceName const deviceLabel = (device: HomeDevice): string => device.name || device.deviceName
@ -207,7 +228,14 @@ export default function DeviceList() {
<View key={device.installId} className={styles.card}> <View key={device.installId} className={styles.card}>
<View className={styles.cardTop} onClick={() => goDetail(device)}> <View className={styles.cardTop} onClick={() => goDetail(device)}>
<View className={`${styles.icon} ${!device.onlineStatus ? styles.iconOffline : ''}`}> <View className={`${styles.icon} ${!device.onlineStatus ? styles.iconOffline : ''}`}>
<Text className={styles.iconText}>{FALLBACK_ICON}</Text> {(() => {
const src = pickDeviceIcon(device)
return src ? (
<Image className={styles.iconImg} src={src} mode="aspectFit" />
) : (
<Text className={styles.iconText}>{FALLBACK_ICON}</Text>
)
})()}
</View> </View>
<Text className={styles.name}>{deviceLabel(device)}</Text> <Text className={styles.name}>{deviceLabel(device)}</Text>
<View className={styles.statusRow}> <View className={styles.statusRow}>