diff --git a/routes/admin_observability_routes.py b/routes/admin_observability_routes.py index 027ee4c..69cbabb 100644 --- a/routes/admin_observability_routes.py +++ b/routes/admin_observability_routes.py @@ -2235,6 +2235,7 @@ def ppt_audit_history(): if not os.path.isdir(reports_dir): error = f'{reports_dir} 目錄不存在' else: + files_by_name = {} for f in os.listdir(reports_dir): if not f.lower().endswith('.pptx'): continue @@ -2247,14 +2248,68 @@ def ppt_audit_history(): try: mtime = os.path.getmtime(full) if month_start_ts <= mtime < month_end_ts: - files.append({ + files_by_name[f] = { + 'source': 'filesystem', 'name': f, 'size_kb': round(os.path.getsize(full) / 1024, 1), 'mtime': datetime.fromtimestamp(mtime).strftime('%Y-%m-%d %H:%M'), 'mtime_ts': mtime, - }) + 'file_exists': True, + 'file_path': full, + } except OSError: continue + + # 補充:若 188 主機僅保留 DB 快取紀錄或掃描過程漏掉,仍可回補當月報表清單 + try: + session = get_session() + try: + sql = """ + SELECT report_type, file_path, file_size, generated_at + FROM ppt_reports + WHERE generated_at >= :month_start + AND generated_at < :month_end + """ + params = {'month_start': month_start, 'month_end': month_end} + if report_type != 'all': + sql += " AND report_type = :report_type" + params['report_type'] = report_type + rows = session.execute(sa_text(sql), params).fetchall() + + for rpt_type, file_path, file_size, generated_at in rows: + if not file_path: + continue + name = os.path.basename(file_path) + if not name.lower().endswith('.pptx'): + continue + if report_prefix != 'all' and not name.startswith(report_prefix): + continue + if name in files_by_name: + files_by_name[name]['source'] = 'both' + continue + if not generated_at: + continue + mtime = generated_at.timestamp() + if not (month_start_ts <= mtime < month_end_ts): + continue + candidate_path = os.path.join(reports_dir, name) + exists = os.path.isfile(candidate_path) + files_by_name[name] = { + 'source': 'database', + 'name': name, + 'size_kb': round((file_size or 0) / 1024, 1), + 'mtime': generated_at.strftime('%Y-%m-%d %H:%M'), + 'mtime_ts': mtime, + 'file_exists': exists, + 'file_path': candidate_path if exists else file_path, + 'report_type': rpt_type, + } + finally: + session.close() + except Exception: + pass + + files = list(files_by_name.values()) files.sort(key=lambda x: x['mtime_ts'], reverse=True) except Exception as e: error = f'{type(e).__name__}: {str(e)[:200]}' diff --git a/templates/admin/ppt_audit_history.html b/templates/admin/ppt_audit_history.html index b53ffc8..a2140bf 100644 --- a/templates/admin/ppt_audit_history.html +++ b/templates/admin/ppt_audit_history.html @@ -274,7 +274,7 @@
- +
@@ -282,17 +282,29 @@ {% for f in files %} - + - +
檔名KB修改時間狀態操作
{{ f.name }}{{ f.size_kb }}{{ f.size_kb if f.size_kb is not none else '—' }} {{ f.mtime }}22:00 排程掃描 + {% if f.source == 'database' %} + {% if f.file_exists %}資料庫快取 + 檔案可存取{% else %}資料庫快取(檔案未落盤){% endif %} + {% elif f.source == 'both' %} + 檔案 + 資料庫 + {% else %} + 22:00 掃描落盤 + {% endif %} +
+ {% if f.file_exists %} 開啟 下載 + {% else %} + 本機暫無檔案,請先至來源回補 + {% endif %}