1
1
mirror of https://github.com/KenanZhu/AutoLibrary.git synced 2026-08-02 06:09:36 +08:00

feat(bulletin): 公告栏系统完整实现

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2026-06-24 10:18:30 +08:00
parent 588718f9c5
commit a716e5b945
10 changed files with 1938 additions and 332 deletions
+86 -7
View File
@@ -9,12 +9,15 @@ See the LICENSE file for details.
"""
import os
import sys
import time
import requests
import qtawesome as qta
from PySide6.QtCore import (
QProcess,
Qt,
QTimer,
Signal,
Slot
)
@@ -30,6 +33,7 @@ from PySide6.QtWidgets import (
)
import managers.config.ConfigManager as ConfigManager
from managers.bulletin.BulletinManager import instance as bulletinInstance
from managers.log.LogManager import instance as logInstance
from managers.theme.ThemeManager import(
getActiveStyle,
@@ -96,6 +100,9 @@ class ALSettingsWidget(CenterOnParentMixin, QWidget, Ui_ALSettingsWidget):
self.__original_theme: str = ""
self.__original_custom_theme: str = ""
self.__original_style: str = ""
self.__original_bulletin_url: str = ""
self.__original_bulletin_auto_fetch: bool = False
self.__original_bulletin_sync_interval: int = 10
self.setupUi(self)
self.modifyUi()
@@ -130,6 +137,7 @@ class ALSettingsWidget(CenterOnParentMixin, QWidget, Ui_ALSettingsWidget):
"padding: 5px;"
)
self.NavigationList.setCurrentRow(0)
self.NavigationList.currentRowChanged.connect(self.PageStack.setCurrentIndex)
self.populateStyles()
self.populateCustomThemes()
@@ -139,9 +147,12 @@ class ALSettingsWidget(CenterOnParentMixin, QWidget, Ui_ALSettingsWidget):
app : QApplication | None = QApplication.instance()
color = app.palette().color(app.palette().ColorRole.WindowText).name()
item = self.NavigationList.item(0)
if item:
item.setIcon(qta.icon("fa6s.palette", color=color))
item0 = self.NavigationList.item(0)
if item0:
item0.setIcon(qta.icon("fa6s.palette", color=color))
item1 = self.NavigationList.item(1)
if item1:
item1.setIcon(qta.icon("fa6s.bullhorn", color=color))
def populateStyles(
self
@@ -176,6 +187,7 @@ class ALSettingsWidget(CenterOnParentMixin, QWidget, Ui_ALSettingsWidget):
self.RemoveCustomThemeButton.clicked.connect(self.onRemoveCustomThemeButtonClicked)
self.CustomThemeComboBox.currentIndexChanged.connect(self.onCustomThemeComboBoxChanged)
self.ResetCustomThemeButton.clicked.connect(self.onResetCustomThemeButtonClicked)
self.BulletinTestButton.clicked.connect(self.onBulletinTestButtonClicked)
self.CancelButton.clicked.connect(self.onCancelButtonClicked)
self.ApplyButton.clicked.connect(self.onApplyButtonClicked)
self.ConfirmButton.clicked.connect(self.onConfirmButtonClicked)
@@ -207,6 +219,14 @@ class ALSettingsWidget(CenterOnParentMixin, QWidget, Ui_ALSettingsWidget):
self.updateCustomThemeInfo()
self.updateCustomThemeStatus()
bulletin_mgr = bulletinInstance()
self.__original_bulletin_url = bulletin_mgr.serverUrl()
self.__original_bulletin_auto_fetch = bulletin_mgr.autoFetch()
self.__original_bulletin_sync_interval = bulletin_mgr.syncInterval()
self.BulletinServerUrlEdit.setText(self.__original_bulletin_url)
self.BulletinAutoFetchCheck.setChecked(self.__original_bulletin_auto_fetch)
self.BulletinSyncIntervalSpin.setValue(self.__original_bulletin_sync_interval)
def updateCustomThemeInfo(
self
):
@@ -270,6 +290,29 @@ class ALSettingsWidget(CenterOnParentMixin, QWidget, Ui_ALSettingsWidget):
custom_theme = ""
return theme, style, custom_theme
def clearBulletinTestStatus(
self
):
self.BulletinTestStatusLabel.setText("")
self.BulletinTestStatusLabel.setStyleSheet("")
def saveBulletinSettings(
self
):
url = self.BulletinServerUrlEdit.text().strip()
auto_fetch = self.BulletinAutoFetchCheck.isChecked()
sync_interval = self.BulletinSyncIntervalSpin.value()
if sync_interval < 1:
sync_interval = 5
self.__cfg_mgr.set(CfgKey.GLOBAL.BULLETIN.SERVER_URL, url)
self.__cfg_mgr.set(CfgKey.GLOBAL.BULLETIN.AUTO_FETCH, auto_fetch)
self.__cfg_mgr.set(CfgKey.GLOBAL.BULLETIN.SYNC_INTERVAL, sync_interval)
self.__original_bulletin_url = url
self.__original_bulletin_auto_fetch = auto_fetch
self.__original_bulletin_sync_interval = sync_interval
def saveAndApply(
self
):
@@ -281,8 +324,6 @@ class ALSettingsWidget(CenterOnParentMixin, QWidget, Ui_ALSettingsWidget):
if not _applyCustomTheme(custom_theme, theme):
self.__cfg_mgr.set(CfgKey.GLOBAL.APPEARANCE.CUSTOM_THEME, "")
self.syncRadioFromNeedTheme(custom_theme)
# Re-read theme after syncRadioFromNeedTheme — the radio may have
# changed to match the custom theme's need_theme
theme, _, _ = self.collectSettings()
self.__cfg_mgr.set(CfgKey.GLOBAL.APPEARANCE.THEME, theme)
self.setNavigationIcons()
@@ -292,6 +333,8 @@ class ALSettingsWidget(CenterOnParentMixin, QWidget, Ui_ALSettingsWidget):
self.__original_custom_theme = custom_theme if custom_theme else ""
self.__original_style = getActiveStyle()
self.saveBulletinSettings()
def maybeRestart(
self
) -> bool:
@@ -380,7 +423,6 @@ class ALSettingsWidget(CenterOnParentMixin, QWidget, Ui_ALSettingsWidget):
):
self.updateCustomThemeInfo()
# no status update, because custom theme is not applied yet.
@Slot()
def onResetCustomThemeButtonClicked(
@@ -406,6 +448,43 @@ class ALSettingsWidget(CenterOnParentMixin, QWidget, Ui_ALSettingsWidget):
self.updateCustomThemeInfo()
self.updateCustomThemeStatus()
@Slot()
def onBulletinTestButtonClicked(
self
):
url = self.BulletinServerUrlEdit.text().strip()
if not url:
self.BulletinTestStatusLabel.setText("请先输入服务器地址。")
self.BulletinTestStatusLabel.setStyleSheet("color: red;")
return
self.BulletinTestButton.setEnabled(False)
self.BulletinTestStatusLabel.setText("正在测试连接...")
self.BulletinTestStatusLabel.setStyleSheet("")
try:
api_url = url.rstrip("/") + "/bulletins"
t0 = time.monotonic()
response = requests.get(api_url, timeout=5)
elapsed_ms = (time.monotonic() - t0) * 1000
response.raise_for_status()
data = response.json()
if data.get("code") == 200:
self.BulletinTestStatusLabel.setText(
f"连接成功!响应延迟 {elapsed_ms:.0f} ms"
)
self.BulletinTestStatusLabel.setStyleSheet("color: green;")
else:
self.BulletinTestStatusLabel.setText(
f"服务器返回异常: [{data.get('code', '?')}] {data.get('msg', '未知错误')}"
)
self.BulletinTestStatusLabel.setStyleSheet("color: red;")
except Exception as e:
self.BulletinTestStatusLabel.setText(f"连接失败:{e}")
self.BulletinTestStatusLabel.setStyleSheet("color: red;")
finally:
self.BulletinTestButton.setEnabled(True)
QTimer.singleShot(3000, self.clearBulletinTestStatus)
@Slot()
def onCancelButtonClicked(
self
@@ -429,5 +508,5 @@ class ALSettingsWidget(CenterOnParentMixin, QWidget, Ui_ALSettingsWidget):
self
):
self.onApplyButtonClicked() # virtually call apply button clicked
self.onApplyButtonClicked()
self.close()