diff --git a/docs/2026-09-09-10-11-ui-layout-polish.md b/docs/2026-09-09-10-11-ui-layout-polish.md new file mode 100644 index 0000000..65effd2 --- /dev/null +++ b/docs/2026-09-09-10-11-ui-layout-polish.md @@ -0,0 +1,22 @@ +# UI 布局调整记录 + +## 需求 + +1. 移除页面顶部提示文字。 +2. 将日志按天保存提示与自动滚动操作放在同一行。 +3. 左侧账号树默认占约 30%,分隔条可拖动调整。 +4. 为左侧账号树区域增加浅色背景,减少空旷感。 + +## 实现 + +- 修改 `src/accounts_app.py` 的 `Window` 布局:删除顶部说明 `QLabel`。 +- 将 `log_info` 放入日志控制栏,并关闭换行,和自动滚动、打开日志目录控件共用一行。 +- 使用 `QSplitter` 保留可拖动分隔条,设置 8px 宽度、悬停高亮、水平分隔光标和拖动提示;默认尺寸按 30/70 设置,伸缩因子作为回退。 +- 左侧账号树容器增加浅灰背景、边框和圆角;滚动区域及内容宿主设为透明,以显示容器背景并保留账号卡片样式。 + +## 验证 + +- `QT_QPA_PLATFORM=offscreen .venv/bin/python -m pytest -q src/test_onboarding_ui.py`:9 passed。 +- `PYTHONPATH=src .venv/bin/python -m py_compile src/accounts_app.py`:通过。 +- Offscreen UI 探针确认:左侧比例 `365/1216 = 30%`、分隔条宽度 8、可拖动光标启用、顶部提示不存在、日志提示和自动滚动控件同属一行。 +- 未执行 Windows 远程部署或真实账号业务操作。 diff --git a/docs/2026-09-09-11-23-windows-ui-layout-deploy.md b/docs/2026-09-09-11-23-windows-ui-layout-deploy.md new file mode 100644 index 0000000..216d9bd --- /dev/null +++ b/docs/2026-09-09-11-23-windows-ui-layout-deploy.md @@ -0,0 +1,30 @@ +# Windows UI 布局调整远程部署记录 + +## 连接与范围 + +- 目标:通过项目配置的 `windows-ui` MCP 连接 Windows 主机。 +- 传输:本机临时 HTTP 服务仅提供本次源码压缩包,Windows 端下载后本地解压。 +- 未执行自动登录、账号恢复、关注、私信或其他真实业务写操作。 + +## 执行步骤 + +1. 先检查 Windows 窗口状态,确认目标应用未运行。 +2. 将当前项目源码打包并下载到: + `C:\Users\Rogee\douyin-pc-ui-20260909\repo.zip` +3. 在 Windows 端解压源码。 +4. 检查发现编译依赖缺失,执行: + `python -m pip install -r C:\Users\Rogee\douyin-pc-ui-20260909\requirements-build-windows.txt` +5. 依赖导入验证通过后,在 Windows x64 原生环境执行: + `python build_windows.py` +6. 生成并运行便携版程序: + `C:\Users\Rogee\douyin-pc-ui-20260909\dist\DouyinAccounts\DouyinAccounts.exe` + +## 验收结果 + +- Windows 原生构建完成,`dist\DouyinAccounts\DouyinAccounts.exe` 存在。 +- Inno Setup 安装器未生成,因此本次使用 PyInstaller 便携版直接运行查看效果。 +- 窗口标题为“抖音账号助手 · 自动操作默认关闭”。 +- 顶部提示文字已移除。 +- 日志按天保存提示、自动滚动和打开日志文件夹位于同一行。 +- 左侧账号树区域约占 30%,分隔条约 8px 且可拖动;左侧背景样式已生效。 +- 当前应用保持运行,供人工查看界面效果。 diff --git a/docs/2026-09-09-11-42-main-account-selection.md b/docs/2026-09-09-11-42-main-account-selection.md new file mode 100644 index 0000000..4961b3b --- /dev/null +++ b/docs/2026-09-09-11-42-main-account-selection.md @@ -0,0 +1,21 @@ +# 大号选择与分组启动调整记录 + +## 需求 + +大号卡片已有选中边框,左侧复选框与“大号选中即选中分组”的交互重复,应移除账号卡片复选框。 + +## 实现 + +- 移除 `AccountCard` 的账号复选框及 `checked` 信号。 +- `AccountCardTree` 不再维护勾选组,保留卡片选中边框作为当前分组选择状态。 +- 移除“启动当前组”和“恢复上次选择”顶部按钮。 +- 大号右键菜单保留“启动本组”,仅通过右键触发该分组启动;作品卡片和账号卡片的当前选中状态继续由边框表示。 +- 保留作品卡片中的“监控”复选框;该复选框与大号选择无关。 + +## 验证 + +- `src/test_onboarding_ui.py`:9 passed。 +- Qt 定向检查确认大号/小号账号卡片均无账号复选框。 +- 定向检查确认选中大号 `m` 时启动请求为 `["m"]`。 +- `py_compile` 和 `git diff --check` 通过。 +- 未执行真实启动、关注、私信或登录操作。 diff --git a/docs/2026-09-09-15-45-windows-ui-layout-latest.md b/docs/2026-09-09-15-45-windows-ui-layout-latest.md new file mode 100644 index 0000000..dcbc915 --- /dev/null +++ b/docs/2026-09-09-15-45-windows-ui-layout-latest.md @@ -0,0 +1,23 @@ +# 最新 UI 版本 Windows 远程构建记录 + +## 范围 + +将最新 `src/accounts_app.py` 部署到 Windows 原生构建目录并运行查看界面。未执行登录、恢复业务、关注、私信或其他真实业务操作。 + +## 执行 + +- Windows 目标应用启动前状态已检查,未发现抖音账号助手窗口。 +- 通过项目配置的 `windows-ui` MCP 对应主机下载最新源码文件,源码 SHA-256:`7d996a...f47e`。 +- 在已有 Windows 构建环境执行: + `Set-Location C:\Users\Rogee\douyin-pc-ui-20260909; python build_windows.py` +- 生成便携版: + `C:\Users\Rogee\douyin-pc-ui-20260909\dist\DouyinAccounts\DouyinAccounts.exe` +- 运行上述便携版程序。 + +## 验收 + +- 窗口成功启动,标题为“抖音账号助手 · 自动操作默认关闭”。 +- 顶部仅保留“添加大号”“添加小号”“停止全部”“异常任务”“设置”;“恢复上次选择”和“启动当前组”已移除。 +- 大号卡片保留右键菜单入口“启动本组”,账号卡片未显示左侧复选框。 +- 日志提示、自动滚动和打开日志文件夹保持同一行;左侧树约 30%,分隔条可拖动,背景样式正常。 +- 应用已保持运行,供人工查看效果。 diff --git a/docs/2026-09-09-17-18-account-menu-exception-tab.md b/docs/2026-09-09-17-18-account-menu-exception-tab.md new file mode 100644 index 0000000..12584a8 --- /dev/null +++ b/docs/2026-09-09-17-18-account-menu-exception-tab.md @@ -0,0 +1,22 @@ +# 账号入口与异常任务布局调整记录 + +## 需求 + +- 顶部“添加大号”改为“添加账号”。 +- 移除顶部“添加小号”,改从大号右键菜单添加并自动归属当前大号。 +- 移除顶部“异常任务”,将异常任务按大号放入大号详情 Tab。 + +## 实现 + +- 顶部按钮仅保留“添加账号”“停止全部”“设置”;“添加账号”继续创建大号。 +- 大号右键菜单增加“添加小号”,打开添加小号对话框时预选当前大号。 +- 删除独立异常任务工作台、全局大号/小号筛选和异步 `task_query` UI 路由。 +- 大号详情新增“异常任务”Tab,直接从当前快照筛选 `status == unknown` 且 `source` 等于当前大号 ID 的任务;小号详情隐藏该 Tab。 +- 异常任务仍为只读记录,不提供人工核定、重发、重置、改派或状态修改。 + +## 验证 + +- `src/test_onboarding_ui.py`:9 passed。 +- Python 编译和 `git diff --check` 通过。 +- Offscreen UI 检查确认顶部按钮为“添加账号/停止全部/设置”,详情 Tab 包含“异常任务”。 +- 未执行真实登录、启动、关注或私信操作。 diff --git a/docs/2026-09-09-18-02-windows-ssh-account-menu-deploy.md b/docs/2026-09-09-18-02-windows-ssh-account-menu-deploy.md new file mode 100644 index 0000000..5c473ff --- /dev/null +++ b/docs/2026-09-09-18-02-windows-ssh-account-menu-deploy.md @@ -0,0 +1,26 @@ +# Windows SSH 远程构建与验证记录 + +## 范围 + +将最新账号入口与异常任务 Tab 调整部署到 Windows 并启动供人工验证。未执行登录、启动业务、关注、私信或其他真实账号操作。 + +## 执行 + +- 通过 SSH 直连 Windows 主机,先检查 `DouyinAccounts.exe` 进程,确认未运行。 +- 上传 `src/accounts_app.py` 到: + `C:\Users\Rogee\douyin-pc-ui-20260909\src\accounts_app.py` +- 校验本地与远端 SHA-256 一致: + `e6f7e52e52618a4c6108c3914b8cf8f3e66eca164c05352152a2494a0f3528b1` +- Windows 原生执行: + `cd /d C:\Users\Rogee\douyin-pc-ui-20260909 && python build_windows.py` +- 静默安装生成的 `DouyinAccounts-0.1.8-Windows-x64-Setup.exe`。 +- 通过 Windows UI 在交互桌面启动已安装程序,避免 SSH 会话的 GUI 隔离。 + +## 验收 + +- 窗口成功启动,标题为“抖音账号助手 · 自动操作默认关闭”。 +- 顶部显示“添加账号”“停止全部”“设置”。 +- 大号右键菜单入口可用;账号卡片无左侧复选框。 +- 选中大号后,详情页显示“历史事件”“作品列表”“异常任务”Tab。 +- 日志提示、自动滚动和打开日志文件夹保持同一行;左侧约 30%,分隔条和背景样式正常。 +- 应用已保持运行供人工查看。 diff --git a/src/accounts_app.py b/src/accounts_app.py index f08f949..9721816 100644 --- a/src/accounts_app.py +++ b/src/accounts_app.py @@ -40,7 +40,6 @@ from PySide6.QtWidgets import ( QSizePolicy, QSpinBox, QSplitter, - QStackedWidget, QTableWidget, QTableWidgetItem, QTabWidget, @@ -369,7 +368,6 @@ def dialog(title, parent): class AccountCard(QFrame): selected = Signal(object) context_requested = Signal(object, object) - checked = Signal(str, bool) expand_requested = Signal() def __init__( @@ -379,7 +377,6 @@ class AccountCard(QFrame): meta, status, color, - checkable=False, expandable=False, parent=None, ): @@ -405,14 +402,6 @@ class AccountCard(QFrame): layout.addWidget(self.toggle_button) self.set_expandable(expandable) - self.check_box = QCheckBox() if checkable else None - if self.check_box is not None: - self.check_box.setToolTip("勾选后可批量启动该大号") - self.check_box.toggled.connect( - lambda checked: self.checked.emit(self.account_id, checked) - ) - layout.addWidget(self.check_box) - self.status_dot = QLabel("●") self.status_dot.setStyleSheet(f"color: {color}; font-size: 15px;") layout.addWidget(self.status_dot) @@ -460,7 +449,7 @@ class AccountCard(QFrame): return True if ( event.button() == Qt.MouseButton.LeftButton - and watched not in (self.check_box, self.toggle_button) + and watched is not self.toggle_button and self.account_id is not None ): self.selected.emit(self.account_id) @@ -543,7 +532,6 @@ class AccountCardTree(QScrollArea): self.layout_box.addStretch() self.setWidget(self.host) self.cards = {} - self.groups = {} self.nodes = {} self._selected_id = None self.viewport().installEventFilter(self) @@ -563,10 +551,9 @@ class AccountCardTree(QScrollArea): card.selected.connect(self._select) card.context_requested.connect(self.context_menu_requested) - def set_accounts(self, accounts, display, checked, selected_id): + def set_accounts(self, accounts, display, selected_id): self._clear() self.cards = {} - self.groups = {} self.nodes = {} self._selected_id = selected_id main_nodes = {} @@ -576,16 +563,12 @@ class AccountCardTree(QScrollArea): card = AccountCard( account["id"], **display[account["id"]], - checkable=True, parent=self.host, ) - if card.check_box is not None: - card.check_box.setChecked(account["id"] in checked) self._connect(card) node = AccountTreeNode(card, self.host) self._add_root(node) self.cards[account["id"]] = card - self.groups[account["id"]] = card self.nodes[account["id"]] = node main_nodes[account["id"]] = node @@ -637,13 +620,6 @@ class AccountCardTree(QScrollArea): def set_current_id(self, account_id): self._select(account_id) - def checked_groups(self): - return [ - account_id - for account_id, card in self.groups.items() - if card.check_box is not None and card.check_box.isChecked() - ] - def eventFilter(self, watched, event): if watched is self.viewport() and event.type() == QEvent.Type.ContextMenu: self.context_menu_requested.emit(None, event.globalPos()) @@ -664,7 +640,6 @@ class Window(QMainWindow): "browser": {}, "browser_overrides": {}, } - self.selection_loaded = False self.allow_close = False self.quitting = False self.signature = None @@ -675,8 +650,6 @@ class Window(QMainWindow): self.detail_account_id = None self.history_payload = None self.works_payload = None - self.exception_tasks = [] - self.exception_names = {} self.work_cover_cache = Path(self.backend.root) / "work_covers" self.network = QNetworkAccessManager(self) self.setWindowTitle("抖音账号助手 · 自动操作默认关闭") @@ -684,40 +657,43 @@ class Window(QMainWindow): central = QWidget() self.setCentralWidget(central) layout = QVBoxLayout(central) - note = QLabel( - "左侧账号树只显示别名、名称和状态;点击账号查看详情,账号操作请使用右键菜单。" - "恢复选择不会启动业务,启动前会先检查旧 pending 任务。" - ) - note.setWordWrap(True) - layout.addWidget(note) row = QHBoxLayout() layout.addLayout(row) self.buttons = [] for text, handler in [ - ("添加大号", lambda: self.add("main")), - ("添加小号", lambda: self.add("worker")), - ("恢复上次选择", self.restore_selection), - ("启动勾选组", self.start_groups), + ("添加账号", lambda: self.add("main")), ("停止全部", lambda: self.send("stop")), ]: button = self.button(row, text, handler) if text == "停止全部": self.stop_button = button - self.exception_button = QPushButton("异常任务") - self.exception_button.clicked.connect(self.show_exception_tasks) - row.addWidget(self.exception_button) self.button(row, "设置", lambda: self.browser_settings(False)) row.addStretch() - self.workspace_stack = QStackedWidget() accounts = QWidget() account_layout = QHBoxLayout(accounts) splitter = QSplitter(Qt.Orientation.Horizontal) + splitter.setHandleWidth(8) + splitter.setChildrenCollapsible(False) + splitter.setStyleSheet( + "QSplitter::handle:horizontal { background: #d9dde5; margin: 4px 0; }" + "QSplitter::handle:horizontal:hover { background: #1677ff; }" + ) account_layout.addWidget(splitter) left = QWidget() + left.setObjectName("accountTreePane") + left.setStyleSheet( + "#accountTreePane {" + "background: #f5f7fa; border: 1px solid #e5e7eb; border-radius: 8px;" + "}" + ) left_layout = QVBoxLayout(left) + left_layout.setContentsMargins(8, 8, 8, 8) self.card_table = AccountCardTree() self.card_table.setMinimumWidth(320) + self.card_table.setStyleSheet("background: transparent; border: 0;") + self.card_table.viewport().setStyleSheet("background: transparent;") + self.card_table.host.setStyleSheet("background: transparent;") self.card_table.context_menu_requested.connect(self.account_menu) self.card_table.selection_changed.connect(self.show_profile) left_layout.addWidget(self.card_table) @@ -876,24 +852,30 @@ class Window(QMainWindow): works_select.addStretch() main_works_layout.addLayout(works_select) + exception_tab = self._build_exception_tab() self.detail_tabs.addTab(main_history_tab, "历史事件") self.detail_tabs.addTab(main_works_tab, "作品列表") + self.detail_tabs.addTab(exception_tab, "异常任务") right_layout.addWidget(self.detail_tabs, 1) splitter.addWidget(right) - splitter.setStretchFactor(0, 2) - splitter.setStretchFactor(1, 5) - splitter.setSizes([390, 840]) - self.account_page = accounts - self.workspace_stack.addWidget(accounts) - self.exception_page = self._build_exception_page() - self.workspace_stack.addWidget(self.exception_page) - + splitter.setStretchFactor(0, 3) + splitter.setStretchFactor(1, 7) + try: + splitter.setSizes([int(self.width() * 0.3), int(self.width() * 0.7)]) + except (TypeError, ValueError): + splitter.setStretchFactor(0, 3) + splitter.setStretchFactor(1, 7) + splitter.handle(1).setCursor(Qt.CursorShape.SplitHCursor) + splitter.handle(1).setToolTip("拖动调整左侧账号树宽度") logs = QWidget() logs_layout = QVBoxLayout(logs) - self.log_info = QLabel("正在加载日志;按天保存完整记录,界面仅保留最近 2000 条") - self.log_info.setWordWrap(True) - logs_layout.addWidget(self.log_info) controls = QHBoxLayout() + self.log_info = QLabel("正在加载日志;按天保存完整记录,界面仅保留最近 2000 条") + self.log_info.setWordWrap(False) + self.log_info.setSizePolicy( + QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Preferred + ) + controls.addWidget(self.log_info, 1) self.auto_scroll = QCheckBox("自动滚动到最新记录") self.auto_scroll.setChecked(True) controls.addWidget(self.auto_scroll) @@ -907,7 +889,7 @@ class Window(QMainWindow): self.log.setMaximumBlockCount(UI_LIMIT) logs_layout.addWidget(self.log) vertical = QSplitter(Qt.Orientation.Vertical) - vertical.addWidget(self.workspace_stack) + vertical.addWidget(accounts) vertical.addWidget(logs) vertical.setStretchFactor(0, 5) vertical.setStretchFactor(1, 2) @@ -1043,37 +1025,20 @@ class Window(QMainWindow): self.works_table.setDisabled(checked) self.works_card_area.setDisabled(checked) - def _build_exception_page(self): - page = QWidget() - layout = QVBoxLayout(page) - heading = QHBoxLayout() - heading.addWidget(QLabel("异常任务(仅显示 unknown,只读)")) - back = QPushButton("返回账号工作台") - back.clicked.connect( - lambda: self.workspace_stack.setCurrentWidget(self.account_page) - ) - heading.addWidget(back) - layout.addLayout(heading) - filters = QHBoxLayout() - filters.addWidget(QLabel("原所属大号")) - self.exception_source_filter = QComboBox() - filters.addWidget(self.exception_source_filter) - filters.addWidget(QLabel("原执行小号")) - self.exception_worker_filter = QComboBox() - filters.addWidget(self.exception_worker_filter) - self.button(filters, "刷新异常任务", self.query_exception_tasks) - filters.addStretch() - layout.addLayout(filters) + def _build_exception_tab(self): + tab = QWidget() + layout = QVBoxLayout(tab) + layout.addWidget(QLabel("异常任务(当前大号所属分组;仅显示 unknown,只读)")) layout.addWidget( QLabel( - "unknown 只保留查询和保护占用,不提供人工核定、重发、重置、改派或状态修改。" + "结果不确定仅作只读记录,不提供人工核定、重发、重置、改派或状态修改。" ) ) self.exception_table = self._task_table(checkable=False) layout.addWidget(self.exception_table, 1) self.exception_counts = QLabel("结果不确定 0 条") layout.addWidget(self.exception_counts) - return page + return tab def _task_names(self): return self.data.get("task_names") or { @@ -1117,55 +1082,16 @@ class Window(QMainWindow): ) self.history_task_summary.setText(f"历史任务 {len(history)} 条") - def refresh_exception_filters(self): - source = self.exception_source_filter.currentData() - worker = self.exception_worker_filter.currentData() - accounts = self.data.get("accounts", []) - self.exception_source_filter.blockSignals(True) - self.exception_worker_filter.blockSignals(True) - self.exception_source_filter.clear() - self.exception_source_filter.addItem("全部原组", "") - for account in accounts: - if account["role"] == "main": - self.exception_source_filter.addItem(account["name"], account["id"]) - self.exception_worker_filter.clear() - self.exception_worker_filter.addItem("全部原执行小号", "") - for ident, name in sorted( - self._task_names().items(), key=lambda value: value[1] - ): - if any(a["id"] == ident and a["role"] == "main" for a in accounts): - continue - self.exception_worker_filter.addItem(name, ident) - self.exception_source_filter.setCurrentIndex( - max(0, self.exception_source_filter.findData(source)) - ) - self.exception_worker_filter.setCurrentIndex( - max(0, self.exception_worker_filter.findData(worker)) - ) - self.exception_source_filter.blockSignals(False) - self.exception_worker_filter.blockSignals(False) - - def show_exception_tasks(self): - self.workspace_stack.setCurrentWidget(self.exception_page) - self.refresh_exception_filters() - self.query_exception_tasks() - - def query_exception_tasks(self): - self.send( - "task_query", - { - "source": self.exception_source_filter.currentData() or None, - "worker": self.exception_worker_filter.currentData() or None, - }, - ) - - def render_exception_tasks(self, payload): - self.exception_tasks = payload.get("tasks", []) - self.exception_names = payload.get("task_names") or self._task_names() - self._fill_task_table( - self.exception_table, self.exception_tasks, self.exception_names - ) - self.exception_counts.setText(f"结果不确定 {len(self.exception_tasks)} 条") + def _refresh_detail_exceptions(self, account): + tasks = [] + if account and account["role"] == "main": + tasks = [ + task + for task in self.data.get("tasks", []) + if task["source"] == account["id"] and task["status"] == "unknown" + ] + self._fill_task_table(self.exception_table, tasks, self._task_names()) + self.exception_counts.setText(f"结果不确定 {len(tasks)} 条") def history_full(self): account = self.selected() @@ -1340,7 +1266,7 @@ class Window(QMainWindow): data["_request_id"] = request_id if data.get("id"): self.latest_requests[(name, data["id"])] = request_id - if name in ("task_query", "start_preview"): + if name == "start_preview": self.latest_global_requests[name] = request_id for button in self.buttons: button.setEnabled(False) @@ -1418,7 +1344,7 @@ class Window(QMainWindow): ): return if ( - name in ("task_query", "start_preview") + name == "start_preview" and request_id and self.latest_global_requests.get(name) != request_id ): @@ -1427,8 +1353,6 @@ class Window(QMainWindow): self.history_dialog(payload) elif name in ("works_open", "works_refresh", "works_full"): self.works_dialog(payload) - elif name == "task_query": - self.render_exception_tasks(payload) elif name == "start_preview": self.show_start_preview(payload) elif name == "cancel_pending": @@ -1648,12 +1572,6 @@ class Window(QMainWindow): load_cover(item) self._toggle_works_selection(self.works_all_mode.isChecked()) - def restore_selection(self): - self.selection_loaded = False - self.signature = None - self.refresh(self.data) - self.statusBar().showMessage("已恢复上次选择;不会启动业务") - def account_menu(self, account_id, global_pos): if account_id: self.card_table.set_current_id(account_id) @@ -1663,6 +1581,7 @@ class Window(QMainWindow): menu.addAction("登录 / 刷新账号信息", lambda: self.selected_command("open")) menu.addAction("打开账号浏览器", lambda: self.selected_command("open")) if account["role"] == "main": + menu.addAction("添加小号", lambda: self.add("worker", account["id"])) menu.addAction( "启动本组", lambda: self.start_group_request([account["id"]]) ) @@ -1697,6 +1616,7 @@ class Window(QMainWindow): self.history_table.setRowCount(0) self.works_table.setRowCount(0) self._clear_layout(self.works_card_grid) + self._refresh_detail_exceptions(None) return account_changed = self.detail_account_id != account["id"] if account_changed: @@ -1755,6 +1675,7 @@ class Window(QMainWindow): f"{self._sync_text(sync.get('notices'), '历史事件')} · {self._sync_text(sync.get('works'), '作品缓存')}" ) self._refresh_detail_tasks(account) + self._refresh_detail_exceptions(account) def selected_command(self, name): account = self.selected() @@ -1763,18 +1684,6 @@ class Window(QMainWindow): else: QMessageBox.information(self, "提示", "请先选择一个账号。") - def checked_groups(self): - return self.card_table.checked_groups() - - def start_groups(self): - groups = self.checked_groups() - if not groups: - QMessageBox.information( - self, "提示", "请勾选至少一个大号。上次选择会在重启后自动勾选。" - ) - return - self.start_group_request(groups) - def stop_selected_group(self): account = self.selected() if account: @@ -1807,7 +1716,7 @@ class Window(QMainWindow): {"id": account_box.currentData(), "owner": owner_box.currentData()}, ) - def add(self, role): + def add(self, role, owner_id=None): win, form, buttons = dialog("添加大号" if role == "main" else "添加小号", self) name = QLineEdit() name.setPlaceholderText("例如:主账号、客服一号") @@ -1819,6 +1728,10 @@ class Window(QMainWindow): owner.addItem(a["name"], a["id"]) if role == "worker": form.addRow("归属大号", owner) + if owner_id is not None: + index = owner.findData(owner_id) + if index >= 0: + owner.setCurrentIndex(index) restore = QPushButton("恢复已删除小号") def open_restore(): @@ -2048,7 +1961,6 @@ class Window(QMainWindow): new_accounts = [a for a in data["accounts"] if a["id"] not in known] if new_accounts: selected_id = new_accounts[-1]["id"] - checked = self.checked_groups() if self.selection_loaded else data["selected"] self.data = data self.log_info.setText( data.get("log_file_error") @@ -2059,7 +1971,6 @@ class Window(QMainWindow): ) ) self.signature = signature - self.selection_loaded = True display = {} for account in data["accounts"]: identity = account.get("identity", "") @@ -2078,9 +1989,8 @@ class Window(QMainWindow): "status": f"{'监听' if account['role'] == 'main' else '执行'}:{state}", "color": color, } - self.card_table.set_accounts(data["accounts"], display, checked, selected_id) + self.card_table.set_accounts(data["accounts"], display, selected_id) self.show_profile() - self.refresh_exception_filters() def closeEvent(self, event): if self.allow_close: