fix: 时间显示精度问题

This commit is contained in:
imeepos
2025-07-15 09:08:37 +08:00
parent 0a0c281ef6
commit be8c032158
2 changed files with 117 additions and 38 deletions

View File

@@ -21,6 +21,16 @@ export const TemplateDetailModal: React.FC<TemplateDetailModalProps> = ({
return `${minutes}:${remainingSeconds.toString().padStart(2, '0')}`;
};
// 格式化时长(精确到毫秒)
const formatDurationWithMs = (microseconds: number) => {
const totalMs = Math.floor(microseconds / 1000);
const seconds = Math.floor(totalMs / 1000);
const ms = totalMs % 1000;
const minutes = Math.floor(seconds / 60);
const remainingSeconds = seconds % 60;
return `${minutes}:${remainingSeconds.toString().padStart(2, '0')}.${ms.toString().padStart(3, '0')}`;
};
// 格式化文件大小
const formatFileSize = (bytes?: number) => {
if (!bytes) return '未知';
@@ -163,6 +173,25 @@ export const TemplateDetailModal: React.FC<TemplateDetailModalProps> = ({
}
}
// 解析片段属性信息
const parseSegmentProperties = (properties: string | null) => {
if (!properties) return null;
try {
const parsed = JSON.parse(properties);
return {
speed: parsed.speed || 1.0,
source_timerange: parsed.source_timerange || null,
target_timerange: parsed.target_timerange || null,
speed_info: parsed.speed_info || null,
visible: parsed.visible,
volume: parsed.volume
};
} catch (e) {
return null;
}
};
const tabs = [
{ id: 'overview', label: '概览', icon: Monitor },
{ id: 'materials', label: '素材', icon: FileText },
@@ -440,31 +469,88 @@ export const TemplateDetailModal: React.FC<TemplateDetailModalProps> = ({
{track.segments.length > 0 && (
<div className="space-y-2">
{track.segments.map((segment) => (
<div key={segment.id} className="bg-white p-3 rounded border">
<div className="flex items-center justify-between mb-2">
<span className="text-sm text-gray-900">{segment.name}</span>
<span className="text-xs text-gray-500">
{formatDuration(segment.start_time)} - {formatDuration(segment.end_time)}
</span>
</div>
<div className="text-xs text-gray-500 space-y-1">
<div>
<span>ID: <span className="font-mono text-orange-600">{segment.id}</span></span>
<span className="ml-3">: {segment.segment_index}</span>
{track.segments.map((segment) => {
const segmentProps = parseSegmentProperties(segment.properties || null);
return (
<div key={segment.id} className="bg-white p-3 rounded border">
<div className="flex items-center justify-between mb-2">
<span className="text-sm text-gray-900">{segment.name}</span>
<span className="text-xs text-gray-500">
{formatDurationWithMs(segment.start_time)} - {formatDurationWithMs(segment.end_time)}
</span>
</div>
<div>: {formatDuration(segment.duration)}</div>
{segment.template_material_id && (
<div className="text-xs text-gray-500 space-y-1">
<div>
使ID: <span className="font-mono text-blue-600">{segment.template_material_id}</span>
<span>ID: <span className="font-mono text-orange-600">{segment.id}</span></span>
<span className="ml-3">: {segment.segment_index}</span>
</div>
)}
{!segment.template_material_id && (
<div className="text-gray-400"></div>
)}
<div className="flex items-center space-x-4">
<span>: {formatDurationWithMs(segment.duration)}</span>
{segmentProps?.speed && segmentProps.speed !== 1.0 && (
<span className={`px-2 py-0.5 rounded text-xs ${
segmentProps.speed > 1.0
? 'bg-red-100 text-red-800'
: 'bg-green-100 text-green-800'
}`}>
: {segmentProps.speed.toFixed(3)}x {segmentProps.speed > 1.0 ? '(加速)' : '(减速)'}
</span>
)}
{segmentProps?.speed === 1.0 && (
<span className="bg-gray-100 text-gray-600 px-2 py-0.5 rounded text-xs"></span>
)}
</div>
{/* 播放速度不影响片段时长,移除实际播放时长显示 */}
{/* 时间轴位置信息 */}
{segmentProps?.target_timerange && (
<div className="bg-blue-50 p-2 rounded mt-1">
<div className="text-xs font-medium text-blue-700 mb-1">:</div>
<div className="text-xs text-blue-600 space-y-0.5">
<div>: {formatDurationWithMs(segmentProps.target_timerange.start)}</div>
<div>: {formatDurationWithMs(segmentProps.target_timerange.duration)}</div>
<div>: {formatDurationWithMs(segmentProps.target_timerange.start + segmentProps.target_timerange.duration)}</div>
</div>
</div>
)}
{/* 源素材时间范围 */}
{segmentProps?.source_timerange && (
<div className="bg-purple-50 p-2 rounded mt-1">
<div className="text-xs font-medium text-purple-700 mb-1">:</div>
<div className="text-xs text-purple-600 space-y-0.5">
<div>: {formatDurationWithMs(segmentProps.source_timerange.start)}</div>
<div>: {formatDurationWithMs(segmentProps.source_timerange.duration)}</div>
<div>: {formatDurationWithMs(segmentProps.source_timerange.start + segmentProps.source_timerange.duration)}</div>
</div>
</div>
)}
{/* 其他属性信息 */}
{(segmentProps?.visible !== undefined || segmentProps?.volume !== undefined) && (
<div className="bg-gray-50 p-2 rounded mt-1">
<div className="text-xs font-medium text-gray-700 mb-1">:</div>
<div className="text-xs text-gray-600 space-y-0.5">
{segmentProps?.visible !== undefined && (
<div>: {segmentProps.visible ? '可见' : '隐藏'}</div>
)}
{segmentProps?.volume !== undefined && (
<div>: {(segmentProps.volume * 100).toFixed(0)}%</div>
)}
</div>
</div>
)}
{segment.template_material_id && (
<div>
使ID: <span className="font-mono text-blue-600">{segment.template_material_id}</span>
</div>
)}
{!segment.template_material_id && (
<div className="text-gray-400"></div>
)}
</div>
</div>
</div>
))}
);
})}
</div>
)}
</div>