修复了测试提交bug。 排序、蓝牙名称修改不生效等

This commit is contained in:
root 2026-01-27 18:16:12 +08:00
parent 641bc9e8a0
commit 5059ad6158
6 changed files with 152 additions and 221 deletions

View File

@ -60,7 +60,7 @@ pressure_port = COM5
pressure_baudrate = 115200
[REMOTE]
enable = False
enable = True
port = COM6
baudrate = 115200
timeout = 0.1

View File

@ -830,7 +830,7 @@ class DatabaseManager:
cursor.execute('''
SELECT * FROM detection_data
WHERE session_id = ?
ORDER BY timestamp
ORDER BY timestamp desc
''', (session_id,))
data_rows = cursor.fetchall()
@ -849,7 +849,7 @@ class DatabaseManager:
cursor.execute('''
SELECT * FROM detection_video
WHERE session_id = ?
ORDER BY timestamp
ORDER BY timestamp desc
''', (session_id,))
video_rows = cursor.fetchall()

View File

@ -291,9 +291,11 @@ class DeviceCoordinator:
from .remote_control_manager import RemoteControlManager
remote = RemoteControlManager(self.socketio, self.config_manager)
self.devices['remote'] = remote
if remote.initialize():
return True
if not remote.initialize():
return False
if hasattr(remote, 'start_streaming'):
return bool(remote.start_streaming())
return True
except Exception as e:
self.logger.error(f"初始化遥控器失败: {e}")
return False
@ -743,6 +745,12 @@ class DeviceCoordinator:
except ImportError:
from femtobolt_manager import FemtoBoltManager
new_device = FemtoBoltManager(self.socketio, self.config_manager)
elif device_name == 'remote':
try:
from .remote_control_manager import RemoteControlManager
except ImportError:
from remote_control_manager import RemoteControlManager
new_device = RemoteControlManager(self.socketio, self.config_manager)
else:
raise ValueError(f"未知的设备类型: {device_name}")
@ -777,6 +785,17 @@ class DeviceCoordinator:
init_time = (time.time() - init_start) * 1000
self.logger.info(f"{device_name} 设备初始化成功 (耗时: {init_time:.1f}ms)")
if device_name == 'remote' and hasattr(new_device, 'start_streaming'):
self.logger.info(f"正在启动 {device_name} 设备推流...")
try:
if not new_device.start_streaming():
self.logger.error(f"启动 {device_name} 设备推流失败")
return False
was_streaming = True
except Exception as e:
self.logger.error(f"启动 {device_name} 推流异常: {e}")
return False
# 设备初始化成功后,确保状态广播正确
# 此时设备应该已经通过initialize()方法中的set_connected(True)触发了状态变化通知
# 但为了确保状态一致性,我们再次确认状态

View File

@ -66,7 +66,7 @@ class RemoteControlManager(BaseDevice):
def initialize(self) -> bool:
try:
self.logger.info(f"初始化遥控器串口: {self.port}, {self.baudrate}bps, 8N1")
self.set_connected(True)
self.set_connected(False)
self._device_info['initialized_at'] = time.time()
return True
except Exception as e:
@ -88,6 +88,9 @@ class RemoteControlManager(BaseDevice):
stopbits=self.stopbits,
timeout=self.timeout,
)
self.set_connected(True)
self.update_heartbeat()
self.is_streaming = True
self._running = True
self._thread = threading.Thread(target=self._worker_loop, daemon=True)
self._thread.start()
@ -110,6 +113,9 @@ class RemoteControlManager(BaseDevice):
self._thread.join(timeout=2.0)
if self._ser and self._ser.is_open:
self._ser.close()
self._ser = None
self.set_connected(False)
self.is_streaming = False
self.logger.info("遥控器串口监听已停止")
return True
except Exception as e:
@ -248,6 +254,7 @@ class RemoteControlManager(BaseDevice):
time.sleep(0.05)
continue
chunk = self._ser.read(64)
self.update_heartbeat()
if chunk:
try:
hexstr = ' '.join(f'{b:02X}' for b in chunk)
@ -262,5 +269,14 @@ class RemoteControlManager(BaseDevice):
self.logger.debug("遥控器串口暂无数据")
except Exception as e:
self.logger.error(f"遥控器串口读取异常: {e}")
try:
if self._ser and self._ser.is_open:
self._ser.close()
except Exception:
pass
self._ser = None
self.set_connected(False)
self.is_streaming = False
self._running = False
time.sleep(0.1)
self.logger.info("遥控器串口线程结束")

View File

@ -434,6 +434,8 @@ class ConfigManager:
self.set_config_value('DEVICES', 'imu_use_mock', str(config_data['use_mock']))
if 'mac_address' in config_data:
self.set_config_value('DEVICES', 'imu_mac_address', config_data['mac_address'])
if 'ble_name' in config_data:
self.set_config_value('DEVICES', 'imu_ble_name', config_data['ble_name'])
results['imu'] = {
'success': True,

View File

@ -3,6 +3,7 @@
<Header />
<div class="displaycontainer">
<div class="displayleft" style="width: 550px;">
<img src="@/assets/detection/progress.png" alt="" style=" margin-left:10px;margin-right:15px">
<div style="
font-size: 18px;
@ -47,7 +48,7 @@
</div>
</div>
</div>
<div style="width:100%;height: calc(100% - 115px);" ref="contenGridRef">
<div style="width:100%;height: calc(100% - 131px);" ref="contenGridRef">
<!-- 主内容区域 -->
<el-row :gutter="15" style="padding: 10px;padding-top:0" >
<el-col :span="6" style="flex: 0 0 24%;height: calc(100% - 0px);">
@ -192,7 +193,6 @@
</div>
</div>
<div class="body-footbottom-box" ref="pressureRef">
<div style="width: 100%;height: calc(100% - 57px);display: flex; align-items: center;justify-content: center;">
<div class="body-footbottom-left">
<div style="width:100%;height: 50px;"></div>
<div class="body-footbottom-leftbottom">
@ -208,12 +208,12 @@
{{ footPressure.left_rear }}%
</span>
</div>
<!-- <div class="body-footbottom-leftbox">
<div class="body-footbottom-leftbox">
<span class="currencytext1">左足总压力</span>
<span class="currencytext2">
{{ footPressure.left_total}}%
</span>
</div> -->
</div>
</div>
</div>
<div class="body-footbottom-center">
@ -229,10 +229,8 @@
<img :src="noImageSvg" style="margin-left: 15px;">
<div style="font-size:14px;color:#ffffff99;text-align: center;">连接已断开</div>
</div>
<div class="xline"></div>
<div class="yline"></div>
<!-- <div v-if="(pressureStatus === '已连接' && footImgSrc)" class="xline"></div>
<div v-if="(pressureStatus === '已连接' && footImgSrc)" class="yline"></div> -->
<div v-if="(pressureStatus === '已连接' && footImgSrc)" class="xline"></div>
<div v-if="(pressureStatus === '已连接' && footImgSrc)" class="yline"></div>
</div>
</div>
<div class="body-footbottom-left">
@ -250,35 +248,19 @@
{{ footPressure.right_rear }}%
</span>
</div>
<!-- <div class="body-footbottom-leftbox">
<span class="currencytext1">右足总压力</span>
<span class="currencytext2">
{{ footPressure.right_total}}%
</span>
</div> -->
</div>
</div>
</div>
<div style="display: flex;justify-content: center; width: 100%;">
<div class="body-footbottom-leftbox" style="width:calc(22% + 2px)">
<span class="currencytext1">左足总压力</span>
<span class="currencytext2">
{{ footPressure.left_total}}%
</span>
</div>
<div class="body-footbottom-leftbox" style="width:calc(22% + 2px);margin-left: 20px">
<div class="body-footbottom-leftbox">
<span class="currencytext1">右足总压力</span>
<span class="currencytext2">
{{ footPressure.right_total}}%
</span>
</div>
</div>
</div>
</div>
</div>
</el-col>
<el-col v-if=" false || camera1Status === '已连接' && camera2Status === '已连接'"
<el-col v-if="camera1Status === '已连接' && camera2Status === '已连接'"
:span="6" style="flex: 0 0 24%;height: calc(100% - 0px); position: relative;">
<div class="body-userinfo-box" :class="isExpand == true?'body-userinfo-expandbox':''">
<div class="body-title-display">
@ -448,9 +430,9 @@
</div>
</div>
</el-col>
<el-col v-if="true || camera1Status === '已连接' || camera2Status === '已连接'"
:span="6" style="flex: 0 0 24%;height: calc(100% - 0px);position: relative;">
<div class="body-userinfo-box1" :class="isExpand == true?'body-userinfo-expandbox':''">
<el-col v-if="camera1Status === '已连接' || camera2Status === '已连接'"
:span="6" style="flex: 0 0 24%;height: calc(100% - 0px);">
<div class="body-userinfo-box1">
<div class="body-title-display">
<div class="body-son-display">
<img src="@/assets/detection/title4.png" alt="" style="margin-right: 8px;">
@ -479,116 +461,61 @@
</div>
</div>
<div class="body-userinfo-content-bottom0" v-if="isExpand == false">
<img src="@/assets/detection/userinfo.png" alt=""
class="userinfo-edit-img" style="cursor: pointer;"
@click="viewClick(true)">
<div class="userinfo-disyplaypadding1 ">
<div class="userinfo-text4 padding10">出生日期</div>
<div class="body-userinfo-content-bottom1">
<div class="userinfo-disyplaypadding4">
<div class="userinfo-text4">出生日期</div>
<div class="userinfo-text5">
<span v-if="patientInfo && patientInfo.birth_date">
{{ formatDate(patientInfo.birth_date) }}
</span>
</div>
</div>
<div class="userinfo-disyplaypadding2">
<div class="userinfo-text4 padding10">身高</div>
<div class="userinfo-disyplaypadding5">
<div class="userinfo-text4">身高</div>
<div class="userinfo-text5">
{{ patientInfo.height ==''||patientInfo.height ==null ?'—':patientInfo.height}}cm
</div>
</div>
<div class="userinfo-disyplaypadding1">
<div class="userinfo-text4 padding10">体重</div>
<div class="userinfo-disyplaypadding4">
<div class="userinfo-text4">体重</div>
<div class="userinfo-text5">
{{ patientInfo.weight ==''||patientInfo.weight ==null ?'—':patientInfo.weight}}kg
</div>
</div>
<div class="userinfo-disyplaypadding2">
<div class="userinfo-text4 padding10">鞋码</div>
<div class="userinfo-disyplaypadding5">
<div class="userinfo-text4">鞋码</div>
<div class="userinfo-text5">
{{ patientInfo.shoe_size ==''||patientInfo.shoe_size ==null ?'—':patientInfo.shoe_size}}</div>
</div>
<div class="userinfo-disyplaypadding1">
<div class="userinfo-text4 padding10">电话</div>
<div class="userinfo-disyplaypadding4">
<div class="userinfo-text4">电话</div>
<div class="userinfo-text5">
{{ patientInfo.phone ==''||patientInfo.phone ==null ?'—':patientInfo.phone}}
</div>
</div>
<div class="userinfo-disyplaypadding2">
<div class="userinfo-text4 padding10">民族</div>
<div class="userinfo-disyplaypadding5">
<div class="userinfo-text4">民族</div>
<div class="userinfo-text5">
{{ patientInfo.nationality ==''||patientInfo.nationality ==null ?'—':patientInfo.nationality}}</div>
</div>
<div class="userinfo-disyplaypadding1">
<div class="userinfo-text4 padding10">身份证号</div>
<div class="userinfo-disyplaypadding4">
<div class="userinfo-text4">身份证号</div>
<div class="userinfo-text5">
{{ patientInfo.idcode ==''||patientInfo.idcode ==null ?'—':patientInfo.idcode}}
</div>
</div>
<div class="userinfo-disyplaypadding2">
<div class="userinfo-text4 padding10">职业</div>
<div class="userinfo-disyplaypadding5">
<div class="userinfo-text4">职业</div>
<div class="userinfo-text5">
{{ patientInfo.occupation ==''||patientInfo.occupation ==null ?'—':patientInfo.occupation}}</div>
</div>
</div>
<div class="body-userinfo-content-bottom2" v-if="isExpand == true">
<img src="@/assets/detection/userinfo.png" alt=""
class="userinfo-edit-img" style="cursor: pointer;"
@click="viewClick(false)">
<div class="userinfo-disyplaypadding1 ">
<div class="userinfo-text4 padding10">出生日期</div>
<div class="userinfo-text5">
<span v-if="patientInfo && patientInfo.birth_date">
{{ formatDate(patientInfo.birth_date) }}
</span>
</div>
</div>
<div class="userinfo-disyplaypadding2">
<div class="userinfo-text4 padding10">身高</div>
<div class="userinfo-text5">
{{ patientInfo.height ==''||patientInfo.height ==null ?'—':patientInfo.height}}cm
</div>
</div>
<div class="userinfo-disyplaypadding1">
<div class="userinfo-text4 padding10">体重</div>
<div class="userinfo-text5">
{{ patientInfo.weight ==''||patientInfo.weight ==null ?'—':patientInfo.weight}}kg
</div>
</div>
<div class="userinfo-disyplaypadding2">
<div class="userinfo-text4 padding10">鞋码</div>
<div class="userinfo-text5">
{{ patientInfo.shoe_size ==''||patientInfo.shoe_size ==null ?'—':patientInfo.shoe_size}}</div>
</div>
<div class="userinfo-disyplaypadding1">
<div class="userinfo-text4 padding10">电话</div>
<div class="userinfo-text5">
{{ patientInfo.phone ==''||patientInfo.phone ==null ?'—':patientInfo.phone}}
</div>
</div>
<div class="userinfo-disyplaypadding2">
<div class="userinfo-text4 padding10">民族</div>
<div class="userinfo-text5">
{{ patientInfo.nationality ==''||patientInfo.nationality ==null ?'—':patientInfo.nationality}}</div>
</div>
<div class="userinfo-disyplaypadding1">
<div class="userinfo-text4 padding10">身份证号</div>
<div class="userinfo-text5">
{{ patientInfo.idcode ==''||patientInfo.idcode ==null ?'—':patientInfo.idcode}}
</div>
</div>
<div class="userinfo-disyplaypadding2">
<div class="userinfo-text4 padding10">职业</div>
<div class="userinfo-text5">
{{ patientInfo.occupation ==''||patientInfo.occupation ==null ?'—':patientInfo.occupation}}</div>
</div>
<div class="userinfo-disyplaypadding3">
<div class="userinfo-text4 padding10">居住地</div>
<div class="userinfo-disyplaypadding6">
<div class="userinfo-text4">居住地</div>
<div class="userinfo-text5">
{{ patientInfo.residence ==''||patientInfo.residence ==null ?'—':patientInfo.residence}}</div>
</div>
<div class="userinfo-disyplaypadding3">
<div class="userinfo-text4 padding10">邮箱</div>
<div class="userinfo-disyplaypadding6">
<div class="userinfo-text4">邮箱</div>
<div class="userinfo-text5">
{{ patientInfo.email ==''||patientInfo.email ==null ?'—':patientInfo.email}}</div>
</div>
@ -596,8 +523,7 @@
</div>
</div>
</div>
<div class="body-video-box1" style="position: absolute; top: 522px; width: calc(100% - 15px);">
<div class="body-video-box1">
<div class="body-title-display">
<div class="body-son-display">
<img src="@/assets/detection/title5.png" alt="" style="margin-right: 8px;">
@ -612,14 +538,14 @@
</div>
</div>
</div>
<div class="body-video-content" style="padding: 0;">
<div class="body-video-content">
<div v-show="camera1Status === '已连接'" class="body-video-imgbox3" ref="camera1Ref" :class="(camera1Status === '已连接' && camera1ImgSrc)?'':'noImageSvg-bg'">
<div v-if="(camera1Status === '已连接' && camera1ImgSrc)"
@click="isBig1 = true" class="big-img">
<img src="@/assets/detection/big.png">
</div>
<img v-if="(camera1Status === '已连接' && camera1ImgSrc)" :src="camera1ImgSrc" alt="camera1"
style="width: 100%; height: 100%;object-fit:contain;" />
style="width: 100%; height: 100%;" />
<div v-else style="width:90px;height:60px">
<img :src="noImageSvg" style="margin-left: 15px;">
<div style="font-size:14px;color:#ffffff99;text-align: center;">连接已断开</div>
@ -631,7 +557,7 @@
<img src="@/assets/detection/big.png">
</div>
<img v-if="(camera2Status === '已连接' && camera2ImgSrc)" :src="camera2ImgSrc" alt="camera2"
style="width: 100%; height: 100%;object-fit:contain;" />
style="width: 100%; height: 100%;" />
<div v-else style="width:90px;height:60px">
<img :src="noImageSvg" style="margin-left: 15px;">
<div style="font-size:14px;color:#ffffff99;text-align: center;">连接已断开</div>
@ -640,7 +566,7 @@
</div>
</div>
</el-col>
<el-col v-if="false || camera1Status !== '已连接' && camera2Status !== '已连接'" :span="6" style="flex: 0 0 24%;height: calc(100% - 0px);">
<el-col v-if="camera1Status !== '已连接' && camera2Status !== '已连接'" :span="6" style="flex: 0 0 24%;height: calc(100% - 0px);">
<div class="body-userinfo-box3">
<div class="body-title-display">
<div class="body-son-display">
@ -787,7 +713,6 @@
<div class="pop-up-tip-text" v-if="!isVideoOperation">本次检测未截图或录像操作不予存档记录</div>
<div class="pop-up-tip-text" v-if="isVideoOperation">本次检测未截图操作存档记录不可生成报告</div>
<div class="tipconfirmbutton-box">
<div class="tipclosebutton" @click="handleCancel">取消</div>
<el-button type="primary" class="tipconfirmbutton" @click="closeTipClick">确定</el-button>
</div>
</div>
@ -2709,23 +2634,9 @@ const isPhotoAlbum = ref(false)
function closePhotoAlbum(){
isPhotoAlbum.value = false
}
function closecreatbox(e,info){
if(e === '编辑'){
patientInfo.value.age = info.age
patientInfo.value.birth_date = info.birth_date
patientInfo.value.email = info.email
patientInfo.value.gender = info.gender
patientInfo.value.height = info.height
patientInfo.value.id = info.id
patientInfo.value.idcode = info.idcode
patientInfo.value.name = info.name
patientInfo.value.nationality = info.nationality
patientInfo.value.occupation = info.occupation
patientInfo.value.phone = info.phone
patientInfo.value.residence = info.residence
patientInfo.value.shoe_size = info.shoe_size
patientInfo.value.weight = info.weight
// loadPatientInfo()
function closecreatbox(e){
if(e === true){
loadPatientInfo()
}
isCloseCreat.value = false
}
@ -2767,7 +2678,7 @@ function viewClick(e){
.displaycontainer {
width: 100%;
height: 46px;
height: 62px;
display: flex;
align-items: center;
justify-content: space-between;
@ -2944,8 +2855,10 @@ function viewClick(e){
text-align: left;
}
.body-footbottom-box{
height: calc(100% - 50px);
padding-bottom: 15px;
display: flex;
align-items: center;
justify-content: center;
height: calc(100% - 70px);
}
.body-footbottom-left{
width: 28%;
@ -2958,8 +2871,8 @@ function viewClick(e){
.body-footbottom-leftbox{
min-width: 215px;
width: 80%;
min-height: 57px;
height: 57px;
min-height: 60px;
height: 20%;
background: inherit;
background-color: rgba(255, 255, 255, 0.1);
border-radius: 4px;
@ -2969,8 +2882,8 @@ function viewClick(e){
padding: 0px 20px;
}
.body-footbottom-center{
width: 37%;
height: calc(100% - 0px);
width: 40%;
height: calc(100%);
}
.body-footbottom-topbox{
display: flex;
@ -3005,7 +2918,7 @@ function viewClick(e){
display: flex;
justify-content: center;
flex-wrap: wrap;
align-content:space-around;
align-content:space-between ;
}
.body-userinfo-box{
@ -3013,18 +2926,18 @@ function viewClick(e){
z-index: 10;
width: 100%;
height: 346px;
/* background: linear-gradient(135deg, rgba(42, 54, 73, 1) 0%, rgba(42, 54, 73, 1) 0%, rgba(34, 43, 56, 1) 100%, rgba(34, 43, 56, 1) 100%); */
background: linear-gradient(135deg, #1a1e2a 0%, #222b38 100%);
border: 1px solid #242E3D;
border-radius: 4px;
}
.body-userinfo-expandbox{
height: 680px !important;
height: 638px ;
}
.body-userinfo-box1{
position: relative;
z-index: 10;
width: 100%;
height: 524px ;
height: 534px ;
/* background: linear-gradient(135deg, rgba(42, 54, 73, 1) 0%, rgba(42, 54, 73, 1) 0%, rgba(34, 43, 56, 1) 100%, rgba(34, 43, 56, 1) 100%); */
background: linear-gradient(135deg, #1a1e2a 0%, #222b38 100%);
border: 1px solid #242E3D;
border-radius: 4px;
@ -3050,7 +2963,7 @@ function viewClick(e){
}
.body-video-box1{
width: 100%;
height: calc(100% - 534px - 4px) ;
height: calc(100% - 534px - 14px) ;
background: linear-gradient(135deg, #1a1e2a 0%, #222b38 100%);
border: 1px solid #242E3D;
border-radius: 4px;
@ -3187,10 +3100,10 @@ function viewClick(e){
}
.userinfo-disyplaypadding1{
width: calc(64%);
padding-bottom: 20px;
padding-bottom: 15px;
}
.padding10{
padding-bottom: 10px;
padding-bottom: 5px;
}
.userinfo-disyplaypadding2{
width: calc(36%);
@ -3425,25 +3338,6 @@ function viewClick(e){
background:#14aaff;
border:1px solid #14aaff;
}
.tipclosebutton{
width: 80px;
height: 40px;
background-color: #597194;
border-radius: 4px;
color: rgba(255, 255, 255, 0.6);
font-weight: 400;
font-style: normal;
font-size: 16px;
display: flex;
align-items: center;
justify-content: center;
margin-right: 20px;
cursor: pointer;
}
.tipclosebutton:hover{
background-color: #14aaff;
color: #fff;
}
.pop-up-tip-text{
width:100%;
font-weight: 400;