41026f54 by shady

增加部分log日志文件处理

1 parent ab1a3122
...@@ -379,7 +379,8 @@ class HistoryManager: ...@@ -379,7 +379,8 @@ class HistoryManager:
379 # 保存生成的图片 - 使用PNG格式验证 379 # 保存生成的图片 - 使用PNG格式验证
380 generated_image_path = record_dir / "generated.png" 380 generated_image_path = record_dir / "generated.png"
381 if not save_png_with_validation(str(generated_image_path), image_bytes): 381 if not save_png_with_validation(str(generated_image_path), image_bytes):
382 # Pillow处理失败,回退到原始方法 382 #
383 # ¬,回退到原始方法
383 with open(generated_image_path, 'wb') as f: 384 with open(generated_image_path, 'wb') as f:
384 f.write(image_bytes) 385 f.write(image_bytes)
385 self.logger.warning(f"使用原始保存方法: {generated_image_path}") 386 self.logger.warning(f"使用原始保存方法: {generated_image_path}")
...@@ -1679,6 +1680,7 @@ class ImageGeneratorWindow(QMainWindow): ...@@ -1679,6 +1680,7 @@ class ImageGeneratorWindow(QMainWindow):
1679 1680
1680 def upload_images(self): 1681 def upload_images(self):
1681 """Upload reference images""" 1682 """Upload reference images"""
1683 self.logger.info("开始上传参考图片")
1682 files, _ = QFileDialog.getOpenFileNames( 1684 files, _ = QFileDialog.getOpenFileNames(
1683 self, 1685 self,
1684 "选择参考图片", 1686 "选择参考图片",
...@@ -1687,198 +1689,285 @@ class ImageGeneratorWindow(QMainWindow): ...@@ -1687,198 +1689,285 @@ class ImageGeneratorWindow(QMainWindow):
1687 ) 1689 )
1688 1690
1689 if files: 1691 if files:
1692 self.logger.info(f"选择了 {len(files)} 个文件: {files}")
1693 valid_count = 0
1690 for file_path in files: 1694 for file_path in files:
1691 try: 1695 try:
1692 self.uploaded_images.append(file_path) 1696 if self.validate_image_file(file_path):
1697 self.uploaded_images.append(file_path)
1698 valid_count += 1
1699 self.logger.info(f"成功添加图片: {file_path}")
1700 else:
1701 self.logger.warning(f"图片验证失败: {file_path}")
1693 except Exception as e: 1702 except Exception as e:
1703 self.logger.error(f"加载图片失败: {file_path}, 错误: {str(e)}", exc_info=True)
1694 QMessageBox.critical(self, "错误", f"无法加载图片: {file_path}\n{str(e)}") 1704 QMessageBox.critical(self, "错误", f"无法加载图片: {file_path}\n{str(e)}")
1695 1705
1696 self.update_image_preview() 1706 self.update_image_preview()
1697 self.image_count_label.setText(f"已选择 {len(self.uploaded_images)} 张") 1707 self.image_count_label.setText(f"已选择 {len(self.uploaded_images)} 张")
1698 self.status_label.setText(f"● 已添加 {len(files)} 张参考图片") 1708 self.status_label.setText(f"● 已添加 {valid_count} 张参考图片")
1699 self.status_label.setStyleSheet("QLabel { color: #34C759; }") 1709 self.status_label.setStyleSheet("QLabel { color: #34C759; }")
1710 self.logger.info(f"图片上传完成,有效图片: {valid_count} 张")
1711 else:
1712 self.logger.info("用户取消了图片选择")
1700 1713
1701 def add_image_files(self, file_paths): 1714 def add_image_files(self, file_paths):
1702 """添加图像文件到上传列表(用于拖拽功能)""" 1715 """添加图像文件到上传列表(用于拖拽功能)"""
1716 self.logger.info(f"开始处理拖拽文件,共 {len(file_paths) if file_paths else 0} 个")
1703 if not file_paths: 1717 if not file_paths:
1718 self.logger.warning("拖拽文件列表为空")
1704 return 1719 return
1705 1720
1706 added_count = 0 1721 added_count = 0
1707 for file_path in file_paths: 1722 for file_path in file_paths:
1723 self.logger.info(f"处理拖拽文件: {file_path}")
1708 try: 1724 try:
1709 if self.validate_image_file(file_path): 1725 if self.validate_image_file(file_path):
1710 self.uploaded_images.append(file_path) 1726 self.uploaded_images.append(file_path)
1711 added_count += 1 1727 added_count += 1
1728 self.logger.info(f"成功添加拖拽图片: {file_path}")
1712 else: 1729 else:
1713 self.logger.warning(f"无效的图像文件: {file_path}") 1730 self.logger.warning(f"无效的图像文件: {file_path}")
1714 except Exception as e: 1731 except Exception as e:
1715 self.logger.error(f"添加图片失败: {file_path}, 错误: {str(e)}") 1732 self.logger.error(f"添加图片失败: {file_path}, 错误: {str(e)}", exc_info=True)
1716 1733
1717 if added_count > 0: 1734 if added_count > 0:
1735 self.logger.info(f"拖拽添加成功,共 {added_count} 张图片")
1718 self.update_image_preview() 1736 self.update_image_preview()
1719 self.image_count_label.setText(f"已选择 {len(self.uploaded_images)} 张") 1737 self.image_count_label.setText(f"已选择 {len(self.uploaded_images)} 张")
1720 self.status_label.setText(f"● 已通过拖拽添加 {added_count} 张参考图片") 1738 self.status_label.setText(f"● 已通过拖拽添加 {added_count} 张参考图片")
1721 self.status_label.setStyleSheet("QLabel { color: #34C759; }") 1739 self.status_label.setStyleSheet("QLabel { color: #34C759; }")
1722 else: 1740 else:
1741 self.logger.warning("没有找到有效的拖拽图片文件")
1723 QMessageBox.warning(self, "警告", "没有找到有效的图片文件") 1742 QMessageBox.warning(self, "警告", "没有找到有效的图片文件")
1724 1743
1725 def add_clipboard_image(self, image): 1744 def add_clipboard_image(self, image):
1726 """添加剪贴板图像(用于拖拽和粘贴功能)""" 1745 """添加剪贴板图像(用于拖拽和粘贴功能)"""
1727 try: 1746 try:
1747 self.logger.info("开始处理剪贴板图像")
1728 # 生成临时文件名 1748 # 生成临时文件名
1729 timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") 1749 timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
1730 temp_dir = Path(tempfile.gettempdir()) / "nano_banana_app" 1750 temp_dir = Path(tempfile.gettempdir()) / "nano_banana_app"
1731 temp_dir.mkdir(exist_ok=True) 1751 temp_dir.mkdir(exist_ok=True)
1752 self.logger.info(f"临时目录: {temp_dir}")
1732 1753
1733 # 根据图像格式选择文件扩展名 1754 # 统一使用PNG格式保存,确保跨平台兼容
1734 file_extension = ".png" # 默认使用PNG格式 1755 file_extension = ".png"
1735 if image.format() == QImage.Format_RGB32:
1736 file_extension = ".bmp"
1737 elif image.format() == QImage.Format_RGB888:
1738 file_extension = ".jpg"
1739
1740 temp_file_path = temp_dir / f"clipboard_{timestamp}{file_extension}" 1756 temp_file_path = temp_dir / f"clipboard_{timestamp}{file_extension}"
1741 1757
1742 # 保存图像到临时文件 1758 # 尝试多种保存方式,确保兼容性
1743 if image.save(str(temp_file_path)): 1759 success = False
1760 try:
1761 # 方法1: 指定PNG格式
1762 success = image.save(str(temp_file_path), "PNG")
1763 self.logger.info(f"方法1保存结果: {success}")
1764 except:
1765 try:
1766 # 方法2: 自动格式
1767 success = image.save(str(temp_file_path))
1768 self.logger.info(f"方法2保存结果: {success}")
1769 except:
1770 # 方法3: 转换格式再保存
1771 converted_image = QImage(image)
1772 success = converted_image.save(str(temp_file_path), "PNG")
1773 self.logger.info(f"方法3保存结果: {success}")
1774
1775 if success and temp_file_path.exists():
1744 self.uploaded_images.append(str(temp_file_path)) 1776 self.uploaded_images.append(str(temp_file_path))
1745 self.update_image_preview() 1777 self.update_image_preview()
1746 self.image_count_label.setText(f"已选择 {len(self.uploaded_images)} 张") 1778 self.image_count_label.setText(f"已选择 {len(self.uploaded_images)} 张")
1747 self.status_label.setText("● 已添加剪贴板图片") 1779 self.status_label.setText("● 已添加剪贴板图片")
1748 self.status_label.setStyleSheet("QLabel { color: #34C759; }") 1780 self.status_label.setStyleSheet("QLabel { color: #34C759; }")
1749 self.logger.info(f"剪贴板图片已保存到: {temp_file_path}") 1781 self.logger.info(f"剪贴板图片已成功保存到: {temp_file_path}")
1750 else: 1782 else:
1783 self.logger.error("图片保存失败")
1751 QMessageBox.critical(self, "错误", "无法保存剪贴板图片") 1784 QMessageBox.critical(self, "错误", "无法保存剪贴板图片")
1752 1785
1753 except Exception as e: 1786 except Exception as e:
1754 self.logger.error(f"添加剪贴板图片失败: {str(e)}") 1787 self.logger.error(f"添加剪贴板图片失败: {str(e)}", exc_info=True)
1755 QMessageBox.critical(self, "错误", f"添加剪贴板图片失败: {str(e)}") 1788 QMessageBox.critical(self, "错误", f"添加剪贴板图片失败: {str(e)}")
1756 1789
1757 def paste_from_clipboard(self): 1790 def paste_from_clipboard(self):
1758 """从剪贴板粘贴图像""" 1791 """从剪贴板粘贴图像"""
1759 clipboard = QApplication.clipboard() 1792 try:
1793 self.logger.info("开始粘贴剪贴板图片")
1794 clipboard = QApplication.clipboard()
1795
1796 # 获取剪贴板MIME数据
1797 mime_data = clipboard.mimeData()
1798 self.logger.info(f"剪贴板MIME类型: {[mime for mime in mime_data.formats()]}")
1799
1800 # 检查剪贴板中是否有图像
1801 if mime_data.hasImage():
1802 self.logger.info("检测到剪贴板中有图像数据")
1803 image = clipboard.image()
1760 1804
1761 # 检查剪贴板中是否有图像 1805 if not image.isNull():
1762 if clipboard.mimeData().hasImage(): 1806 self.logger.info(f"图像尺寸: {image.width()}x{image.height()}, 格式: {image.format()}")
1763 image = clipboard.image() 1807 self.add_clipboard_image(image)
1764 if not image.isNull(): 1808 else:
1765 self.add_clipboard_image(image) 1809 self.logger.warning("剪贴板图像为空")
1810 QMessageBox.information(self, "信息", "剪贴板中没有有效的图片")
1766 else: 1811 else:
1767 QMessageBox.information(self, "信息", "剪贴板中没有有效的图片") 1812 self.logger.warning(f"剪贴板中没有图像,可用格式: {mime_data.formats()}")
1768 else: 1813 QMessageBox.information(self, "信息", "剪贴板中没有图片,请先复制一张图片")
1769 QMessageBox.information(self, "信息", "剪贴板中没有图片,请先复制一张图片") 1814
1815 except Exception as e:
1816 self.logger.error(f"粘贴剪贴板图片时发生错误: {str(e)}", exc_info=True)
1817 QMessageBox.critical(self, "错误", f"粘贴失败: {str(e)}")
1770 1818
1771 def validate_image_file(self, file_path: str) -> bool: 1819 def validate_image_file(self, file_path: str) -> bool:
1772 """验证图像文件""" 1820 """验证图像文件"""
1821 self.logger.info(f"开始验证图像文件: {file_path}")
1773 try: 1822 try:
1774 # 检查文件是否存在 1823 # 检查文件是否存在
1775 if not Path(file_path).exists(): 1824 if not Path(file_path).exists():
1825 self.logger.warning(f"文件不存在: {file_path}")
1776 return False 1826 return False
1777 1827
1778 # 检查文件扩展名 1828 # 检查文件扩展名
1779 valid_extensions = {'.png', '.jpg', '.jpeg', '.gif', '.bmp', '.webp'} 1829 valid_extensions = {'.png', '.jpg', '.jpeg', '.gif', '.bmp', '.webp'}
1780 if Path(file_path).suffix.lower() not in valid_extensions: 1830 file_extension = Path(file_path).suffix.lower()
1831 if file_extension not in valid_extensions:
1832 self.logger.warning(f"不支持的文件格式: {file_extension}, 文件: {file_path}")
1781 return False 1833 return False
1782 1834
1783 # 尝试加载图像以验证文件完整性 1835 # 检查文件大小
1784 pixmap = QPixmap(file_path)
1785 if pixmap.isNull():
1786 return False
1787
1788 # 检查文件大小(限制为10MB)
1789 file_size = Path(file_path).stat().st_size 1836 file_size = Path(file_path).stat().st_size
1837 self.logger.info(f"文件大小: {file_size} bytes, 格式: {file_extension}")
1838
1790 if file_size > 10 * 1024 * 1024: # 10MB 1839 if file_size > 10 * 1024 * 1024: # 10MB
1840 self.logger.warning(f"文件过大: {file_size} bytes, 文件: {file_path}")
1791 QMessageBox.warning(self, "警告", f"图片文件过大: {file_path}\n请选择小于10MB的图片") 1841 QMessageBox.warning(self, "警告", f"图片文件过大: {file_path}\n请选择小于10MB的图片")
1792 return False 1842 return False
1793 1843
1844 if file_size == 0:
1845 self.logger.warning(f"文件为空: {file_path}")
1846 return False
1847
1848 # 尝试加载图像以验证文件完整性
1849 self.logger.info(f"尝试加载图片验证完整性: {file_path}")
1850 pixmap = QPixmap(file_path)
1851 if pixmap.isNull():
1852 self.logger.error(f"图片加载失败或损坏: {file_path}")
1853 return False
1854
1855 self.logger.info(f"图片验证成功,尺寸: {pixmap.width()}x{pixmap.height()}, 文件: {file_path}")
1794 return True 1856 return True
1795 1857
1796 except Exception as e: 1858 except Exception as e:
1797 self.logger.error(f"图像文件验证失败: {file_path}, 错误: {str(e)}") 1859 self.logger.error(f"图像文件验证异常: {file_path}, 错误: {str(e)}", exc_info=True)
1798 return False 1860 return False
1799 1861
1800 def keyPressEvent(self, event): 1862 def keyPressEvent(self, event):
1801 """处理键盘事件""" 1863 """处理键盘事件"""
1864 # 检测键盘组合键
1865 key_text = event.text()
1866 key_int = event.key()
1867 modifiers = event.modifiers()
1868 self.logger.info(f"键盘事件: key={key_int}, text='{key_text}', modifiers={modifiers}")
1869
1802 # Ctrl+V 粘贴 1870 # Ctrl+V 粘贴
1803 if event.key() == Qt.Key_V and event.modifiers() == Qt.ControlModifier: 1871 if event.key() == Qt.Key_V and event.modifiers() == Qt.ControlModifier:
1872 self.logger.info("检测到 Ctrl+V 粘贴组合键")
1804 self.paste_from_clipboard() 1873 self.paste_from_clipboard()
1805 event.accept() 1874 event.accept()
1806 return 1875 return
1807 1876
1808 # Cmd+V 粘贴 (macOS) 1877 # Cmd+V 粘贴 (macOS)
1809 elif event.key() == Qt.Key_V and event.modifiers() == Qt.MetaModifier: 1878 elif event.key() == Qt.Key_V and event.modifiers() == Qt.MetaModifier:
1879 self.logger.info("检测到 Cmd+V 粘贴组合键 (macOS)")
1810 self.paste_from_clipboard() 1880 self.paste_from_clipboard()
1811 event.accept() 1881 event.accept()
1812 return 1882 return
1813 1883
1884 self.logger.debug(f"未处理的键盘事件: {key_text}")
1814 super().keyPressEvent(event) 1885 super().keyPressEvent(event)
1815 1886
1816 def update_image_preview(self): 1887 def update_image_preview(self):
1817 """Update image preview thumbnails""" 1888 """Update image preview thumbnails"""
1818 # Clear existing previews 1889 self.logger.info(f"更新图片预览,共 {len(self.uploaded_images)} 张图片")
1819 while self.img_layout.count() > 1: # Keep the stretch 1890 try:
1820 item = self.img_layout.takeAt(0) 1891 # Clear existing previews
1821 if item.widget(): 1892 while self.img_layout.count() > 1: # Keep the stretch
1822 item.widget().deleteLater() 1893 item = self.img_layout.takeAt(0)
1823 1894 if item.widget():
1824 # Add thumbnails 1895 item.widget().deleteLater()
1825 for idx, file_path in enumerate(self.uploaded_images): 1896
1826 try: 1897 # Add thumbnails
1827 # Load and create thumbnail 1898 for idx, file_path in enumerate(self.uploaded_images):
1828 pixmap = QPixmap(file_path) 1899 self.logger.info(f"创建第 {idx + 1} 张图片缩略图: {file_path}")
1829 pixmap = pixmap.scaled(100, 100, Qt.KeepAspectRatio, Qt.SmoothTransformation) 1900 try:
1830 1901 # Load and create thumbnail
1831 # Container 1902 pixmap = QPixmap(file_path)
1832 container = QWidget() 1903 if pixmap.isNull():
1833 container_layout = QVBoxLayout() 1904 self.logger.warning(f"无法加载图片进行预览: {file_path}")
1834 container_layout.setContentsMargins(5, 5, 5, 5) 1905 continue
1835
1836 # Image label
1837 img_label = QLabel()
1838 img_label.setPixmap(pixmap)
1839 img_label.setFixedSize(100, 100)
1840 img_label.setStyleSheet("QLabel { border: 1px solid #e5e5e5; }")
1841 container_layout.addWidget(img_label)
1842
1843 # Info row
1844 info_layout = QHBoxLayout()
1845 index_label = QLabel(f"图 {idx + 1}")
1846 index_label.setStyleSheet("QLabel { font-size: 8pt; color: #666666; }")
1847 info_layout.addWidget(index_label)
1848
1849 del_btn = QPushButton("✕")
1850 del_btn.setFixedSize(20, 20)
1851 del_btn.setStyleSheet("""
1852 QPushButton {
1853 background-color: #ff4444;
1854 color: white;
1855 font-weight: bold;
1856 border: none;
1857 border-radius: 3px;
1858 padding: 0px;
1859 }
1860 QPushButton:hover {
1861 background-color: #FF3B30;
1862 }
1863 """)
1864 del_btn.clicked.connect(lambda checked, i=idx: self.delete_image(i))
1865 info_layout.addWidget(del_btn)
1866 1906
1867 container_layout.addLayout(info_layout) 1907 pixmap = pixmap.scaled(100, 100, Qt.KeepAspectRatio, Qt.SmoothTransformation)
1868 container.setLayout(container_layout) 1908 self.logger.info(f"缩略图创建成功: {pixmap.width()}x{pixmap.height()}")
1909
1910 # Container
1911 container = QWidget()
1912 container_layout = QVBoxLayout()
1913 container_layout.setContentsMargins(5, 5, 5, 5)
1914
1915 # Image label
1916 img_label = QLabel()
1917 img_label.setPixmap(pixmap)
1918 img_label.setFixedSize(100, 100)
1919 img_label.setStyleSheet("QLabel { border: 1px solid #e5e5e5; }")
1920 container_layout.addWidget(img_label)
1921
1922 # Info row
1923 info_layout = QHBoxLayout()
1924 index_label = QLabel(f"图 {idx + 1}")
1925 index_label.setStyleSheet("QLabel { font-size: 8pt; color: #666666; }")
1926 info_layout.addWidget(index_label)
1927
1928 del_btn = QPushButton("✕")
1929 del_btn.setFixedSize(20, 20)
1930 del_btn.setStyleSheet("""
1931 QPushButton {
1932 background-color: #ff4444;
1933 color: white;
1934 font-weight: bold;
1935 border: none;
1936 border-radius: 3px;
1937 padding: 0px;
1938 }
1939 QPushButton:hover {
1940 background-color: #FF3B30;
1941 }
1942 """)
1943 del_btn.clicked.connect(lambda checked, i=idx: self.delete_image(i))
1944 info_layout.addWidget(del_btn)
1945
1946 container_layout.addLayout(info_layout)
1947 container.setLayout(container_layout)
1948
1949 self.img_layout.insertWidget(self.img_layout.count() - 1, container)
1950 self.logger.info(f"缩略图UI组件创建完成: {file_path}")
1869 1951
1870 self.img_layout.insertWidget(self.img_layout.count() - 1, container) 1952 except Exception as e:
1871 except Exception as e: 1953 self.logger.error(f"创建缩略图失败: {file_path}, 错误: {str(e)}", exc_info=True)
1872 print(f"Failed to create thumbnail for {file_path}: {e}") 1954
1955 except Exception as e:
1956 self.logger.error(f"更新图片预览失败: {str(e)}", exc_info=True)
1873 1957
1874 def delete_image(self, index): 1958 def delete_image(self, index):
1875 """Delete an image by index""" 1959 """Delete an image by index"""
1960 self.logger.info(f"尝试删除第 {index + 1} 张图片")
1876 if 0 <= index < len(self.uploaded_images): 1961 if 0 <= index < len(self.uploaded_images):
1962 deleted_file = self.uploaded_images[index]
1877 self.uploaded_images.pop(index) 1963 self.uploaded_images.pop(index)
1964 self.logger.info(f"已删除图片: {deleted_file}")
1878 self.update_image_preview() 1965 self.update_image_preview()
1879 self.image_count_label.setText(f"已选择 {len(self.uploaded_images)} 张") 1966 self.image_count_label.setText(f"已选择 {len(self.uploaded_images)} 张")
1880 self.status_label.setText("● 已删除图片") 1967 self.status_label.setText("● 已删除图片")
1881 self.status_label.setStyleSheet("QLabel { color: #FF9500; }") 1968 self.status_label.setStyleSheet("QLabel { color: #FF9500; }")
1969 else:
1970 self.logger.warning(f"无效的图片索引: {index}")
1882 1971
1883 def update_saved_prompts_list(self): 1972 def update_saved_prompts_list(self):
1884 """Update the saved prompts dropdown""" 1973 """Update the saved prompts dropdown"""
...@@ -2749,98 +2838,57 @@ class JewelryLibraryManager: ...@@ -2749,98 +2838,57 @@ class JewelryLibraryManager:
2749 self.logger = logging.getLogger(__name__) 2838 self.logger = logging.getLogger(__name__)
2750 self.config_dir = config_dir 2839 self.config_dir = config_dir
2751 self.config_path = config_dir / "jewelry_library.json" 2840 self.config_path = config_dir / "jewelry_library.json"
2752 # 获取默认词库文件的路径
2753 self.default_library_path = Path(__file__).parent / "data" / "default_jewelry_library.json"
2754 self.library = self.load_library() 2841 self.library = self.load_library()
2755 2842
2756 def load_library(self) -> Dict[str, List[str]]: 2843 def load_library(self) -> Dict[str, List[str]]:
2757 """加载词库,不存在则创建默认词库""" 2844 """加载词库,优先使用用户配置,不存在则使用默认词库"""
2758 if self.config_path.exists(): 2845 if self.config_path.exists():
2759 try: 2846 try:
2760 with open(self.config_path, 'r', encoding='utf-8') as f: 2847 with open(self.config_path, 'r', encoding='utf-8') as f:
2761 library = json.load(f) 2848 library = json.load(f)
2762 2849
2763 # 检查是否需要进行数据迁移 2850 # 验证数据完整性,补全缺失的类别
2764 library = self._migrate_library_if_needed(library) 2851 needs_update = False
2852 for category, default_items in DEFAULT_JEWELRY_LIBRARY.items():
2853 if category not in library:
2854 self.logger.warning(f"检测到缺失类别: {category},从默认配置补全")
2855 library[category] = default_items.copy()
2856 needs_update = True
2857 elif not library[category] or len(library[category]) == 0:
2858 self.logger.warning(f"检测到空类别: {category},从默认配置补全")
2859 library[category] = default_items.copy()
2860 needs_update = True
2861 elif len(library[category]) < len(default_items) * 0.5:
2862 # 如果类别数据量少于默认值的50%,认为数据不完整,使用默认数据
2863 self.logger.warning(f"检测到类别 {category} 数据不完整(仅{len(library[category])}项,默认{len(default_items)}项),从默认配置补全")
2864 library[category] = default_items.copy()
2865 needs_update = True
2866
2867 # 如果数据被补全,保存更新后的配置
2868 if needs_update:
2869 self.logger.info("词库数据已补全,保存更新")
2870 self.save_library(library)
2765 2871
2766 self.logger.info(f"珠宝词库加载成功: {self.config_path}") 2872 self.logger.info(f"珠宝词库加载成功: {self.config_path}")
2767 return library 2873 return library
2768 except Exception as e: 2874 except Exception as e:
2769 self.logger.error(f"珠宝词库加载失败: {e},使用默认词库") 2875 self.logger.error(f"珠宝词库加载失败: {e},使用默认词库")
2770 return DEFAULT_JEWELRY_LIBRARY.copy() 2876 library = DEFAULT_JEWELRY_LIBRARY.copy()
2877 # 尝试保存默认配置,覆盖损坏的文件
2878 try:
2879 self.save_library(library)
2880 except:
2881 pass
2882 return library
2771 else: 2883 else:
2772 # 首次使用,创建默认词库 2884 # 首次使用,从代码中的默认配置创建用户配置文件
2773 self.logger.info("未找到珠宝词库文件,创建默认词库") 2885 self.logger.info("首次使用,创建用户配置文件")
2774 library = DEFAULT_JEWELRY_LIBRARY.copy() 2886 library = DEFAULT_JEWELRY_LIBRARY.copy()
2775 self.save_library(library) 2887 self.save_library(library)
2776 return library 2888 return library
2777 2889
2778 def _migrate_library_if_needed(self, library: Dict[str, List[str]]) -> Dict[str, List[str]]:
2779 """检查并执行数据迁移"""
2780 # 如果存在旧的"主石"字段,需要拆分
2781 if "主石" in library:
2782 self.logger.info("检测到旧版主石字段,执行数据迁移...")
2783
2784 # 创建新字段
2785 shapes = []
2786 materials = []
2787
2788 # 分析现有数据
2789 for item in library["主石"]:
2790 # 提取形状信息
2791 shape = self._extract_shape(item)
2792 if shape and shape not in shapes:
2793 shapes.append(shape)
2794
2795 # 提取材质信息
2796 material = self._extract_material(item)
2797 if material and material not in materials:
2798 materials.append(material)
2799
2800 # 更新词库
2801 library["主石形状"] = shapes if shapes else DEFAULT_JEWELRY_LIBRARY["主石形状"]
2802 library["主石材质"] = materials if materials else DEFAULT_JEWELRY_LIBRARY["主石材质"]
2803
2804 # 保留旧字段作为备份
2805 # library.pop("主石", None) # 可以选择是否移除
2806
2807 # 保存迁移后的数据
2808 self.save_library(library)
2809 self.logger.info(f"数据迁移完成:形状 {len(shapes)} 个,材质 {len(materials)} 个")
2810
2811 return library
2812
2813 def _extract_shape(self, item: str) -> Optional[str]:
2814 """从主石描述中提取形状"""
2815 # 直接从 DEFAULT_JEWELRY_LIBRARY 获取形状列表,确保同步
2816 shapes = DEFAULT_JEWELRY_LIBRARY.get("主石形状", [])
2817 for shape in shapes:
2818 # 处理带括号的形状(如"子弹形(Baguette 子弹刻面)")
2819 if "(" in shape:
2820 shape_base = shape.split("(")[0]
2821 if item.startswith(shape_base):
2822 return shape_base
2823 elif item.startswith(shape):
2824 return shape
2825 return None
2826
2827 def _extract_material(self, item: str) -> Optional[str]:
2828 """从主石描述中提取材质"""
2829 # 直接从 DEFAULT_JEWELRY_LIBRARY 获取形状列表,确保同步
2830 shapes = DEFAULT_JEWELRY_LIBRARY.get("主石形状", [])
2831 for shape in shapes:
2832 # 处理带括号的形状(如"子弹形(Baguette 子弹刻面)")
2833 shape_base = shape.split("(")[0] if "(" in shape else shape
2834 if item.startswith(shape_base):
2835 material = item[len(shape_base):]
2836 # 去除可能的连接词
2837 if material.startswith("的"):
2838 material = material[1:]
2839 return material if material else None
2840 return item # 如果没有形状前缀,返回整个字符串
2841
2842 def save_library(self, library: Dict[str, List[str]] = None): 2890 def save_library(self, library: Dict[str, List[str]] = None):
2843 """保存词库到配置文件 2891 """保存词库到用户配置目录
2844 2892
2845 Args: 2893 Args:
2846 library: 要保存的词库,如果为None则保存当前词库 2894 library: 要保存的词库,如果为None则保存当前词库
...@@ -3096,6 +3144,8 @@ class StyleDesignerTab(QWidget): ...@@ -3096,6 +3144,8 @@ class StyleDesignerTab(QWidget):
3096 self.prompt_preview.setReadOnly(True) 3144 self.prompt_preview.setReadOnly(True)
3097 prompt_layout.addWidget(self.prompt_preview) 3145 prompt_layout.addWidget(self.prompt_preview)
3098 prompt_group.setLayout(prompt_layout) 3146 prompt_group.setLayout(prompt_layout)
3147 prompt_group.setStyleSheet("font-size: 16px;")
3148
3099 content_row.addWidget(prompt_group, 2) 3149 content_row.addWidget(prompt_group, 2)
3100 3150
3101 # Settings section 3151 # Settings section
......