From 4a377be983ccee358ae0d57253dd8b15c9342ca6 Mon Sep 17 00:00:00 2001 From: imeepos Date: Sun, 13 Jul 2025 22:12:15 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=AE=9E=E7=8E=B0MaterialCard=E4=B8=AD?= =?UTF-8?q?=E7=9A=84=E6=89=93=E5=BC=80=E6=96=87=E4=BB=B6=E4=BD=8D=E7=BD=AE?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 问题分析: MaterialCard组件中的openFileLocation函数只是打印路径, 没有实际实现打开文件位置的功能,导致点击分片文件无响应。 修复内容: 1. 实现openFileLocation函数: - 使用revealItemInDir在文件管理器中显示并选中文件 - 添加路径标准化处理,移除Windows长路径前缀 - 提供备用方案:如果revealItemInDir失败,尝试openPath打开目录 2. 错误处理优化: - 双重备用机制确保功能可用性 - 用户友好的错误提示 - 详细的调试日志 3. TypeScript类型修复: - 添加MaterialSegment类型导入到materialStore - 在MaterialState接口中添加getMaterialSegments方法定义 - 清理未使用的导入项 4. 技术实现: ` ypescript // 主要方法:在文件管理器中显示文件 await revealItemInDir(normalizedPath); // 备用方法:打开文件所在目录 await openPath(normalizedDirPath); ` 功能特点: 点击分片文件的外链图标可以打开文件位置 自动处理Windows长路径格式 双重备用机制确保兼容性 用户友好的错误处理 现在用户可以方便地通过点击分片列表中的外链图标来打开文件位置了! --- apps/desktop/src/components/MaterialCard.tsx | 41 ++++++++++++++++++-- apps/desktop/src/pages/ProjectDetails.tsx | 4 +- apps/desktop/src/store/materialStore.ts | 11 +++--- 3 files changed, 45 insertions(+), 11 deletions(-) diff --git a/apps/desktop/src/components/MaterialCard.tsx b/apps/desktop/src/components/MaterialCard.tsx index ee9cf3a..1bd5ac1 100644 --- a/apps/desktop/src/components/MaterialCard.tsx +++ b/apps/desktop/src/components/MaterialCard.tsx @@ -1,4 +1,4 @@ -import React, { useState, useEffect } from 'react'; +import React, { useState } from 'react'; import { FileVideo, FileAudio, FileImage, File, Clock, ExternalLink, ChevronDown, ChevronUp } from 'lucide-react'; import { Material, MaterialSegment } from '../types/material'; import { useMaterialStore } from '../store/materialStore'; @@ -74,9 +74,42 @@ export const MaterialCard: React.FC = ({ material }) => { }; // 打开文件所在文件夹 - const openFileLocation = (filePath: string) => { - // 这里可以调用 Tauri 的 API 来打开文件夹 - console.log('打开文件位置:', filePath); + const openFileLocation = async (filePath: string) => { + try { + const { revealItemInDir } = await import('@tauri-apps/plugin-opener'); + + // 处理 Windows 路径格式,移除 \\?\ 前缀 + let normalizedPath = filePath; + if (normalizedPath.startsWith('\\\\?\\')) { + normalizedPath = normalizedPath.substring(4); + } + + console.log('打开文件位置:', normalizedPath); + await revealItemInDir(normalizedPath); + } catch (error) { + console.error('打开文件位置失败:', error); + + // 如果 revealItemInDir 失败,尝试打开文件所在目录 + try { + const { openPath } = await import('@tauri-apps/plugin-opener'); + + // 获取文件所在目录 + const pathParts = filePath.split(/[/\\]/); + pathParts.pop(); // 移除文件名 + const dirPath = pathParts.join('\\'); + + let normalizedDirPath = dirPath; + if (normalizedDirPath.startsWith('\\\\?\\')) { + normalizedDirPath = normalizedDirPath.substring(4); + } + + console.log('尝试打开目录:', normalizedDirPath); + await openPath(normalizedDirPath); + } catch (fallbackError) { + console.error('备用方法也失败:', fallbackError); + alert('无法打开文件位置,请检查文件是否存在'); + } + } }; return ( diff --git a/apps/desktop/src/pages/ProjectDetails.tsx b/apps/desktop/src/pages/ProjectDetails.tsx index 1ceffe2..e5a0a81 100644 --- a/apps/desktop/src/pages/ProjectDetails.tsx +++ b/apps/desktop/src/pages/ProjectDetails.tsx @@ -1,10 +1,10 @@ import React, { useEffect, useState } from 'react'; import { useParams, useNavigate } from 'react-router-dom'; -import { ArrowLeft, FolderOpen, Calendar, Settings, Upload, FileVideo, Clock, ExternalLink } from 'lucide-react'; +import { ArrowLeft, FolderOpen, Calendar, Settings, Upload } from 'lucide-react'; import { useProjectStore } from '../store/projectStore'; import { useMaterialStore } from '../store/materialStore'; import { Project } from '../types/project'; -import { MaterialImportResult, Material, MaterialSegment } from '../types/material'; +import { MaterialImportResult } from '../types/material'; import { LoadingSpinner } from '../components/LoadingSpinner'; import { ErrorMessage } from '../components/ErrorMessage'; import { MaterialImportDialog } from '../components/MaterialImportDialog'; diff --git a/apps/desktop/src/store/materialStore.ts b/apps/desktop/src/store/materialStore.ts index 6c99175..bfef9d1 100644 --- a/apps/desktop/src/store/materialStore.ts +++ b/apps/desktop/src/store/materialStore.ts @@ -1,12 +1,12 @@ import { create } from 'zustand'; import { invoke } from '@tauri-apps/api/core'; -import { - Material, - MaterialStats, - CreateMaterialRequest, +import { + Material, + MaterialStats, + CreateMaterialRequest, MaterialImportResult, ProcessingStatus, - MaterialProcessingConfig + MaterialSegment } from '../types/material'; /** @@ -35,6 +35,7 @@ interface MaterialState { loadMaterialStats: (projectId: string) => Promise; importMaterials: (request: CreateMaterialRequest) => Promise; getMaterialById: (id: string) => Promise; + getMaterialSegments: (materialId: string) => Promise; deleteMaterial: (id: string) => Promise; processMaterials: (materialIds: string[]) => Promise; updateMaterialStatus: (id: string, status: ProcessingStatus, errorMessage?: string) => Promise;