This commit is contained in:
limengnan 2025-11-28 08:10:35 +08:00
commit da2dc38a51
5 changed files with 57 additions and 46 deletions

View File

@ -305,10 +305,10 @@ class BleIMUDevice:
while self.running: while self.running:
try: try:
logger.info(f"扫描并连接蓝牙IMU: {self.mac_address} ...") # logger.info(f"扫描并连接蓝牙IMU: {self.mac_address} ...")
device = await BleakScanner.find_device_by_address(self.mac_address, cb=dict(use_bdaddr=False)) device = await BleakScanner.find_device_by_address(self.mac_address, cb=dict(use_bdaddr=False))
if device is None: if device is None:
logger.warning(f"未找到设备: {self.mac_address}") # logger.warning(f"未找到设备: {self.mac_address}")
await asyncio.sleep(2.0) await asyncio.sleep(2.0)
continue continue

View File

@ -1017,10 +1017,7 @@ class AppServer:
# 获取患者详情 # 获取患者详情
try: try:
patient = self.db_manager.get_patient(patient_id) patient = self.db_manager.get_patient(patient_id)
if patient: return jsonify({'success': True, 'data': patient})
return jsonify({'success': True, 'data': patient})
else:
return jsonify({'success': False, 'error': '患者不存在'}), 404
except Exception as e: except Exception as e:
self.logger.error(f'获取患者详情失败: {e}') self.logger.error(f'获取患者详情失败: {e}')
@ -1051,12 +1048,7 @@ class AppServer:
} }
self.db_manager.update_patient(patient_id, patient_data) self.db_manager.update_patient(patient_id, patient_data)
result = True return jsonify({'success': True, 'message': '患者信息更新成功'})
if result:
return jsonify({'success': True, 'message': '患者信息更新成功'})
else:
return jsonify({'success': False, 'error': '患者不存在'}), 404
except Exception as e: except Exception as e:
self.logger.error(f'更新患者信息失败: {e}') self.logger.error(f'更新患者信息失败: {e}')
@ -1066,10 +1058,7 @@ class AppServer:
# 删除患者 # 删除患者
try: try:
result = self.db_manager.delete_patient(patient_id) result = self.db_manager.delete_patient(patient_id)
if result: return jsonify({'success': True, 'message': '患者已删除'})
return jsonify({'success': True, 'message': '患者已删除'})
else:
return jsonify({'success': False, 'error': '患者不存在'}), 404
except Exception as e: except Exception as e:
self.logger.error(f'删除患者失败: {e}') self.logger.error(f'删除患者失败: {e}')
@ -1674,7 +1663,7 @@ class AppServer:
def handle_subscribe_device(data): def handle_subscribe_device(data):
"""订阅特定设备数据""" """订阅特定设备数据"""
device_type = data.get('device_type') device_type = data.get('device_type')
if device_type in ['camera', 'femtobolt', 'imu', 'pressure']: if device_type in ['camera1', 'camera2', 'femtobolt', 'imu', 'pressure']:
self.logger.info(f'客户端订阅{device_type}设备数据') self.logger.info(f'客户端订阅{device_type}设备数据')
emit('subscription_status', { emit('subscription_status', {
'device_type': device_type, 'device_type': device_type,
@ -1997,7 +1986,7 @@ def main():
"""主函数""" """主函数"""
# 解析命令行参数 # 解析命令行参数
parser = argparse.ArgumentParser(description='Body Balance Evaluation System Backend') parser = argparse.ArgumentParser(description='Body Balance Evaluation System Backend')
parser.add_argument('--host', default='localhost', help='Host address to bind to') parser.add_argument('--host', default='0.0.0.0', help='Host address to bind to')
parser.add_argument('--port', type=int, default=5000, help='Port number to bind to') parser.add_argument('--port', type=int, default=5000, help='Port number to bind to')
parser.add_argument('--debug', action='store_true', help='Enable debug mode') parser.add_argument('--debug', action='store_true', help='Enable debug mode')
args = parser.parse_args() args = parser.parse_args()
@ -2008,4 +1997,4 @@ def main():
if __name__ == '__main__': if __name__ == '__main__':
main() main()

View File

@ -233,10 +233,13 @@ class DataValidator:
# 出生日期验证 # 出生日期验证
if data.get('birth_date'): if data.get('birth_date'):
try: try:
birth_date = datetime.fromisoformat(data['birth_date'].replace('Z', '+00:00')) birth_dt = datetime.fromisoformat(data['birth_date'].replace('Z', '+00:00'))
if birth_date > datetime.now(): birth = birth_dt.date()
today = datetime.now().date()
lower = datetime(1900, 1, 1).date()
if birth > today:
errors.append('出生日期不能是未来时间') errors.append('出生日期不能是未来时间')
if birth_date < datetime(1900, 1, 1): if birth < lower:
errors.append('出生日期过早') errors.append('出生日期过早')
except ValueError: except ValueError:
errors.append('出生日期格式无效') errors.append('出生日期格式无效')
@ -523,4 +526,4 @@ class ResponseFormatter:
config = Config() config = Config()
# 性能监控实例 # 性能监控实例
performance_monitor = PerformanceMonitor() performance_monitor = PerformanceMonitor()

View File

@ -13,7 +13,7 @@ api.interceptors.request.use(
if (window.electronAPI) { if (window.electronAPI) {
config.baseURL = window.electronAPI.getBackendUrl() config.baseURL = window.electronAPI.getBackendUrl()
} else { } else {
config.baseURL = 'http://192.168.1.60:5000' config.baseURL = 'http://localhost:5000'
} }
// 为需要发送数据的请求设置Content-Type避免覆盖FormData // 为需要发送数据的请求设置Content-Type避免覆盖FormData
@ -660,7 +660,7 @@ export const getBackendUrl = () => {
if (window.electronAPI) { if (window.electronAPI) {
return window.electronAPI.getBackendUrl() return window.electronAPI.getBackendUrl()
} else { } else {
return 'http://192.168.1.60:5000' return 'http://localhost:5000'
} }
} }

View File

@ -314,11 +314,11 @@
</div> </div>
<div class="body-video-content" ref="videoImgRef"> <div class="body-video-content" ref="videoImgRef">
<div class="body-video-imgbox1" ref="camera1Ref"> <div class="body-video-imgbox1" ref="camera1Ref">
<img :src="(cameraStatus === '已连接' && camera1ImgSrc) ? camera1ImgSrc : noImageSvg" alt="camera1" <img :src="(camera1Status === '已连接' && camera1ImgSrc) ? camera1ImgSrc : noImageSvg" alt="camera1"
style="width: 100%; height: 100%; object-fit: contain; background:#323232;" /> style="width: 100%; height: 100%; object-fit: contain; background:#323232;" />
</div> </div>
<div class="body-video-imgbox2" ref="camera2Ref"> <div class="body-video-imgbox2" ref="camera2Ref">
<img :src="(cameraStatus === '已连接' && camera2ImgSrc) ? camera2ImgSrc : noImageSvg" alt="camera2" <img :src="(camera2Status === '已连接' && camera2ImgSrc) ? camera2ImgSrc : noImageSvg" alt="camera2"
style="width: 100%; height: 100%; object-fit: contain; background:#323232;" /> style="width: 100%; height: 100%; object-fit: contain; background:#323232;" />
</div> </div>
</div> </div>
@ -678,7 +678,9 @@ const chartoption = ref({
] ]
}) })
// //
const cameraStatus = ref('未连接') // const camera1Status = ref('未连接')
const camera2Status = ref('未连接')
const cameraStatus = computed(() => (camera1Status.value === '已连接' || camera2Status.value === '已连接') ? '已连接' : '未连接')
const femtoboltStatus = ref('未连接') // (FemtoBolt) const femtoboltStatus = ref('未连接') // (FemtoBolt)
const imuStatus = ref('未连接') // IMU const imuStatus = ref('未连接') // IMU
const pressureStatus = ref('未连接') // const pressureStatus = ref('未连接') //
@ -937,7 +939,8 @@ function connectWebSocket() {
console.log('🔗 设备命名空间连接成功') console.log('🔗 设备命名空间连接成功')
// //
devicesSocket.emit('subscribe_device', { device_type: 'camera' }) devicesSocket.emit('subscribe_device', { device_type: 'camera1' })
devicesSocket.emit('subscribe_device', { device_type: 'camera2' })
devicesSocket.emit('subscribe_device', { device_type: 'femtobolt' }) devicesSocket.emit('subscribe_device', { device_type: 'femtobolt' })
devicesSocket.emit('subscribe_device', { device_type: 'imu' }) devicesSocket.emit('subscribe_device', { device_type: 'imu' })
devicesSocket.emit('subscribe_device', { device_type: 'pressure' }) devicesSocket.emit('subscribe_device', { device_type: 'pressure' })
@ -949,7 +952,8 @@ function connectWebSocket() {
devicesSocket.on('disconnect', () => { devicesSocket.on('disconnect', () => {
console.log('🔗 设备命名空间断开连接') console.log('🔗 设备命名空间断开连接')
// //
cameraStatus.value = '未连接' camera1Status.value = '未连接'
camera2Status.value = '未连接'
femtoboltStatus.value = '未连接' femtoboltStatus.value = '未连接'
imuStatus.value = '未连接' imuStatus.value = '未连接'
pressureStatus.value = '未连接' pressureStatus.value = '未连接'
@ -1019,9 +1023,13 @@ function connectWebSocket() {
const statusText = status ? '已连接' : '未连接' const statusText = status ? '已连接' : '未连接'
switch (device_type) { switch (device_type) {
case 'camera': case 'camera1':
cameraStatus.value = statusText camera1Status.value = statusText
console.log(`📷 相机状态: ${statusText}`) console.log(`📷 相机1状态: ${statusText}`)
break
case 'camera2':
camera2Status.value = statusText
console.log(`📷 相机2状态: ${statusText}`)
break break
case 'femtobolt': case 'femtobolt':
femtoboltStatus.value = statusText femtoboltStatus.value = statusText
@ -1080,7 +1088,8 @@ function disconnectWebSocket() {
if (devicesSocket.connected) { if (devicesSocket.connected) {
// //
try { try {
devicesSocket.emit('unsubscribe_device', { device_type: 'camera' }) devicesSocket.emit('unsubscribe_device', { device_type: 'camera1' })
devicesSocket.emit('unsubscribe_device', { device_type: 'camera2' })
devicesSocket.emit('unsubscribe_device', { device_type: 'femtobolt' }) devicesSocket.emit('unsubscribe_device', { device_type: 'femtobolt' })
devicesSocket.emit('unsubscribe_device', { device_type: 'imu' }) devicesSocket.emit('unsubscribe_device', { device_type: 'imu' })
devicesSocket.emit('unsubscribe_device', { device_type: 'pressure' }) devicesSocket.emit('unsubscribe_device', { device_type: 'pressure' })
@ -1106,7 +1115,8 @@ function disconnectWebSocket() {
} }
// //
cameraStatus.value = '未连接' camera1Status.value = '未连接'
camera2Status.value = '未连接'
femtoboltStatus.value = '未连接' femtoboltStatus.value = '未连接'
imuStatus.value = '未连接' imuStatus.value = '未连接'
pressureStatus.value = '未连接' pressureStatus.value = '未连接'
@ -1501,11 +1511,17 @@ async function saveDetectionData() {
pressure_image = tempInfo.value.pressure_data.foot_pressure.pressure_image pressure_image = tempInfo.value.pressure_data.foot_pressure.pressure_image
foot_data = tempInfo.value.pressure_data.foot_pressure.pressure_zones foot_data = tempInfo.value.pressure_data.foot_pressure.pressure_zones
} }
let foot_image="" let foot1_image=""
if(tempInfo.value.camera_frame != null if(tempInfo.value.camera1_frame != null
&& tempInfo.value.camera_frame.image != null ){ && tempInfo.value.camera1_frame.image != null ){
foot_image=base64 + tempInfo.value.camera_frame.image foot1_image=base64 + tempInfo.value.camera1_frame.image
} }
let foot2_image=""
if(tempInfo.value.camera2_frame != null
&& tempInfo.value.camera2_frame.image != null ){
foot2_image=base64 + tempInfo.value.camera2_frame.image
}
let head_pose={} let head_pose={}
if(tempInfo.value.imu_data != null ){ if(tempInfo.value.imu_data != null ){
@ -1526,7 +1542,8 @@ async function saveDetectionData() {
body_image: body_image, body_image: body_image,
foot_data:foot_data, foot_data:foot_data,
foot_image:foot_image, foot1_image:foot1_image,
foot2_image:foot2_image,
foot_data_image:pressure_image, foot_data_image:pressure_image,
screen_image:null screen_image:null
@ -1569,7 +1586,7 @@ async function saveDetectionData() {
// API // API
async function sendDetectionData(data) { async function sendDetectionData(data) {
try { try {
const response = await fetch(`${BACKEND_URL}/api/detection/${patientInfo.value.sessionId}/collect` const response = await fetch(`${BACKEND_URL}/api/detection/${patientInfo.value.sessionId}/save-data`
, { , {
method: 'POST', method: 'POST',
headers: { headers: {
@ -1872,8 +1889,8 @@ onMounted(() => {
console.log(authStore.currentUser) console.log(authStore.currentUser)
creatorId.value = authStore.currentUser.id creatorId.value = authStore.currentUser.id
} }
// patientId.value = props.selectedPatient.id patientId.value = props.selectedPatient.id
patientId.value = '202511150005' //patientId.value = '202511150005'
// //
loadPatientInfo() loadPatientInfo()
// //
@ -2053,8 +2070,10 @@ function refreshClick(type) {
}, 5000) }, 5000)
ElMessage.warning(`🚀 发送重启设备请求...`) ElMessage.warning(`🚀 发送重启设备请求...`)
if (devicesSocket && devicesSocket.connected) { if (devicesSocket && devicesSocket.connected) {
if(type == 'camera'){ if(type == 'camera1'){
devicesSocket.emit('restart_device', { device_type: 'camera' }) devicesSocket.emit('restart_device', { device_type: 'camera1' })
}else if(type == 'camera2'){
devicesSocket.emit('restart_device', { device_type: 'camera2' })
}else if(type == 'femtobolt'){ }else if(type == 'femtobolt'){
devicesSocket.emit('restart_device', { device_type: 'femtobolt' }) devicesSocket.emit('restart_device', { device_type: 'femtobolt' })
}else if(type == 'imu'){ }else if(type == 'imu'){
@ -2716,4 +2735,4 @@ function handleEditUserInfo(){
padding-top: 50px; padding-top: 50px;
padding-right: 10px; padding-right: 10px;
} }
</style> </style>