From a5b23dc37f3c27d3f4f1127fb26d57c01c1b4cd8 Mon Sep 17 00:00:00 2001 From: zydi Date: Tue, 14 Jan 2025 10:02:31 +0000 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BA=86=E8=AE=BE=E5=A4=87?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- device.html | 38 ++++++++----------- lab.html | 88 +++++++++++++++++++++++++++++++------------ main.py | 106 ++++++++++++++++++++++++++++++++++++---------------- 3 files changed, 154 insertions(+), 78 deletions(-) diff --git a/device.html b/device.html index d2423f9..20ab6a8 100644 --- a/device.html +++ b/device.html @@ -1051,6 +1051,9 @@ if (response.ok) { let devices = await response.json(); + // 只显示 active 状态的设备 + devices = devices.filter(device => device.status === 'active'); + // 应用在线设备过滤 if (onlineDevicesOnly) { devices = devices.filter(device => device.status === 'online'); @@ -1162,42 +1165,33 @@ } } - // Modify remove device function - async function removeDevice(deviceId, experimentId = null) { - let message = experimentId - ? 'Are you sure you want to remove this device from the current experiment?' - : 'Are you sure you want to remove this device? This will remove the device from all experiments.'; - - if (!confirm(message)) { + // 修改移除设备的函数 + async function removeDevice(deviceId) { + if (!confirm('Are you sure you want to deactivate this device?')) { return; } try { - let url = `${API_BASE_URL}/user/devices/${deviceId}`; - if (experimentId) { - url = `${API_BASE_URL}/experiments/${experimentId}/devices/${deviceId}`; - } - - const response = await fetch(url, { + const response = await fetch(`${API_BASE_URL}/user/devices/${deviceId}`, { method: 'DELETE', headers: { 'Authorization': `Bearer ${token}` } }); + const data = await response.json(); + if (response.ok) { - const result = await response.json(); - alert(result.message); - if (experimentId) { - // 如果是从实验中除,只重新载该实验的设备列表 - await loadExperimentDevices(experimentId); - } else { - // 如果是完全移除设备,重新加载设备列表 + // 检查返回的状态 + if (data.status === 'inactive') { + alert('Device deactivated successfully'); + // 重新加载设备列表 loadDevices(); + } else { + alert('Failed to deactivate device'); } } else { - const error = await response.json(); - alert(`Failed to remove device: ${error.detail}`); + alert(`Failed: ${data.detail}`); } } catch (error) { console.error('Failed to remove device:', error); diff --git a/lab.html b/lab.html index 1749133..0c9cbb4 100644 --- a/lab.html +++ b/lab.html @@ -1546,7 +1546,6 @@ } } - // Modify loadExperiments function's device part async function loadExperiments(projectId) { try { const response = await fetch(`${API_BASE_URL}/experiments?project_id=${projectId}`, { @@ -1558,18 +1557,14 @@ if (response.ok) { const experiments = await response.json(); - // 对实验进行排序,未完成的排在前面 experiments.sort((a, b) => { - // 如果状态不同,completed 排在后面 if (a.status !== b.status) { return a.status === 'completed' ? 1 : -1; } - // 如果状态相同,按创建时间倒序排列 return new Date(b.create_time) - new Date(a.create_time); }); const experimentsHtml = await Promise.all(experiments.map(async exp => { - // Get experiment devices const devicesResponse = await fetch(`${API_BASE_URL}/experiments/${exp._id}/devices`, { headers: { 'Authorization': `Bearer ${token}` @@ -1583,7 +1578,7 @@
${devices.map(device => ` -
+
${device.device_name}
@@ -1604,7 +1599,6 @@ `; } - // 根据实验状态显示同的按钮组 const buttonsHtml = exp.status === 'completed' ? `
+ // 如果没有活动设备,显示提示信息 + if (activeDevices.length === 0) { + devicesList.innerHTML = ` +
+

No active devices available

-
- `).join(''); + `; + } else { + devicesList.innerHTML = activeDevices.map(device => ` +
+
+
${device.device_name}
+

+ Serial Number: ${device.serial_number}
+ Type: ${device.device_type}
+ Channel Number: ${device.device_number} +

+ +
+
+ `).join(''); + } // 显示模态框 const modal = new bootstrap.Modal(document.getElementById('addDeviceToExperimentModal')); diff --git a/main.py b/main.py index 1ee4b62..b6894dd 100644 --- a/main.py +++ b/main.py @@ -306,14 +306,20 @@ async def add_device_to_user( device = await db.devices.find_one({ "serial_numbers": { "$elemMatch": { - "serial": serial_number, - "status": "available" + "serial": serial_number } } }) if not device: raise HTTPException(status_code=404, detail="Device not found or invalid serial number") + # 检查该序列号是否已被其他用户激活 + active_device = await db.user_devices.find_one({ + "serial_number": serial_number, + "status": "active" + }) + if active_device: + raise HTTPException(status_code=400, detail="Device is already in use by another user") # Check if this serial number has already been added existing = await db.user_devices.find_one({ @@ -321,7 +327,27 @@ async def add_device_to_user( "serial_number": serial_number }) if existing: - raise HTTPException(status_code=400, detail="This device has already been added to your device list") + if existing["status"] == "active": + raise HTTPException(status_code=400, detail="This device is already active") + else: + # 如果设备存在但状态是inactive,则重新激活 + await db.user_devices.update_one( + {"_id": existing["_id"]}, + {"$set": {"status": "active"}} + ) + return { + "message": "Device reactivated successfully", + "device": { + "user_device_id": str(existing["_id"]), + "device_id": str(existing["device_id"]), + "serial_number": serial_number, + "device_name": existing["device_name"], + "device_type": existing["device_type"], + "device_number": existing["device_number"], + "sensors": existing.get("sensors", []), + "status": "active" + } + } # 创建新的关联记录,包含完整的设备信息、序列号和传感器信息 user_device_dict = { @@ -331,14 +357,20 @@ async def add_device_to_user( "device_name": device["device_name"], "device_type": device["device_type"], "device_number": device["device_number"], - "sensors": device.get("sensors", []) # 添加传感器信息 + "sensors": device.get("sensors", []), # 添加传感器信息 + "status": "active", # 添加状态字段 + "add_time": datetime.now(timezone.utc) # 添加时间记录 } - - # 更新设备序列号状态为已使用 + # 只有当序列号状态为available时才更新为in_use await db.devices.update_one( { "_id": device["_id"], - "serial_numbers.serial": serial_number + "serial_numbers": { + "$elemMatch": { + "serial": serial_number, + "status": "available" # 只匹配状态为available的序列号 + } + } }, { "$set": { @@ -359,7 +391,8 @@ async def add_device_to_user( "device_name": device["device_name"], "device_type": device["device_type"], "device_number": device["device_number"], - "sensors": device.get("sensors", []) # 在响应中包含传感器信息 + "sensors": device.get("sensors", []), # 在响应中包含传感器信息 + "status": "active" # 添加状态字段"status": "active" # 添加状态字段 } } @@ -387,7 +420,8 @@ async def get_user_devices(current_user: UserModel = Depends(get_current_user)): "device_name": device["device_name"], "device_type": device["device_type"], "device_number": device["device_number"], - "sensors": device.get("sensors", []) # 在响应中包含传感器信息 + "sensors": device.get("sensors", []), # 在响应中包含传感器信息 + "status": device.get("status", "active") }) return devices @@ -536,13 +570,14 @@ async def add_device_to_experiment( if not project: raise HTTPException(status_code=403, detail="Unauthorized access to this experiment") - # 验证用户设备是否存在 + # 验证用户设备是否存在且状态为active user_device = await db.user_devices.find_one({ "_id": ObjectId(user_device_id), - "user_id": current_user.id + "user_id": current_user.id, + "status": "active" # 添加状态检查 }) if not user_device: - raise HTTPException(status_code=404, detail="Device not found or unauthorized access") + raise HTTPException(status_code=404, detail="Active device not found or unauthorized access") # 检查是否已经添加过这个设备 existing = await db.experiment_devices.find_one({ @@ -736,7 +771,7 @@ async def remove_user_device( current_user: UserModel = Depends(get_current_user) ): """ - 移除��的设备,同时清理验中的关联记录 + 将设备标记为非活动状态 参数: device_id: 用户设备的ID @@ -745,35 +780,42 @@ async def remove_user_device( db = await get_database() try: - # 验证设备是否存在且属于当前用户 + # 验证设备是否存在且属于当前用户,且状态为active device = await db.user_devices.find_one({ "_id": ObjectId(device_id), - "user_id": current_user.id + "user_id": current_user.id, + "status": "active" # 只能停用活动状态的设备 }) if not device: - raise HTTPException(status_code=404, detail="Device not found or unauthorized access") + raise HTTPException(status_code=404, detail="Active device not found or unauthorized access") - # 首先删除所有实验中与该设备的关联 - delete_result = await db.experiment_devices.delete_many({ - "user_device_id": ObjectId(device_id) - }) - - # 然后删除用户设备记录 - await db.user_devices.delete_one({ - "_id": ObjectId(device_id), - "user_id": current_user.id - }) + # 更新设备状态为非活动 + result = await db.user_devices.update_one( + { + "_id": ObjectId(device_id), + "user_id": current_user.id + }, + { + "$set": { + "status": "inactive", + "deactivate_time": datetime.now(timezone.utc) # 记录停用时间 + } + } + ) + if result.modified_count == 0: + raise HTTPException(status_code=500, detail="Failed to deactivate device") + return { - "message": "Device removed successfully", - "removed_experiment_associations": delete_result.deleted_count + "message": "Device deactivated successfully", + "device_id": device_id, + "status": "inactive", # 添加状态字段 + "deactivate_time": datetime.now(timezone.utc).isoformat() } except Exception as e: - print(f"Error removing device: {str(e)}") - raise HTTPException(status_code=500, detail=f"Failed to remove device: {str(e)}") - - + print(f"Error deactivating device: {str(e)}") + raise HTTPException(status_code=500, detail=f"Failed to deactivate device: {str(e)}") # Connection Manager for WebSocket clients class ConnectionManager: