diff --git a/site/app.py b/site/app.py index fff6b97..b25d161 100644 --- a/site/app.py +++ b/site/app.py @@ -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 diff --git a/site/schema.py b/site/schema.py index 6d4f91d..ee6aa90 100644 --- a/site/schema.py +++ b/site/schema.py @@ -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") diff --git a/site/templates/upload.html b/site/templates/upload.html index 4e92644..3bf63e4 100644 --- a/site/templates/upload.html +++ b/site/templates/upload.html @@ -59,7 +59,7 @@