From 8a2319e10871d5d709d36c0febb669a943ad3f58 Mon Sep 17 00:00:00 2001 From: zhaozilong12 <405241463@qq.com> Date: Thu, 21 Aug 2025 17:35:09 +0800 Subject: [PATCH 1/2] =?UTF-8?q?IMU=E6=A0=A1=E5=87=86=E8=A7=92=E5=BA=A6?= =?UTF-8?q?=E5=BD=92=E4=B8=80=E5=8C=96=E5=8A=9F=E8=83=BD=E6=8F=90=E4=BA=A4?= =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 + backend/devices/imu_manager.py | 52 ++++--------- backend/devices/utils/config.ini | 2 +- backend/main.py | 2 +- backend/tests/test111.py | 122 ++++++++++++------------------- backend/tests/test1imu10a.py | 2 +- backend/tests/test44femtobolt.py | 94 ++++++++++++++++++++++++ 7 files changed, 161 insertions(+), 115 deletions(-) create mode 100644 backend/tests/test44femtobolt.py diff --git a/.gitignore b/.gitignore index 1086e3f3..794d571a 100644 --- a/.gitignore +++ b/.gitignore @@ -21420,3 +21420,5 @@ frontend/src/renderer/src/services/api.js frontend/src/renderer/src/services/api.js frontend/src/renderer/src/services/api.js frontend/src/renderer/src/services/api.js +frontend/src/renderer/src/services/api.js +backend/devices/utils/config.ini diff --git a/backend/devices/imu_manager.py b/backend/devices/imu_manager.py index d925bc5e..f24bab8f 100644 --- a/backend/devices/imu_manager.py +++ b/backend/devices/imu_manager.py @@ -67,7 +67,6 @@ class RealIMUDevice: if 'head_pose_offset' in calibration: self.head_pose_offset = calibration['head_pose_offset'] logger.debug(f'应用IMU校准数据: {self.head_pose_offset}') - def apply_calibration(self, raw_data: Dict[str, Any]) -> Dict[str, Any]: """应用校准:将当前姿态减去初始偏移,得到相对于初始姿态的变化量""" if not raw_data or 'head_pose' not in raw_data: @@ -76,15 +75,14 @@ class RealIMUDevice: # 应用校准偏移 calibrated_data = raw_data.copy() head_pose = raw_data['head_pose'].copy() - + angle=head_pose['rotation'] - self.head_pose_offset['rotation'] # 减去基准值(零点偏移) - head_pose['rotation'] = head_pose['rotation'] - self.head_pose_offset['rotation'] + head_pose['rotation'] = ((angle + 180) % 360) - 180 head_pose['tilt'] = head_pose['tilt'] - self.head_pose_offset['tilt'] head_pose['pitch'] = head_pose['pitch'] - self.head_pose_offset['pitch'] calibrated_data['head_pose'] = head_pose return calibrated_data - @staticmethod def _checksum(data: bytes) -> int: return sum(data[:-1]) & 0xFF @@ -115,7 +113,7 @@ class RealIMUDevice: 'yaw': yaw, 'temperature': temp } - # logger.debug(f'解析姿态角包: roll={roll}, pitch={pitch}, yaw={yaw}, temp={temp}') + # print(f'解析姿态角包: roll={roll}, pitch={pitch}, yaw={yaw}, temp={temp}') return self.last_data else: # logger.debug(f'忽略的数据包类型: 0x{packet_type:02X}') @@ -356,37 +354,16 @@ class IMUManager(BaseDevice): self.logger.info('开始IMU快速零点校准...') - # 收集校准样本 - calibration_samples = [] - sample_count = 50 # 减少样本数量以加快校准速度 + # 直接读取一次原始数据作为校准偏移量 + raw_data = self.imu_device.read_data(apply_calibration=False) + if not raw_data or 'head_pose' not in raw_data: + return {'status': 'error', 'error': '无法读取IMU原始数据'} - for i in range(sample_count): - try: - # 读取原始数据(不应用校准) - raw_data = self.imu_device.read_data(apply_calibration=False) - if raw_data and 'head_pose' in raw_data: - calibration_samples.append(raw_data['head_pose']) - time.sleep(0.02) # 20ms间隔 - except Exception as e: - self.logger.warning(f'校准样本采集失败: {e}') - continue - - if len(calibration_samples) < sample_count * 0.7: - return { - 'status': 'error', - 'error': f'校准样本不足: {len(calibration_samples)}/{sample_count}' - } - - # 计算平均值作为零点偏移 - rotation_sum = sum(sample['rotation'] for sample in calibration_samples) - tilt_sum = sum(sample['tilt'] for sample in calibration_samples) - pitch_sum = sum(sample['pitch'] for sample in calibration_samples) - - count = len(calibration_samples) + # 使用当前姿态作为零点偏移 self.head_pose_offset = { - 'rotation': rotation_sum / count, - 'tilt': tilt_sum / count, - 'pitch': pitch_sum / count + 'rotation': raw_data['head_pose']['rotation'], + 'tilt': raw_data['head_pose']['tilt'], + 'pitch': raw_data['head_pose']['pitch'] } # 应用校准到设备 @@ -396,8 +373,7 @@ class IMUManager(BaseDevice): self.logger.info(f'IMU快速校准完成: {self.head_pose_offset}') return { 'status': 'success', - 'head_pose_offset': self.head_pose_offset, - 'samples_used': count + 'head_pose_offset': self.head_pose_offset } except Exception as e: @@ -504,8 +480,8 @@ class IMUManager(BaseDevice): if data: # 缓存数据 - self.data_buffer.append(data) - self.last_valid_data = data + # self.data_buffer.append(data) + # self.last_valid_data = data # 发送数据到前端 if self._socketio: diff --git a/backend/devices/utils/config.ini b/backend/devices/utils/config.ini index 5cf905ba..215581bd 100644 --- a/backend/devices/utils/config.ini +++ b/backend/devices/utils/config.ini @@ -29,7 +29,7 @@ depth_range_max = 1700 [DEVICES] imu_device_type = real -imu_port = COM3 +imu_port = COM8 imu_baudrate = 9600 pressure_device_type = real pressure_use_mock = False diff --git a/backend/main.py b/backend/main.py index 7fcbf172..e7ab525b 100644 --- a/backend/main.py +++ b/backend/main.py @@ -947,7 +947,7 @@ class AppServer: self.logger.error(f'校准设备失败: {e}') return jsonify({'success': False, 'error': str(e)}), 500 - @self.app.route('/api/devices/imu/calibrate', methods=['POST']) + @self.app.route('/api/devices/calibrate/imu', methods=['POST']) def calibrate_imu(): """校准IMU""" try: diff --git a/backend/tests/test111.py b/backend/tests/test111.py index 4680a9b1..cdb324bb 100644 --- a/backend/tests/test111.py +++ b/backend/tests/test111.py @@ -1,79 +1,53 @@ -import ctypes -import time -import numpy as np +from PIL import Image +import colorsys -# === DLL 加载 === -dll = ctypes.WinDLL(r"D:\BodyBalanceEvaluation\backend\dll\smitsense\SMiTSenseUsbWrapper.dll") +def get_unique_colors(image_path): + img = Image.open(image_path).convert("RGB") + unique_colors = list(set(img.getdata())) + return unique_colors -# === DLL 函数声明 === -dll.SMiTSenseUsb_Init.argtypes = [ctypes.c_int] -dll.SMiTSenseUsb_Init.restype = ctypes.c_int +def get_representative_colors(colors, n=12): + # 按亮度排序并均匀抽取 + def brightness(rgb): + r, g, b = rgb + return 0.2126*r + 0.7152*g + 0.0722*b + + colors.sort(key=brightness) + total = len(colors) + if total <= n: + return colors + step = total / n + return [colors[int(i*step)] for i in range(n)] -dll.SMiTSenseUsb_ScanDevices.argtypes = [ctypes.POINTER(ctypes.c_int)] -dll.SMiTSenseUsb_ScanDevices.restype = ctypes.c_int +def sort_colors_by_hue(colors): + # 转为 HSV,并按色相排序 + def rgb_to_hue(rgb): + r, g, b = [x/255.0 for x in rgb] + h, s, v = colorsys.rgb_to_hsv(r, g, b) + return h + return sorted(colors, key=rgb_to_hue) -dll.SMiTSenseUsb_OpenAndStart.argtypes = [ - ctypes.c_int, - ctypes.POINTER(ctypes.c_uint16), - ctypes.POINTER(ctypes.c_uint16) -] -dll.SMiTSenseUsb_OpenAndStart.restype = ctypes.c_int +def show_color_preview(colors, width=600, height_per_color=50): + n = len(colors) + height = n * height_per_color + img = Image.new("RGB", (width, height)) + + for i, color in enumerate(colors): + for y in range(i*height_per_color, (i+1)*height_per_color): + for x in range(width): + img.putpixel((x, y), color) + + img.show() -dll.SMiTSenseUsb_GetLatestFrame.argtypes = [ - ctypes.POINTER(ctypes.c_uint16), - ctypes.c_int -] -dll.SMiTSenseUsb_GetLatestFrame.restype = ctypes.c_int - -dll.SMiTSenseUsb_StopAndClose.argtypes = [] -dll.SMiTSenseUsb_StopAndClose.restype = ctypes.c_int - -# === 初始化设备 === -ret = dll.SMiTSenseUsb_Init(0) -if ret != 0: - raise RuntimeError(f"Init failed: {ret}") - -count = ctypes.c_int() -ret = dll.SMiTSenseUsb_ScanDevices(ctypes.byref(count)) -if ret != 0 or count.value == 0: - raise RuntimeError("No devices found") - -# 打开设备 -rows = ctypes.c_uint16() -cols = ctypes.c_uint16() -ret = dll.SMiTSenseUsb_OpenAndStart(0, ctypes.byref(rows), ctypes.byref(cols)) -if ret != 0: - raise RuntimeError("OpenAndStart failed") - -rows_val, cols_val = rows.value, cols.value -frame_size = rows_val * cols_val -buf_type = ctypes.c_uint16 * frame_size -buf = buf_type() - -# 创建一个 NumPy 数组视图,复用内存 -data_array = np.ctypeslib.as_array(buf).reshape((rows_val, cols_val)) - -print(f"设备已打开: {rows_val}x{cols_val}") - -try: - while True: - ret = dll.SMiTSenseUsb_GetLatestFrame(buf, frame_size) - time.sleep(1) - # while True: - # ret = dll.SMiTSenseUsb_GetLatestFrame(buf, frame_size) - # if ret == 0: - # # data_array 已经复用缓冲区内存,每次直接访问即可 - # # 例如打印最大值和前5行前5列的数据 - # print("最大压力值:", data_array.max()) - # print("前5x5数据:\n", data_array[:5, :5]) - # else: - # print("读取数据帧失败") - - # time.sleep(1) # 每秒读取一帧 - -except KeyboardInterrupt: - print("退出中...") - -finally: - dll.SMiTSenseUsb_StopAndClose() - print("设备已关闭") +if __name__ == "__main__": + image_path = r"D:\项目资料\技术文档资料\中康项目资料\11.png" + + colors = get_unique_colors(image_path) + rep_colors = get_representative_colors(colors, 12) + sorted_colors = sort_colors_by_hue(rep_colors) + + print("12 个代表性颜色(按彩虹顺序):") + for i, color in enumerate(sorted_colors, 1): + print(f"{i}: {color}") + + show_color_preview(sorted_colors) diff --git a/backend/tests/test1imu10a.py b/backend/tests/test1imu10a.py index 231c172b..c316509d 100644 --- a/backend/tests/test1imu10a.py +++ b/backend/tests/test1imu10a.py @@ -59,7 +59,7 @@ def parse_packet(data): # else: # return f"未知包类型: {packet_type:#04x}" -def read_imu(port='COM6', baudrate=9600): +def read_imu(port='COM8', baudrate=9600): ser = serial.Serial(port, baudrate, timeout=1) buffer = bytearray() diff --git a/backend/tests/test44femtobolt.py b/backend/tests/test44femtobolt.py new file mode 100644 index 00000000..af8b7b91 --- /dev/null +++ b/backend/tests/test44femtobolt.py @@ -0,0 +1,94 @@ +import os +import numpy as np +import matplotlib.pyplot as plt +from matplotlib.colors import ListedColormap +import pykinect_azure as pykinect + + +class FemtoBoltContourViewer: + def __init__(self, depth_min=900, depth_max=1100): + self.depth_min = depth_min + self.depth_max = depth_max + + # 自定义离散彩虹色,层次明显 + colors = [ + 'darkblue', 'blue', 'cyan', 'lime', 'yellow', + 'orange', 'red', 'darkred' + ] + self.cmap = ListedColormap(colors) + + self.device_handle = None + self.pykinect = None + self.config = None + + def _load_sdk(self): + """加载并初始化 FemtoBolt SDK""" + base_dir = os.path.dirname(os.path.abspath(__file__)) + dll_path = os.path.join(base_dir, "..", "dll", "femtobolt", "bin", "k4a.dll") + self.pykinect = pykinect + self.pykinect.initialize_libraries(track_body=False, module_k4a_path=dll_path) + + def _configure_device(self): + """配置 FemtoBolt 深度相机""" + self.config = self.pykinect.default_configuration + self.config.depth_mode = self.pykinect.K4A_DEPTH_MODE_NFOV_UNBINNED + self.config.camera_fps = self.pykinect.K4A_FRAMES_PER_SECOND_15 + self.config.synchronized_images_only = False + self.config.color_resolution = 0 + self.device_handle = self.pykinect.start_device(config=self.config) + + def run(self): + self._load_sdk() + self._configure_device() + + plt.ion() # 打开交互模式 + fig, ax = plt.subplots(figsize=(7, 7)) + print("FemtoBolt 深度相机启动成功,关闭窗口或 Ctrl+C 退出") + + # 设置离散等高线层次 + levels = np.linspace(self.depth_min, self.depth_max, len(self.cmap.colors) + 1) + + try: + while plt.fignum_exists(fig.number): # 窗口存在才继续 + capture = self.device_handle.update() + if capture is None: + continue + ret, depth_image = capture.get_depth_image() + if not ret or depth_image is None: + continue + + depth = depth_image.astype(np.uint16) + # 限制深度范围 + depth[depth > self.depth_max] = 0 + depth[depth < self.depth_min] = 0 + depth = depth[0:350, 0:350] + + # 屏蔽无效值 + depth_masked = np.ma.masked_equal(depth, 0) + + # 背景灰色 + background = np.ones_like(depth) * 0.5 + + # 绘制 + ax.clear() + ax.imshow(background, origin='lower', cmap='gray', alpha=0.3) + ax.grid(True, which='both', axis='both', color='white', + linestyle='--', linewidth=1, zorder=0) + ax.contourf(depth_masked, levels=levels, cmap=self.cmap, + vmin=self.depth_min, vmax=self.depth_max, + origin='upper', zorder=2) + + plt.pause(0.05) + + except KeyboardInterrupt: + print("检测到退出信号,结束程序") + finally: + if self.device_handle: + self.device_handle.stop() + self.device_handle.close() + plt.close(fig) + + +if __name__ == "__main__": + viewer = FemtoBoltContourViewer(depth_min=900, depth_max=1100) + viewer.run() From 6d4c22d3f4393d074ee6ac21d8e43eb9b4467347 Mon Sep 17 00:00:00 2001 From: limengnan <420004014@qq.com> Date: Thu, 21 Aug 2025 18:33:16 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=AE=9E=E6=97=B6?= =?UTF-8?q?=E6=A3=80=E6=9F=A5=E4=BF=9D=E5=AD=98=E6=96=B9=E6=B3=95=EF=BC=8C?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=88=A0=E9=99=A4=E5=8E=86=E5=8F=B2=E6=A3=80?= =?UTF-8?q?=E6=9F=A5=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/renderer/src/services/api.js | 18 ++- frontend/src/renderer/src/views/Detection.vue | 46 ++++--- .../src/renderer/src/views/PatientProfile.vue | 113 +++++++++--------- 3 files changed, 97 insertions(+), 80 deletions(-) diff --git a/frontend/src/renderer/src/services/api.js b/frontend/src/renderer/src/services/api.js index 1c471ff8..dc470627 100644 --- a/frontend/src/renderer/src/services/api.js +++ b/frontend/src/renderer/src/services/api.js @@ -13,7 +13,7 @@ api.interceptors.request.use( if (window.electronAPI) { config.baseURL = window.electronAPI.getBackendUrl() } else { - config.baseURL = 'http://192.168.1.173:5000' + config.baseURL = 'http://192.168.1.58:5000' } // 只为需要发送数据的请求设置Content-Type @@ -610,16 +610,22 @@ export const historyAPI = { // 删除检测数据记录 detectionDelById(id) { return api.delete(`/api/detection/data/${id}`, {}) + }, + // 删除检测会话及其相关的检测数据 + sessionsDelById(id) { + return api.delete(`api/detection/sessions/${id}`, {}) }, // 获取检测会话历史 sessionById(id) { return api.get(`/api/history/sessions/${id}`) }, - // detectionLatestById(id) { - // return api.get(`/api/detection/data/detail/${id}`) - // }, - detectionLatestById(id) { + //获取最新的检测数据 + detectionLatestList(id) { + return api.get(`/api/detection/data/detail/${id}/latest`) + }, + //根据主键ID查询检测数据详情 + detectionById(id) { return api.get(`/api/detection/data/detail/${id}`) }, @@ -631,7 +637,7 @@ export const getBackendUrl = () => { if (window.electronAPI) { return window.electronAPI.getBackendUrl() } else { - return 'http://192.168.1.173:5000' + return 'http://192.168.1.58:5000' } } diff --git a/frontend/src/renderer/src/views/Detection.vue b/frontend/src/renderer/src/views/Detection.vue index 8105a67f..dc0d4bc0 100644 --- a/frontend/src/renderer/src/views/Detection.vue +++ b/frontend/src/renderer/src/views/Detection.vue @@ -64,7 +64,7 @@
{{ femtoboltStatus }}
-
+
深度相机视频流 @@ -323,7 +323,7 @@
-
+
@@ -334,9 +334,12 @@
{{ cameraStatus }}
+
+ +
- +
@@ -569,6 +572,9 @@ const dataCollectionLoading = ref(false) const isRecording = ref(false) const cameraDialogVisible =ref(false) // 设置相机参数弹框 +const wholeBodyRef = ref(null) // 身体姿态ref +const videoImgRef =ref(null) // 视频流图片ref + // 录像相关变量 let mediaRecorder = null let recordedChunks = [] @@ -908,6 +914,7 @@ const editPatient = () => { } dialogVisible.value = true } +const tempInfo = ref({}) // WebSocket连接函数 function connectWebSocket() { try { @@ -1037,25 +1044,29 @@ function connectWebSocket() { // 监听各设备数据事件 devicesSocket.on('camera_frame', (data) => { frameCount++ + tempInfo.value.camera_frame = data displayFrame(data.image) }) - devicesSocket.on('video_frame', (data) => { - frameCount++ - displayFrame(data.image) - }) + // devicesSocket.on('video_frame', (data) => { + // frameCount++ + // displayFrame(data.image) + // }) devicesSocket.on('femtobolt_frame', (data) => { + tempInfo.value.femtobolt_frame = data displayDepthCameraFrame(data.depth_image || data.image) }) - devicesSocket.on('depth_camera_frame', (data) => { - displayDepthCameraFrame(data.depth_image || data.image) - }) + // devicesSocket.on('depth_camera_frame', (data) => { + // displayDepthCameraFrame(data.depth_image || data.image) + // }) devicesSocket.on('imu_data', (data) => { + tempInfo.value.imu_data = data handleIMUData(data) }) devicesSocket.on('pressure_data', (data) => { + tempInfo.value.pressure_data = data handlePressureData(data) }) @@ -1634,11 +1645,12 @@ async function saveDetectionData() { patientId: patientInfo.value.id, patientName: patientInfo.value.name, sessionId: patientInfo.value.sessionId, - head_pose: {}, - body_pose: {}, - foot_data: {} + head_data: imu_data, + body_data: femtobolt_frame, + foot_data: pressure_data, + camera_data: camera_frame, }) - + tempInfo.value // 显示成功消息和文件路径 ElMessage.success({ message: `截图保存成功!`, @@ -2286,6 +2298,9 @@ const getDevicesInit = async () => { } onMounted(() => { + // wholeBodyRef.value + console.log(wholeBodyRef.value.getBoundingClientRect()) + console.log(videoImgRef.value.getBoundingClientRect()) // 加载患者信息 loadPatientInfo() @@ -2301,6 +2316,7 @@ onMounted(() => { }) onUnmounted(() => { + if (timerId.value) { clearInterval(timerId.value); } diff --git a/frontend/src/renderer/src/views/PatientProfile.vue b/frontend/src/renderer/src/views/PatientProfile.vue index 4afef145..136e182b 100644 --- a/frontend/src/renderer/src/views/PatientProfile.vue +++ b/frontend/src/renderer/src/views/PatientProfile.vue @@ -26,7 +26,7 @@
{{ item.created_at }}
最近会诊
{{ getDayNum(item.created_at,index) }}
- + 删除
@@ -75,11 +75,11 @@
-
+
- +
@@ -435,6 +435,10 @@ function getDayNum(date2,index){ // 转换为天数 const daysDiff = Math.floor(timeDiff / (1000 * 3600 * 24)); + + if(daysDiff == 0){ + return "当天"; + } return daysDiff + "天"; } @@ -544,6 +548,7 @@ const deleteScreenshot = async (screenshot) => { } } + const exportReport = async (record) => { try { ElMessage.info('正在生成报告...') @@ -712,8 +717,7 @@ function editClick(row,index) { } //数据详情 function patientdetails(row) { - // historyAPI.sessionById(row.id).then(res => { - // }) + detectionById(row) detailsDialogVisible.value = true } async function handleDiagnosticInfo(status) { @@ -776,8 +780,42 @@ const playNewVideo = () => { videoPlayerRef.value[index].play() } } +function detectionById(row) { + historyAPI.detectionById(row.id).then((response)=>{ + if(response.success){ + debugger + } + }).catch(()=>{ -const deleteClick = async (row) => { + }) +} +const deleteClick = async (row,row2) => { + detectionLatestList(row.id) + ElMessageBox.confirm( + '确定义删除此条数据?', + '提示', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning', + } + ).then(() => { + historyAPI.detectionDelById(row2.id).then((response)=>{ + if(response.success){ + ElMessage.success({ + message: response.message, + duration: 5000 + }); + sessionsInit() + // detectionLatestList(row.id) + } + }).catch(()=>{ + }) + }) +} + + +const sessionsDelById = async (row) => { ElMessageBox.confirm( '确定义删除此条数据?', @@ -788,7 +826,7 @@ const deleteClick = async (row) => { type: 'warning', } ).then(() => { - historyAPI.detectionDelById(row.id).then((response)=>{ + historyAPI.sessionsDelById(row.id).then((response)=>{ if(response.success){ ElMessage.success({ message: response.message, @@ -796,63 +834,20 @@ const deleteClick = async (row) => { }); sessionsInit() } - - }).catch(()=>{ - }) }) +} - - // try { - // // 检查是否有活跃的会话ID - // if (!row.id) { - // throw new Error('缺少会话Id'); +const detectionLatestList = async(id)=>{ + const response = await historyAPI.detectionLatestList(id) + console.log(response) + // historyAPI.detectionLatestList(id).then((response)=>{ + // if(response.success){ + // console.log(response) // } - - // // 显示确认对话框 - // await ElMessageBox.confirm( - // '确定要删除此条数据?', - // '警告', - // { - // confirmButtonText: '确定', - // cancelButtonText: '取消', - // type: 'warning', - // } - // ); - - // // 调用后端API删除数据 - // const response = await fetch(`${BACKEND_URL}/api/detection/data/${row.id}`, { - // method: 'DELETE', - // headers: { - // 'Content-Type': 'application/json' - // }, - // }); - - // if (!response.ok) { - // throw new Error(`HTTP ${response.status}: ${response.statusText}`); - // } - - // const result = await response.json(); - // if (result.success) { - // ElMessage.success({ - // message: '删除成功', - // duration: 5000 - // }); - // } else { - // throw new Error(result.message || '删除失败'); - // } - // } catch (error) { - // // 如果是用户取消操作,不显示错误 - // if (error === 'cancel' || error === 'close') { - // return; - // } - - // ElMessage.error({ - // message: error.message || '删除过程中发生错误', - // duration: 5000 - // }); - // } + // }).catch(()=>{ + // }) } // // 其他控制方法 // const togglePlayPause = () => {