feat(admin): apply shared blue-white self-operated workbench style

This commit is contained in:
2026-10-20 19:16:47 +08:00
parent 9bfce44988
commit 464b72cff9
38 changed files with 1851 additions and 340 deletions
@@ -12,6 +12,9 @@ function overview(account: Task | null = source): Overview {
warehouses: [{ warehouseCode: 'US01', dataFamily: 'OUTBOUND', activeTasks: [child], sharedUpstream: account }, { warehouseCode: 'US02', dataFamily: 'OUTBOUND', activeTasks: [{ ...child, taskNo: 'CHILD-2', warehouseCode: 'US02' }], sharedUpstream: account }] as WarehouseOverview[] }
}
const options = { global: { stubs: { 'el-button': true } } }
const retained: Task = { ...source, dataFamily: 'MASTER_DATA', taskStatus: 'RETRY_WAIT', attemptCount: 1, latestAttemptNo: 1, blockingReason: 'RETRY_SCHEDULED',
progress: { ...source.progress, phase: 'PRODUCTS', unit: 'PAGE', completed: 37, total: 86, attemptNo: 1 },
latestAttempt: { attemptNo: 1, status: 'YIELDED', phase: 'PRODUCTS', startedAt: null, finishedAt: null, progressUpdatedAt: null, heartbeatAt: null, executionHealth: null, elapsedSeconds: 20, errorCode: null, failureSummary: null } }
describe('single account collection monitor', () => {
it('identifies account master-data work without calling it outbound detail fetching', () => {
const task = { ...source, dataFamily: 'MASTER_DATA', taskType: 'MASTER_DATA', progress: { ...source.progress!, phase: 'PRODUCTS', unit: 'PAGE', completed: 2, total: 86 } }
@@ -25,7 +28,8 @@ describe('single account collection monitor', () => {
const w = mount(CollectionAccountMonitor, { ...options, props: { overview: data } })
expect(w.find('.account-schedules').text()).toContain('US01 / US02')
expect(w.find('.account-schedules').text()).toContain('2026/10/14 00:05:00')
expect(w.find('.account-schedules').text()).toContain('计划时间不代表当前任务完成时间')
expect(w.get('.account-schedules strong').attributes('title')).toContain('计划时间不代表当前任务完成时间')
expect(w.find('.account-schedules').text()).not.toContain('计划时间不代表当前任务完成时间')
await w.setProps({ stale: true })
expect(w.find('.account-schedules').text()).toContain('上次自动采集计划')
await w.setProps({ overview: { ...data, warehouses: data.warehouses.map(row => ({ ...row, executionEnabled: false })) } })
@@ -55,7 +59,13 @@ describe('single account collection monitor', () => {
expect(w.findComponent(CollectionTaskProgress).props('task').taskNo).toBe('SOURCE')
expect(w.text()).toContain('12.1%'); expect(w.text()).toContain('2448')
expect(w.text()).toContain('US01 · 出库销量'); expect(w.text()).toContain('US02 · 出库销量')
expect(w.text()).toContain('完整队列数量及下一任务顺序尚未提供')
expect(w.get('.account-upnext h3').attributes('title')).toContain('完整队列数量及下一任务顺序尚未提供')
expect(w.text()).not.toContain('完整队列数量及下一任务顺序尚未提供')
expect(w.get('.account-flow h4').attributes('title')).toBe('只标记已确认的推进状态')
expect(w.get('.account-results > .account-section-title h4').attributes('title')).toBe('采集进度与报表发布分别确认')
expect(w.text()).not.toContain('只标记已确认的推进状态')
expect(w.text()).not.toContain('采集进度与报表发布分别确认')
expect(w.text()).not.toContain('运行看板')
expect(w.text()).not.toContain('查看配置'); expect(w.text()).not.toContain('执行心跳')
w.unmount()
})
@@ -74,8 +84,71 @@ describe('single account collection monitor', () => {
it('preserves real last counts when stale without claiming an estimate', () => {
const w = mount(CollectionAccountMonitor, { ...options, props: { overview: overview(), stale: true } })
expect(w.text()).toContain('339'); expect(w.text()).toContain('状态更新失败')
expect(w.text()).toContain('已暂停估算')
expect(w.find('.collection-estimate').exists()).toBe(false)
expect(w.get('.account-live').text()).toBe('状态待确认')
expect(w.find('.account-flow li[data-state="active"]').exists()).toBe(false)
w.unmount()
})
it('presents off as the main state while retaining a completed batch and reliable stage counts', () => {
const w = mount(CollectionAccountMonitor, { ...options, props: { overview: { ...overview(retained), collectionMode: 'OFF', warehouses: [] } } })
expect(w.get('.account-live').text()).toBe('采集已关闭')
expect(w.get('.account-status').text()).toBe('本批已完成')
expect(w.find('.collection-estimate').exists()).toBe(false)
expect(w.text().match(/采集已关闭/g)).toHaveLength(1)
expect(w.text()).not.toContain('等待续采')
expect(w.get('[role="progressbar"]').attributes('aria-valuenow')).toBe('43')
expect(w.findAll('.collection-count-grid dd strong').map(x => x.text())).toEqual(['86', '37', '49'])
const stages = w.findAll('.account-flow li')
expect(stages[0]?.text()).toContain('等待状态确认')
expect(stages[1]?.text()).toContain('当前阶段')
expect(stages[2]?.text()).toContain('等待状态确认')
expect(w.find('.account-flow li[data-state="done"]').exists()).toBe(false)
w.unmount()
})
it('retains running evidence when collection is off, then makes stale evidence explicit', async () => {
const w = mount(CollectionAccountMonitor, { ...options, props: { overview: { ...overview(source), collectionMode: 'OFF' } } })
expect(w.get('.account-live').text()).toBe('已关闭 · 执行中')
expect(w.find('.account-status').exists()).toBe(false)
expect(w.find('.account-flow li[data-state="active"]').exists()).toBe(true)
expect(w.find('.collection-estimate').exists()).toBe(false)
await w.setProps({ stale: true })
expect(w.get('.account-live').text()).toBe('状态待确认')
expect(w.find('.account-status').exists()).toBe(false)
expect(w.get('.account-now .account-eyebrow').text()).toBe('上次阶段记录')
expect(w.find('.account-flow li[data-state="active"]').exists()).toBe(false)
expect(w.get('.account-flow li[data-state="stale"]').text()).toContain('上次阶段')
expect(w.find('.collection-estimate').exists()).toBe(false)
expect(w.text()).toContain('12.1%')
w.unmount()
})
it('uses explicit account pause evidence without marking earlier stages as completed', () => {
const data = overview(retained)
data.warehouses = [{ ...data.warehouses[0]!, activeTasks: [], sharedUpstream: null, protection: {
accountPauseReason: 'MANUAL_PAUSE', accountCooldownUntil: null,
dailyRequestBudget: null, reservedHttpRequests: null, confirmedHttpRequests: null, budgetDate: null,
} }]
const w = mount(CollectionAccountMonitor, { ...options, props: { overview: data } })
expect(w.get('.account-live').text()).toBe('已暂停')
expect(w.get('.account-status').text()).toBe('本批已完成')
expect(w.get('.account-flow li[data-state="paused"]').text()).toContain('当前阶段')
expect(w.find('.account-flow li[data-state="done"]').exists()).toBe(false)
expect(w.text()).not.toContain('等待续采')
w.unmount()
})
it('keeps idle distinct from off and unknown when there is no current task', async () => {
const data = { ...overview(null), warehouses: [] }
const w = mount(CollectionAccountMonitor, { ...options, props: { overview: data } })
expect(w.get('.account-live').text()).toBe('待机')
expect(w.get('.account-empty h3').text()).toBe('等待下一次采集')
await w.setProps({ overview: { ...data, collectionMode: 'OFF' } })
expect(w.get('.account-live').text()).toBe('采集已关闭')
expect(w.find('.account-empty h3').exists()).toBe(false)
await w.setProps({ stale: true })
expect(w.get('.account-live').text()).toBe('状态待确认')
expect(w.get('.account-empty').text()).not.toContain('当前没有正在运行的采集')
await w.setProps({ overview: null, stale: false })
expect(w.get('.account-live').text()).toBe('未连接')
expect(w.text()).not.toContain('待机')
w.unmount()
})
})