import { html } from 'htm/preact'; import { useState, useEffect, useRef } from 'preact/hooks'; import { getRowBySeq } from '~/utils/api.js'; const styles = { overlay: { position: 'fixed', top: 0, left: 0, right: 0, bottom: 0, background: 'rgba(0, 0, 0, 0.5)', backdropFilter: 'blur(4px)', display: 'flex', alignItems: 'center', justifyContent: 'center', zIndex: 10000, padding: '20px' }, modal: { background: 'var(--bg-elevated)', borderRadius: 'var(--radius-lg)', boxShadow: 'var(--shadow-xl)', maxWidth: '800px', width: '100%', maxHeight: '90vh', display: 'flex', flexDirection: 'column', border: '1px solid var(--border-color)' }, header: { padding: '20px', borderBottom: '1px solid var(--border-color)', display: 'flex', alignItems: 'center', justifyContent: 'space-between' }, title: { fontSize: '18px', fontWeight: 600, color: 'var(--text-primary)', margin: 0 }, closeButton: { background: 'none', border: 'none', fontSize: '24px', color: 'var(--text-secondary)', cursor: 'pointer', padding: '4px 8px', borderRadius: 'var(--radius-sm)', transition: 'var(--transition)', lineHeight: 1 }, content: { padding: '20px', overflowY: 'auto', flex: 1 }, fieldGroup: { marginBottom: '16px', padding: '12px', background: 'var(--bg-surface)', borderRadius: 'var(--radius-md)', border: '1px solid var(--border-color)' }, fieldLabel: { fontSize: '12px', fontWeight: 600, color: 'var(--text-secondary)', textTransform: 'uppercase', marginBottom: '4px', display: 'flex', alignItems: 'center', gap: '6px' }, fieldValue: { fontSize: '14px', color: 'var(--text-primary)', wordBreak: 'break-word', fontFamily: '"Courier New", monospace', whiteSpace: 'pre-wrap', lineHeight: 1.5 }, metaTag: { display: 'inline-block', padding: '2px 6px', fontSize: '10px', fontWeight: 600, borderRadius: 'var(--radius-sm)', background: 'var(--primary-bg)', color: 'var(--primary)', marginLeft: '6px' } }; export function RowDetailModal({ tableName, seq, onClose }) { const overlayRef = useRef(null); const [rowData, setRowData] = useState(null); const [loading, setLoading] = useState(true); useEffect(() => { fetchRowData(); }, [tableName, seq]); // ESC 键关闭 useEffect(() => { const handleKeyDown = (e) => { if (e.key === 'Escape') { onClose(); } }; document.addEventListener('keydown', handleKeyDown); return () => document.removeEventListener('keydown', handleKeyDown); }, [onClose]); const fetchRowData = async () => { try { setLoading(true); const data = await getRowBySeq(tableName, seq); setRowData(data); } catch (error) { console.error('Failed to fetch row data:', error); } finally { setLoading(false); } }; const handleOverlayClick = (e) => { if (e.target === overlayRef.current) { onClose(); } }; const formatTime = (nanoTime) => { if (!nanoTime) return ''; const date = new Date(nanoTime / 1000000); return date.toLocaleString('zh-CN', { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit', hour12: false }); }; const formatValue = (value, key) => { if (value === null) return 'null'; if (value === undefined) return 'undefined'; if (key === '_time') { return formatTime(value); } if (typeof value === 'object') { try { return JSON.stringify(value, null, 2); } catch (e) { return '[Object]'; } } return String(value); }; const renderField = (key, value) => { const isMeta = key === '_seq' || key === '_time'; return html`
${key} ${isMeta && html`系统字段`}
${formatValue(value, key)}
`; }; return html`

记录详情 - ${tableName}

${loading && html`

加载中...

`} ${!loading && rowData && html`
${Object.entries(rowData).map(([key, value]) => renderField(key, value))}
`} ${!loading && !rowData && html`

未找到数据

`}
`; }