WeChatMsg_NY/newYear/ui/version_compare.py
2025-01-22 17:35:47 +08:00

262 lines
9.2 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from PyQt5.QtWidgets import (QDialog, QVBoxLayout, QHBoxLayout, QLabel,
QComboBox, QPushButton, QTextEdit, QFrame,
QScrollArea, QWidget)
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QColor, QTextCharFormat, QTextCursor
import difflib
class VersionCompareDialog(QDialog):
"""版本比较对话框"""
def __init__(self, versions, parent=None):
super().__init__(parent)
# 按联系人分组版本
self.contact_versions = self.group_versions_by_contact(versions)
self.init_ui()
self.apply_style()
def group_versions_by_contact(self, versions):
"""将版本按联系人分组
Returns:
Dict[str, List[Dict]]: 以联系人wxid为键版本列表为值的字典
"""
grouped = {}
for version in versions:
contact = version['contact']
wxid = contact['wxid']
if wxid not in grouped:
grouped[wxid] = []
grouped[wxid].append(version)
return grouped
def init_ui(self):
"""初始化UI"""
self.setWindowTitle("版本比较")
self.setMinimumSize(800, 600)
layout = QVBoxLayout(self)
# 联系人选择
contact_layout = QHBoxLayout()
contact_layout.addWidget(QLabel("选择联系人:"))
self.contact_combo = QComboBox()
self.contact_combo.currentIndexChanged.connect(self.on_contact_changed)
contact_layout.addWidget(self.contact_combo)
layout.addLayout(contact_layout)
# 版本选择区域
select_layout = QHBoxLayout()
# 版本A选择
version_a_layout = QVBoxLayout()
version_a_layout.addWidget(QLabel("版本A"))
self.version_a_combo = QComboBox()
self.version_a_combo.currentIndexChanged.connect(self.compare_versions)
version_a_layout.addWidget(self.version_a_combo)
select_layout.addLayout(version_a_layout)
# 版本B选择
version_b_layout = QVBoxLayout()
version_b_layout.addWidget(QLabel("版本B"))
self.version_b_combo = QComboBox()
self.version_b_combo.currentIndexChanged.connect(self.compare_versions)
version_b_layout.addWidget(self.version_b_combo)
select_layout.addLayout(version_b_layout)
layout.addLayout(select_layout)
# 比较结果区域
scroll = QScrollArea()
scroll.setWidgetResizable(True)
scroll.setObjectName("compare-scroll")
content_widget = QWidget()
self.content_layout = QVBoxLayout(content_widget)
# 各部分内容比较
self.add_compare_section("新年祝福语", "greeting")
self.add_compare_section("美好祝愿", "wishes")
self.add_compare_section("祝福成语", "idioms")
self.add_compare_section("新年图片提示词", "image_prompt")
scroll.setWidget(content_widget)
layout.addWidget(scroll)
# 底部按钮
button_layout = QHBoxLayout()
close_btn = QPushButton("关闭")
close_btn.setObjectName("close-btn")
close_btn.clicked.connect(self.accept)
button_layout.addStretch()
button_layout.addWidget(close_btn)
layout.addLayout(button_layout)
# 初始化联系人列表
self.init_contacts()
def init_contacts(self):
"""初始化联系人列表"""
self.contact_combo.clear()
for wxid, versions in self.contact_versions.items():
if versions: # 确保有版本数据
contact_name = versions[0]['contact']['name'] # 使用第一个版本中的联系人名称
self.contact_combo.addItem(contact_name, wxid) # 使用wxid作为用户数据
def on_contact_changed(self, index):
"""联系人选择改变时的处理"""
if index < 0:
return
# 获取选中联系人的wxid
wxid = self.contact_combo.currentData()
versions = self.contact_versions.get(wxid, [])
# 更新版本选择框
self.version_a_combo.clear()
self.version_b_combo.clear()
contact_name = versions[0]['contact']['name']
for version in versions:
version_text = f"{contact_name} - 版本{version['version_number']} ({version['create_time']})"
self.version_a_combo.addItem(version_text, version)
self.version_b_combo.addItem(version_text, version)
# 默认选择最新的两个版本
if len(versions) >= 2:
self.version_a_combo.setCurrentIndex(len(versions) - 2)
self.version_b_combo.setCurrentIndex(len(versions) - 1)
def add_compare_section(self, title, content_key):
"""添加比较部分"""
section = QWidget()
layout = QVBoxLayout(section)
# 标题
title_label = QLabel(title)
title_label.setObjectName("title")
layout.addWidget(title_label)
# 内容比较区域
content_layout = QHBoxLayout()
# 版本A内容
text_a = QTextEdit()
text_a.setReadOnly(True)
setattr(self, f"{content_key}_a", text_a)
content_layout.addWidget(text_a)
# 版本B内容
text_b = QTextEdit()
text_b.setReadOnly(True)
setattr(self, f"{content_key}_b", text_b)
content_layout.addWidget(text_b)
layout.addLayout(content_layout)
self.content_layout.addWidget(section)
def compare_versions(self):
"""比较选中的两个版本"""
if self.version_a_combo.currentIndex() < 0 or self.version_b_combo.currentIndex() < 0:
return
version_a = self.version_a_combo.currentData()
version_b = self.version_b_combo.currentData()
if version_a and version_b:
self.compare_content("greeting", version_a, version_b)
self.compare_content("wishes", version_a, version_b)
self.compare_content("idioms", version_a, version_b)
self.compare_content("image_prompt", version_a, version_b)
def compare_content(self, content_key, version_a, version_b):
"""比较特定内容"""
text_a = version_a.get(content_key, '')
text_b = version_b.get(content_key, '')
# 获取文本框引用
text_edit_a = getattr(self, f"{content_key}_a")
text_edit_b = getattr(self, f"{content_key}_b")
# 清空文本框
text_edit_a.clear()
text_edit_b.clear()
# 计算差异
differ = difflib.Differ()
diff = list(differ.compare(text_a.splitlines(), text_b.splitlines()))
# 设置差异高亮格式
add_format = QTextCharFormat()
add_format.setBackground(QColor(200, 255, 200)) # 浅绿色背景
del_format = QTextCharFormat()
del_format.setBackground(QColor(255, 200, 200)) # 浅红色背景
# 显示差异
cursor_a = text_edit_a.textCursor()
cursor_b = text_edit_b.textCursor()
for line in diff:
if line.startswith('- '):
cursor_a.insertText(line[2:] + '\n', del_format)
cursor_b.insertText('\n')
elif line.startswith('+ '):
cursor_a.insertText('\n')
cursor_b.insertText(line[2:] + '\n', add_format)
else:
cursor_a.insertText(line[2:] + '\n')
cursor_b.insertText(line[2:] + '\n')
# 滚动到顶部
text_edit_a.verticalScrollBar().setValue(0)
text_edit_b.verticalScrollBar().setValue(0)
def apply_style(self):
"""应用样式"""
self.setStyleSheet("""
QDialog {
background-color: #F9F4E6;
min-width: 800px;
min-height: 600px;
}
QLabel {
color: #333333;
}
QLabel#title {
font-size: 18px;
font-weight: bold;
color: #D4341F;
padding: 10px;
}
QLabel#version-label {
font-size: 16px;
font-weight: bold;
color: #D4341F;
padding: 5px;
}
QTextEdit {
background-color: white;
border: 1px solid #E8C06F;
border-radius: 4px;
padding: 8px;
font-size: 14px;
}
QPushButton {
background-color: #E8C06F;
color: #333333;
border: none;
padding: 8px 16px;
border-radius: 4px;
min-width: 80px;
}
QPushButton:hover {
background-color: #D4B05F;
}
QPushButton#close-btn {
background-color: #D4341F;
color: white;
}
QPushButton#close-btn:hover {
background-color: #A61F14;
}
""")