feat: complete production workflow migration

This commit is contained in:
wangyunlong committed 2026-08-06 14:29:57 +08:00
1 parent 7f215e79c4
commit 8df5266abb
448 files changed
+56937 -14619

No files matched your search

+8
View File
@@ -0,0 +1,8 @@
"""Static assets for the GYXX Flow workflow console."""
from pathlib import Path
WEB_ROOT = Path(__file__).resolve().parent
INDEX_HTML = WEB_ROOT / "index.html"
__all__ = ["INDEX_HTML", "WEB_ROOT"]
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+303
View File
@@ -0,0 +1,303 @@
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="color-scheme" content="light">
<meta name="theme-color" content="#f5f7fb">
<title>GYXX Flow · 工作流控制台</title>
<meta name="description" content="按业务模块查看、配置和运行 GYXX Flow 工作流。">
<link rel="stylesheet" href="/assets/app.css?v=workflow-lineage-20260803a">
</head>
<body>
<a class="skip-link" href="#main-content">跳到主要内容</a>
<div class="app-shell" id="app-shell">
<header class="topbar">
<div class="topbar__brand">
<button class="icon-button mobile-menu-button" id="mobile-menu-button" type="button" aria-label="打开模块导航" aria-controls="sidebar" aria-expanded="false">
☰
</button>
<span class="brand-mark" aria-hidden="true">G</span>
<span class="brand-copy">
<strong>GYXX Flow</strong>
<small>工作流控制台</small>
</span>
</div>
<div class="topbar__actions">
<div class="service-pill" id="service-pill" data-tone="neutral" role="status" aria-live="polite" title="正在读取调度服务状态">
<span class="service-pill__dot" aria-hidden="true"></span>
<span id="service-pill-label">正在连接</span>
</div>
<span class="timezone-chip" id="timezone-chip">Asia/Shanghai</span>
<span class="refresh-time" id="refresh-time">尚未刷新</span>
<button class="icon-button" id="refresh-button" type="button" aria-label="刷新工作流数据" title="刷新">
↻
</button>
<button class="token-button" id="token-button" type="button" title="管理访问令牌">令牌</button>
</div>
</header>
<div class="sidebar-scrim" id="sidebar-scrim" hidden></div>
<aside class="sidebar" id="sidebar" aria-label="业务模块导航">
<div class="sidebar__intro">
<span class="eyebrow">业务模块</span>
<p>选择模块,快速聚焦对应工作流。</p>
</div>
<nav class="module-nav" id="module-nav" aria-label="工作流模块">
<button class="module-nav__item is-active" type="button" data-module="all" aria-current="page">
<span class="module-nav__glyph module-nav__glyph--all" aria-hidden="true">全</span>
<span class="module-nav__copy"><strong>全部工作流</strong><small>读取中</small></span>
<span class="module-nav__count" id="all-module-count">…</span>
</button>
</nav>
<div class="sidebar__footer">
<span class="sidebar__status-dot" id="sidebar-status-dot" aria-hidden="true"></span>
<div>
<strong id="sidebar-status-title">控制台待连接</strong>
<small id="sidebar-status-detail">等待服务器响应</small>
</div>
</div>
</aside>
<main class="main" id="main-content" tabindex="-1">
<section class="hero" aria-labelledby="page-title">
<div class="hero__copy">
<span class="eyebrow">WORKFLOW OPERATIONS</span>
<h1 id="page-title">让每条工作流,都清晰可控</h1>
<p>集中查看自动计划、手动启动任务,并快速定位最近一次执行结果与错误。</p>
</div>
<div class="hero__meta">
<span>数据生成时间</span>
<strong id="generated-at">等待数据</strong>
</div>
</section>
<section class="summary-grid" aria-label="工作流概览">
<article class="summary-card summary-card--total">
<span class="summary-card__icon" aria-hidden="true">流</span>
<div><span>全部工作流</span><strong id="summary-total">…</strong><small>统一目录</small></div>
</article>
<article class="summary-card summary-card--enabled">
<span class="summary-card__icon" aria-hidden="true">启</span>
<div><span>自动运行</span><strong id="summary-enabled">…</strong><small id="summary-scheduled-detail">定时计划</small></div>
</article>
<article class="summary-card summary-card--running">
<span class="summary-card__icon" aria-hidden="true">行</span>
<div><span>当前运行中</span><strong id="summary-running">…</strong><small>实时任务</small></div>
</article>
<article class="summary-card summary-card--failed">
<span class="summary-card__icon" aria-hidden="true">异</span>
<div><span>最近失败</span><strong id="summary-failed">…</strong><small id="summary-unavailable-detail">含不可用项</small></div>
</article>
</section>
<section class="control-bar" aria-label="筛选工作流">
<label class="search-field" for="workflow-search">
<span aria-hidden="true">⌕</span>
<input id="workflow-search" type="search" placeholder="搜索名称、ID 或来源任务" autocomplete="off">
<kbd aria-hidden="true">/</kbd>
</label>
<div class="control-bar__filters">
<div class="select-field" data-custom-select>
<label class="sr-only" for="trigger-filter">触发方式</label>
<select id="trigger-filter" aria-label="触发方式">
<option value="all" data-description="显示所有触发类型">全部触发方式</option>
<option value="scheduled" data-description="由常驻调度服务按计划启动">定时工作流</option>
<option value="manual" data-description="仅可从控制台手动启动">仅手动</option>
<option value="unavailable" data-description="当前没有可用执行入口">不可执行</option>
</select>
</div>
<div class="select-field" data-custom-select>
<label class="sr-only" for="status-filter">执行状态</label>
<select id="status-filter" aria-label="执行状态">
<option value="all" data-description="显示全部运行结果">全部执行状态</option>
<option value="running" data-description="正在执行或同步结果">运行中</option>
<option value="failed" data-description="最近一次执行失败">最近失败</option>
<option value="success" data-description="最近一次执行成功">最近成功</option>
<option value="cancelled" data-description="最近一次执行由操作员停止">最近取消</option>
<option value="idle" data-description="还没有执行记录">暂无记录</option>
<option value="paused" data-description="自动计划已经暂停">已暂停</option>
</select>
</div>
<label class="filter-switch">
<input id="error-only-filter" type="checkbox">
<span aria-hidden="true"></span>
只看异常
</label>
</div>
</section>
<div class="filter-context" id="filter-context" hidden>
<span id="filter-context-label" role="status" aria-live="polite"></span>
<button type="button" id="clear-filters-button">清除筛选</button>
</div>
<div class="dashboard" id="workflow-dashboard" aria-busy="true">
<section class="module-section skeleton-section" aria-hidden="true">
<div class="skeleton skeleton--heading"></div>
<div class="workflow-grid">
<div class="workflow-card skeleton-card"><span class="skeleton skeleton--line skeleton--wide"></span><span class="skeleton skeleton--line"></span><span class="skeleton skeleton--block"></span></div>
<div class="workflow-card skeleton-card"><span class="skeleton skeleton--line skeleton--wide"></span><span class="skeleton skeleton--line"></span><span class="skeleton skeleton--block"></span></div>
<div class="workflow-card skeleton-card"><span class="skeleton skeleton--line skeleton--wide"></span><span class="skeleton skeleton--line"></span><span class="skeleton skeleton--block"></span></div>
</div>
</section>
</div>
</main>
</div>
<div class="overlay" id="drawer-overlay" hidden>
<div class="overlay__backdrop" data-close="drawer" aria-hidden="true"></div>
<aside class="drawer" id="workflow-drawer" role="dialog" aria-modal="true" aria-labelledby="drawer-title" aria-hidden="true">
<header class="drawer__header">
<div class="drawer__identity">
<span class="module-glyph" id="drawer-module-glyph" aria-hidden="true">流</span>
<div class="drawer__title-copy">
<span class="eyebrow" id="drawer-module-name">工作流详情</span>
<div class="drawer__title-row" id="drawer-title-row">
<h2 id="drawer-title">…</h2>
<button class="drawer__rename-button" id="drawer-rename-button" type="button" aria-label="修改工作流显示名称" aria-controls="drawer-name-form" aria-expanded="false">
<svg aria-hidden="true" viewBox="0 0 16 16"><path d="M10.8 2.3a1.4 1.4 0 0 1 2 2L6 11.1l-2.8.7.7-2.8 6.9-6.7Z"/><path d="m9.7 3.4 2.9 2.9"/></svg>
<span>修改名称</span>
</button>
</div>
<form class="drawer-name-editor" id="drawer-name-form" aria-label="修改工作流显示名称" hidden>
<div class="drawer-name-editor__row">
<label class="sr-only" for="drawer-name-input">工作流显示名称</label>
<input id="drawer-name-input" name="display_name" type="text" maxlength="64" autocomplete="off" aria-describedby="drawer-name-hint drawer-name-error" required>
<button class="button button--primary drawer-name-editor__save" id="drawer-name-save" type="submit">保存</button>
<button class="button button--ghost drawer-name-editor__cancel" id="drawer-name-cancel" type="button">取消</button>
</div>
<div class="drawer-name-editor__meta">
<span id="drawer-name-hint">只改变控制台显示,不影响执行、定时计划和历史记录。</span>
<button id="drawer-name-reset" type="button" hidden>恢复默认名称</button>
<span id="drawer-name-count" aria-live="polite">0 / 64</span>
</div>
<p class="drawer-name-editor__error" id="drawer-name-error" role="alert" hidden></p>
</form>
<code id="drawer-workflow-id">…</code>
</div>
</div>
<button class="icon-button" id="drawer-close-button" type="button" aria-label="关闭详情">×</button>
</header>
<div class="drawer__status-row" id="drawer-status-row"></div>
<div class="drawer-tabs" role="tablist" aria-label="工作流详情分类">
<button type="button" role="tab" id="tab-overview" aria-controls="panel-overview" aria-selected="true" data-tab="overview">概览</button>
<button type="button" role="tab" id="tab-steps" aria-controls="panel-steps" aria-selected="false" data-tab="steps" tabindex="-1">执行流程</button>
<button type="button" role="tab" id="tab-history" aria-controls="panel-history" aria-selected="false" data-tab="history" tabindex="-1">运行历史</button>
<button type="button" role="tab" id="tab-schedule" aria-controls="panel-schedule" aria-selected="false" data-tab="schedule" tabindex="-1">定时配置</button>
</div>
<div class="drawer__body">
<section class="drawer-panel" id="panel-overview" role="tabpanel" aria-labelledby="tab-overview" data-panel="overview"></section>
<section class="drawer-panel" id="panel-steps" role="tabpanel" aria-labelledby="tab-steps" data-panel="steps" hidden></section>
<section class="drawer-panel" id="panel-history" role="tabpanel" aria-labelledby="tab-history" data-panel="history" hidden></section>
<section class="drawer-panel" id="panel-schedule" role="tabpanel" aria-labelledby="tab-schedule" data-panel="schedule" hidden></section>
</div>
<footer class="drawer__footer">
<button class="button button--secondary" id="drawer-configure-button" type="button">配置定时</button>
<button class="button button--stop" id="drawer-stop-button" type="button" hidden>停止执行</button>
<button class="button button--primary" id="drawer-run-button" type="button">立即运行</button>
</footer>
</aside>
</div>
<div class="overlay overlay--center" id="run-overlay" hidden>
<div class="overlay__backdrop" data-close="run" aria-hidden="true"></div>
<section class="modal run-modal" id="run-modal" role="dialog" aria-modal="true" aria-labelledby="run-modal-title" aria-hidden="true">
<header class="modal__header">
<div><span class="eyebrow">MANUAL RUN</span><h2 id="run-modal-title">运行工作流</h2><code id="run-workflow-id">…</code></div>
<button class="icon-button" id="run-close-button" type="button" aria-label="关闭运行确认">×</button>
</header>
<form id="run-form" novalidate>
<div class="modal__body">
<label class="field">
<span id="run-period-label">业务日期</span>
<input id="run-business-date" name="business_date" type="date" required>
<small id="run-date-hint">本次数据处理所对应的业务日期。</small>
</label>
<fieldset class="field">
<legend>执行方式</legend>
<div class="segmented-control">
<label><input type="radio" name="execute" value="true"><span><strong>真实执行</strong><small>允许产生实际业务影响</small></span></label>
<label><input type="radio" name="execute" value="false" checked><span><strong>安全预演</strong><small>检查流程但不执行外部效果</small></span></label>
</div>
</fieldset>
<label class="switch-row">
<span><strong>影子模式</strong><small>保留执行证据并标记为 shadow</small></span>
<input id="run-shadow" name="shadow" type="checkbox">
<span class="switch-control" aria-hidden="true"></span>
</label>
<div class="run-warning" id="run-warning">
<span aria-hidden="true">!</span>
<p><strong>这是一次真实执行</strong>任务可能进行采集、写库或发送通知等外部操作。</p>
</div>
<label class="confirm-check" id="run-confirm-row">
<input id="run-confirmed" name="confirmed" type="checkbox">
<span>我已确认业务日期和执行影响,并继续运行</span>
</label>
<p class="form-error" id="run-form-error" role="alert" hidden></p>
</div>
<footer class="modal__footer">
<button class="button button--ghost" type="button" id="run-cancel-button">取消</button>
<button class="button button--danger" type="submit" id="run-submit-button" disabled>确认并运行</button>
</footer>
</form>
</section>
</div>
<div class="overlay overlay--center" id="stop-overlay" hidden>
<div class="overlay__backdrop" data-close="stop" aria-hidden="true"></div>
<section class="modal stop-modal" id="stop-modal" role="alertdialog" aria-modal="true" aria-labelledby="stop-modal-title" aria-describedby="stop-modal-description" aria-hidden="true" tabindex="-1">
<header class="modal__header">
<div><span class="eyebrow">STOP RUN</span><h2 id="stop-modal-title">停止工作流</h2><code id="stop-workflow-id">…</code></div>
<button class="icon-button" id="stop-close-button" type="button" aria-label="关闭停止确认">×</button>
</header>
<form id="stop-form">
<div class="modal__body">
<div class="stop-warning">
<span aria-hidden="true">!</span>
<div><strong>确认停止当前执行?</strong><p id="stop-modal-description">系统会终止工作流及其仍在运行的子进程;已经完成的步骤和已产生的外部影响不会回滚。</p></div>
</div>
<dl class="stop-run-facts">
<div><dt>工作流</dt><dd id="stop-workflow-name">…</dd></div>
<div><dt>业务日期</dt><dd id="stop-business-date">…</dd></div>
<div><dt>操作编号</dt><dd><code id="stop-operation-id">…</code></dd></div>
</dl>
<p class="form-error" id="stop-form-error" role="alert" aria-live="assertive" hidden></p>
</div>
<footer class="modal__footer">
<button class="button button--ghost" type="button" id="stop-cancel-button">继续执行</button>
<button class="button button--danger" type="submit" id="stop-submit-button">确认停止</button>
</footer>
</form>
</section>
</div>
<div class="overlay overlay--center overlay--auth" id="token-overlay" hidden>
<div class="overlay__backdrop"></div>
<section class="modal token-modal" id="token-modal" role="dialog" aria-modal="true" aria-labelledby="token-modal-title" aria-hidden="true">
<div class="token-modal__mark" aria-hidden="true">G</div>
<span class="eyebrow">SECURE CONSOLE</span>
<h2 id="token-modal-title">连接工作流控制台</h2>
<p>请输入控制台访问令牌。令牌仅保存在当前浏览器会话中,关闭页面后自动清除。</p>
<form id="token-form">
<label class="field">
<span>访问令牌</span>
<input id="token-input" type="password" autocomplete="current-password" placeholder="粘贴 Bearer Token" required>
</label>
<p class="form-error" id="token-form-error" role="alert" hidden></p>
<button class="button button--primary button--full" type="submit" id="token-submit-button">验证并进入</button>
</form>
</section>
</div>
<div class="toast-region" id="toast-region" aria-live="polite" aria-atomic="false"></div>
<script src="/assets/app.js?v=monthly-range-20260806a" defer></script>
</body>
</html>