diff --git a/api/main.py b/api/main.py index 06b6264..a72e895 100644 --- a/api/main.py +++ b/api/main.py @@ -36,6 +36,8 @@ app.add_middleware( def db() -> sqlite3.Connection: conn = sqlite3.connect(DB_PATH) conn.row_factory = sqlite3.Row + # Отложенные оператором позиции (чтобы пропущенное не возвращалось в начало очереди). + conn.execute("CREATE TABLE IF NOT EXISTS skipped_item (item_id INTEGER PRIMARY KEY)") return conn @@ -155,6 +157,7 @@ def unmatched(limit: int = 50, offset: int = 0): JOIN partner p ON pi.partner_id = p.partner_id LEFT JOIN service s ON pi.suggested_service_id = s.service_id WHERE pi.service_id IS NULL AND pi.is_active = 1 + AND pi.item_id NOT IN (SELECT item_id FROM skipped_item) ORDER BY pi.suggested_score DESC, pi.item_id LIMIT ? OFFSET ?""" with db() as conn: @@ -184,12 +187,22 @@ def unmatched(limit: int = 50, offset: int = 0): def unmatched_count(): with db() as conn: n = conn.execute( - "SELECT COUNT(*) FROM price_item WHERE service_id IS NULL AND is_active = 1" + """SELECT COUNT(*) FROM price_item + WHERE service_id IS NULL AND is_active = 1 + AND item_id NOT IN (SELECT item_id FROM skipped_item)""" ).fetchone()[0] learned = conn.execute("SELECT COUNT(*) FROM learned_synonym").fetchone()[0] return {"remaining": n, "learned_synonyms": learned} +@app.post("/skip", summary="Отложить позицию (пропустить в очереди верификации)") +def skip_item(item_id: int): + with db() as conn: + conn.execute("INSERT OR IGNORE INTO skipped_item (item_id) VALUES (?)", [item_id]) + conn.commit() + return {"item_id": item_id, "status": "skipped"} + + @app.post("/match", summary="Ручное сопоставление позиции (с дообучением)") def manual_match(item_id: int, service_id: str): with db() as conn: diff --git a/web/index.html b/web/index.html index ed0346a..4e444f7 100644 --- a/web/index.html +++ b/web/index.html @@ -57,6 +57,7 @@
Система предлагает кандидата из справочника — подтвердите, выберите другой или пропустите. Подтверждение обучает систему.
+ @@ -145,11 +146,17 @@ async function loadAdmin() { } async function loadQueue() { - const items = await fetch(`${API}/unmatched?limit=40`).then(r => r.json()); + const items = await fetch(`${API}/unmatched?limit=25`).then(r => r.json()); $('queue').innerHTML = items.map(renderCard).join('') || '