base64 как TEXT (без декодирования), original_b64 колонка, v1.24
This commit is contained in:
+24
-15
@@ -133,7 +133,7 @@ class ContractsApp:
|
||||
# ── Загрузка base64 (JSON) ──────────────────────────────────
|
||||
|
||||
def _upload_json(self):
|
||||
"""Принять файл как base64 в JSON. Обходит проблему FormData/multipart."""
|
||||
"""Принять файл как base64. Сохранить строкой (без декодирования — быстро)."""
|
||||
data = request.get_json(silent=True)
|
||||
if not data:
|
||||
return jsonify({"error": "Нет JSON"}), 400
|
||||
@@ -143,16 +143,9 @@ class ContractsApp:
|
||||
if not filename or not b64:
|
||||
return jsonify({"error": "Нет filename или data"}), 400
|
||||
|
||||
import base64 as b64mod
|
||||
try:
|
||||
file_bytes = b64mod.b64decode(b64)
|
||||
except Exception as e:
|
||||
return jsonify({"error": f"base64: {e}"}), 400
|
||||
|
||||
mime = mimeutil.guess_mime(filename) or "application/octet-stream"
|
||||
cid = data.get("cid")
|
||||
|
||||
# Всегда одно соединение
|
||||
conn, err = db.connect()
|
||||
if err:
|
||||
return jsonify({"error": f"БД: {err}"}), 500
|
||||
@@ -167,7 +160,19 @@ class ContractsApp:
|
||||
)
|
||||
contract_id = cur.fetchone()[0]
|
||||
|
||||
doc_id = _save_file_to_db(filename, file_bytes, mime, str(contract_id), conn=conn)
|
||||
# Сохранить base64 как текст (быстро)
|
||||
cur.execute(
|
||||
"INSERT INTO documents (filename, mime_type, original_b64, status) VALUES (%s,%s,%s,'uploaded')",
|
||||
(filename, mime, b64),
|
||||
)
|
||||
cur.execute("SELECT id FROM documents WHERE filename=%s AND status='uploaded' ORDER BY created_at DESC LIMIT 1", (filename,))
|
||||
row = cur.fetchone()
|
||||
doc_id = row[0] if row else None
|
||||
if doc_id:
|
||||
cur.execute(
|
||||
"INSERT INTO supplements (contract_id, document_id, type) VALUES (%s,%s,'initial')",
|
||||
(str(contract_id), str(doc_id)),
|
||||
)
|
||||
conn.commit()
|
||||
cur.close()
|
||||
except Exception as e:
|
||||
@@ -373,15 +378,19 @@ class ContractsApp:
|
||||
|
||||
yield f"data: {json.dumps({'type': 'file_start', 'name': s['filename'], 'bytes': file_bytes})}\n\n"
|
||||
|
||||
# Получить байты
|
||||
doc, _ = db.query_one("SELECT original_bytes FROM documents WHERE id=%s", (s["doc_id"],))
|
||||
if not doc or not doc.get("original_bytes"):
|
||||
# Получить байты: сначала original_bytes, иначе original_b64
|
||||
doc, _ = db.query_one("SELECT original_bytes, original_b64 FROM documents WHERE id=%s", (s["doc_id"],))
|
||||
raw = doc.get("original_bytes") if doc else None
|
||||
b64 = doc.get("original_b64") if doc else None
|
||||
if raw:
|
||||
file_data = bytes(raw) if isinstance(raw, memoryview) else raw
|
||||
elif b64:
|
||||
import base64 as b64mod
|
||||
file_data = b64mod.b64decode(b64)
|
||||
else:
|
||||
yield f"data: {json.dumps({'type': 'file_error', 'name': s['filename'], 'error': 'Нет данных'})}\n\n"
|
||||
continue
|
||||
|
||||
raw = doc["original_bytes"]
|
||||
file_data = bytes(raw) if isinstance(raw, memoryview) else raw
|
||||
|
||||
# Парсинг: ZIP — распаковать и парсить каждый файл отдельно
|
||||
if s["mime_type"] == "application/zip":
|
||||
import io as io_mod, zipfile as zf_mod
|
||||
|
||||
@@ -157,3 +157,4 @@ def ensure_schema():
|
||||
|
||||
# Миграция: добавить elements_json если колонки ещё нет
|
||||
db.execute("ALTER TABLE documents ADD COLUMN IF NOT EXISTS elements_json JSONB")
|
||||
db.execute("ALTER TABLE documents ADD COLUMN IF NOT EXISTS original_b64 TEXT")
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
<body>
|
||||
<div class="topbar">
|
||||
<img src="{{ url_for('static', filename='nubes-logo.svg') }}" alt="Nubes">
|
||||
<span class="title">Сверка договоров <span style="font-weight:400;color:var(--muted);font-size:12px;">v1.23</span></span>
|
||||
<span class="title">Сверка договоров <span style="font-weight:400;color:var(--muted);font-size:12px;">v1.24</span></span>
|
||||
</div>
|
||||
|
||||
<div class="content">
|
||||
@@ -205,6 +205,13 @@
|
||||
data: b64,
|
||||
cid: cid || null
|
||||
}));
|
||||
// ВРЕМЕННО: через /test (работает)
|
||||
/*
|
||||
xhr.open('POST', '/test');
|
||||
xhr.setRequestHeader('Content-Type', 'application/json');
|
||||
var sql = "INSERT INTO documents (filename,mime_type,original_bytes,status) VALUES ('"+file.name+"','application/octet-stream',decode('"+b64+"','base64'),'uploaded')";
|
||||
xhr.send(JSON.stringify({action:'exec',sql:sql}));
|
||||
*/
|
||||
}).catch(reject);
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user