157 lines
6.2 KiB
HTML
157 lines
6.2 KiB
HTML
<!doctype html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="utf-8" />
|
||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||
<title>二维码批量识别工具</title>
|
||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" />
|
||
<link href="/static/style.css" rel="stylesheet" />
|
||
</head>
|
||
<body class="bg-light">
|
||
<main class="container py-4" id="app">
|
||
<header class="d-flex align-items-center justify-content-between mb-3">
|
||
<h1 class="h4 mb-0">二维码批量识别工具 v1.0</h1>
|
||
<div class="text-muted small" id="statusText">就绪</div>
|
||
</header>
|
||
|
||
<section class="card mb-3" id="viewUpload">
|
||
<div class="card-body">
|
||
<div class="mb-3">
|
||
<div id="dropzone" class="dropzone">
|
||
<div class="fw-semibold">拖拽压缩包或图片到此处</div>
|
||
<div class="text-muted small">或点击选择文件(ZIP / PNG / JPG / JPEG / BMP)</div>
|
||
<input id="fileInput" type="file" class="d-none" multiple accept=".zip,.png,.jpg,.jpeg,.bmp,image/png,image/jpeg,image/bmp" />
|
||
</div>
|
||
</div>
|
||
|
||
<div class="row g-3">
|
||
<div class="col-12 col-lg-8">
|
||
<div class="border rounded-3 p-3 bg-white">
|
||
<div class="d-flex align-items-center justify-content-between mb-2">
|
||
<div class="fw-semibold">上传的文件</div>
|
||
<button class="btn btn-sm btn-outline-secondary" id="btnClear">清空列表</button>
|
||
</div>
|
||
<div id="fileList" class="file-list text-muted">暂无文件</div>
|
||
</div>
|
||
</div>
|
||
<div class="col-12 col-lg-4">
|
||
<div class="border rounded-3 p-3 bg-white">
|
||
<div class="fw-semibold mb-2">参数</div>
|
||
<div class="mb-2">
|
||
<label class="form-label small text-muted mb-1" for="concurrencyInput">并发数</label>
|
||
<input class="form-control form-control-sm" id="concurrencyInput" type="number" min="1" max="32" value="4" />
|
||
</div>
|
||
<div class="mb-3">
|
||
<label class="form-label small text-muted mb-1" for="timeoutInput">单张超时(秒)</label>
|
||
<input class="form-control form-control-sm" id="timeoutInput" type="number" min="1" max="60" value="30" />
|
||
</div>
|
||
<div class="text-muted small">ZIP≤100MB;图片≤10MB/张;非图片会被忽略</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card-footer d-flex gap-2 justify-content-end">
|
||
<button class="btn btn-primary" id="btnStart" disabled>开始处理</button>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="card mb-3 d-none" id="viewProgress">
|
||
<div class="card-body">
|
||
<div class="d-flex align-items-center justify-content-between">
|
||
<div class="fw-semibold">处理中…</div>
|
||
<div class="text-muted small" id="progressPercent">0%</div>
|
||
</div>
|
||
<div class="progress mt-2" role="progressbar" aria-label="处理进度">
|
||
<div class="progress-bar" id="progressBar" style="width:0%"></div>
|
||
</div>
|
||
|
||
<div class="row mt-3 g-3">
|
||
<div class="col-6 col-lg-3">
|
||
<div class="stat">
|
||
<div class="stat-label">总计</div>
|
||
<div class="stat-value" id="statTotal">0</div>
|
||
</div>
|
||
</div>
|
||
<div class="col-6 col-lg-3">
|
||
<div class="stat">
|
||
<div class="stat-label">已处理</div>
|
||
<div class="stat-value" id="statProcessed">0</div>
|
||
</div>
|
||
</div>
|
||
<div class="col-6 col-lg-3">
|
||
<div class="stat">
|
||
<div class="stat-label">成功</div>
|
||
<div class="stat-value text-success" id="statSuccess">0</div>
|
||
</div>
|
||
</div>
|
||
<div class="col-6 col-lg-3">
|
||
<div class="stat">
|
||
<div class="stat-label">失败</div>
|
||
<div class="stat-value text-danger" id="statFailed">0</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="mt-3 text-muted small">
|
||
<div>当前处理:<span id="currentFile">-</span></div>
|
||
<div>速度:<span id="speed">-</span> 张/秒 | 预计剩余:<span id="remaining">-</span></div>
|
||
</div>
|
||
</div>
|
||
<div class="card-footer d-flex gap-2 justify-content-end">
|
||
<button class="btn btn-outline-danger" id="btnCancel">取消</button>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="card mb-3 d-none" id="viewResult">
|
||
<div class="card-body">
|
||
<div class="d-flex align-items-center justify-content-between">
|
||
<div class="fw-semibold" id="resultTitle">处理完成!</div>
|
||
<div class="text-muted small" id="taskMeta">-</div>
|
||
</div>
|
||
|
||
<div class="row mt-3 g-3">
|
||
<div class="col-6">
|
||
<div class="stat">
|
||
<div class="stat-label">成功</div>
|
||
<div class="stat-value text-success" id="resultSuccess">0</div>
|
||
</div>
|
||
</div>
|
||
<div class="col-6">
|
||
<div class="stat">
|
||
<div class="stat-label">失败</div>
|
||
<div class="stat-value text-danger" id="resultFailed">0</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="d-flex gap-2 mt-3 flex-wrap">
|
||
<button class="btn btn-primary" id="btnDownloadExcel">下载Excel结果</button>
|
||
<button class="btn btn-outline-secondary" id="btnBack">返回首页</button>
|
||
</div>
|
||
|
||
<div class="mt-4 d-none" id="failuresWrap">
|
||
<div class="fw-semibold mb-2">失败文件列表</div>
|
||
<div class="table-responsive">
|
||
<table class="table table-sm table-striped align-middle mb-0">
|
||
<thead>
|
||
<tr>
|
||
<th style="width:72px">序号</th>
|
||
<th>图片路径</th>
|
||
<th style="width:260px">失败原因</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody id="failuresBody"></tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<div class="alert alert-danger d-none" id="errorAlert" role="alert"></div>
|
||
</main>
|
||
|
||
<script src="/static/app.js"></script>
|
||
</body>
|
||
</html>
|