91 lines
2.5 KiB
Vue
91 lines
2.5 KiB
Vue
<template>
|
|
<div v-if="!devices?.length" class="w-full text-center">暂无绑定设备</div>
|
|
<div class="grid min-h-[76px] grid-cols-2 gap-3">
|
|
<div
|
|
v-for="device in devices"
|
|
:key="device.id"
|
|
@click="delDevice(device)"
|
|
class="relative h-[76px] rounded-[25px] border-2 p-4 text-[10px]"
|
|
>
|
|
<div class="flex h-full items-center justify-center gap-3">
|
|
<component
|
|
:is="getDeviceTypeInfo(device.user_agent)?.iconComponent"
|
|
class="h-6 w-6 text-white"
|
|
/>
|
|
<div class="flex flex-col overflow-hidden">
|
|
<span class="text-white">设备: {{ getDeviceTypeInfo(device.user_agent)?.type }}</span>
|
|
<span class="font-mono text-[11px] tracking-tighter uppercase"
|
|
>SN: {{ device?.identifier?.slice(0, 4) }}{{ device.id }}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
<X :size="16" class="absolute top-[5px] right-[10px] text-[12px]" />
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { Laptop, Smartphone, Tablet, Monitor, Cpu, HelpCircle, X } from 'lucide-vue-next'
|
|
import request from '@/utils/request'
|
|
import { toast } from 'vue-sonner'
|
|
|
|
interface Device {
|
|
id: string
|
|
name: string
|
|
user_agent: string
|
|
identifier: string
|
|
type: 'mobile' | 'desktop'
|
|
deviceId: string
|
|
}
|
|
|
|
defineProps<{
|
|
devices: Device[]
|
|
}>()
|
|
|
|
const emit = defineEmits(['refresh'])
|
|
|
|
function delDevice(device: Device) {
|
|
if (confirm('请确认是否移除此设备?')) {
|
|
request.put('/api/v1/public/user/unbind_device', { id: device.id }).then(() => {
|
|
toast.success('设备已移除')
|
|
emit('refresh')
|
|
})
|
|
}
|
|
}
|
|
|
|
interface DeviceTypeInfo {
|
|
type: string
|
|
iconComponent: any
|
|
}
|
|
|
|
/**
|
|
* 获取设备类型和图标
|
|
* @param userAgent 浏览器代理字符串
|
|
*/
|
|
const getDeviceTypeInfo = (userAgent: string): DeviceTypeInfo => {
|
|
// 转换为小写以便进行不区分大小写的匹配
|
|
const ua = userAgent.toLowerCase()
|
|
|
|
if (ua.includes('ipad')) {
|
|
return { type: 'iPad', iconComponent: Tablet }
|
|
}
|
|
if (ua.includes('iphone') || ua.includes('ios')) {
|
|
return { type: 'iPhone', iconComponent: Smartphone }
|
|
}
|
|
if (ua.includes('android')) {
|
|
return { type: 'Android', iconComponent: Smartphone }
|
|
}
|
|
if (ua.includes('mac') || ua.includes('macos')) {
|
|
return { type: 'Mac', iconComponent: Laptop }
|
|
}
|
|
if (ua.includes('windows')) {
|
|
return { type: 'Windows', iconComponent: Monitor }
|
|
}
|
|
if (ua.includes('linux')) {
|
|
return { type: 'Linux', iconComponent: Cpu }
|
|
}
|
|
|
|
return { type: 'Unknown', iconComponent: HelpCircle }
|
|
}
|
|
</script>
|