feat: 设备名称前添加智能匹配的SVG图标

This commit is contained in:
2026-05-21 15:09:55 +08:00
parent 50a49c1bcd
commit cf2c5b5a3d
3 changed files with 79 additions and 2 deletions

View File

@@ -1,3 +1,4 @@
{% load device_tags %}
<!DOCTYPE html>
<html lang="zh-CN">
<head>
@@ -102,10 +103,45 @@
{% for device in devices %}
<tr class="device-row transition-colors">
<td class="px-4 py-3">
<div class="font-medium">
<div class="font-medium flex items-center space-x-2">
<span class="flex-shrink-0 device-icon-{{ device.device_name|device_icon }}">
{% with icon_type=device.device_name|device_icon %}
{% if icon_type == 'nvr' %}
<svg class="w-5 h-5 text-blue-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M4 7v10c0 1.1.9 2 2 2h12a2 2 0 002-2V7a2 2 0 00-2-2H6a2 2 0 00-2 2z"/><path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M7 10h2v2H7zM11 10h2v2h-2zM7 14h2v2H7z"/><circle cx="17" cy="15" r="2" stroke-width="1.5"/></svg>
{% elif icon_type == 'codec' %}
<svg class="w-5 h-5 text-indigo-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M15 10l4.553-2.276A1 1 0 0121 8.618v6.764a1 1 0 01-1.447.894L15 14M5 18h8a2 2 0 002-2V8a2 2 0 00-2-2H5a2 2 0 00-2 2v8a2 2 0 002 2z"/></svg>
{% elif icon_type == 'matrix' %}
<svg class="w-5 h-5 text-purple-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M4 5a1 1 0 011-1h4a1 1 0 011 1v4a1 1 0 01-1 1H5a1 1 0 01-1-1V5zM14 5a1 1 0 011-1h4a1 1 0 011 1v4a1 1 0 01-1 1h-4a1 1 0 01-1-1V5zM4 15a1 1 0 011-1h4a1 1 0 011 1v4a1 1 0 01-1 1H5a1 1 0 01-1-1v-4zM14 15a1 1 0 011-1h4a1 1 0 011 1v4a1 1 0 01-1 1h-4a1 1 0 01-1-1v-4z"/></svg>
{% elif icon_type == 'amplifier' %}
<svg class="w-5 h-5 text-orange-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M15.536 8.464a5 5 0 010 7.072M18.364 5.636a9 9 0 010 12.728M8 12h4m-2-2v4"/><rect x="3" y="6" width="6" height="12" rx="1" stroke-width="1.5"/></svg>
{% elif icon_type == 'mixer' %}
<svg class="w-5 h-5 text-teal-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M12 6V4m0 2a2 2 0 100 4m0-4a2 2 0 110 4m-6 8v-2m0 2a2 2 0 100 4m0-4a2 2 0 110 4m6-4v-2m0 2a2 2 0 100 4m0-4a2 2 0 110 4"/><rect x="3" y="3" width="18" height="18" rx="2" stroke-width="1.5"/></svg>
{% elif icon_type == 'microphone' %}
<svg class="w-5 h-5 text-red-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M19 11a7 7 0 01-7 7m0 0a7 7 0 01-7-7m7 7v4m-4 0h8M12 1a3 3 0 00-3 3v6a3 3 0 006 0V4a3 3 0 00-3-3z"/></svg>
{% elif icon_type == 'camera' %}
<svg class="w-5 h-5 text-cyan-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M15 10l4.553-2.276A1 1 0 0121 8.618v6.764a1 1 0 01-1.447.894L15 14M3 8h8a2 2 0 012 2v4a2 2 0 01-2 2H3a2 2 0 01-2-2v-4a2 2 0 012-2z"/><circle cx="7" cy="12" r="2" stroke-width="1.5"/></svg>
{% elif icon_type == 'screen' %}
<svg class="w-5 h-5 text-sky-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M9.75 17L9 20l-1 1h8l-1-1-.75-3M3 13h18M5 17h14a2 2 0 002-2V5a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"/></svg>
{% elif icon_type == 'processor' %}
<svg class="w-5 h-5 text-amber-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"><rect x="6" y="6" width="12" height="12" rx="1" stroke-width="1.5"/><path stroke-linecap="round" stroke-width="1.5" d="M9 1v3M15 1v3M9 20v3M15 20v3M1 9h3M1 15h3M20 9h3M20 15h3"/></svg>
{% elif icon_type == 'controller' %}
<svg class="w-5 h-5 text-violet-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"><rect x="4" y="4" width="16" height="16" rx="3" stroke-width="1.5"/><circle cx="9" cy="9" r="1.5" fill="currentColor"/><circle cx="15" cy="9" r="1.5" fill="currentColor"/><circle cx="9" cy="15" r="1.5" fill="currentColor"/><circle cx="15" cy="15" r="1.5" fill="currentColor"/></svg>
{% elif icon_type == 'cast' %}
<svg class="w-5 h-5 text-pink-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M8.288 15.038a5.25 5.25 0 017.424 0M5.106 11.856c3.807-3.808 9.98-3.808 13.788 0M1.924 8.674c5.565-5.565 14.587-5.565 20.152 0M12.53 18.22l-.53.53-.53-.53a.75.75 0 011.06 0z"/></svg>
{% elif icon_type == 'power' %}
<svg class="w-5 h-5 text-yellow-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M13 10V3L4 14h7v7l9-11h-7z"/></svg>
{% elif icon_type == 'player' %}
<svg class="w-5 h-5 text-green-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M9 19V6l12-3v13M9 19c0 1.105-1.343 2-3 2s-3-.895-3-2 1.343-2 3-2 3 .895 3 2zm12-3c0 1.105-1.343 2-3 2s-3-.895-3-2 1.343-2 3-2 3 .895 3 2z"/></svg>
{% elif icon_type == 'switch' %}
<svg class="w-5 h-5 text-gray-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"><rect x="2" y="8" width="20" height="8" rx="2" stroke-width="1.5"/><circle cx="7" cy="12" r="1.5" fill="currentColor"/><circle cx="12" cy="12" r="1.5" fill="currentColor"/><circle cx="17" cy="12" r="1.5" fill="currentColor"/></svg>
{% else %}
<svg class="w-5 h-5 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24"><rect x="4" y="4" width="16" height="16" rx="2" stroke-width="1.5"/><circle cx="9" cy="10" r="1.5" fill="currentColor"/><circle cx="15" cy="10" r="1.5" fill="currentColor"/><path stroke-linecap="round" stroke-width="1.5" d="M9 15h6"/></svg>
{% endif %}
{% endwith %}
</span>
<a href="/device/{{ device.id }}/" class="text-blue-600 hover:text-blue-800">{{ device.device_name }}</a>
</div>
<div class="text-xs text-gray-400">{{ device.brand|default:"" }}</div>
<div class="text-xs text-gray-400 ml-7">{{ device.brand|default:"" }}</div>
</td>
<td class="px-4 py-3 text-gray-600">{{ device.model|default:"-" }}</td>
<td class="px-4 py-3">

View File

@@ -0,0 +1,41 @@
from django import template
register = template.Library()
@register.filter
def device_icon(name):
if not name:
return 'default'
name = name.lower()
if any(k in name for k in ['nvr', '硬盘刻录', '刻录机', '录像']):
return 'nvr'
if any(k in name for k in ['编码器', '解码器', '终端', '视频会议']):
return 'codec'
if any(k in name for k in ['矩阵']):
return 'matrix'
if any(k in name for k in ['功放']):
return 'amplifier'
if any(k in name for k in ['调音台']):
return 'mixer'
if any(k in name for k in ['麦克', '话筒']):
return 'microphone'
if any(k in name for k in ['摄像头', '相机', '摄像机']):
return 'camera'
if any(k in name for k in ['屏幕', '显示器', '大屏']):
return 'screen'
if any(k in name for k in ['处理器', '音频处理']):
return 'processor'
if any(k in name for k in ['中控']):
return 'controller'
if any(k in name for k in ['投屏']):
return 'cast'
if any(k in name for k in ['放大器']):
return 'amplifier'
if any(k in name for k in ['电源', '时序']):
return 'power'
if any(k in name for k in ['播放器', '音乐']):
return 'player'
if any(k in name for k in ['交换机']):
return 'switch'
return 'default'