230 lines
5.6 KiB
TypeScript
230 lines
5.6 KiB
TypeScript
|
|
import Logger from '../utils/Logger'
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 设备信息接口
|
|||
|
|
*/
|
|||
|
|
export interface DeviceInfo {
|
|||
|
|
id: string
|
|||
|
|
socketId: string
|
|||
|
|
name: string
|
|||
|
|
model: string
|
|||
|
|
osVersion: string
|
|||
|
|
appVersion: string
|
|||
|
|
appPackage?: string
|
|||
|
|
appName?: string
|
|||
|
|
screenWidth: number
|
|||
|
|
screenHeight: number
|
|||
|
|
capabilities: string[]
|
|||
|
|
connectedAt: Date
|
|||
|
|
lastSeen: Date
|
|||
|
|
status: 'online' | 'offline' | 'busy'
|
|||
|
|
inputBlocked?: boolean
|
|||
|
|
isLocked?: boolean // 设备锁屏状态
|
|||
|
|
remark?: string // 🆕 设备备注
|
|||
|
|
publicIP?: string
|
|||
|
|
// 🆕 新增系统版本信息字段
|
|||
|
|
systemVersionName?: string // 如"Android 11"、"Android 12"
|
|||
|
|
romType?: string // 如"MIUI"、"ColorOS"、"原生Android"
|
|||
|
|
romVersion?: string // 如"MIUI 12.5"、"ColorOS 11.1"
|
|||
|
|
osBuildVersion?: string // 如"1.0.19.0.UMCCNXM"等完整构建版本号
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 设备状态接口
|
|||
|
|
*/
|
|||
|
|
export interface DeviceStatus {
|
|||
|
|
cpu: number
|
|||
|
|
memory: number
|
|||
|
|
battery: number
|
|||
|
|
networkSpeed: number
|
|||
|
|
orientation: 'portrait' | 'landscape'
|
|||
|
|
screenOn: boolean
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 设备管理器
|
|||
|
|
*/
|
|||
|
|
class DeviceManager {
|
|||
|
|
private devices: Map<string, DeviceInfo> = new Map()
|
|||
|
|
private deviceStatuses: Map<string, DeviceStatus> = new Map()
|
|||
|
|
private socketToDevice: Map<string, string> = new Map()
|
|||
|
|
private logger: Logger
|
|||
|
|
|
|||
|
|
constructor() {
|
|||
|
|
this.logger = new Logger('DeviceManager')
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* ✅ 清理所有设备记录(服务器重启时调用)
|
|||
|
|
*/
|
|||
|
|
clearAllDevices(): void {
|
|||
|
|
const deviceCount = this.devices.size
|
|||
|
|
this.devices.clear()
|
|||
|
|
this.deviceStatuses.clear()
|
|||
|
|
this.socketToDevice.clear()
|
|||
|
|
this.logger.info(`🧹 已清理所有设备记录: ${deviceCount} 个设备`)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 添加设备
|
|||
|
|
*/
|
|||
|
|
addDevice(deviceInfo: DeviceInfo): void {
|
|||
|
|
this.devices.set(deviceInfo.id, deviceInfo)
|
|||
|
|
this.socketToDevice.set(deviceInfo.socketId, deviceInfo.id)
|
|||
|
|
this.logger.info(`设备已添加: ${deviceInfo.name} (${deviceInfo.id})`)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 移除设备
|
|||
|
|
*/
|
|||
|
|
removeDevice(deviceId: string): boolean {
|
|||
|
|
const device = this.devices.get(deviceId)
|
|||
|
|
if (device) {
|
|||
|
|
this.devices.delete(deviceId)
|
|||
|
|
this.deviceStatuses.delete(deviceId)
|
|||
|
|
this.socketToDevice.delete(device.socketId)
|
|||
|
|
this.logger.info(`设备已移除: ${device.name} (${deviceId})`)
|
|||
|
|
return true
|
|||
|
|
}
|
|||
|
|
return false
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 通过Socket ID移除设备
|
|||
|
|
*/
|
|||
|
|
removeDeviceBySocketId(socketId: string): boolean {
|
|||
|
|
const deviceId = this.socketToDevice.get(socketId)
|
|||
|
|
if (deviceId) {
|
|||
|
|
return this.removeDevice(deviceId)
|
|||
|
|
}
|
|||
|
|
return false
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 获取设备信息
|
|||
|
|
*/
|
|||
|
|
getDevice(deviceId: string): DeviceInfo | undefined {
|
|||
|
|
return this.devices.get(deviceId)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 通过Socket ID获取设备
|
|||
|
|
*/
|
|||
|
|
getDeviceBySocketId(socketId: string): DeviceInfo | undefined {
|
|||
|
|
const deviceId = this.socketToDevice.get(socketId)
|
|||
|
|
return deviceId ? this.devices.get(deviceId) : undefined
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 获取所有设备
|
|||
|
|
*/
|
|||
|
|
getAllDevices(): DeviceInfo[] {
|
|||
|
|
return Array.from(this.devices.values())
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 获取在线设备
|
|||
|
|
*/
|
|||
|
|
getOnlineDevices(): DeviceInfo[] {
|
|||
|
|
return Array.from(this.devices.values()).filter(device => device.status === 'online')
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 获取设备数量
|
|||
|
|
*/
|
|||
|
|
getDeviceCount(): number {
|
|||
|
|
return this.devices.size
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 更新设备状态
|
|||
|
|
*/
|
|||
|
|
updateDeviceStatus(socketId: string, status: DeviceStatus): void {
|
|||
|
|
const deviceId = this.socketToDevice.get(socketId)
|
|||
|
|
if (deviceId) {
|
|||
|
|
const device = this.devices.get(deviceId)
|
|||
|
|
if (device) {
|
|||
|
|
device.lastSeen = new Date()
|
|||
|
|
this.deviceStatuses.set(deviceId, status)
|
|||
|
|
this.logger.debug(`设备状态已更新: ${deviceId}`, status)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 获取设备状态
|
|||
|
|
*/
|
|||
|
|
getDeviceStatus(deviceId: string): DeviceStatus | undefined {
|
|||
|
|
return this.deviceStatuses.get(deviceId)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 更新设备连接状态
|
|||
|
|
*/
|
|||
|
|
updateDeviceConnectionStatus(deviceId: string, status: DeviceInfo['status']): void {
|
|||
|
|
const device = this.devices.get(deviceId)
|
|||
|
|
if (device) {
|
|||
|
|
device.status = status
|
|||
|
|
device.lastSeen = new Date()
|
|||
|
|
this.logger.info(`设备连接状态已更新: ${deviceId} -> ${status}`)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 检查设备是否在线
|
|||
|
|
*/
|
|||
|
|
isDeviceOnline(deviceId: string): boolean {
|
|||
|
|
const device = this.devices.get(deviceId)
|
|||
|
|
return device ? device.status === 'online' : false
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 获取设备的Socket ID
|
|||
|
|
*/
|
|||
|
|
getDeviceSocketId(deviceId: string): string | undefined {
|
|||
|
|
const device = this.devices.get(deviceId)
|
|||
|
|
return device?.socketId
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 清理离线设备 (超过指定时间未活跃)
|
|||
|
|
*/
|
|||
|
|
cleanupOfflineDevices(timeoutMs: number = 300000): void {
|
|||
|
|
const now = Date.now()
|
|||
|
|
const devicesToRemove: string[] = []
|
|||
|
|
|
|||
|
|
for (const [deviceId, device] of this.devices.entries()) {
|
|||
|
|
if (now - device.lastSeen.getTime() > timeoutMs) {
|
|||
|
|
devicesToRemove.push(deviceId)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
devicesToRemove.forEach(deviceId => {
|
|||
|
|
this.removeDevice(deviceId)
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
if (devicesToRemove.length > 0) {
|
|||
|
|
this.logger.info(`已清理 ${devicesToRemove.length} 个离线设备`)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 获取设备统计信息
|
|||
|
|
*/
|
|||
|
|
getDeviceStats(): {
|
|||
|
|
total: number
|
|||
|
|
online: number
|
|||
|
|
offline: number
|
|||
|
|
busy: number
|
|||
|
|
} {
|
|||
|
|
const devices = Array.from(this.devices.values())
|
|||
|
|
return {
|
|||
|
|
total: devices.length,
|
|||
|
|
online: devices.filter(d => d.status === 'online').length,
|
|||
|
|
offline: devices.filter(d => d.status === 'offline').length,
|
|||
|
|
busy: devices.filter(d => d.status === 'busy').length,
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
export default DeviceManager
|