feat: 添加名单表格搜索筛选功能#240
Conversation
在点名表格和抽奖表格中添加搜索栏,支持按关键词实时筛选表格行。 - 点名表格:支持按学号、姓名、性别、小组、标签筛选 - 抽奖表格:支持按序号、奖品、权重、标签、数量筛选 - 使用 SearchLineEdit 组件,带防抖处理(300ms) - 添加中/英/日三语国际化翻译 - 刷新数据后自动重新应用搜索过滤 Closes SECTL#232
在点名历史记录和抽奖历史记录表格中添加导出按钮, 支持将当前表格数据导出为 xlsx、csv、txt 格式。 - 点名历史记录:支持导出全部记录、按时间查看、个人统计三种模式的数据 - 抽奖历史记录:支持导出全部记录、按时间查看、奖品统计三种模式的数据 - 导出内容与用户当前看到的表格一致(包括筛选和排序状态) - 添加中/英/日三语国际化翻译 - 添加 QFileDialog 翻译配置 Closes SECTL#232
| export_type = ( | ||
| "excel" | ||
| if "Excel 文件 (*.xlsx)" in selected_filter | ||
| else "csv" | ||
| if "CSV 文件 (*.csv)" in selected_filter | ||
| else "txt" | ||
| ) |
This comment was marked as outdated.
This comment was marked as outdated.
Sorry, something went wrong.
| export_type = ( | ||
| "excel" | ||
| if "Excel 文件 (*.xlsx)" in selected_filter | ||
| else "csv" | ||
| if "CSV 文件 (*.csv)" in selected_filter | ||
| else "txt" | ||
| ) |
This comment was marked as outdated.
This comment was marked as outdated.
Sorry, something went wrong.
修复非中文语言环境下导出格式判断失败的问题。 将 'Excel 文件 (*.xlsx)' 改为 '.xlsx' 匹配, 确保所有语言下都能正确识别导出格式。
Signed-off-by: Hongbro886 <hongbroyier@gmail.com>
| content=get_any_position_value_async( | ||
| "notification", | ||
| "lottery", | ||
| "export", | ||
| "content", | ||
| "error", | ||
| "name", | ||
| ).format(message=str(e)), |
This comment was marked as outdated.
This comment was marked as outdated.
Sorry, something went wrong.
- 为 notification 模块补充缺失的 JA_JP 翻译 - 为 get_any_position_value_async 返回值添加空值保护, 防止翻译缺失时 .format() 调用 None 导致 AttributeError
- 修复导出仅导出已加载行而非全部数据的问题(Critical) 导出前检查是否所有数据已加载,未加载时强制加载全部数据 - 修复预期导出错误使用 logger.exception 导致误报 Sentry 的问题 改用 logger.error() 符合项目 Sentry 日志策略 - 修复默认文件名硬编码中文字符串的问题 添加 export_default_filename i18n 键,支持三语 - 修复 TXT 导出硬编码中文表头匹配的问题 改用列索引识别名称列,不再依赖表头文本 - 抽取共享导出工具 export_utils.py 消除代码重复 - 添加 get_path() 和 mkdir() 路径保护,与项目既有模式一致
| def _apply_search_filter(self): | ||
| """根据搜索关键词过滤表格行""" | ||
| if not hasattr(self, "table") or self.table is None: | ||
| return | ||
|
|
||
| keyword = self.search_line_edit.text().strip().lower() |
There was a problem hiding this comment.
Bug: A race condition during initialization can cause an AttributeError if refresh_data is signaled before create_search_bar completes, as _apply_search_filter accesses an uninitialized attribute.
Severity: MEDIUM
Suggested Fix
Add a guard at the beginning of the _apply_search_filter method to ensure the search_line_edit attribute exists before attempting to access it, for example: if not hasattr(self, "search_line_edit"): return.
Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.
Location: app/view/settings/list_management/roll_call_table.py#L111-L116
Potential issue: A race condition can occur during component initialization. Several
setup methods, including `create_search_bar`, are scheduled to run deferred using
`QTimer.singleShot`. However, the `refresh_signal` is connected before these methods
execute. If this signal is emitted before the event loop processes the deferred calls,
`refresh_data` is invoked. Its `finally` block calls `_apply_search_filter`, which
attempts to access `self.search_line_edit`. Because `create_search_bar` has not yet run,
this attribute does not exist, resulting in an `AttributeError`.
Also affects:
app/view/settings/list_management/lottery_table.py:117~122
| def export_history_data(self): | ||
| if not self.current_class_name: | ||
| return | ||
|
|
||
| if self.current_row < self.total_rows: |
There was a problem hiding this comment.
Bug: Exporting large history datasets results in incomplete files because the data loading logic is capped at ~630 rows when the UI is not rendered.
Severity: HIGH
Suggested Fix
Modify the data loading logic in _ensure_scrollable_rows to not depend on the scrollbar's visibility when force_load_all is true. Instead, it should loop until all expected rows (self.total_rows) are loaded.
Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.
Location: app/view/settings/history/roll_call_history_table.py#L1163-L1167
Potential issue: When exporting a history table with more than approximately 630 rows,
the resulting file is incomplete. The `export_history_data` function triggers a data
load that relies on a loop in `_ensure_scrollable_rows`. This loop's condition depends
on the scrollbar's visibility (`max_value == 0`) and is limited to 20 attempts. When
exporting, the widget may not be rendered, so the scrollbar never appears, and the loop
loads a maximum of 20 batches (600 rows). Data beyond this limit is never loaded into
the table, causing it to be exported as empty rows.
Also affects:
app/view/settings/history/lottery_history_table.py:997~1001
概述
实现 #232 请求的功能:在查看名单时添加搜索/筛选功能。
变更内容
新增功能
技术实现
SearchLineEdit组件(qfluentwidgets),与项目现有搜索组件风格一致ic_fluent_search_20_filled图标,与 Fluent Design 风格一致国际化
修改文件
app/view/settings/list_management/roll_call_table.py— 点名表格添加搜索功能app/view/settings/list_management/lottery_table.py— 抽奖表格添加搜索功能app/Language/modules/list_management.py— 添加搜索相关翻译截图
搜索栏位于班级/奖池选择器下方、表格上方,输入关键词即可实时筛选。
Closes #232