mirror of
https://github.com/goldenfishs/MRobot.git
synced 2026-02-04 18:00:19 +08:00
6.5 KiB
6.5 KiB
导入账户查询问题 - 解决方案文档
🐛 问题描述
用户反馈:导入的账户无法进行查询操作。
问题表现
- 账户成功导入(UI显示导入成功)
- 账户出现在账户列表中
- 但是使用查询功能时无法显示结果
- 做账页面也可能无法显示导入账户的记录
🔍 根本原因
问题源于 import_account_package 方法中的两个bug:
Bug #1: 元数据ID不同步
问题流程:
1. ZIP包中存储原始账户ID (例如: f78adb43-cf2c-49be-8e36-361908db6d68)
2. 导入时如果账户已存在,创建新ID (例如: 1c4b2c9f-1629-463d-b7a0-cbcff93c99)
3. 新ID用于创建文件夹
4. 但metadata.json中的ID仍然是原始ID
5. 加载时,目录名(新ID)与metadata中的ID(原始ID)不匹配
6. load_all_accounts() 无法正确识别账户
Bug #2: UI刷新不完整
问题流程:
1. 导入后只调用 refresh_account_list()
2. 但没有设置导入账户为当前选中账户
3. 用户可能仍在查看旧账户的数据
4. 查询页面没有被清空
✅ 解决方案
修复1: 同步metadata中的账户ID
文件: app/tools/finance_manager.py
修改:
def import_account_package(self, zip_path: str) -> Optional[str]:
"""导入账户压缩包,返回导入的账户ID"""
try:
zip_path = Path(zip_path)
if not zip_path.exists():
return None
# 先加载元数据以获取账户ID
with zipfile.ZipFile(zip_path, 'r') as zipf:
metadata_content = zipf.read('metadata.json')
metadata = json.loads(metadata_content)
account_id = metadata['id']
# 如果账户已存在,创建新ID
if account_id in self.accounts:
account_id = str(uuid.uuid4())
# ✅ 关键修复: 更新元数据中的ID
metadata['id'] = account_id
# 解压到临时目录
temp_dir = self.data_root / f"_temp_{uuid.uuid4()}"
with zipfile.ZipFile(zip_path, 'r') as zipf:
zipf.extractall(temp_dir)
# ✅ 关键修复: 更新临时目录中的元数据文件
metadata_file = temp_dir / 'metadata.json'
with open(metadata_file, 'w', encoding='utf-8') as f:
json.dump(metadata, f, ensure_ascii=False, indent=2)
# 移动到正式目录
account_dir = self._get_account_dir(account_id)
if account_dir.exists():
shutil.rmtree(account_dir)
shutil.move(str(temp_dir), str(account_dir))
# 重新加载账户
self.load_all_accounts()
return account_id
except Exception as e:
print(f"导入账户出错: {e}")
return None
修复2: 完整的UI刷新流程
文件: app/finance_interface.py
修改:
def import_account(self):
"""导入账户ZIP包"""
zip_file, _ = QFileDialog.getOpenFileName(
self, "选择要导入的账户文件",
"", "ZIP文件 (*.zip)"
)
if zip_file:
account_id = self.finance_manager.import_account_package(zip_file)
if account_id:
# ✅ 关键修复: 刷新账户列表
self.refresh_account_list()
# ✅ 关键修复: 找到新导入的账户并设置为当前账户
for i in range(self.account_combo.count()):
if self.account_combo.itemData(i) == account_id:
self.account_combo.setCurrentIndex(i)
break
# ✅ 关键修复: 清空查询结果以显示新导入账户的数据
self.query_result_table.setRowCount(0)
InfoBar.success("账户导入成功", "", duration=2000, parent=self)
else:
QMessageBox.warning(self, "错误", "导入账户失败")
修复3: 账户切换时清空查询结果
文件: app/finance_interface.py
修改:
def on_account_changed(self):
"""账户改变时刷新显示"""
account_id = self.get_current_account_id()
if account_id:
self.refresh_records_display()
# ✅ 关键修复: 切换账户时清空查询结果
self.query_result_table.setRowCount(0)
🧪 验证
运行测试脚本 test_import_query.py 验证修复:
python test_import_query.py
预期输出:
✅ 找到有数据的测试账户: '测试账户'
✅ 导出成功
✅ 导入成功
✅ 导入的账户信息: 名称: 测试账户, 交易数: 1
✅ 无条件查询: 1 条记录
✅ 按交易人'测试商家'查询: 1 条记录
📝 使用流程
修复后,导入账户的完整流程:
-
打开财务做账模块
- 点击左侧"财务做账"导航
-
点击"导出"标签页
- 选择要导入的ZIP文件
- 点击"导入账户"按钮
-
验证导入结果
- 新账户自动出现在账户列表中
- 新账户自动设置为当前选中账户
- 做账页显示导入的交易记录
- 可以立即在查询页进行查询
🔧 技术细节
数据结构
assets/Finance_Data/
└── accounts/
└── [账户ID]/
├── metadata.json ← 关键: ID必须与文件夹名一致
└── [交易ID]/
├── data.json
├── invoice/
├── payment/
└── purchase/
关键对象关系
FinanceManager.accounts = {
'账户ID': Account(...),
...
}
Account.id ↔ 文件夹名称 ↔ metadata.json中的id
加载流程
load_all_accounts()
├─ 遍历 accounts/ 目录
├─ 加载每个目录下的 metadata.json
├─ 使用 metadata['id'] 作为关键字
└─ 如果ID与文件夹名不匹配 → 账户加载失败
⚠️ 重要提醒
-
ID一致性: 账户ID必须在三个地方一致:
- 文件夹名称
- metadata.json中的id字段
- FinanceManager.accounts字典的键
-
元数据更新: 创建新ID时必须更新元数据文件
-
重新加载: 导入后必须调用load_all_accounts()刷新内存中的账户
📊 测试结果
| 测试项 | 修复前 | 修复后 |
|---|---|---|
| 账户导入 | ✅ 成功 | ✅ 成功 |
| 账户识别 | ❌ 失败 | ✅ 成功 |
| 数据查询 | ❌ 无结果 | ✅ 正常 |
| UI更新 | ❌ 不完整 | ✅ 完整 |
| 做账显示 | ❌ 无数据 | ✅ 显示数据 |
更新日期: 2025-11-25
修复状态: ✅ 完成
测试状态: ✅ 通过
生产准备: ✅ 就绪