Files
leonpan-pc/app/view/share_interface.py
2025-11-03 22:28:58 +08:00

320 lines
12 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 loguru import logger
from PyQt6.QtCore import Qt, QThread, pyqtSignal
from PyQt6.QtWidgets import QVBoxLayout, QWidget, QTableWidget, QTableWidgetItem, QHeaderView, QAbstractItemView, QMenu, QLabel, QFrame, QHBoxLayout
from PyQt6.QtGui import QAction
from qfluentwidgets import (CardWidget, ToolButton,
LineEdit, PrimaryPushButton, InfoBar, InfoBarPosition,
Dialog)
from app.core.api import miaoStarsBasicApi as basicApi
from app.core import lang
class ShareThread(QThread):
"""获取分享列表的线程"""
successSignal = pyqtSignal(dict)
errorSignal = pyqtSignal(str)
def __init__(self, page=1, pageSize=10, nextToken=None):
super().__init__()
self.page = page
self.pageSize = pageSize
self.nextToken = nextToken
def run(self):
try:
api = basicApi
# 注意getMyShares方法当前只支持page和pageSize参数
# 未来如果API支持next_token参数这里需要更新调用方式
result = api.getMyShares(self.page, self.pageSize)
if result['code'] == 0:
self.successSignal.emit(result)
else:
self.errorSignal.emit(result['msg'])
except Exception as e:
logger.error(f"获取分享列表失败: {e}")
self.errorSignal.emit(str(e))
class DeleteShareThread(QThread):
"""删除分享的线程"""
successSignal = pyqtSignal(str)
errorSignal = pyqtSignal(str)
def __init__(self, shareId):
super().__init__()
self.shareId = shareId
def run(self):
try:
api = basicApi
result = api.deleteShare(self.shareId)
if result['code'] == 0:
self.successSignal.emit(self.shareId)
else:
self.errorSignal.emit(result['msg'])
except Exception as e:
logger.error(f"删除分享失败: {e}")
self.errorSignal.emit(str(e))
class ShareWidget(QWidget):
"""分享页面组件"""
def __init__(self, parent=None):
super().__init__(parent)
self.page = 1
self.pageSize = 10
self.total = 0
self.nextToken = None
self.setupUi()
self.connectSignals()
self.loadShares()
def setupUi(self):
"""初始化UI"""
self.mainLayout = QVBoxLayout(self)
self.mainLayout.setSpacing(20)
# 标题
titleCard = CardWidget(self)
titleLayout = QVBoxLayout(titleCard)
self.titleLabel = QLabel(lang("我的分享"), parent=titleCard)
font = self.titleLabel.font()
font.setBold(True)
self.titleLabel.setFont(font)
self.titleLabel.setStyleSheet("font-size: 20px;")
titleLayout.addWidget(self.titleLabel, alignment=Qt.AlignmentFlag.AlignLeft)
self.mainLayout.addWidget(titleCard)
# 表格
self.tableWidget = QTableWidget(self)
self.tableWidget.setColumnCount(5)
self.tableWidget.setHorizontalHeaderLabels([
lang("分享名称"),
lang("分享链接"),
lang("创建时间"),
lang("访问次数"),
lang("操作")
])
# 设置表格属性
self.tableWidget.horizontalHeader().setSectionResizeMode(QHeaderView.ResizeMode.Stretch)
self.tableWidget.horizontalHeader().setSectionResizeMode(0, QHeaderView.ResizeMode.ResizeToContents)
self.tableWidget.horizontalHeader().setSectionResizeMode(4, QHeaderView.ResizeMode.Fixed)
self.tableWidget.setColumnWidth(4, 100)
self.tableWidget.setEditTriggers(QAbstractItemView.EditTrigger.NoEditTriggers)
self.tableWidget.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
self.mainLayout.addWidget(self.tableWidget)
# 空状态
self.emptyWidget = QFrame(self)
self.emptyWidget.setFixedSize(400, 250)
self.emptyWidget.setStyleSheet("background-color: transparent;")
emptyLayout = QVBoxLayout(self.emptyWidget)
# 图标标签(使用占位文本代替图标)
self.iconLabel = QLabel("☁️", self.emptyWidget)
self.iconLabel.setStyleSheet("font-size: 48px;")
self.iconLabel.setAlignment(Qt.AlignmentFlag.AlignCenter)
# 标题
self.emptyTitleLabel = QLabel(lang("暂无分享"), self.emptyWidget)
self.emptyTitleLabel.setStyleSheet("font-size: 18px; font-weight: bold;")
self.emptyTitleLabel.setAlignment(Qt.AlignmentFlag.AlignCenter)
# 描述
self.emptyDescLabel = QLabel(lang("你还没有任何分享,分享文件可以让他人便捷地获取你的资料"), self.emptyWidget)
self.emptyDescLabel.setStyleSheet("font-size: 14px; color: #666;")
self.emptyDescLabel.setAlignment(Qt.AlignmentFlag.AlignCenter)
self.emptyDescLabel.setWordWrap(True)
emptyLayout.addWidget(self.iconLabel)
emptyLayout.addWidget(self.emptyTitleLabel, 0, Qt.AlignmentFlag.AlignCenter)
emptyLayout.addWidget(self.emptyDescLabel, 0, Qt.AlignmentFlag.AlignCenter)
self.emptyWidget.setVisible(False)
self.mainLayout.addWidget(self.emptyWidget, 1, Qt.AlignmentFlag.AlignCenter)
# 自定义分页组件
self.paginationWidget = QWidget(self)
paginationLayout = QHBoxLayout(self.paginationWidget)
paginationLayout.setContentsMargins(0, 0, 0, 0)
# 页码显示
self.currentPage = 1
self.totalPages = 1
self.pageLabel = QLabel("1/1", self.paginationWidget)
paginationLayout.addWidget(self.pageLabel)
self.mainLayout.addWidget(self.paginationWidget, alignment=Qt.AlignmentFlag.AlignRight)
def connectSignals(self):
"""连接信号与槽"""
self.tableWidget.customContextMenuRequested.connect(self.showContextMenu)
def loadShares(self):
"""加载分享列表"""
self.tableWidget.setRowCount(0)
self.emptyWidget.setVisible(False)
self.shareThread = ShareThread(self.page, self.pageSize, self.nextToken)
self.shareThread.successSignal.connect(self.onSharesLoaded)
self.shareThread.errorSignal.connect(self.onSharesLoadError)
self.shareThread.start()
def onSharesLoaded(self, result):
"""处理分享列表加载成功"""
data = result.get('data', {})
shares = data.get('shares', [])
pagination = data.get('pagination', {})
# 更新表格
self.tableWidget.setRowCount(len(shares))
for row, share in enumerate(shares):
# 分享名称
nameItem = QTableWidgetItem(share.get('name', '-'))
nameItem.setData(Qt.ItemDataRole.UserRole, share)
nameItem.setTextAlignment(Qt.AlignmentFlag.AlignVCenter)
self.tableWidget.setItem(row, 0, nameItem)
# 分享链接
shareUrl = share.get('url', '')
urlItem = QTableWidgetItem(shareUrl)
urlItem.setTextAlignment(Qt.AlignmentFlag.AlignVCenter)
self.tableWidget.setItem(row, 1, urlItem)
# 创建时间
createTime = share.get('created_at', '-')
timeItem = QTableWidgetItem(createTime)
timeItem.setTextAlignment(Qt.AlignmentFlag.AlignVCenter)
self.tableWidget.setItem(row, 2, timeItem)
# 访问次数
visits = share.get('visited', 0)
visitItem = QTableWidgetItem(str(visits))
visitItem.setTextAlignment(Qt.AlignmentFlag.AlignVCenter)
self.tableWidget.setItem(row, 3, visitItem)
# 操作按钮
actionWidget = QWidget()
actionLayout = QVBoxLayout(actionWidget)
actionLayout.setContentsMargins(0, 0, 0, 0)
deleteButton = ToolButton()
deleteButton.setText(lang("删除"))
deleteButton.setProperty("shareId", share.get('id'))
deleteButton.clicked.connect(lambda checked, shareId=share.get('id'): self.deleteShare(shareId))
actionLayout.addWidget(deleteButton, alignment=Qt.AlignmentFlag.AlignCenter)
actionWidget.setLayout(actionLayout)
self.tableWidget.setCellWidget(row, 4, actionWidget)
# 更新分页显示
self.nextToken = pagination.get('next_token')
# 对于基于token的分页我们仍然显示页码信息以保持UI一致性
pageSize = pagination.get('page_size', self.pageSize)
# 估算总页数(基于当前获取的数量和每页大小)
estimatedTotalPages = (len(shares) + pageSize - 1) // pageSize
self.totalPages = max(1, estimatedTotalPages)
self.pageLabel.setText(f"{self.currentPage}/{self.totalPages}")
# 显示空状态
if not shares:
self.emptyWidget.setVisible(True)
def onSharesLoadError(self, errorMsg):
"""处理分享列表加载失败"""
logger.error(f"加载分享列表失败: {errorMsg}")
InfoBar.error(
lang("失败"),
f"{lang('加载分享列表失败')}: {errorMsg}",
parent=self.window()
)
self.emptyWidget.setVisible(True)
def showContextMenu(self, pos):
"""显示右键菜单"""
item = self.tableWidget.itemAt(pos)
if not item:
return
share = item.data(Qt.ItemDataRole.UserRole)
if not share:
return
menu = QMenu(self)
deleteAction = QAction(lang("删除"), self)
deleteAction.triggered.connect(lambda: self.deleteShare(share.get('id')))
menu.addAction(deleteAction)
menu.exec(self.tableWidget.mapToGlobal(pos))
def deleteShare(self, shareId):
"""删除分享"""
# 确认对话框
from qfluentwidgets import FluentIcon as FIF
from qfluentwidgets import MessageBox
dialog = MessageBox(
lang("确认删除"),
lang("确定要删除这个分享链接吗?删除后将无法恢复。"),
self.window()
)
if dialog.exec() == MessageBox.DialogCode.Accepted:
self.deleteShareThread = DeleteShareThread(shareId)
self.deleteShareThread.successSignal.connect(self.onShareDeleted)
self.deleteShareThread.errorSignal.connect(self.onShareDeleteError)
self.deleteShareThread.start()
def onShareDeleted(self, shareId):
"""处理分享删除成功"""
logger.success(f"分享删除成功: {shareId}")
InfoBar.success(
lang("成功"),
lang("分享删除成功"),
parent=self.window()
)
# 重新加载当前页
self.loadShares()
def onShareDeleteError(self, errorMsg):
"""处理分享删除失败"""
logger.error(f"删除分享失败: {errorMsg}")
InfoBar.error(
lang("失败"),
f"{lang('删除分享失败')}: {errorMsg}",
parent=self.window()
)
def onPageChanged(self, page):
"""处理页码变化"""
self.page = page
self.loadShares()
class ShareInterface(QWidget):
"""分享页面接口"""
def __init__(self, parent=None):
super().__init__(parent)
self.setObjectName("shareInterface")
self.setupUi()
def setupUi(self):
"""初始化UI"""
self.mainLayout = QVBoxLayout(self)
self.mainLayout.setContentsMargins(30, 30, 30, 30)
self.shareWidget = ShareWidget(self)
self.mainLayout.addWidget(self.shareWidget)
def refresh(self):
"""刷新页面"""
if hasattr(self, 'shareWidget'):
self.shareWidget.loadShares()