🐛 修复生命周期取件次数占位符
This commit is contained in:
@@ -83,6 +83,7 @@ const hourInMilliseconds = 60 * 60 * 1000
|
||||
const dayInMilliseconds = 24 * 60 * 60 * 1000
|
||||
const adminPageSizeOptions = [5, 10, 20, 50, 100] as const
|
||||
const defaultAdminPageSize = 10
|
||||
const legacyUsedCountTimelineKeys = new Set(['legacy-used-count', 'legacy_used_count'])
|
||||
|
||||
type DetailPolicyActionOption = {
|
||||
action: AdminFilePolicyAction
|
||||
@@ -595,45 +596,109 @@ export function useAdminFiles() {
|
||||
}
|
||||
}
|
||||
|
||||
const normalizeTimelineNumber = (value: unknown) => {
|
||||
if (typeof value === 'number' && Number.isFinite(value)) return value
|
||||
if (typeof value === 'string' && value.trim() !== '') {
|
||||
const numberValue = Number(value)
|
||||
if (Number.isFinite(numberValue)) return numberValue
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
const hasNumericTimelineValue = (item: AdminFileDetailTimelineItem) =>
|
||||
normalizeTimelineNumber(item.value) !== null
|
||||
|
||||
const isLegacyUsedCountTimelineValue = (value: unknown) =>
|
||||
typeof value === 'string' && legacyUsedCountTimelineKeys.has(value.trim())
|
||||
|
||||
const normalizeTimelineItem = (
|
||||
item: AdminFileDetailTimelineItem,
|
||||
fallbackUsedCount: number
|
||||
) => {
|
||||
const normalizedItem = { ...item }
|
||||
|
||||
if (legacyUsedCountTimelineKeys.has(normalizedItem.key)) {
|
||||
normalizedItem.key = 'retrieved'
|
||||
}
|
||||
|
||||
if (isLegacyUsedCountTimelineValue(normalizedItem.value)) {
|
||||
normalizedItem.value = fallbackUsedCount > 0 ? fallbackUsedCount : null
|
||||
}
|
||||
|
||||
return normalizedItem
|
||||
}
|
||||
|
||||
const getTimelineTranslationKey = (item: AdminFileDetailTimelineItem) => {
|
||||
if (
|
||||
(item.key === 'retrieved' ||
|
||||
item.key === 'retrieved_event' ||
|
||||
legacyUsedCountTimelineKeys.has(item.key)) &&
|
||||
!hasNumericTimelineValue(item) &&
|
||||
!item.detail
|
||||
) {
|
||||
return 'retrieved_event_unknown'
|
||||
}
|
||||
|
||||
return item.key
|
||||
}
|
||||
|
||||
const formatTimelineValue = (item: AdminFileDetailTimelineItem) => {
|
||||
if (item.key === 'download_limit') {
|
||||
if (item.status === 'unlimited') return t('fileManage.unlimited')
|
||||
if (typeof item.value === 'number') return t('fileManage.remaining', { count: item.value })
|
||||
const numericValue = normalizeTimelineNumber(item.value)
|
||||
if (numericValue !== null) return t('fileManage.remaining', { count: numericValue })
|
||||
}
|
||||
|
||||
if (item.key === 'retrieved' && typeof item.value === 'number') {
|
||||
return `${item.value} ${t('common.times')}`
|
||||
if ((item.key === 'retrieved' || item.key === 'retrieved_event') && hasNumericTimelineValue(item)) {
|
||||
return `${normalizeTimelineNumber(item.value)} ${t('common.times')}`
|
||||
}
|
||||
|
||||
if (item.key === 'expiration_policy') {
|
||||
if (item.status === 'unlimited') return t('send.expiration.units.forever')
|
||||
if (typeof item.value === 'number') {
|
||||
const duration = formatDuration(Math.abs(item.value), (key) => t(key))
|
||||
return item.value <= 0
|
||||
const numericValue = normalizeTimelineNumber(item.value)
|
||||
if (numericValue !== null) {
|
||||
const duration = formatDuration(Math.abs(numericValue), (key) => t(key))
|
||||
return numericValue <= 0
|
||||
? t('fileManage.timeline.expiration_policy.overdue', { time: duration })
|
||||
: t('fileManage.timeline.expiration_policy.remaining', { time: duration })
|
||||
}
|
||||
}
|
||||
|
||||
if (item.detail) return item.detail
|
||||
if (item.value !== null && item.value !== undefined) return String(item.value)
|
||||
const numericValue = normalizeTimelineNumber(item.value)
|
||||
if (numericValue !== null) return String(numericValue)
|
||||
return ''
|
||||
}
|
||||
|
||||
const createTimelineViewItems = (items: AdminFileDetailTimelineItem[] = []) =>
|
||||
items.map((item) => {
|
||||
const formatTimelineTitleValue = (item: AdminFileDetailTimelineItem, valueText: string) => {
|
||||
if (item.key === 'retrieved_event') {
|
||||
const numericValue = normalizeTimelineNumber(item.value)
|
||||
return numericValue === null ? '' : String(numericValue)
|
||||
}
|
||||
|
||||
return valueText
|
||||
}
|
||||
|
||||
const createTimelineViewItems = (
|
||||
items: AdminFileDetailTimelineItem[] = [],
|
||||
fallbackUsedCount = 0
|
||||
) =>
|
||||
items.map((rawItem) => {
|
||||
const item = normalizeTimelineItem(rawItem, fallbackUsedCount)
|
||||
const timelineKey = getTimelineTranslationKey(item)
|
||||
const timestampText = item.timestamp ? formatTimestamp(item.timestamp) : ''
|
||||
const valueText = formatTimelineValue(item)
|
||||
const titleValue = formatTimelineTitleValue(item, valueText)
|
||||
const metaParts = [timestampText, valueText].filter(Boolean)
|
||||
return {
|
||||
...item,
|
||||
severity: normalizeInsightSeverity(item.severity),
|
||||
displayTitle: t(`fileManage.timeline.${item.key}.title`, {
|
||||
displayTitle: t(`fileManage.timeline.${timelineKey}.title`, {
|
||||
status: t(`fileManage.timeline.status.${item.status || 'pending'}`),
|
||||
detail: item.detail || '',
|
||||
value: valueText || item.value || ''
|
||||
value: titleValue
|
||||
}),
|
||||
displayDescription: t(`fileManage.timeline.${item.key}.description`, {
|
||||
displayDescription: t(`fileManage.timeline.${timelineKey}.description`, {
|
||||
status: t(`fileManage.timeline.status.${item.status || 'pending'}`),
|
||||
detail: item.detail || '',
|
||||
value: valueText || ''
|
||||
@@ -701,6 +766,14 @@ export function useAdminFiles() {
|
||||
(viewItem.isExpiredFile ? 'expired' : isPermanentFile ? 'permanent' : 'available')
|
||||
const statusInsightNextAction =
|
||||
statusInsights?.nextAction ?? statusInsights?.next_action ?? 'monitor'
|
||||
const usedCountValue = normalizeCount(
|
||||
detail.usedCount ??
|
||||
detail.used_count ??
|
||||
statusInsights?.metrics?.usedCount ??
|
||||
statusInsights?.metrics?.used_count ??
|
||||
file.usedCount ??
|
||||
file.used_count
|
||||
)
|
||||
const metadata = detail.metadata ?? detail.meta
|
||||
const metadataNote = detail.note ?? metadata?.note ?? ''
|
||||
const metadataTags = normalizeMetadataTags(detail.tags ?? metadata?.tags)
|
||||
@@ -742,7 +815,7 @@ export function useAdminFiles() {
|
||||
statusInsightNextAction,
|
||||
statusInsightReasons: statusInsights?.reasons || [],
|
||||
statusInsightMetrics: statusInsights?.metrics,
|
||||
detailTimeline: createTimelineViewItems(detail.timeline || [])
|
||||
detailTimeline: createTimelineViewItems(detail.timeline || [], usedCountValue)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -618,6 +618,10 @@ export default {
|
||||
retrieved_event: {
|
||||
title: 'Retrieval #{value}',
|
||||
description: 'This retrieval is complete; current status is {status}.'
|
||||
},
|
||||
retrieved_event_unknown: {
|
||||
title: 'Retrieval History',
|
||||
description: 'This retrieval is complete; current status is {status}.'
|
||||
}
|
||||
},
|
||||
headers: {
|
||||
|
||||
@@ -615,6 +615,10 @@ export default {
|
||||
retrieved_event: {
|
||||
title: '第 {value} 次取件',
|
||||
description: '本次取件已完成,当前状态为 {status}。'
|
||||
},
|
||||
retrieved_event_unknown: {
|
||||
title: '取件记录',
|
||||
description: '本次取件已完成,当前状态为 {status}。'
|
||||
}
|
||||
},
|
||||
headers: {
|
||||
|
||||
Reference in New Issue
Block a user