diff --git a/web/src/components/common/ui/CardTable.js b/web/src/components/common/ui/CardTable.js index f39c6d48..b24bc708 100644 --- a/web/src/components/common/ui/CardTable.js +++ b/web/src/components/common/ui/CardTable.js @@ -18,7 +18,9 @@ For commercial licensing, please contact support@quantumnous.com */ import React, { useState, useEffect, useRef } from 'react'; -import { Table, Card, Skeleton, Pagination, Empty } from '@douyinfe/semi-ui'; +import { useTranslation } from 'react-i18next'; +import { Table, Card, Skeleton, Pagination, Empty, Button, Collapsible } from '@douyinfe/semi-ui'; +import { IconChevronDown, IconChevronUp } from '@douyinfe/semi-icons'; import PropTypes from 'prop-types'; import { useIsMobile } from '../../../hooks/common/useIsMobile'; @@ -30,6 +32,7 @@ import { useIsMobile } from '../../../hooks/common/useIsMobile'; */ const CardTable = ({ columns = [], dataSource = [], loading = false, rowKey = 'key', ...tableProps }) => { const isMobile = useIsMobile(); + const { t } = useTranslation(); // Skeleton 显示控制,确保至少展示 500ms 动效 const [showSkeleton, setShowSkeleton] = useState(loading); @@ -94,7 +97,14 @@ const CardTable = ({ columns = [], dataSource = [], loading = false, rowKey = 'k return (
- +
); })} @@ -118,6 +128,78 @@ const CardTable = ({ columns = [], dataSource = [], loading = false, rowKey = 'k // 渲染移动端卡片 const isEmpty = !showSkeleton && (!dataSource || dataSource.length === 0); + // 移动端行卡片组件(含可折叠详情) + const MobileRowCard = ({ record, index }) => { + const [showDetails, setShowDetails] = useState(false); + const rowKeyVal = getRowKey(record, index); + + const hasDetails = + tableProps.expandedRowRender && + (!tableProps.rowExpandable || tableProps.rowExpandable(record)); + + return ( + + {columns.map((col, colIdx) => { + // 忽略隐藏列 + if (tableProps?.visibleColumns && !tableProps.visibleColumns[col.key]) { + return null; + } + + const title = col.title; + const cellContent = col.render + ? col.render(record[col.dataIndex], record, index) + : record[col.dataIndex]; + + // 空标题列(通常为操作按钮)单独渲染 + if (!title) { + return ( +
+ {cellContent} +
+ ); + } + + return ( +
+ + {title} + +
+ {cellContent !== undefined && cellContent !== null ? cellContent : '-'} +
+
+ ); + })} + + {hasDetails && ( + <> + + +
+ {tableProps.expandedRowRender(record, index)} +
+
+ + )} +
+ ); + }; + if (isEmpty) { // 若传入 empty 属性则使用之,否则使用默认 Empty if (tableProps.empty) return tableProps.empty; @@ -130,52 +212,9 @@ const CardTable = ({ columns = [], dataSource = [], loading = false, rowKey = 'k return (
- {dataSource.map((record, index) => { - const rowKeyVal = getRowKey(record, index); - return ( - - {columns.map((col, colIdx) => { - // 忽略隐藏列 - if (tableProps?.visibleColumns && !tableProps.visibleColumns[col.key]) { - return null; - } - - const title = col.title; - // 计算单元格内容 - const cellContent = col.render - ? col.render(record[col.dataIndex], record, index) - : record[col.dataIndex]; - - // 空标题列(通常为操作按钮)单独渲染 - if (!title) { - return ( -
- {cellContent} -
- ); - } - - return ( -
- - {title} - -
- {cellContent !== undefined && cellContent !== null ? cellContent : '-'} -
-
- ); - })} -
- ); - })} + {dataSource.map((record, index) => ( + + ))} {/* 分页组件 */} {tableProps.pagination && dataSource.length > 0 && (
diff --git a/web/src/components/table/usage-logs/UsageLogsColumnDefs.js b/web/src/components/table/usage-logs/UsageLogsColumnDefs.js index 2de5f7e2..d4ff1713 100644 --- a/web/src/components/table/usage-logs/UsageLogsColumnDefs.js +++ b/web/src/components/table/usage-logs/UsageLogsColumnDefs.js @@ -268,12 +268,14 @@ export const getLogsColumns = ({ return isAdminUser && (record.type === 0 || record.type === 2 || record.type === 5) ? ( - - {text} - + + + {text} + + {isMultiKey && ( @@ -466,15 +468,17 @@ export const getLogsColumns = ({ render: (text, record, index) => { return (record.type === 2 || record.type === 5) && text ? ( - { - copyText(event, text); - }} - > - {text} - + + { + copyText(event, text); + }} + > + {text} + + ) : ( <>