feat(self-operated): add charts and continuous collection status
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import type { BusinessQuery, DailyPoint, Progress, QueryContext, RetryCommand, Scope, Task } from './types'
|
||||
import type { BusinessQuery, Progress, QueryContext, RetryCommand, Scope, Task } from './types'
|
||||
|
||||
// Aborting saves work; generation fencing also protects against adapters that return after abort.
|
||||
export class RequestFence {
|
||||
@@ -90,7 +90,7 @@ export const reasonLabels: Record<string, string> = {
|
||||
}
|
||||
export function reasonsText(reasons: readonly string[] | null | undefined) { return reasons?.map(reason => reasonLabels[reason] ?? statusLabels[reason] ?? '存在待核对项').join('、') || '—' }
|
||||
export function phaseText(phase: string | null | undefined) {
|
||||
const phases: Record<string, string> = { DIRECTORY: '获取出库目录', DISCOVERY: '获取出库目录', DETAIL: '获取出库详情', DETAILS: '获取出库详情', INVENTORY: '获取产品库存', VALIDATE: '校验', VALIDATION: '校验', MERGE: '归并', BUILD: '统计计算', PUBLISH: '发布', WAIT_UPSTREAM: '等待账号共享上游', WAIT_BUDGET: '预算等待', WAITING_SOURCE: '等待来源准备', WAITING: '等待执行', SAMPLE_DONE: '样本结束', FAILED: '执行失败', FETCH: '获取数据', PLANNED: '已规划', FETCHED: '数据已取完', VALIDATED: '已校验', BUILDING: '统计计算', BUILT: '计算完成', PUBLISHED: '已发布' }
|
||||
const phases: Record<string, string> = { DIRECTORY: '获取出库目录', DISCOVERY: '获取出库目录', DETAIL: '获取出库详情', DETAILS: '获取出库详情', INVENTORY: '获取产品库存', VALIDATE: '校验', VALIDATION: '校验', MERGE: '更新本仓出库数据', BUILD: '统计计算', PUBLISH: '发布', WAIT_UPSTREAM: '等待账号共享上游', WAIT_BUDGET: '预算等待', WAITING_SOURCE: '等待来源准备', WAITING: '等待执行', SAMPLE_DONE: '样本结束', FAILED: '执行失败', FETCH: '获取数据', PLANNED: '已规划', FETCHED: '数据已取完', VALIDATED: '已校验', BUILDING: '统计计算', BUILT: '计算完成', PUBLISHED: '已发布' }
|
||||
return phase ? phases[phase] ?? '阶段待核对' : '阶段待确认'
|
||||
}
|
||||
export function label(value: string | null | undefined) { return value ? statusLabels[value] ?? '待核对' : '—' }
|
||||
@@ -142,22 +142,3 @@ export class RuntimePoller {
|
||||
if (generation === this.generation && this.active && this.visible) this.timer = setTimeout(() => void this.tick(generation), busy ? 10000 : 60000)
|
||||
}
|
||||
}
|
||||
export function trendSegments(points: DailyPoint[]) {
|
||||
const max = Math.max(1, ...points.map(point => Number(shownQuantity(point) ?? 0)))
|
||||
const segments: { path: string; partial: boolean }[] = []
|
||||
let path = ''
|
||||
let partial = false
|
||||
const flush = () => { if (path) segments.push({ path, partial }); path = '' }
|
||||
points.forEach((point, index) => {
|
||||
const quantity = shownQuantity(point)
|
||||
if (quantity == null || point.dataStatus === 'UNKNOWN') { flush(); return }
|
||||
const x = points.length === 1 ? 400 : 30 + index / (points.length - 1) * 740
|
||||
const y = 175 - Number(quantity) / max * 145
|
||||
const pointPartial = point.dataStatus !== 'COMPLETE'
|
||||
if (path && partial !== pointPartial) { flush() }
|
||||
path += `${path ? ' L' : 'M'}${x},${y}`
|
||||
partial = pointPartial
|
||||
})
|
||||
flush()
|
||||
return segments
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user