修正了main设备初始化顺序、pdf黑白bug、桌面快捷图标bug
This commit is contained in:
parent
685765e2b2
commit
5ed15ce017
@ -154,6 +154,19 @@ class CameraManager(BaseDevice):
|
||||
|
||||
return True
|
||||
|
||||
def set_connected(self, is_connected: bool):
|
||||
"""
|
||||
设置连接状态并触发回调
|
||||
|
||||
Args:
|
||||
is_connected: 连接状态
|
||||
"""
|
||||
# 更新心跳时间,防止刚连接就被判定超时
|
||||
if is_connected:
|
||||
self.update_heartbeat()
|
||||
|
||||
super().set_connected(is_connected)
|
||||
|
||||
def initialize(self) -> bool:
|
||||
"""
|
||||
初始化相机设备
|
||||
@ -222,6 +235,8 @@ class CameraManager(BaseDevice):
|
||||
# 使用set_connected方法来正确启动连接监控线程
|
||||
self.set_connected(True)
|
||||
self._last_connected_state = True
|
||||
# 更新心跳时间,防止连接监控线程刚启动就判定为超时
|
||||
self.update_heartbeat()
|
||||
self._device_info.update({
|
||||
'device_index': self.device_index,
|
||||
'resolution': f"{self.width}x{self.height}",
|
||||
@ -493,6 +508,8 @@ class CameraManager(BaseDevice):
|
||||
|
||||
try:
|
||||
self.is_streaming = True
|
||||
# 更新心跳时间,确保流开始时不会被误判超时
|
||||
self.update_heartbeat()
|
||||
self.streaming_thread = threading.Thread(
|
||||
target=self._streaming_worker,
|
||||
name=f"Camera-{self.device_index}-Stream",
|
||||
@ -919,7 +936,7 @@ class CameraManager(BaseDevice):
|
||||
"""
|
||||
try:
|
||||
if not self.is_connected:
|
||||
self.logger.info("相机未连接,检查连接状态")
|
||||
# self.logger.info("相机未连接,检查连接状态")
|
||||
return False
|
||||
|
||||
# 尝试读取一帧
|
||||
@ -928,7 +945,7 @@ class CameraManager(BaseDevice):
|
||||
self.logger.error("相机连接已断开,读取失败")
|
||||
return False
|
||||
|
||||
self.logger.info("相机硬件连接正常")
|
||||
# self.logger.info("相机硬件连接正常")
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
|
||||
@ -86,7 +86,8 @@ class AppServer:
|
||||
self.config_manager = None
|
||||
self.device_coordinator = None
|
||||
self.device_managers = {
|
||||
'camera': None,
|
||||
'camera1': None,
|
||||
'camera2': None,
|
||||
'femtobolt': None,
|
||||
'imu': None,
|
||||
'pressure': None,
|
||||
@ -167,7 +168,7 @@ class AppServer:
|
||||
self.config.read(config_path, encoding='utf-8')
|
||||
camera1_index = self.config.get('CAMERA1', 'device_index', fallback=None)
|
||||
camera2_index = self.config.get('CAMERA2', 'device_index', fallback=None)
|
||||
print(f"相机1设备号: {camera1_index}, 相机2设备号: {camera2_index}")
|
||||
|
||||
|
||||
def init_app(self):
|
||||
"""初始化应用组件"""
|
||||
@ -226,9 +227,6 @@ class AppServer:
|
||||
# 初始化设备协调器(统一管理所有设备)
|
||||
self.logger.info('正在初始化设备协调器...')
|
||||
self.device_coordinator = DeviceCoordinator(self.socketio)
|
||||
# 设置状态变化回调
|
||||
self.device_coordinator.set_status_change_callback(self._on_device_status_change)
|
||||
# 设备初始化现在延迟到用户登录成功后进行,加快启动速度
|
||||
|
||||
# 初始化录制管理器
|
||||
self.logger.info('正在初始化录制管理器...')
|
||||
@ -1876,7 +1874,23 @@ class AppServer:
|
||||
emit('status', {'message': '设备命名空间连接成功'}, namespace='/devices')
|
||||
|
||||
# 连接时发送当前所有设备的状态
|
||||
self.broadcast_all_device_status()
|
||||
try:
|
||||
if self.device_coordinator and getattr(self.device_coordinator, 'is_initialized', False):
|
||||
self.broadcast_all_device_status()
|
||||
else:
|
||||
def _delayed_broadcast():
|
||||
start_ts = time.time()
|
||||
while self.device_coordinator and not getattr(self.device_coordinator, 'is_initialized', False):
|
||||
if time.time() - start_ts > 15:
|
||||
return
|
||||
time.sleep(0.2)
|
||||
try:
|
||||
self.broadcast_all_device_status()
|
||||
except Exception:
|
||||
pass
|
||||
threading.Thread(target=_delayed_broadcast, daemon=True).start()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
@self.socketio.on('disconnect', namespace='/devices')
|
||||
def handle_devices_disconnect():
|
||||
@ -1941,7 +1955,7 @@ class AppServer:
|
||||
"""重启指定类型的设备
|
||||
|
||||
Args:
|
||||
device_type (str): 设备类型 (camera, imu, pressure, femtobolt)
|
||||
device_type (str): 设备类型 (camera1, camera2, femtobolt, imu, pressure, remote)
|
||||
"""
|
||||
if not self.device_coordinator:
|
||||
self.logger.error('设备协调器未初始化,无法重启设备')
|
||||
@ -1994,6 +2008,11 @@ class AppServer:
|
||||
return
|
||||
|
||||
try:
|
||||
if self.device_coordinator and not getattr(self.device_coordinator, 'is_initialized', False):
|
||||
self._initialize_devices()
|
||||
if self.device_coordinator:
|
||||
self.device_managers = self.device_coordinator.get_device_managers()
|
||||
|
||||
self.logger.info('开始设备数据推送...')
|
||||
self.is_pushing_data = True
|
||||
|
||||
|
||||
@ -15,6 +15,19 @@ ipcMain.handle('generate-report-pdf', async (event, payload) => {
|
||||
const win = BrowserWindow.fromWebContents(event.sender);
|
||||
if (!win) throw new Error('窗口未找到');
|
||||
|
||||
let prevWinBg = null;
|
||||
try {
|
||||
if (typeof win.getBackgroundColor === 'function') {
|
||||
prevWinBg = win.getBackgroundColor();
|
||||
}
|
||||
if (typeof win.setBackgroundColor === 'function') {
|
||||
win.setBackgroundColor('#FFFFFFFF');
|
||||
}
|
||||
if (win.webContents && typeof win.webContents.setBackgroundColor === 'function') {
|
||||
win.webContents.setBackgroundColor('#FFFFFFFF');
|
||||
}
|
||||
} catch (e) {}
|
||||
|
||||
// 1. 准备打印环境:克隆节点到独立的打印容器,确保流式布局
|
||||
await win.webContents.executeJavaScript(`
|
||||
(function(){
|
||||
@ -61,18 +74,24 @@ ipcMain.handle('generate-report-pdf', async (event, payload) => {
|
||||
style.id = 'print-style-override';
|
||||
style.innerHTML = \`
|
||||
@media print {
|
||||
html, body {
|
||||
background: #ffffff !important;
|
||||
margin: 0 !important;
|
||||
padding: 0 !important;
|
||||
-webkit-print-color-adjust: exact;
|
||||
print-color-adjust: exact;
|
||||
}
|
||||
body > *:not(#electron-print-container) {
|
||||
display: none !important;
|
||||
}
|
||||
#electron-print-container {
|
||||
display: block !important;
|
||||
background: #ffffff !important;
|
||||
}
|
||||
}
|
||||
\`;
|
||||
document.head.appendChild(style);
|
||||
|
||||
document.body.classList.add('print-mode');
|
||||
|
||||
return true;
|
||||
})()
|
||||
`);
|
||||
@ -86,7 +105,7 @@ ipcMain.handle('generate-report-pdf', async (event, payload) => {
|
||||
displayHeaderFooter: true, // 启用页眉页脚
|
||||
headerTemplate: '<div></div>', // 空页眉
|
||||
footerTemplate: `
|
||||
<div style="width: 100%; text-align: center; font-size: 10px; font-family: 'Microsoft YaHei', sans-serif; padding-top: 5px; padding-bottom: 5px;">
|
||||
<div style="width: 100%; text-align: center; font-size: 10px; font-family: 'Microsoft YaHei', sans-serif; padding-top: 5px; padding-bottom: 5px; background: #ffffff;">
|
||||
第 <span class="pageNumber"></span> 页 / 共 <span class="totalPages"></span> 页
|
||||
</div>
|
||||
`
|
||||
@ -98,10 +117,19 @@ ipcMain.handle('generate-report-pdf', async (event, payload) => {
|
||||
(function(){
|
||||
const container = document.getElementById('electron-print-container');
|
||||
if (container) container.remove();
|
||||
document.body.classList.remove('print-mode');
|
||||
const style = document.getElementById('print-style-override');
|
||||
if (style) style.remove();
|
||||
return true;
|
||||
})()
|
||||
`);
|
||||
try {
|
||||
if (prevWinBg && typeof win.setBackgroundColor === 'function') {
|
||||
win.setBackgroundColor(prevWinBg);
|
||||
}
|
||||
if (prevWinBg && win.webContents && typeof win.webContents.setBackgroundColor === 'function') {
|
||||
win.webContents.setBackgroundColor(prevWinBg);
|
||||
}
|
||||
} catch (e) {}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
BIN
frontend/src/renderer/src/report_212121965.pdf
Normal file
BIN
frontend/src/renderer/src/report_212121965.pdf
Normal file
Binary file not shown.
@ -25,7 +25,7 @@ api.interceptors.request.use(
|
||||
}
|
||||
|
||||
// 添加认证token
|
||||
const token = localStorage.getItem('authToken')
|
||||
const token = sessionStorage.getItem('authToken')
|
||||
if (token) {
|
||||
config.headers['Authorization'] = `Bearer ${token}`
|
||||
}
|
||||
|
||||
@ -13,8 +13,8 @@
|
||||
justify-content: start;">
|
||||
<div v-for="(item, index) in useImgList" :key="index"
|
||||
class="PhotoAlbum-imgbox">
|
||||
<div class="PhotoAlbum-imgactive" @click="clickImg(item,index)">
|
||||
<img v-if="item.type == 'data'" :src="BACKEND_URL+'/' + item.screen_image" alt="" style="width: 100%;height: 100%;">
|
||||
<div class="PhotoAlbum-imgactive" >
|
||||
<img v-if="item.type == 'data'" :src="BACKEND_URL+'/' + item.screen_image" alt="" style="width: 100%;height: 100%;" @click="clickImg(item,index)">
|
||||
<video v-else-if="item.type == 'video'" :src="item.screen_video ? BACKEND_URL+'/' + item.screen_video.replace(/\\/g, '/') : ''" controls width="100%" height="100%">
|
||||
您的浏览器不支持视频播放
|
||||
</video>
|
||||
@ -216,7 +216,7 @@ onMounted(() => {
|
||||
height: calc(100% - 160px);
|
||||
/* background: red; */
|
||||
margin-top: 20px;
|
||||
padding:0px 52px;
|
||||
padding:0px 48px;
|
||||
display: flex;
|
||||
flex-wrap:wrap ;
|
||||
align-content: flex-start;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user