5 Commits

Author SHA1 Message Date
07d3a4420c 生成镜像[0.2.7.9][ci]
All checks were successful
CI / docker-ci (push) Successful in 25s
2026-03-23 11:28:14 +08:00
2c3c2d6acf Merge branch 'Django' of gitea.spdis.space:Viajero/Achievement_Inputing into Django
All checks were successful
CI / docker-ci (push) Has been skipped
2026-03-23 11:06:59 +08:00
afc663844b 修复主页的类型分析的500问题[0.2.7.9][ci] 2026-03-23 11:06:45 +08:00
DSQ
9e3fe7150b [0.2.7.8][ci]
All checks were successful
CI / docker-ci (push) Successful in 26s
2026-03-23 11:02:00 +08:00
DSQ
c9611fa622 [0.2.7.7][ci]
All checks were successful
CI / docker-ci (push) Successful in 35s
2026-03-23 10:37:46 +08:00
4 changed files with 202 additions and 185 deletions

View File

@@ -192,5 +192,6 @@ def get_visible_data(current_user):
生产环境用于创建数据库结构的临时命令: 生产环境用于创建数据库结构的临时命令:
python manage.py shell -c "from elastic.es_connect import create_index_with_mapping; create_index_with_mapping()" python manage.py shell -c "from elastic.es_connect import create_index_with_mapping; create_index_with_mapping()"

View File

@@ -445,6 +445,11 @@ async function generateReport() {
try { try {
const params = buildReportParams(); const params = buildReportParams();
const resp = await fetch(`/elastic/report/?${params.toString()}`, { credentials: 'same-origin' }); const resp = await fetch(`/elastic/report/?${params.toString()}`, { credentials: 'same-origin' });
const ct = (resp.headers.get('content-type') || '').toLowerCase();
if (!ct.includes('application/json')) {
const text = await resp.text();
throw new Error(text ? String(text).slice(0, 200) : `HTTP ${resp.status}`);
}
const data = await resp.json(); const data = await resp.json();
if (data.status !== 'success') { if (data.status !== 'success') {
reportBox.className = 'search-result error'; reportBox.className = 'search-result error';

View File

@@ -494,6 +494,11 @@ uploadForm.addEventListener('submit', async (e) => {
body: formData, body: formData,
}); });
clearInterval(timer); clearInterval(timer);
const ct = (resp.headers.get('content-type') || '').toLowerCase();
if (!ct.includes('application/json')) {
const text = await resp.text();
throw new Error(text ? String(text).slice(0, 200) : `HTTP ${resp.status}`);
}
const data = await resp.json(); const data = await resp.json();
if (!resp.ok || data.status !== 'success') { if (!resp.ok || data.status !== 'success') {
throw new Error(data.message || '上传识别失败'); throw new Error(data.message || '上传识别失败');

View File

@@ -8,6 +8,7 @@ import base64
import json import json
import csv import csv
import io import io
from datetime import datetime, timezone, timedelta
import tempfile import tempfile
import concurrent.futures import concurrent.futures
from django.conf import settings from django.conf import settings
@@ -721,6 +722,7 @@ def upload_page(request):
# 上传并识别(不入库) # 上传并识别(不入库)
@require_http_methods(["POST"]) @require_http_methods(["POST"])
def upload(request): def upload(request):
try:
if request.session.get("user_id") is None: if request.session.get("user_id") is None:
fallback_uid = request.POST.get("user_id") or request.GET.get("user_id") fallback_uid = request.POST.get("user_id") or request.GET.get("user_id")
if fallback_uid: if fallback_uid:
@@ -740,11 +742,10 @@ def upload(request):
images_dir = os.path.join(settings.MEDIA_ROOT, "images") images_dir = os.path.join(settings.MEDIA_ROOT, "images")
os.makedirs(images_dir, exist_ok=True) os.makedirs(images_dir, exist_ok=True)
# 按照原始文件进行分组处理
file_results = [] file_results = []
for f in files: for f in files:
group_images = [] # 存储该文件生成的所有图片路径信息 (abs_path, filename) group_images = []
is_pdf = f.name.lower().endswith('.pdf') is_pdf = f.name.lower().endswith('.pdf')
if is_pdf: if is_pdf:
@@ -779,7 +780,6 @@ def upload(request):
dst.write(chunk) dst.write(chunk)
group_images.append((abs_path, filename)) group_images.append((abs_path, filename))
# 对该组图片并行进行 OCR 识别
def run_ocr(img_info): def run_ocr(img_info):
abs_p, fname = img_info abs_p, fname = img_info
try: try:
@@ -796,23 +796,24 @@ def upload(request):
if res: if res:
group_data_list.append(res) group_data_list.append(res)
# 合并该文件的多页识别结果
merged_group_data = {} merged_group_data = {}
for item in group_data_list: for item in group_data_list:
if not isinstance(item, dict): continue if not isinstance(item, dict):
continue
for k, v in item.items(): for k, v in item.items():
key = str(k).strip() key = str(k).strip()
if not key: continue if not key:
continue
if key not in merged_group_data or merged_group_data.get(key) in (None, ''): if key not in merged_group_data or merged_group_data.get(key) in (None, ''):
merged_group_data[key] = v merged_group_data[key] = v
elif merged_group_data.get(key) != v: elif merged_group_data.get(key) != v:
base = key base = key
idx = 2 idx = 2
while f"{base}_{idx}" in merged_group_data: idx += 1 while f"{base}_{idx}" in merged_group_data:
idx += 1
merged_group_data[f"{base}_{idx}"] = v merged_group_data[f"{base}_{idx}"] = v
if not merged_group_data: if not merged_group_data:
# 如果没识别到,至少保留一个空结构或者包含文件名的提示
merged_group_data = {"文件名": f.name, "提示": "未识别到具体内容"} merged_group_data = {"文件名": f.name, "提示": "未识别到具体内容"}
rel_paths = [f"images/{img[1]}" for img in group_images] rel_paths = [f"images/{img[1]}" for img in group_images]
@@ -830,6 +831,8 @@ def upload(request):
"message": f"成功处理 {len(file_results)} 个文件,请确认数据后点击录入", "message": f"成功处理 {len(file_results)} 个文件,请确认数据后点击录入",
"items": file_results, "items": file_results,
}) })
except Exception as e:
return JsonResponse({"status": "error", "message": str(e) or "上传失败"}, status=500)
# 确认并入库 # 确认并入库
@@ -1024,7 +1027,7 @@ def analytics_types_view(request):
size_int = int(size) if size is not None else 10 size_int = int(size) if size is not None else 10
except Exception: except Exception:
size_int = 10 size_int = 10
data = es_analytics_types(gte=gte, lte=lte, size=size_int) data = es_analytics_types(gte=gte, lte=lte, limit=size_int)
return JsonResponse({"status": "success", "data": data}) return JsonResponse({"status": "success", "data": data})
except Exception as e: except Exception as e:
return JsonResponse({"status": "error", "message": str(e)}, status=500) return JsonResponse({"status": "error", "message": str(e)}, status=500)
@@ -1580,6 +1583,7 @@ def _dt_label(dt, interval: str):
@require_http_methods(["GET"]) @require_http_methods(["GET"])
def report_view(request): def report_view(request):
try:
session_user_id = request.session.get("user_id") session_user_id = request.session.get("user_id")
if session_user_id is None: if session_user_id is None:
return JsonResponse({"status": "error", "message": "未登录"}, status=401) return JsonResponse({"status": "error", "message": "未登录"}, status=401)
@@ -1678,6 +1682,8 @@ def report_view(request):
}, },
} }
) )
except Exception as e:
return JsonResponse({"status": "error", "message": str(e) or "生成失败"}, status=500)
@require_http_methods(["GET"]) @require_http_methods(["GET"])