Merge branch 'dev-v15' of http://121.37.111.42:3000/ThbTech/BodyBalanceEvaluation into dev-v15
This commit is contained in:
commit
da2dc38a51
@ -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
|
||||||
|
|
||||||
|
|||||||
@ -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()
|
||||||
|
|||||||
@ -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()
|
||||||
|
|||||||
@ -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'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user