diff --git a/app/view/components/file_card.py b/app/view/components/file_card.py index ed5fd9e..0343462 100644 --- a/app/view/components/file_card.py +++ b/app/view/components/file_card.py @@ -83,7 +83,7 @@ class FileCard(CardWidget): "gif", ]: signalBus.imagePreviewSignal.emit(self._id) - if self.fileType == "file" and self.suffix in ["txt", "py", "md"]: + if self.fileType == "file" and self.suffix in ["txt", "py", "md", "js", "html"]: signalBus.txtPreviewSignal.emit(self._id) def downloadFile(self): diff --git a/app/view/widgets/preview_box.py b/app/view/widgets/preview_box.py index 719dbb0..06fa902 100644 --- a/app/view/widgets/preview_box.py +++ b/app/view/widgets/preview_box.py @@ -14,6 +14,7 @@ from qfluentwidgets import ( ) from app.core import (ImageLoaderThread, TextLoaderThread, UpdateFileContentThread) +from app.core.api import miaoStarsBasicApi from app.core.services.text_speech import LocalSpeechController from app.view.components.empty_card import EmptyCard @@ -38,6 +39,9 @@ def createThumbnail(pixmap, max_size=200): class OptimizedPreviewBox(MessageBoxBase): def __init__(self, parent=None, url=None): super().__init__(parent=parent) + # 处理URL,确保它是完整的URL + self.url = self._ensure_full_url(url) + logger.info(f"初始化图片预览框,URL: {self.url}") self.widget.setMinimumSize(500, 500) self.original_pixmap = None @@ -55,7 +59,7 @@ class OptimizedPreviewBox(MessageBoxBase): self.viewLayout.addWidget(self.previewLabel, 0, Qt.AlignmentFlag.AlignCenter) # 使用优化的图片加载线程 - self.imageLoaderThread = ImageLoaderThread(url) + self.imageLoaderThread = ImageLoaderThread(self.url) self.imageLoaderThread.imageLoaded.connect(self.setPreviewImg) self.imageLoaderThread.errorOccurred.connect(self.handleError) self.imageLoaderThread.progressUpdated.connect(self.updateProgress) @@ -65,16 +69,37 @@ class OptimizedPreviewBox(MessageBoxBase): QTimer.singleShot(100, self.startLoading) + def _ensure_full_url(self, url): + """确保URL是完整的,添加scheme和base URL(如果缺失)""" + if not url: + return url + + # 检查URL是否已经包含scheme + if url.startswith(('http://', 'https://')): + return url + + # 对于相对路径,使用API的base URL构建完整URL + # 移除可能的前导斜杠,避免重复 + path = url.lstrip('/') + # 从MiaoStarsBasicApi获取base URL,但只使用到域名部分 + base_url = miaoStarsBasicApi.basicApi.split('/api/v4')[0] + full_url = f"{base_url}/{path}" + logger.debug(f"将相对路径转换为完整URL: {url} -> {full_url}") + return full_url + def startLoading(self): """开始加载图片""" + logger.info(f"开始加载图片: {self.url}") self.imageLoaderThread.start() def updateProgress(self, progress): """更新加载进度""" + logger.debug(f"图片加载进度: {progress}%") self.loadingCard.setText(f"正在加载图片... {progress}%") def setPreviewImg(self, img: QPixmap): """设置预览图片""" + logger.info(f"图片加载成功,尺寸: {img.width()}x{img.height()}px") self.loadingCard.hide() self.original_pixmap = img @@ -131,6 +156,7 @@ class OptimizedPreviewBox(MessageBoxBase): def handleError(self, msg): """处理加载错误""" + logger.error(f"图片预览失败: {msg}") self.loadingCard.error() self.previewLabel.hide() @@ -141,6 +167,9 @@ class PreviewTextBox(MessageBoxBase): def __init__(self, parent=None, url=None, _id=None): super().__init__(parent=parent) + # 处理URL,确保它是完整的URL + self.url = self._ensure_full_url(url) + logger.info(f"初始化文本预览框,URL: {self.url}, 文件ID: {_id}") self.updateTxtThread = None self.widget.setMinimumSize(600, 400) self._id = _id @@ -205,7 +234,7 @@ class PreviewTextBox(MessageBoxBase): QTimer.singleShot(100, self.startLoading) def saveText(self): - logger.info("保存用户修改") + logger.info(f"保存文本文件修改,文件ID: {self._id}") # 显示进度条并禁用按钮 self.saveProgressBar.show() self.saveButton.setEnabled(False) @@ -218,6 +247,7 @@ class PreviewTextBox(MessageBoxBase): self.saveTextThread.start() def _successSave(self): + logger.info(f"文本文件保存成功,文件ID: {self._id}") InfoBar.success( "成功", "修改保存成功", @@ -232,6 +262,7 @@ class PreviewTextBox(MessageBoxBase): QTimer.singleShot(700, self.accept) def _errorSave(self, msg): + logger.error(f"文本文件保存失败,文件ID: {self._id}, 错误: {msg}") InfoBar.error( "失败", msg, @@ -250,24 +281,47 @@ class PreviewTextBox(MessageBoxBase): if not self.isSpeaking: text = self.textEdit.toPlainText() if text and len(text.strip()) > 0: + logger.info(f"开始文本朗读,文件ID: {self._id}") self.speech_controller.play_text(text) self.isSpeaking = True self.textSpeakButton.setText("暂停朗读") else: + logger.info(f"暂停文本朗读,文件ID: {self._id}") self.speech_controller.stop_playback() self.isSpeaking = False self.textSpeakButton.setText("朗读文本") + def _ensure_full_url(self, url): + """确保URL是完整的,添加scheme和base URL(如果缺失)""" + if not url: + return url + + # 检查URL是否已经包含scheme + if url.startswith(('http://', 'https://')): + return url + + # 对于相对路径,使用API的base URL构建完整URL + # 移除可能的前导斜杠,避免重复 + path = url.lstrip('/') + # 从MiaoStarsBasicApi获取base URL,但只使用到域名部分 + base_url = miaoStarsBasicApi.basicApi.split('/api/v4')[0] + full_url = f"{base_url}/{path}" + logger.debug(f"将相对路径转换为完整URL: {url} -> {full_url}") + return full_url + def startLoading(self): """开始加载文本""" + logger.info(f"开始加载文本文件: {self.url}") self.textLoaderThread.start() def updateProgress(self, progress): """更新加载进度""" + logger.debug(f"文本加载进度: {progress}%") self.loadingCard.setText(f"正在加载文本... {progress}%") def setTextContent(self, content): """设置文本内容""" + logger.info(f"文本文件加载成功,原始内容长度: {len(content)}字符") self.loadingCard.hide() self.textEdit.show() self.textSpeakButton.show() @@ -275,6 +329,7 @@ class PreviewTextBox(MessageBoxBase): # 限制显示的内容长度,避免性能问题 max_display_length = 100000 # 最多显示10万个字符 if len(content) > max_display_length: + logger.warning(f"文本内容过长,已截断显示,原始长度: {len(content)}字符") content = ( content[:max_display_length] + f"\n\n... (内容过长,已截断前{max_display_length}个字符,完整内容请下载文件查看)" @@ -284,6 +339,7 @@ class PreviewTextBox(MessageBoxBase): def handleError(self, error_msg): """处理加载错误""" + logger.error(f"文本预览失败,URL: {self.url}, 错误: {error_msg}") self.loadingCard.error() def resizeEvent(self, event):