91 lines
2.8 KiB
HTML
91 lines
2.8 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="zh-CN">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<title>测试执行</title>
|
|
<link rel="stylesheet" href="/static/static.css">
|
|
</head>
|
|
<body>
|
|
<div class="wrap">
|
|
<header>
|
|
<h1>测试:执行一次同步</h1>
|
|
<nav class="nav"><a href="/">首页</a><a href="/runs">同步流水</a></nav>
|
|
</header>
|
|
<p class="status-msg" id="hint"></p>
|
|
<div class="toolbar">
|
|
<label>类型
|
|
<select id="step"></select>
|
|
</label>
|
|
<label>锚定日 <input type="date" id="date" placeholder="空=按配置推算"></label>
|
|
<button class="primary" id="run">执行一次</button>
|
|
</div>
|
|
<div class="panel">
|
|
<h3>执行状态</h3>
|
|
<pre id="status">加载中…</pre>
|
|
</div>
|
|
</div>
|
|
<script src="/static/app.js"></script>
|
|
<script>
|
|
let pollTimer;
|
|
|
|
function formatStatus(s) {
|
|
const lines = [
|
|
'运行中: ' + (s.running ? '是' : '否'),
|
|
'类型: ' + (s.last_step_label || s.last_step || '-'),
|
|
'锚定日: ' + (s.last_date || '-'),
|
|
'开始: ' + fmtTimeAny(s.started_at),
|
|
'结束: ' + fmtTimeAny(s.finished_at),
|
|
];
|
|
if (s.last_error) lines.push('错误: ' + s.last_error);
|
|
return lines.join('\n');
|
|
}
|
|
|
|
async function refreshStatus() {
|
|
const s = await api('/api/test/status');
|
|
document.getElementById('status').textContent = formatStatus(s);
|
|
document.getElementById('run').disabled = s.running;
|
|
if (!s.running && s.finishedAt && s.finishedAt !== '0001-01-01T00:00:00Z') {
|
|
const d = s.last_date;
|
|
if (d && !pollTimer) {
|
|
const go = confirm('执行已结束。是否打开同步流水?');
|
|
if (go) location.href = '/runs?anchor_date=' + d;
|
|
}
|
|
}
|
|
}
|
|
|
|
async function init() {
|
|
const m = await loadMeta();
|
|
if (m && m.testStepOptions) fillStepSelect(document.getElementById('step'), m.testStepOptions);
|
|
const hint = document.getElementById('hint');
|
|
if (!m || !m.allowTest) {
|
|
hint.innerHTML = '<span class="badge err">测试同步不可用</span> 请使用 <code>transit serve</code> 启动,并设置 LOG_WEB_ALLOW_TEST=true';
|
|
document.getElementById('run').disabled = true;
|
|
} else {
|
|
hint.textContent = '将执行完整链路:建批次 → 拉取 → 上报 → 批量回调。与 CLI transit sync 相同。';
|
|
}
|
|
await refreshStatus();
|
|
setInterval(refreshStatus, 2000);
|
|
}
|
|
|
|
document.getElementById('run').onclick = async () => {
|
|
const step = document.getElementById('step').value;
|
|
const date = document.getElementById('date').value;
|
|
try {
|
|
const r = await api('/api/test/sync', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ step, date }),
|
|
});
|
|
showToast('已启动: ' + (r.step_label || r.step) + ' 锚定日=' + r.date, 'ok');
|
|
pollTimer = null;
|
|
refreshStatus();
|
|
} catch (e) {
|
|
showToast(e.message, 'err');
|
|
}
|
|
};
|
|
|
|
init();
|
|
</script>
|
|
</body>
|
|
</html>
|