重构前端逻辑
This commit is contained in:
parent
a80eea3a1e
commit
11c44bc95d
@ -8,7 +8,6 @@ import {
|
|||||||
DialogFooter,
|
DialogFooter,
|
||||||
} from '@/components/ui/dialog';
|
} from '@/components/ui/dialog';
|
||||||
import { Button } from '@/components/ui/button';
|
import { Button } from '@/components/ui/button';
|
||||||
import { ScrollArea, ScrollBar } from '@/components/ui/scroll-area';
|
|
||||||
import { Loader2, AlertCircle, Clock, FileText, RefreshCw } from 'lucide-react';
|
import { Loader2, AlertCircle, Clock, FileText, RefreshCw } from 'lucide-react';
|
||||||
import { cn } from '@/lib/utils';
|
import { cn } from '@/lib/utils';
|
||||||
import { getDeployNodeLogs } from '../service';
|
import { getDeployNodeLogs } from '../service';
|
||||||
@ -56,10 +55,7 @@ const DeployNodeLogDialog: React.FC<DeployNodeLogDialogProps> = ({
|
|||||||
if (response && !response.expired && response.logs.length > 0) {
|
if (response && !response.expired && response.logs.length > 0) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (scrollAreaRef.current) {
|
if (scrollAreaRef.current) {
|
||||||
const viewport = scrollAreaRef.current.querySelector('[data-radix-scroll-area-viewport]');
|
scrollAreaRef.current.scrollTop = scrollAreaRef.current.scrollHeight;
|
||||||
if (viewport) {
|
|
||||||
viewport.scrollTop = viewport.scrollHeight;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}, 100);
|
}, 100);
|
||||||
}
|
}
|
||||||
@ -148,52 +144,57 @@ const DeployNodeLogDialog: React.FC<DeployNodeLogDialogProps> = ({
|
|||||||
<p className="text-sm mt-2">日志通常保留 7 天,请检查部署时间</p>
|
<p className="text-sm mt-2">日志通常保留 7 天,请检查部署时间</p>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<ScrollArea className="flex-1 border rounded-md bg-gray-50" ref={scrollAreaRef}>
|
<div
|
||||||
|
className="flex-1 border rounded-md bg-gray-50 overflow-auto"
|
||||||
|
ref={scrollAreaRef}
|
||||||
|
>
|
||||||
<div className="p-2 font-mono text-xs w-max min-w-full">
|
<div className="p-2 font-mono text-xs w-max min-w-full">
|
||||||
{logData?.logs && logData.logs.length > 0 ? (
|
{logData?.logs && logData.logs.length > 0 ? (
|
||||||
logData.logs.map((log, index) => {
|
(() => {
|
||||||
// 计算行号宽度
|
// 计算行号宽度(只计算一次)
|
||||||
const lineNumWidth = Math.max(4, String(logData.logs.length).length + 1);
|
const lineNumWidth = Math.max(4, String(logData.logs.length).length + 1);
|
||||||
|
|
||||||
// 格式化时间戳为可读格式:2025-11-07 16:27:41.494
|
return logData.logs.map((log, index) => {
|
||||||
const timestamp = dayjs(log.timestamp).format('YYYY-MM-DD HH:mm:ss.SSS');
|
// 格式化时间戳为可读格式:2025-11-07 16:27:41.494
|
||||||
|
const timestamp = dayjs(log.timestamp).format('YYYY-MM-DD HH:mm:ss.SSS');
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
key={log.sequenceId}
|
key={log.sequenceId}
|
||||||
className="flex items-start hover:bg-gray-100 px-2 py-0.5 whitespace-nowrap"
|
className="flex items-start px-2 py-0.5 whitespace-nowrap"
|
||||||
>
|
|
||||||
{/* 行号 - 动态宽度,右对齐 */}
|
|
||||||
<span
|
|
||||||
className="text-gray-400 flex-shrink-0 text-right select-none"
|
|
||||||
style={{ width: `${lineNumWidth}ch`, marginRight: '1ch' }}
|
|
||||||
>
|
>
|
||||||
{index + 1}
|
{/* 行号 - 动态宽度,右对齐 */}
|
||||||
</span>
|
<span
|
||||||
|
className="text-gray-400 flex-shrink-0 text-right select-none"
|
||||||
|
style={{ width: `${lineNumWidth}ch`, marginRight: '1ch' }}
|
||||||
|
>
|
||||||
|
{index + 1}
|
||||||
|
</span>
|
||||||
|
|
||||||
{/* 时间戳 - 可读格式,23个字符 (2025-11-07 16:27:41.494) */}
|
{/* 时间戳 - 可读格式,23个字符 (2025-11-07 16:27:41.494) */}
|
||||||
<span
|
<span
|
||||||
className="text-gray-600 flex-shrink-0"
|
className="text-gray-600 flex-shrink-0"
|
||||||
style={{ width: '23ch', marginRight: '2ch' }}
|
style={{ width: '23ch', marginRight: '2ch' }}
|
||||||
>
|
>
|
||||||
{timestamp}
|
{timestamp}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
{/* 日志级别 - 5个字符,右对齐 */}
|
{/* 日志级别 - 5个字符,右对齐 */}
|
||||||
<span
|
<span
|
||||||
className={cn('flex-shrink-0 font-semibold text-right', getLevelClass(log.level))}
|
className={cn('flex-shrink-0 font-semibold text-right', getLevelClass(log.level))}
|
||||||
style={{ width: '5ch', marginRight: '2ch' }}
|
style={{ width: '5ch', marginRight: '2ch' }}
|
||||||
>
|
>
|
||||||
{log.level}
|
{log.level}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
{/* 日志消息 - 不换行显示 */}
|
{/* 日志消息 - 不换行显示 */}
|
||||||
<span className="text-gray-800">
|
<span className="text-gray-800">
|
||||||
{log.message}
|
{log.message}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
})
|
});
|
||||||
|
})()
|
||||||
) : (
|
) : (
|
||||||
<div className="flex flex-col items-center justify-center h-64 text-muted-foreground">
|
<div className="flex flex-col items-center justify-center h-64 text-muted-foreground">
|
||||||
<Clock className="h-12 w-12 mb-4 text-muted-foreground/30" />
|
<Clock className="h-12 w-12 mb-4 text-muted-foreground/30" />
|
||||||
@ -202,8 +203,7 @@ const DeployNodeLogDialog: React.FC<DeployNodeLogDialogProps> = ({
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<ScrollBar orientation="horizontal" />
|
</div>
|
||||||
</ScrollArea>
|
|
||||||
)}
|
)}
|
||||||
</DialogBody>
|
</DialogBody>
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user