检测页面性能测试
This commit is contained in:
parent
0b1af5bc78
commit
79b8268ff8
Binary file not shown.
@ -50,12 +50,12 @@ synchronized_images_only = False
|
|||||||
|
|
||||||
[DEVICES]
|
[DEVICES]
|
||||||
imu_enabled = True
|
imu_enabled = True
|
||||||
imu_device_type = ble
|
imu_device_type = mock
|
||||||
imu_port = COM9
|
imu_port = COM9
|
||||||
imu_mac_address = ef:3c:1a:0a:fe:02
|
imu_mac_address = ef:3c:1a:0a:fe:02
|
||||||
imu_baudrate = 9600
|
imu_baudrate = 9600
|
||||||
pressure_enabled = True
|
pressure_enabled = True
|
||||||
pressure_device_type = real
|
pressure_device_type = mock
|
||||||
pressure_use_mock = False
|
pressure_use_mock = False
|
||||||
pressure_port = COM5
|
pressure_port = COM5
|
||||||
pressure_baudrate = 115200
|
pressure_baudrate = 115200
|
||||||
|
|||||||
@ -2077,7 +2077,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='0.0.0.0', help='Host address to bind to')
|
parser.add_argument('--host', default='localhost', 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()
|
||||||
|
|||||||
@ -192,7 +192,8 @@ function createWindow() {
|
|||||||
webPreferences: {
|
webPreferences: {
|
||||||
nodeIntegration: false,
|
nodeIntegration: false,
|
||||||
contextIsolation: true,
|
contextIsolation: true,
|
||||||
sandbox: false, // 显式关闭沙盒,避免 preload 加载问题
|
// sandbox: false, // 显式关闭沙盒,避免 preload 加载问题
|
||||||
|
// backgroundThrottling: false,
|
||||||
preload: path.join(__dirname, 'preload.js')
|
preload: path.join(__dirname, 'preload.js')
|
||||||
},
|
},
|
||||||
icon: path.join(__dirname, '../public/logo.png'),
|
icon: path.join(__dirname, '../public/logo.png'),
|
||||||
|
|||||||
@ -2,5 +2,5 @@ const { contextBridge, ipcRenderer } = require('electron');
|
|||||||
|
|
||||||
contextBridge.exposeInMainWorld('electronAPI', {
|
contextBridge.exposeInMainWorld('electronAPI', {
|
||||||
generateReportPdf: (payload) => ipcRenderer.invoke('generate-report-pdf', payload),
|
generateReportPdf: (payload) => ipcRenderer.invoke('generate-report-pdf', payload),
|
||||||
getBackendUrl: () => 'http://localhost:5000'
|
getBackendUrl: () => process.env.BACKEND_URL || 'http://localhost:5000',
|
||||||
});
|
});
|
||||||
|
|||||||
@ -932,7 +932,7 @@ function connectWebSocket() {
|
|||||||
|
|
||||||
// 创建主Socket.IO连接
|
// 创建主Socket.IO连接
|
||||||
socket = io(BACKEND_URL, {
|
socket = io(BACKEND_URL, {
|
||||||
transports: ['websocket', 'polling'], // 只使用polling,与后端保持一致
|
transports: ['websocket'],
|
||||||
timeout: 10000,
|
timeout: 10000,
|
||||||
forceNew: true,
|
forceNew: true,
|
||||||
reconnection: true,
|
reconnection: true,
|
||||||
@ -942,7 +942,7 @@ function connectWebSocket() {
|
|||||||
|
|
||||||
// 创建统一设备命名空间连接
|
// 创建统一设备命名空间连接
|
||||||
devicesSocket = io(BACKEND_URL + '/devices', {
|
devicesSocket = io(BACKEND_URL + '/devices', {
|
||||||
transports: ['websocket', 'polling'], // 只使用polling,与后端保持一致
|
transports: ['websocket'],
|
||||||
timeout: 10000,
|
timeout: 10000,
|
||||||
forceNew: true
|
forceNew: true
|
||||||
})
|
})
|
||||||
@ -995,9 +995,16 @@ function connectWebSocket() {
|
|||||||
devicesSocket.on('connect', () => {
|
devicesSocket.on('connect', () => {
|
||||||
console.log('🔗 设备命名空间连接成功')
|
console.log('🔗 设备命名空间连接成功')
|
||||||
|
|
||||||
// 连接成功后订阅所有设备数据
|
const enabledCameras = (() => {
|
||||||
devicesSocket.emit('subscribe_device', { device_type: 'camera1' })
|
const list = []
|
||||||
devicesSocket.emit('subscribe_device', { device_type: 'camera2' })
|
const idx1 = String((cameraForm.value && cameraForm.value.camera1 && cameraForm.value.camera1.device_index) || '').trim()
|
||||||
|
const idx2 = String((cameraForm.value && cameraForm.value.camera2 && cameraForm.value.camera2.device_index) || '').trim()
|
||||||
|
if (idx1 !== '') list.push('camera1')
|
||||||
|
if (idx2 !== '') list.push('camera2')
|
||||||
|
if (list.length === 0) list.push('camera1')
|
||||||
|
return list
|
||||||
|
})()
|
||||||
|
enabledCameras.forEach(t => devicesSocket.emit('subscribe_device', { device_type: t }))
|
||||||
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' })
|
||||||
@ -1033,9 +1040,9 @@ function connectWebSocket() {
|
|||||||
frameCount++
|
frameCount++
|
||||||
// 区分 camera1 / camera2 帧
|
// 区分 camera1 / camera2 帧
|
||||||
const devId = (data && data.device_id) ? String(data.device_id).toLowerCase() : ''
|
const devId = (data && data.device_id) ? String(data.device_id).toLowerCase() : ''
|
||||||
if (!tempInfo.value.camera_frames) {
|
if (!tempInfo.value.camera_frames) {
|
||||||
tempInfo.value.camera_frames = {}
|
tempInfo.value.camera_frames = {}
|
||||||
}
|
}
|
||||||
if (devId === 'camera1') {
|
if (devId === 'camera1') {
|
||||||
tempInfo.value.camera_frames['camera1'] = data
|
tempInfo.value.camera_frames['camera1'] = data
|
||||||
tempInfo.value.camera1_frame = data
|
tempInfo.value.camera1_frame = data
|
||||||
@ -1080,15 +1087,15 @@ function connectWebSocket() {
|
|||||||
const { device_type, status } = data
|
const { device_type, status } = data
|
||||||
const statusText = status ? '已连接' : '未连接'
|
const statusText = status ? '已连接' : '未连接'
|
||||||
|
|
||||||
switch (device_type) {
|
switch (device_type) {
|
||||||
case 'camera1':
|
case 'camera1':
|
||||||
camera1Status.value = statusText
|
camera1Status.value = statusText
|
||||||
console.log(`📷 相机1状态: ${statusText}`)
|
console.log(`📷 相机1状态: ${statusText}`)
|
||||||
break
|
break
|
||||||
case 'camera2':
|
case 'camera2':
|
||||||
camera2Status.value = statusText
|
camera2Status.value = statusText
|
||||||
console.log(`📷 相机2状态: ${statusText}`)
|
console.log(`📷 相机2状态: ${statusText}`)
|
||||||
break
|
break
|
||||||
case 'femtobolt':
|
case 'femtobolt':
|
||||||
femtoboltStatus.value = statusText
|
femtoboltStatus.value = statusText
|
||||||
console.log(`🔍 深度相机状态: ${statusText}`)
|
console.log(`🔍 深度相机状态: ${statusText}`)
|
||||||
|
|||||||
@ -41,9 +41,9 @@ function initThreeJS() {
|
|||||||
camera.lookAt(0, 0, 0);
|
camera.lookAt(0, 0, 0);
|
||||||
|
|
||||||
// 创建渲染器
|
// 创建渲染器
|
||||||
renderer = new THREE.WebGLRenderer({ antialias: true,alpha: true });
|
renderer = new THREE.WebGLRenderer({ antialias: true, alpha: false, powerPreference: 'high-performance' });
|
||||||
scene.background = null; // 置空场景背景
|
scene.background = null; // 置空场景背景
|
||||||
renderer.setClearColor(0x000000, 0); // 设置透明度为0(完全透明)
|
renderer.setClearColor(0x000000, 0.02);
|
||||||
renderer.setSize(containermodel.offsetWidth, containermodel.offsetHeight);
|
renderer.setSize(containermodel.offsetWidth, containermodel.offsetHeight);
|
||||||
renderer.shadowMap.enabled = true;
|
renderer.shadowMap.enabled = true;
|
||||||
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
|
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
|
||||||
|
|||||||
@ -20,7 +20,7 @@
|
|||||||
import { patientAPI, detectionAPI,historyAPI,getBackendUrl } from '@/services/api.js'
|
import { patientAPI, detectionAPI,historyAPI,getBackendUrl } from '@/services/api.js'
|
||||||
|
|
||||||
import { ref, onMounted } from 'vue'
|
import { ref, onMounted } from 'vue'
|
||||||
import * as pdfjsLib from 'pdfjs-dist'
|
// import * as pdfjsLib from 'pdfjs-dist'
|
||||||
const emit = defineEmits([ 'closeViewPDF' ]);
|
const emit = defineEmits([ 'closeViewPDF' ]);
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
pdfUrl: {
|
pdfUrl: {
|
||||||
@ -32,7 +32,7 @@ const props = defineProps({
|
|||||||
const pdfUrl = ref(props.pdfUrl)
|
const pdfUrl = ref(props.pdfUrl)
|
||||||
const pdfContainer = ref(null) // 容器用于挂载多个 canvas
|
const pdfContainer = ref(null) // 容器用于挂载多个 canvas
|
||||||
// 设置 worker 路径(重要)
|
// 设置 worker 路径(重要)
|
||||||
pdfjsLib.GlobalWorkerOptions.workerSrc = '/pdf.worker.min.js'
|
// pdfjsLib.GlobalWorkerOptions.workerSrc = '/pdf.worker.min.js'
|
||||||
const BACKEND_URL = getBackendUrl()
|
const BACKEND_URL = getBackendUrl()
|
||||||
const pdfCanvas = ref(null)
|
const pdfCanvas = ref(null)
|
||||||
function handleCancel(){
|
function handleCancel(){
|
||||||
@ -66,64 +66,42 @@ const pdfCanvas = ref(null)
|
|||||||
// console.error('Error rendering PDF:', error)
|
// console.error('Error rendering PDF:', error)
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
const renderPDF = async (url) => {
|
// const renderPDF = async (url) => {
|
||||||
try {
|
// try {
|
||||||
// 1️⃣ 加载 PDF 文档
|
// const pdfjsLib = await import('pdfjs-dist/legacy/build/pdf')
|
||||||
const loadingTask = pdfjsLib.getDocument(url)
|
// if (pdfjsLib && pdfjsLib.GlobalWorkerOptions) {
|
||||||
const pdf = await loadingTask.promise
|
// pdfjsLib.GlobalWorkerOptions.workerSrc = 'https://cdn.jsdelivr.net/npm/pdfjs-dist@3.11.174/build/pdf.worker.min.js'
|
||||||
console.log(`PDF loaded: ${pdf.numPages} pages`)
|
// }
|
||||||
|
// const loadingTask = pdfjsLib.getDocument(url)
|
||||||
// 2️⃣ 清空旧内容
|
// const pdf = await loadingTask.promise
|
||||||
if (pdfContainer.value) {
|
// if (pdfContainer.value) {
|
||||||
pdfContainer.value.innerHTML = ''
|
// pdfContainer.value.innerHTML = ''
|
||||||
}
|
// }
|
||||||
|
// const scale = 1.5
|
||||||
const scale = 1.5 // 可根据设备 DPR 动态调整
|
// const pagePromises = []
|
||||||
const pagePromises = []
|
// for (let pageNum = 1; pageNum <= pdf.numPages; pageNum++) {
|
||||||
|
// pagePromises.push(renderPage(pdf, pageNum, scale))
|
||||||
// 3️⃣ 预处理:循环加载每一页(不立即渲染)
|
// }
|
||||||
for (let pageNum = 1; pageNum <= pdf.numPages; pageNum++) {
|
// await Promise.all(pagePromises)
|
||||||
pagePromises.push(renderPage(pdf, pageNum, scale))
|
// } catch (error) {
|
||||||
}
|
// console.error('Error rendering PDF:', error)
|
||||||
|
// }
|
||||||
// 4️⃣ 并行渲染所有页面(注意:大量页面时需节流)
|
// }
|
||||||
await Promise.all(pagePromises)
|
|
||||||
console.log('✅ All PDF pages rendered successfully')
|
|
||||||
} catch (error) {
|
|
||||||
console.error('❌ Error rendering PDF:', error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 单独封装 renderPage 函数便于复用与控制并发
|
// 单独封装 renderPage 函数便于复用与控制并发
|
||||||
const renderPage = async (pdf, pageNum, scale) => {
|
// const renderPage = async (pdf, pageNum, scale) => {
|
||||||
const page = await pdf.getPage(pageNum)
|
// const page = await pdf.getPage(pageNum)
|
||||||
|
// const viewport = page.getViewport({ scale })
|
||||||
// 获取视口(viewport)
|
// const canvas = document.createElement('canvas')
|
||||||
const viewport = page.getViewport({ scale })
|
// const context = canvas.getContext('2d')
|
||||||
|
// canvas.height = viewport.height
|
||||||
// 创建 canvas
|
// canvas.width = viewport.width
|
||||||
const canvas = document.createElement('canvas')
|
// if (pdfContainer.value) {
|
||||||
const context = canvas.getContext('2d')
|
// pdfContainer.value.appendChild(canvas)
|
||||||
canvas.height = viewport.height
|
// }
|
||||||
canvas.width = viewport.width
|
// const renderContext = { canvasContext: context, viewport }
|
||||||
|
// await page.render(renderContext).promise
|
||||||
|
// }
|
||||||
// 添加页码标识(可选)
|
|
||||||
const pageNumberDiv = document.createElement('div')
|
|
||||||
// 插入到容器
|
|
||||||
if (pdfContainer.value) {
|
|
||||||
pdfContainer.value.appendChild(canvas)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 渲染上下文
|
|
||||||
const renderContext = {
|
|
||||||
canvasContext: context,
|
|
||||||
viewport,
|
|
||||||
}
|
|
||||||
|
|
||||||
// 执行渲染
|
|
||||||
await page.render(renderContext).promise
|
|
||||||
}
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
// 替换为你的 PDF 文件路径或 URL
|
// 替换为你的 PDF 文件路径或 URL
|
||||||
// renderPDF(`${BACKEND_URL}/202512070001/20251209141628/report_142802459.pdf`) // 可以是本地文件或远程链接
|
// renderPDF(`${BACKEND_URL}/202512070001/20251209141628/report_142802459.pdf`) // 可以是本地文件或远程链接
|
||||||
|
|||||||
@ -24,7 +24,7 @@ export default defineConfig({
|
|||||||
},
|
},
|
||||||
server: {
|
server: {
|
||||||
port: 3000,
|
port: 3000,
|
||||||
host: '0.0.0.0',
|
host: 'localhost',
|
||||||
// 开发服务器配置
|
// 开发服务器配置
|
||||||
cors: true,
|
cors: true,
|
||||||
strictPort: false
|
strictPort: false
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user