fix: 增强导出下载诊断能力,缩短超时时间

下载超时从 300s 减至 120s,失败时自动保存截图、打印服务端响应内容、
检查页面错误提示和新标签页,便于定位 download 事件未触发的根因。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-17 18:23:32 +08:00
parent 975f9e5887
commit b402612641
2 changed files with 99 additions and 21 deletions
+10 -7
View File
@@ -4,7 +4,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
## Project Overview
SalesShow is a monolithic Flask web application for analyzing sales data from Excel files. It supports manual Excel uploads and automated daily downloads from secsion.com via Playwright browser automation. There is no database — all data lives as Excel files on disk in `uploads/`.
SaleShow is a monolithic Flask web application for analyzing sales data from Excel files. It supports manual Excel uploads and automated daily downloads from secsion.com via Playwright browser automation. There is no database — all data lives as Excel files on disk in `uploads/`.
## Commands
@@ -23,6 +23,7 @@ gunicorn -w 4 -b 0.0.0.0:8000 app:app
# CLI automation — download reports from secsion.com
python -m automation.secsion --start 2026-04-28 --end 2026-04-28
python -m automation.secsion --start 2026-05-15 --end 2026-05-17 --username 15682076681 --password yourpassword
```
No test framework or linter is configured in this project.
@@ -31,17 +32,19 @@ No test framework or linter is configured in this project.
**Backend (Flask, single `app.py`):**
- Routes handle file upload (`/upload`), file listing (`/files`), data loading/processing (`/load/<filename>`), deletion, and cleanup.
- `process_sales_data()` (~lines 371-575 in `app.py`) is the core logic. It uses a state-machine approach to handle two Excel formats: "flat tables" (each row has code + product) and "hierarchical tables" (code row is a header, product rows are children). Outputs daily summaries with per-product breakdowns.
- `process_sales_data()` (~lines 371-575) is the core logic. It uses a state-machine approach to handle two Excel formats: "flat tables" (each row has code + product) and "hierarchical tables" (code row is a header, product rows are children). Outputs daily summaries with per-product breakdowns.
- `find_header_row()` dynamically detects the header row by scanning first 20 rows for keyword matches.
- Auto-download routes use a global `download_status` dict and run Playwright in daemon threads via `threading.Thread`.
**Automation module (`automation/`):**
- `secsion.py``SecsionDownloader` uses Playwright headless Chromium to log into secsion.com, navigate to reports, set date range via TDesign date picker, optionally inject `shop_id` via route interception, and download exports.
- `uploader.py` — copies downloaded files into `uploads/` with timestamp-prefix naming (same convention as manual uploads).
- `scheduler.py` — APScheduler `BackgroundScheduler` with `CronTrigger` runs daily auto-download (default 01:00).
- `secsion.py``SecsionDownloader` uses Playwright headless Chromium to log into secsion.com, navigate to reports, set date range via TDesign date picker (requires click → select day → Enter confirm → Escape close sequence), optionally inject `shop_id` via route interception on `**/api/bill/export`, and download exports. Has 3-retry logic with exponential backoff.
- `uploader.py` — copies downloaded files into `uploads/` with `YYYYMMDD_HHMMSS_` prefix naming (same convention as manual uploads).
- `scheduler.py` — APScheduler `BackgroundScheduler` with `CronTrigger` runs daily auto-download (default 01:00). Uses `misfire_grace_time=3600`.
**Configuration (`config.py`):**
- Three-tier priority: Web UI settings (`data/config.json`) > environment variables (`.env` / system env) > defaults.
- `Config` class provides static methods for reading/writing secsion credentials, shop ID, and scheduler settings.
- Passwords are masked (`******`) when returned via the API.
**Frontend (vanilla JS/CSS, no build step):**
- `main.js` — all client-side interactivity: file upload (drag-and-drop), AJAX to API, data rendering (card/table view), client-side filtering, sorting, pagination (50 items/page), export.
@@ -52,5 +55,5 @@ No test framework or linter is configured in this project.
- No database — Excel files on disk are the data store.
- No frontend build step — vanilla JS/CSS served directly via Flask static files.
- Playwright automation runs in daemon threads with a global `download_status` dict for status tracking.
- Passwords are masked (`******`) when returned via the API.
- Playwright automation runs in daemon threads; status tracked via module-level `download_status` dict in `app.py`.
- The secsion.com date picker uses TDesign's `needconfirm="true"` mode — simply calling `.fill()` won't work; must click cell then press Enter.