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:
2026-05-05 19:37:10 +08:00
parent c18039f790
commit 81bafaf557
20 changed files with 1610 additions and 502 deletions
+39 -3
View File
@@ -18,18 +18,31 @@ _excel_source = str(_project_root / "templates" / "商品资料.xlsx")
class MemoryItem(BaseModel):
barcode: str
name: str
spec: Optional[str] = None
specification: Optional[str] = None
unit: Optional[str] = None
price: Optional[float] = None
avg_price: Optional[float] = None
min_price: Optional[float] = None
max_price: Optional[float] = None
price_count: int = 0
confidence: int = 0
source: str = "ocr"
last_used: Optional[str] = None
use_count: int = 0
class MemoryCreate(BaseModel):
barcode: str
name: Optional[str] = ""
specification: Optional[str] = None
unit: Optional[str] = None
price: Optional[float] = None
confidence: int = 50
class MemoryUpdate(BaseModel):
name: Optional[str] = None
spec: Optional[str] = None
specification: Optional[str] = None
unit: Optional[str] = None
price: Optional[float] = None
confidence: Optional[int] = None
@@ -51,9 +64,13 @@ def _row_to_item(row: Dict) -> MemoryItem:
return MemoryItem(
barcode=row.get("barcode", ""),
name=row.get("name", ""),
spec=row.get("spec"),
specification=row.get("specification"),
unit=row.get("unit"),
price=row.get("price"),
avg_price=row.get("avg_price"),
min_price=row.get("min_price"),
max_price=row.get("max_price"),
price_count=row.get("price_count", 0),
confidence=row.get("confidence", 0),
source=row.get("source", "ocr"),
last_used=row.get("last_used"),
@@ -99,6 +116,25 @@ async def get_memory(
return product
@router.post("")
async def create_memory(
body: MemoryCreate,
current_user: dict = Depends(get_current_user),
):
db = _get_db()
existing = db.get_memory(body.barcode)
if existing:
raise HTTPException(409, f"条码 {body.barcode} 已存在,请使用编辑功能")
db.learn_from_product({
"barcode": body.barcode,
"name": body.name or "",
"specification": body.specification or "",
"unit": body.unit or "",
"price": body.price or 0,
}, source="user_confirmed")
return {"message": f"已创建记忆记录 {body.barcode}"}
@router.put("/{barcode}")
async def update_memory(
barcode: str,