Files
xk-hy-transit-go/internal/logweb/web/supervise_step.html
2026-07-15 08:47:41 +08:00

144 lines
5.8 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<title>处方/核销联调</title>
<link rel="stylesheet" href="/static/static.css">
<style>
.step-block { margin-bottom: 2rem; }
.step-block h2 { margin: 0 0 0.5rem; font-size: 1.15rem; }
.muted-note { color: var(--muted); font-size: 0.88rem; margin: 0 0 0.75rem; }
.result-panel { margin-top: 0.75rem; }
.result-panel h4 { margin: 0.75rem 0 0.25rem; font-size: 0.9rem; color: var(--accent); }
.result-panel pre { margin: 0 0 0.5rem; max-height: 14rem; overflow: auto; font-size: 0.82rem; }
</style>
</head>
<body>
<div class="wrap">
<header>
<h1>处方上传 / 处方核销联调</h1>
<nav class="nav" id="main-nav"></nav>
</header>
<p class="muted-note">与 Cron/CLI 自动同步共用 <code>executeStep</code>(开头刷新 token/config → 拉取 → 组包签名上报 → 批量回调)。默认每条 step 只处理 <b>1</b> 条;对比验收可设 limit=0。</p>
<div class="step-block" id="block-recipe">
<h2>测试在线处方上传</h2>
<div class="toolbar">
<label>锚定日 <input type="date" id="date-recipe"></label>
<label>条数 limit
<input type="number" id="limit-recipe" min="0" value="1" style="width:4rem" title="0=全部">
</label>
<button class="primary" id="run-recipe">执行</button>
</div>
<div class="result-panel" id="out-recipe"><pre>尚未执行</pre></div>
</div>
<div class="step-block" id="block-verification">
<h2>测试处方核销</h2>
<div class="toolbar">
<label>锚定日 <input type="date" id="date-verification"></label>
<label>条数 limit
<input type="number" id="limit-verification" min="0" value="1" style="width:4rem">
</label>
<button class="primary" id="run-verification">执行</button>
</div>
<div class="result-panel" id="out-verification"><pre>尚未执行</pre></div>
</div>
</div>
<script src="/static/app.js"></script>
<script>
if (typeof renderMainNav === 'function') renderMainNav('supervise-step');
function renderStepResult(data) {
if (!data) return '(无数据)';
const lines = [];
lines.push('step: ' + (data.step_label || data.step) + ' anchor: ' + data.anchor_date + ' batch_id: ' + data.batch_id);
if (data.pull_summary) {
const p = data.pull_summary;
lines.push('拉取: total=' + p.total + ' validation_failed=' + p.validation_failed + ' processed=' + p.processed);
}
if (data.summary) {
const s = data.summary;
lines.push('结果: success=' + s.success + ' failed=' + s.failed + ' skipped=' + s.skipped);
}
if (data.callback_error) {
lines.push('callback_error: ' + data.callback_error);
}
if (!data.items || !data.items.length) {
lines.push('(无业务条)');
return lines.join('\n') + '\n\n' + JSON.stringify(data, null, 2);
}
data.items.forEach((it, i) => {
lines.push('\n--- 记录 #' + (i + 1) + ' biz_key=' + (it.biz_key || '-') + ' ---');
if (it.validation_errors && it.validation_errors.length) {
lines.push('validation_errors: ' + JSON.stringify(it.validation_errors));
}
if (it.payload_snapshot) {
lines.push('\n[组包 payload 快照]\n' + it.payload_snapshot);
}
if (it.push_plain_json) {
lines.push('\n[推送明文 push_plain_json]\n' + it.push_plain_json);
}
const fu = it.recipe_file_upload;
if (fu) {
lines.push('\n[文件上传 28211]\n' + JSON.stringify(fu, null, 2));
}
if (it.push_headers) {
lines.push('\n[推送头 push_headers]\n' + JSON.stringify(it.push_headers, null, 2));
}
if (it.push) {
const hasResp = it.push.response_body || it.push.http_code || it.push.msg;
if (hasResp) {
lines.push('\n[政务云上报]\n' + JSON.stringify(it.push, null, 2));
} else if (it.validation_errors && it.validation_errors.length) {
lines.push('\n[政务云上报] 未执行(组包校验失败,记录已 skipped');
} else {
lines.push('\n[政务云上报] 未执行(未到达 PostForward请检查拉取条数或前置步骤');
}
}
if (it.callback) {
lines.push('\n[云端回调 CallbackItem]\n' + JSON.stringify(it.callback, null, 2));
}
});
return lines.join('\n');
}
async function runStep(step, dateEl, limitEl, outEl, btn) {
const date = dateEl.value;
const limit = parseInt(limitEl.value, 10);
const body = { step, date, limit: isNaN(limit) ? 1 : limit };
btn.disabled = true;
outEl.innerHTML = '<pre>执行中…(开头会 ReloadCloudConfig</pre>';
try {
const r = await fetch('/api/supervise/step-test', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(body),
});
const j = await r.json().catch(() => ({}));
if (!r.ok) {
const text = (j.result ? renderStepResult(j.result) + '\n\n错误: ' : '') + (j.error || r.statusText);
outEl.innerHTML = '<pre>' + esc(text) + '</pre>';
showToast(firstLine(j.error || text), 'err');
return;
}
outEl.innerHTML = '<pre>' + esc(renderStepResult(j)) + '</pre>';
showToast('完成 step=' + step, 'ok');
} catch (e) {
outEl.innerHTML = '<pre>' + esc(e.message) + '</pre>';
showToast(e.message, 'err');
} finally {
btn.disabled = false;
}
}
const dateRecipe = document.getElementById('date-recipe');
const dateVer = document.getElementById('date-verification');
document.getElementById('run-recipe').onclick = () =>
runStep('recipe', dateRecipe, document.getElementById('limit-recipe'), document.getElementById('out-recipe'), document.getElementById('run-recipe'));
document.getElementById('run-verification').onclick = () =>
runStep('verification', dateVer, document.getElementById('limit-verification'), document.getElementById('out-verification'), document.getElementById('run-verification'));
</script>
</body>
</html>