diff --git a/web/src/components/table/ChannelsTable.js b/web/src/components/table/ChannelsTable.js
index 68babe2e..1907387d 100644
--- a/web/src/components/table/ChannelsTable.js
+++ b/web/src/components/table/ChannelsTable.js
@@ -41,6 +41,7 @@ import {
Tag,
Tooltip,
Typography,
+ Checkbox,
Card,
Form
} from '@douyinfe/semi-ui';
@@ -172,17 +173,108 @@ const ChannelsTable = () => {
}
};
- // Define all columns
- const columns = [
+ // Define column keys for selection
+ const COLUMN_KEYS = {
+ ID: 'id',
+ NAME: 'name',
+ GROUP: 'group',
+ TYPE: 'type',
+ STATUS: 'status',
+ RESPONSE_TIME: 'response_time',
+ BALANCE: 'balance',
+ PRIORITY: 'priority',
+ WEIGHT: 'weight',
+ OPERATE: 'operate',
+ };
+
+ // State for column visibility
+ const [visibleColumns, setVisibleColumns] = useState({});
+ const [showColumnSelector, setShowColumnSelector] = useState(false);
+
+ // Load saved column preferences from localStorage
+ useEffect(() => {
+ const savedColumns = localStorage.getItem('channels-table-columns');
+ if (savedColumns) {
+ try {
+ const parsed = JSON.parse(savedColumns);
+ // Make sure all columns are accounted for
+ const defaults = getDefaultColumnVisibility();
+ const merged = { ...defaults, ...parsed };
+ setVisibleColumns(merged);
+ } catch (e) {
+ console.error('Failed to parse saved column preferences', e);
+ initDefaultColumns();
+ }
+ } else {
+ initDefaultColumns();
+ }
+ }, []);
+
+ // Update table when column visibility changes
+ useEffect(() => {
+ if (Object.keys(visibleColumns).length > 0) {
+ // Save to localStorage
+ localStorage.setItem(
+ 'channels-table-columns',
+ JSON.stringify(visibleColumns),
+ );
+ }
+ }, [visibleColumns]);
+
+ // Get default column visibility
+ const getDefaultColumnVisibility = () => {
+ return {
+ [COLUMN_KEYS.ID]: true,
+ [COLUMN_KEYS.NAME]: true,
+ [COLUMN_KEYS.GROUP]: true,
+ [COLUMN_KEYS.TYPE]: true,
+ [COLUMN_KEYS.STATUS]: true,
+ [COLUMN_KEYS.RESPONSE_TIME]: true,
+ [COLUMN_KEYS.BALANCE]: true,
+ [COLUMN_KEYS.PRIORITY]: true,
+ [COLUMN_KEYS.WEIGHT]: true,
+ [COLUMN_KEYS.OPERATE]: true,
+ };
+ };
+
+ // Initialize default column visibility
+ const initDefaultColumns = () => {
+ const defaults = getDefaultColumnVisibility();
+ setVisibleColumns(defaults);
+ };
+
+ // Handle column visibility change
+ const handleColumnVisibilityChange = (columnKey, checked) => {
+ const updatedColumns = { ...visibleColumns, [columnKey]: checked };
+ setVisibleColumns(updatedColumns);
+ };
+
+ // Handle "Select All" checkbox
+ const handleSelectAll = (checked) => {
+ const allKeys = Object.keys(COLUMN_KEYS).map((key) => COLUMN_KEYS[key]);
+ const updatedColumns = {};
+
+ allKeys.forEach((key) => {
+ updatedColumns[key] = checked;
+ });
+
+ setVisibleColumns(updatedColumns);
+ };
+
+ // Define all columns with keys
+ const allColumns = [
{
+ key: COLUMN_KEYS.ID,
title: t('ID'),
dataIndex: 'id',
},
{
+ key: COLUMN_KEYS.NAME,
title: t('名称'),
dataIndex: 'name',
},
{
+ key: COLUMN_KEYS.GROUP,
title: t('分组'),
dataIndex: 'group',
render: (text, record, index) => (
@@ -201,6 +293,7 @@ const ChannelsTable = () => {
),
},
{
+ key: COLUMN_KEYS.TYPE,
title: t('类型'),
dataIndex: 'type',
render: (text, record, index) => {
@@ -212,6 +305,7 @@ const ChannelsTable = () => {
},
},
{
+ key: COLUMN_KEYS.STATUS,
title: t('状态'),
dataIndex: 'status',
render: (text, record, index) => {
@@ -237,6 +331,7 @@ const ChannelsTable = () => {
},
},
{
+ key: COLUMN_KEYS.RESPONSE_TIME,
title: t('响应时间'),
dataIndex: 'response_time',
render: (text, record, index) => (
@@ -244,6 +339,7 @@ const ChannelsTable = () => {
),
},
{
+ key: COLUMN_KEYS.BALANCE,
title: t('已用/剩余'),
dataIndex: 'expired_time',
render: (text, record, index) => {
@@ -283,6 +379,7 @@ const ChannelsTable = () => {
},
},
{
+ key: COLUMN_KEYS.PRIORITY,
title: t('优先级'),
dataIndex: 'priority',
render: (text, record, index) => {
@@ -334,6 +431,7 @@ const ChannelsTable = () => {
},
},
{
+ key: COLUMN_KEYS.WEIGHT,
title: t('权重'),
dataIndex: 'weight',
render: (text, record, index) => {
@@ -385,6 +483,7 @@ const ChannelsTable = () => {
},
},
{
+ key: COLUMN_KEYS.OPERATE,
title: '',
dataIndex: 'operate',
fixed: 'right',
@@ -595,6 +694,89 @@ const ChannelsTable = () => {
searchModel: '',
};
+ // Filter columns based on visibility settings
+ const getVisibleColumns = () => {
+ return allColumns.filter((column) => visibleColumns[column.key]);
+ };
+
+ // Column selector modal
+ const renderColumnSelector = () => {
+ return (
+