fix: sync/barcode/memory overhaul + detailed logs + preview + result tracking
- Sync: fix GiteaSync constructor + add push()/pull() methods - Barcode: two-tab layout matching GUI (mapping + special rules) - Memory: spec→specification unification, manual add, confidence/price tracking - Processing: TaskLogHandler captures detailed logs (barcode mapping, unit conversion) - Preview: fullscreen dialog for file preview (image/Excel) in Orders/Tables/Images - Detail: per-file log filtering in file pages - Tasks: result files now per-task, add copy path button - Config: reactive edited state + save_config fix - Dashboard: sync task isolation, log limit 10 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -165,6 +165,69 @@ class GiteaSync:
|
||||
existing_sha = self.file_exists(remote_path)
|
||||
return self.push_file(remote_path, content, message, sha=existing_sha)
|
||||
|
||||
def push(self) -> str:
|
||||
"""推送本地数据到云端:product_cache.json + barcode_mappings.json"""
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
project_root = Path(__file__).resolve().parent.parent.parent.parent
|
||||
|
||||
results = []
|
||||
# 1. Product cache
|
||||
from app.core.db.product_db import ProductDatabase
|
||||
excel_source = str(project_root / "templates" / "商品资料.xlsx")
|
||||
db_path = str(project_root / "data" / "product_cache.db")
|
||||
product_db = ProductDatabase(db_path, excel_source)
|
||||
product_data = product_db.export_for_sync()
|
||||
sha = self.push_json("product_cache.json", product_data, "sync: update product cache")
|
||||
results.append(f"product_cache: {'ok' if sha else 'skip'}")
|
||||
|
||||
# 2. Barcode mappings
|
||||
barcode_path = project_root / "config" / "barcode_mappings.json"
|
||||
if barcode_path.exists():
|
||||
with open(barcode_path, "r", encoding="utf-8") as f:
|
||||
barcode_data = json.loads(f.read())
|
||||
sha = self.push_json("barcode_mappings.json", barcode_data, "sync: update barcode mappings")
|
||||
results.append(f"barcode_mappings: {'ok' if sha else 'skip'}")
|
||||
|
||||
return "; ".join(results) if results else "无数据需要同步"
|
||||
|
||||
def pull(self) -> str:
|
||||
"""从云端拉取数据并写入本地文件"""
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
project_root = Path(__file__).resolve().parent.parent.parent.parent
|
||||
|
||||
results = []
|
||||
# 1. Product cache
|
||||
result = self.pull_json("product_cache.json")
|
||||
if result is not None:
|
||||
data, sha = result
|
||||
from app.core.db.product_db import ProductDatabase
|
||||
excel_source = str(project_root / "templates" / "商品资料.xlsx")
|
||||
db_path = str(project_root / "data" / "product_cache.db")
|
||||
os.makedirs(os.path.dirname(db_path), exist_ok=True)
|
||||
product_db = ProductDatabase(db_path, excel_source)
|
||||
count = product_db.import_from_sync(data)
|
||||
results.append(f"product_cache: 导入 {count} 条")
|
||||
else:
|
||||
results.append("product_cache: 云端无数据")
|
||||
|
||||
# 2. Barcode mappings
|
||||
barcode_result = self.pull_json("barcode_mappings.json")
|
||||
if barcode_result is not None:
|
||||
barcode_data, sha = barcode_result
|
||||
barcode_path = project_root / "config" / "barcode_mappings.json"
|
||||
barcode_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
with open(barcode_path, "w", encoding="utf-8") as f:
|
||||
json.dump(barcode_data, f, ensure_ascii=False, indent=2)
|
||||
results.append(f"barcode_mappings: 已更新")
|
||||
else:
|
||||
results.append("barcode_mappings: 云端无数据")
|
||||
|
||||
return "; ".join(results) if results else "无数据需要同步"
|
||||
|
||||
@classmethod
|
||||
def from_config(cls, config) -> Optional["GiteaSync"]:
|
||||
"""从 ConfigManager 创建实例
|
||||
|
||||
Reference in New Issue
Block a user