= ({
document.body
)}
- {/* Cell Context Menu - 使用 Portal 渲染到 body,避免 backdropFilter 影响 fixed 定位 */}
- {isTableSurfaceActive && !isV2Ui && cellContextMenu.visible && createPortal(
-
e.stopPropagation()}
- >
-
e.currentTarget.style.background = darkMode ? '#303030' : '#f5f5f5'}
- onMouseLeave={(e) => e.currentTarget.style.background = 'transparent'}
- onClick={handleCopyContextMenuFieldName}
- >
-
- 复制字段名称
-
-
- {canModifyData && (
- <>
-
e.currentTarget.style.background = darkMode ? '#303030' : '#f5f5f5'}
- onMouseLeave={(e) => e.currentTarget.style.background = 'transparent'}
- onClick={handleCellSetNull}
- >
- 设置为 NULL
-
-
e.currentTarget.style.background = darkMode ? '#303030' : '#f5f5f5'}
- onMouseLeave={(e) => e.currentTarget.style.background = 'transparent'}
- onClick={handleOpenContextMenuRowEditor}
- >
-
- 编辑本行
-
-
0 ? 'pointer' : 'not-allowed',
- transition: 'background 0.2s',
- opacity: selectedRowKeys.length > 0 ? 1 : 0.5,
- }}
- onMouseEnter={(e) => {
- if (selectedRowKeys.length > 0) e.currentTarget.style.background = darkMode ? '#303030' : '#f5f5f5';
- }}
- onMouseLeave={(e) => e.currentTarget.style.background = 'transparent'}
- onClick={() => {
- if (selectedRowKeys.length > 0 && cellContextMenu.record) {
- handleBatchFillToSelected(cellContextMenu.record, cellContextMenu.dataIndex);
- }
- }}
- >
-
- 填充到选中行 ({selectedRowKeys.length})
-
-
{
- if (copiedCellPatch) e.currentTarget.style.background = darkMode ? '#303030' : '#f5f5f5';
- }}
- onMouseLeave={(e) => e.currentTarget.style.background = 'transparent'}
- onClick={() => {
- if (!copiedCellPatch) return;
- const fallbackKey = cellContextMenu.record?.[GONAVI_ROW_KEY];
- handlePasteCopiedColumnsToSelectedRows(fallbackKey);
- }}
- >
-
- 粘贴已复制列(同名列)
-
-
- >
- )}
- {supportsCopyInsert && (
- <>
-
e.currentTarget.style.background = darkMode ? '#303030' : '#f5f5f5'}
- onMouseLeave={(e) => e.currentTarget.style.background = 'transparent'}
- onClick={() => {
- if (cellContextMenu.record) handleCopyInsert(cellContextMenu.record);
- setCellContextMenu(prev => ({ ...prev, visible: false }));
- }}
- >
- 复制为 INSERT
-
-
e.currentTarget.style.background = darkMode ? '#303030' : '#f5f5f5'}
- onMouseLeave={(e) => e.currentTarget.style.background = 'transparent'}
- onClick={() => {
- if (cellContextMenu.record) handleCopyUpdate(cellContextMenu.record);
- setCellContextMenu(prev => ({ ...prev, visible: false }));
- }}
- >
- 复制为 UPDATE
-
-
e.currentTarget.style.background = darkMode ? '#303030' : '#f5f5f5'}
- onMouseLeave={(e) => e.currentTarget.style.background = 'transparent'}
- onClick={() => {
- if (cellContextMenu.record) handleCopyDelete(cellContextMenu.record);
- setCellContextMenu(prev => ({ ...prev, visible: false }));
- }}
- >
- 复制为 DELETE
-
- >
- )}
-
e.currentTarget.style.background = darkMode ? '#303030' : '#f5f5f5'}
- onMouseLeave={(e) => e.currentTarget.style.background = 'transparent'}
- onClick={() => {
- if (cellContextMenu.record) handleCopyJson(cellContextMenu.record);
- setCellContextMenu(prev => ({ ...prev, visible: false }));
- }}
- >
- 复制为 JSON
-
-
e.currentTarget.style.background = darkMode ? '#303030' : '#f5f5f5'}
- onMouseLeave={(e) => e.currentTarget.style.background = 'transparent'}
- onClick={() => {
- if (cellContextMenu.record) handleCopyCsv(cellContextMenu.record);
- setCellContextMenu(prev => ({ ...prev, visible: false }));
- }}
- >
- 复制为 CSV
-
-
e.currentTarget.style.background = darkMode ? '#303030' : '#f5f5f5'}
- onMouseLeave={(e) => e.currentTarget.style.background = 'transparent'}
- onClick={() => {
- if (cellContextMenu.record) {
- const records = getTargets(cellContextMenu.record);
- const lines = records.map((r: any) => {
- const { [GONAVI_ROW_KEY]: _rowKey, ...vals } = r;
- return `| ${Object.values(vals).join(' | ')} |`;
- });
- copyToClipboard(lines.join('\n'));
- }
- setCellContextMenu(prev => ({ ...prev, visible: false }));
- }}
- >
- 复制为 Markdown
-
-
-
e.currentTarget.style.background = darkMode ? '#303030' : '#f5f5f5'}
- onMouseLeave={(e) => e.currentTarget.style.background = 'transparent'}
- onClick={() => {
- if (cellContextMenu.record) handleExportSelected('csv', cellContextMenu.record).catch(console.error);
- setCellContextMenu(prev => ({ ...prev, visible: false }));
- }}
- >
- 导出为 CSV
-
-
e.currentTarget.style.background = darkMode ? '#303030' : '#f5f5f5'}
- onMouseLeave={(e) => e.currentTarget.style.background = 'transparent'}
- onClick={() => {
- if (cellContextMenu.record) handleExportSelected('xlsx', cellContextMenu.record).catch(console.error);
- setCellContextMenu(prev => ({ ...prev, visible: false }));
- }}
- >
- 导出为 Excel
-
-
e.currentTarget.style.background = darkMode ? '#303030' : '#f5f5f5'}
- onMouseLeave={(e) => e.currentTarget.style.background = 'transparent'}
- onClick={() => {
- if (cellContextMenu.record) handleExportSelected('json', cellContextMenu.record).catch(console.error);
- setCellContextMenu(prev => ({ ...prev, visible: false }));
- }}
- >
- 导出为 JSON
-
-
e.currentTarget.style.background = darkMode ? '#303030' : '#f5f5f5'}
- onMouseLeave={(e) => e.currentTarget.style.background = 'transparent'}
- onClick={() => {
- if (cellContextMenu.record) handleExportSelected('html', cellContextMenu.record).catch(console.error);
- setCellContextMenu(prev => ({ ...prev, visible: false }));
- }}
- >
- 导出为 HTML
-
-