This commit is contained in:
2026-10-14 00:07:05 +08:00
parent 4c4a3db1eb
commit 2cf9129606
16 changed files with 592 additions and 20 deletions
@@ -84,6 +84,7 @@ function nodeState(phases: string[]) {
<div v-else class="account-empty"><div class="standby-ring"><Pause :size="38" /><span>{{ loading ? '读取中' : !overview ? '未连接' : '待机' }}</span></div><div><span class="account-eyebrow">{{ overview ? '当前没有正在运行的采集' : '连接状态' }}</span><h3>{{ idleReason }}</h3><p>有新任务时自动更新进度。</p><div class="last-result"><Check :size="18" v-if="latestPublication" /><Clock3 :size="18" v-else /><div><strong>{{ latestPublication ? '最近发布结果' : '最近发布结果尚未提供' }}</strong><span v-if="latestPublication">{{ latestPublication.warehouseCode }} · {{ latestPublication.dataFamily === 'INVENTORY' ? '产品库存' : '出库销量' }}<br />{{ beijingTime(latestPublication.lastPublishedAt) }}</span></div></div></div></div>
</section><aside class="account-upnext"><span class="account-eyebrow">后续安排</span><h3>{{ !overview ? '暂未取得安排' : upcoming.length ? '等待处理' : '等待新任务' }}</h3><ul v-if="upcoming.length"><li v-for="group in upcoming" :key="group.name"><span>{{ group.name }}</span><b>{{ group.count }} 项</b></li></ul><p v-else>{{ overview ? '当前摘要中暂无其他待处理项' : '连接恢复后更新后续任务' }}</p><div v-if="current" class="account-next"><strong>本阶段之后</strong><span>{{ nextStep }}</span></div><div v-if="schedules.length" class="account-next account-schedules"><strong>{{ stale ? '上次自动采集计划' : '下次自动采集计划' }}</strong><span v-for="schedule in schedules" :key="schedule.family + schedule.at">{{ schedule.family }} · {{ schedule.warehouses.join(' / ') }}<br />{{ beijingTime(schedule.at) }}(北京时间)</span><small>计划时间不代表当前任务完成时间。</small></div><small>仅已知活动摘要;完整队列数量及下一任务顺序尚未提供。</small></aside></div>
<section class="account-flow"><div class="account-section-title"><h4><Activity :size="16" />处理阶段</h4><span>只标记已确认的推进状态</span></div><ol :style="{ gridTemplateColumns: `repeat(${flow.length}, minmax(0, 1fr))` }"><li v-for="(node, index) in flow" :key="node.name" :data-state="nodeState(node.phases)"><span class="step-index"><Check v-if="nodeState(node.phases) === 'done'" :size="16" /><template v-else>{{ index + 1 }}</template></span><strong>{{ node.name }}</strong><small>{{ nodeState(node.phases) === 'done' ? '已确认完成' : nodeState(node.phases) === 'active' ? '正在处理' : current || !overview ? '等待状态确认' : '待机' }}</small></li></ol></section>
<section class="account-results" v-if="warehouseGroups.length"><div class="account-section-title"><h4><Database :size="16" />各仓最新数据</h4><span>采集进度与报表发布分别确认</span></div><div class="warehouse-results"><article v-for="group in warehouseGroups" :key="group.code"><h4>{{ group.code }}</h4><div v-for="row in group.rows" :key="row.dataFamily" class="warehouse-result"><span>{{ row.dataFamily === 'INVENTORY' ? '产品库存' : '出库销量' }}<small>{{ row.lastPublishedAt ? beijingTime(row.lastPublishedAt) : '暂无发布结果' }}</small></span><span :class="{ 'result-ready': Boolean(row.lastPublishedAt) }">{{ row.lastPublishedAt ? '已有结果' : '尚未发布' }}<small>{{ row.lastPublishedAt ? label(row.dataFreshness) : '—' }}</small></span></div></article></div></section>
<footer><span>最近推进 {{ beijingTime(current?.progressUpdatedAt) }}</span><span>状态更新 {{ beijingTime(overview?.observedAt) }} · 北京时间</span></footer>
</div>
@@ -110,7 +111,7 @@ footer { justify-content: space-between; margin-top: var(--admin-space-5); paddi
.account-primary { min-width: 0; }
.account-brand, .account-controls, .account-live, .account-section-title, h4 { display: flex; align-items: center; gap: 10px; }
.account-brand > svg { color: var(--el-color-primary); background: var(--el-color-primary-light-9); padding: var(--admin-space-3); box-sizing: content-box; border-radius: var(--admin-radius-lg); }
.account-header { background: linear-gradient(105deg, var(--el-color-primary-light-9), var(--el-bg-color) 65%); padding: 16px 24px; border-top: 3px solid var(--el-color-primary); }
.account-header { background: var(--el-bg-color); padding: var(--admin-space-5) var(--admin-space-6); }
.account-header h2 { margin-bottom: 4px; }
.account-live { color: var(--el-text-color-secondary); background: var(--el-fill-color-light); padding: var(--admin-space-2) var(--admin-space-3); border-radius: var(--admin-radius-lg); }
[data-running="true"] .account-live { color: var(--el-color-success-dark-2); background: var(--el-color-success-light-9); }
@@ -151,15 +152,18 @@ h4 { margin: 0; font-size: var(--admin-font-body); }
.warehouse-result small { display: block; margin-top: 4px; }
.warehouse-result > span:last-child { text-align: right; }
.result-ready { color: var(--el-color-success); }
.account-monitor :deep(.collection-count-grid > div) { --metric-color: var(--el-color-primary); --metric-tint: var(--el-color-primary-light-9); position: relative; overflow: hidden; padding: var(--admin-space-4); border: 1px solid var(--metric-tint); border-radius: var(--admin-radius-lg); background: linear-gradient(135deg, var(--el-bg-color), var(--metric-tint)); }
.account-monitor :deep(.collection-count-grid > div:nth-child(2)) { --metric-color: var(--el-color-success-dark-2); --metric-tint: var(--el-color-success-light-9); }
.account-monitor :deep(.collection-count-grid > div:nth-child(3)) { --metric-color: var(--el-color-warning-dark-2); --metric-tint: var(--el-color-warning-light-9); }
.account-monitor :deep(.collection-count-grid > div::before) { content: ''; position: absolute; right: -18px; top: -24px; width: 86px; height: 86px; border-radius: 50%; background: var(--metric-color); opacity: .1; pointer-events: none; }
.account-monitor :deep(.collection-count-grid dt), .account-monitor :deep(.collection-count-grid dd) { position: relative; }
.account-monitor :deep(.collection-count-grid dd) { font-size: 36px; color: var(--metric-color); white-space: nowrap; }
.account-monitor :deep(.collection-ring) { background: var(--el-color-primary-light-9); border-radius: 50%; }
.account-monitor :deep(.collection-count-grid > div) { padding-inline: var(--admin-space-5); }
.account-monitor :deep(.collection-count-grid > div + div) { border-left: 1px solid var(--el-border-color-light); }
.account-monitor :deep(.collection-count-grid dd) { font-size: 36px; font-weight: 600; color: var(--el-text-color-primary); overflow-wrap: anywhere; }
.account-monitor :deep(.collection-count-grid > div:nth-child(2) dd) { color: var(--el-color-primary); }
.account-monitor :deep(.collection-count-grid dd small) { display: block; margin-top: var(--admin-space-2); font-weight: 400; }
.account-monitor :deep(.collection-progress) { display: grid; grid-template-columns: 180px minmax(0, 1fr); gap: var(--admin-space-3) var(--admin-space-6); align-items: center; }
.account-monitor :deep(.collection-stage-counts) { display: contents; }
.account-monitor :deep(.collection-ring) { width: 180px; height: 180px; grid-row: 1 / 3; }
.account-monitor :deep(.compact-counts) { grid-column: 2; }
.account-monitor :deep(.collection-progress > p) { grid-column: 1 / -1; }
.account-monitor :deep(.ring-label strong) { color: var(--el-color-primary); }
.account-monitor :deep(.collection-estimate) { padding: 16px; border-radius: 6px; }
.account-monitor :deep(.collection-estimate) { grid-column: 2; margin: 0; padding: var(--admin-space-4) var(--admin-space-5); border-radius: var(--admin-radius); background: var(--el-color-primary-light-9); }
@keyframes signal { 50% { opacity: .45; } }
@media (prefers-reduced-motion: reduce) { [data-running="true"] .account-live i { animation: none; } }
</style>