From 92d22b0bef407ea81668955d9234f03e5139076e Mon Sep 17 00:00:00 2001
From: hzm <934585316@qq.com>
Date: Sun, 1 Mar 2026 21:03:42 +0800
Subject: [PATCH] =?UTF-8?q?feat=EF=BC=9A=E5=88=86=E7=BB=84=E4=B8=8B?=
=?UTF-8?q?=E4=B8=AA=E6=80=A7=E5=8C=96=E6=95=B0=E6=8D=AE=E7=8B=AC=E7=AB=8B?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
app/components/MobileFundTable.jsx | 168 +++++++++++--------
app/components/PcFundTable.jsx | 257 +++++++++++++++--------------
app/globals.css | 2 +-
app/page.jsx | 33 +++-
4 files changed, 265 insertions(+), 195 deletions(-)
diff --git a/app/components/MobileFundTable.jsx b/app/components/MobileFundTable.jsx
index 9e31718..d2b613f 100644
--- a/app/components/MobileFundTable.jsx
+++ b/app/components/MobileFundTable.jsx
@@ -141,78 +141,112 @@ export default function MobileFundTable({
setActiveId(null);
};
- const getStoredMobileColumnOrder = () => {
- if (typeof window === 'undefined') return null;
+ const groupKey = currentTab ?? 'all';
+
+ const getCustomSettingsWithMigration = () => {
+ if (typeof window === 'undefined') return {};
try {
const raw = window.localStorage.getItem('customSettings');
- if (!raw) return null;
- const parsed = JSON.parse(raw);
- const order = parsed?.mobileTableColumnOrder;
- if (!Array.isArray(order) || order.length === 0) return null;
- const valid = order.filter((id) => MOBILE_NON_FROZEN_COLUMN_IDS.includes(id));
- const missing = MOBILE_NON_FROZEN_COLUMN_IDS.filter((id) => !valid.includes(id));
- return [...valid, ...missing];
+ const parsed = raw ? JSON.parse(raw) : {};
+ if (!parsed || typeof parsed !== 'object') return {};
+ if (parsed.pcTableColumnOrder != null || parsed.pcTableColumnVisibility != null || parsed.pcTableColumns != null || parsed.mobileTableColumnOrder != null || parsed.mobileTableColumnVisibility != null) {
+ const all = {
+ ...(parsed.all && typeof parsed.all === 'object' ? parsed.all : {}),
+ pcTableColumnOrder: parsed.pcTableColumnOrder,
+ pcTableColumnVisibility: parsed.pcTableColumnVisibility,
+ pcTableColumns: parsed.pcTableColumns,
+ mobileTableColumnOrder: parsed.mobileTableColumnOrder,
+ mobileTableColumnVisibility: parsed.mobileTableColumnVisibility,
+ };
+ delete parsed.pcTableColumnOrder;
+ delete parsed.pcTableColumnVisibility;
+ delete parsed.pcTableColumns;
+ delete parsed.mobileTableColumnOrder;
+ delete parsed.mobileTableColumnVisibility;
+ parsed.all = all;
+ window.localStorage.setItem('customSettings', JSON.stringify(parsed));
+ }
+ return parsed;
} catch {
- return null;
+ return {};
}
};
- const persistMobileColumnOrder = (nextOrder) => {
+
+ const getInitialMobileConfigByGroup = () => {
+ const parsed = getCustomSettingsWithMigration();
+ const byGroup = {};
+ Object.keys(parsed).forEach((k) => {
+ if (k === 'pcContainerWidth') return;
+ const group = parsed[k];
+ if (!group || typeof group !== 'object') return;
+ const order = Array.isArray(group.mobileTableColumnOrder) && group.mobileTableColumnOrder.length > 0
+ ? group.mobileTableColumnOrder
+ : null;
+ const visibility = group.mobileTableColumnVisibility && typeof group.mobileTableColumnVisibility === 'object'
+ ? group.mobileTableColumnVisibility
+ : null;
+ byGroup[k] = {
+ mobileTableColumnOrder: order ? (() => {
+ const valid = order.filter((id) => MOBILE_NON_FROZEN_COLUMN_IDS.includes(id));
+ const missing = MOBILE_NON_FROZEN_COLUMN_IDS.filter((id) => !valid.includes(id));
+ return [...valid, ...missing];
+ })() : null,
+ mobileTableColumnVisibility: visibility,
+ };
+ });
+ return byGroup;
+ };
+
+ const [configByGroup, setConfigByGroup] = useState(getInitialMobileConfigByGroup);
+
+ const currentGroupMobile = configByGroup[groupKey];
+ const defaultOrder = [...MOBILE_NON_FROZEN_COLUMN_IDS];
+ const defaultVisibility = (() => {
+ const o = {};
+ MOBILE_NON_FROZEN_COLUMN_IDS.forEach((id) => { o[id] = true; });
+ return o;
+ })();
+
+ const mobileColumnOrder = (() => {
+ const order = currentGroupMobile?.mobileTableColumnOrder ?? defaultOrder;
+ if (!Array.isArray(order) || order.length === 0) return [...MOBILE_NON_FROZEN_COLUMN_IDS];
+ const valid = order.filter((id) => MOBILE_NON_FROZEN_COLUMN_IDS.includes(id));
+ const missing = MOBILE_NON_FROZEN_COLUMN_IDS.filter((id) => !valid.includes(id));
+ return [...valid, ...missing];
+ })();
+ const mobileColumnVisibility = (() => {
+ const vis = currentGroupMobile?.mobileTableColumnVisibility ?? null;
+ if (vis && typeof vis === 'object' && Object.keys(vis).length > 0) return vis;
+ return defaultVisibility;
+ })();
+
+ const persistMobileGroupConfig = (updates) => {
if (typeof window === 'undefined') return;
try {
const raw = window.localStorage.getItem('customSettings');
const parsed = raw ? JSON.parse(raw) : {};
- const nextSettings =
- parsed && typeof parsed === 'object'
- ? { ...parsed, mobileTableColumnOrder: nextOrder }
- : { mobileTableColumnOrder: nextOrder };
- window.localStorage.setItem('customSettings', JSON.stringify(nextSettings));
- onCustomSettingsChange?.();
- } catch {}
- };
- const getStoredMobileColumnVisibility = () => {
- if (typeof window === 'undefined') return null;
- try {
- const raw = window.localStorage.getItem('customSettings');
- if (!raw) return null;
- const parsed = JSON.parse(raw);
- const visibility = parsed?.mobileTableColumnVisibility;
- if (!visibility || typeof visibility !== 'object') return null;
- const normalized = {};
- MOBILE_NON_FROZEN_COLUMN_IDS.forEach((id) => {
- const value = visibility[id];
- if (typeof value === 'boolean') normalized[id] = value;
- });
- return Object.keys(normalized).length ? normalized : null;
- } catch {
- return null;
- }
- };
- const persistMobileColumnVisibility = (nextVisibility) => {
- if (typeof window === 'undefined') return;
- try {
- const raw = window.localStorage.getItem('customSettings');
- const parsed = raw ? JSON.parse(raw) : {};
- const nextSettings =
- parsed && typeof parsed === 'object'
- ? { ...parsed, mobileTableColumnVisibility: nextVisibility }
- : { mobileTableColumnVisibility: nextVisibility };
- window.localStorage.setItem('customSettings', JSON.stringify(nextSettings));
+ const group = parsed[groupKey] && typeof parsed[groupKey] === 'object' ? { ...parsed[groupKey] } : {};
+ if (updates.mobileTableColumnOrder !== undefined) group.mobileTableColumnOrder = updates.mobileTableColumnOrder;
+ if (updates.mobileTableColumnVisibility !== undefined) group.mobileTableColumnVisibility = updates.mobileTableColumnVisibility;
+ parsed[groupKey] = group;
+ window.localStorage.setItem('customSettings', JSON.stringify(parsed));
+ setConfigByGroup((prev) => ({ ...prev, [groupKey]: { ...prev[groupKey], ...updates } }));
onCustomSettingsChange?.();
} catch {}
};
- const [mobileColumnOrder, setMobileColumnOrder] = useState(
- () => getStoredMobileColumnOrder() ?? [...MOBILE_NON_FROZEN_COLUMN_IDS]
- );
- const [mobileColumnVisibility, setMobileColumnVisibility] = useState(() => {
- const stored = getStoredMobileColumnVisibility();
- if (stored) return stored;
- const allVisible = {};
- MOBILE_NON_FROZEN_COLUMN_IDS.forEach((id) => {
- allVisible[id] = true;
- });
- return allVisible;
- });
+ const setMobileColumnOrder = (nextOrderOrUpdater) => {
+ const next = typeof nextOrderOrUpdater === 'function'
+ ? nextOrderOrUpdater(mobileColumnOrder)
+ : nextOrderOrUpdater;
+ persistMobileGroupConfig({ mobileTableColumnOrder: next });
+ };
+ const setMobileColumnVisibility = (nextOrUpdater) => {
+ const next = typeof nextOrUpdater === 'function'
+ ? nextOrUpdater(mobileColumnVisibility)
+ : nextOrUpdater;
+ persistMobileGroupConfig({ mobileTableColumnVisibility: next });
+ };
const [settingModalOpen, setSettingModalOpen] = useState(false);
const tableContainerRef = useRef(null);
const [tableContainerWidth, setTableContainerWidth] = useState(0);
@@ -258,9 +292,7 @@ export default function MobileFundTable({
}, [tableContainerWidth, mobileColumnOrder, mobileColumnVisibility]);
const handleResetMobileColumnOrder = () => {
- const defaultOrder = [...MOBILE_NON_FROZEN_COLUMN_IDS];
- setMobileColumnOrder(defaultOrder);
- persistMobileColumnOrder(defaultOrder);
+ setMobileColumnOrder([...MOBILE_NON_FROZEN_COLUMN_IDS]);
};
const handleResetMobileColumnVisibility = () => {
const allVisible = {};
@@ -268,14 +300,9 @@ export default function MobileFundTable({
allVisible[id] = true;
});
setMobileColumnVisibility(allVisible);
- persistMobileColumnVisibility(allVisible);
};
const handleToggleMobileColumnVisibility = (columnId, visible) => {
- setMobileColumnVisibility((prev = {}) => {
- const next = { ...prev, [columnId]: visible };
- persistMobileColumnVisibility(next);
- return next;
- });
+ setMobileColumnVisibility((prev = {}) => ({ ...prev, [columnId]: visible }));
};
// 移动端名称列:无拖拽把手,长按整行触发排序
@@ -298,6 +325,7 @@ export default function MobileFundTable({
onRemoveFromGroupRef.current?.(original);
}}
title="从当前分组移除"
+ style={{ backgroundColor: 'transparent'}}
>
@@ -309,6 +337,7 @@ export default function MobileFundTable({
onToggleFavoriteRef.current?.(original);
}}
title={isFavorites ? '取消自选' : '添加自选'}
+ style={{ backgroundColor: 'transparent'}}
>
@@ -538,7 +567,6 @@ export default function MobileFundTable({
const newNonFrozen = next.filter((id) => id !== 'fundName');
if (newNonFrozen.length) {
setMobileColumnOrder(newNonFrozen);
- persistMobileColumnOrder(newNonFrozen);
}
},
onColumnVisibilityChange: (updater) => {
@@ -546,7 +574,6 @@ export default function MobileFundTable({
const rest = { ...next };
delete rest.fundName;
setMobileColumnVisibility(rest);
- persistMobileColumnVisibility(rest);
},
initialState: {
columnPinning: {
@@ -738,7 +765,6 @@ export default function MobileFundTable({
columnVisibility={mobileColumnVisibility}
onColumnReorder={(newOrder) => {
setMobileColumnOrder(newOrder);
- persistMobileColumnOrder(newOrder);
}}
onToggleColumnVisibility={handleToggleMobileColumnVisibility}
onResetColumnOrder={handleResetMobileColumnOrder}
diff --git a/app/components/PcFundTable.jsx b/app/components/PcFundTable.jsx
index fc681c2..f966124 100644
--- a/app/components/PcFundTable.jsx
+++ b/app/components/PcFundTable.jsx
@@ -161,131 +161,160 @@ export default function PcFundTable({
}
setActiveId(null);
};
- const getStoredColumnSizing = () => {
+ const groupKey = currentTab ?? 'all';
+
+ const getCustomSettingsWithMigration = () => {
if (typeof window === 'undefined') return {};
try {
const raw = window.localStorage.getItem('customSettings');
- if (!raw) return {};
- const parsed = JSON.parse(raw);
- const sizing = parsed?.pcTableColumns;
- if (!sizing || typeof sizing !== 'object') return {};
- return Object.fromEntries(
- Object.entries(sizing).filter(([, value]) => Number.isFinite(value)),
- );
+ const parsed = raw ? JSON.parse(raw) : {};
+ if (!parsed || typeof parsed !== 'object') return {};
+ if (parsed.pcTableColumnOrder != null || parsed.pcTableColumnVisibility != null || parsed.pcTableColumns != null || parsed.mobileTableColumnOrder != null || parsed.mobileTableColumnVisibility != null) {
+ const all = {
+ ...(parsed.all && typeof parsed.all === 'object' ? parsed.all : {}),
+ pcTableColumnOrder: parsed.pcTableColumnOrder,
+ pcTableColumnVisibility: parsed.pcTableColumnVisibility,
+ pcTableColumns: parsed.pcTableColumns,
+ mobileTableColumnOrder: parsed.mobileTableColumnOrder,
+ mobileTableColumnVisibility: parsed.mobileTableColumnVisibility,
+ };
+ delete parsed.pcTableColumnOrder;
+ delete parsed.pcTableColumnVisibility;
+ delete parsed.pcTableColumns;
+ delete parsed.mobileTableColumnOrder;
+ delete parsed.mobileTableColumnVisibility;
+ parsed.all = all;
+ window.localStorage.setItem('customSettings', JSON.stringify(parsed));
+ }
+ return parsed;
} catch {
return {};
}
};
- const persistColumnSizing = (nextSizing) => {
- if (typeof window === 'undefined') return;
- try {
- const raw = window.localStorage.getItem('customSettings');
- const parsed = raw ? JSON.parse(raw) : {};
- const nextSettings =
- parsed && typeof parsed === 'object'
- ? { ...parsed, pcTableColumns: nextSizing }
- : { pcTableColumns: nextSizing };
- window.localStorage.setItem('customSettings', JSON.stringify(nextSettings));
- onCustomSettingsChange?.();
- } catch { }
- };
-
- const getStoredColumnOrder = () => {
- if (typeof window === 'undefined') return null;
- try {
- const raw = window.localStorage.getItem('customSettings');
- if (!raw) return null;
- const parsed = JSON.parse(raw);
- const order = parsed?.pcTableColumnOrder;
- if (!Array.isArray(order) || order.length === 0) return null;
- const valid = order.filter((id) => NON_FROZEN_COLUMN_IDS.includes(id));
- const missing = NON_FROZEN_COLUMN_IDS.filter((id) => !valid.includes(id));
- return [...valid, ...missing];
- } catch {
- return null;
+ const buildPcConfigFromGroup = (group) => {
+ if (!group || typeof group !== 'object') return null;
+ const sizing = group.pcTableColumns;
+ const sizingObj = sizing && typeof sizing === 'object'
+ ? Object.fromEntries(Object.entries(sizing).filter(([, v]) => Number.isFinite(v)))
+ : {};
+ if (sizingObj.actions) {
+ const { actions, ...rest } = sizingObj;
+ Object.assign(sizingObj, rest);
+ delete sizingObj.actions;
}
+ const order = Array.isArray(group.pcTableColumnOrder) && group.pcTableColumnOrder.length > 0
+ ? group.pcTableColumnOrder
+ : null;
+ const visibility = group.pcTableColumnVisibility && typeof group.pcTableColumnVisibility === 'object'
+ ? group.pcTableColumnVisibility
+ : null;
+ return { sizing: sizingObj, order, visibility };
};
- const persistColumnOrder = (nextOrder) => {
- if (typeof window === 'undefined') return;
- try {
- const raw = window.localStorage.getItem('customSettings');
- const parsed = raw ? JSON.parse(raw) : {};
- const nextSettings =
- parsed && typeof parsed === 'object'
- ? { ...parsed, pcTableColumnOrder: nextOrder }
- : { pcTableColumnOrder: nextOrder };
- window.localStorage.setItem('customSettings', JSON.stringify(nextSettings));
- onCustomSettingsChange?.();
- } catch { }
- };
-
- const getStoredColumnVisibility = () => {
- if (typeof window === 'undefined') return null;
- try {
- const raw = window.localStorage.getItem('customSettings');
- if (!raw) return null;
- const parsed = JSON.parse(raw);
- const visibility = parsed?.pcTableColumnVisibility;
- if (!visibility || typeof visibility !== 'object') return null;
- const normalized = {};
- NON_FROZEN_COLUMN_IDS.forEach((id) => {
- const value = visibility[id];
- if (typeof value === 'boolean') {
- normalized[id] = value;
- }
- });
- return Object.keys(normalized).length ? normalized : null;
- } catch {
- return null;
- }
- };
-
- const persistColumnVisibility = (nextVisibility) => {
- if (typeof window === 'undefined') return;
- try {
- const raw = window.localStorage.getItem('customSettings');
- const parsed = raw ? JSON.parse(raw) : {};
- const nextSettings =
- parsed && typeof parsed === 'object'
- ? { ...parsed, pcTableColumnVisibility: nextVisibility }
- : { pcTableColumnVisibility: nextVisibility };
- window.localStorage.setItem('customSettings', JSON.stringify(nextSettings));
- onCustomSettingsChange?.();
- } catch { }
- };
-
- const [columnSizing, setColumnSizing] = useState(() => {
- const stored = getStoredColumnSizing();
- if (stored.actions) {
- const { actions, ...rest } = stored;
- return rest;
- }
- return stored;
+ const getDefaultPcGroupConfig = () => ({
+ order: [...NON_FROZEN_COLUMN_IDS],
+ visibility: null,
+ sizing: {},
});
- const [columnOrder, setColumnOrder] = useState(() => getStoredColumnOrder() ?? [...NON_FROZEN_COLUMN_IDS]);
- const [columnVisibility, setColumnVisibility] = useState(() => {
- const stored = getStoredColumnVisibility();
- if (stored) return stored;
- const allVisible = {};
- NON_FROZEN_COLUMN_IDS.forEach((id) => {
- allVisible[id] = true;
+
+ const getInitialConfigByGroup = () => {
+ const parsed = getCustomSettingsWithMigration();
+ const byGroup = {};
+ Object.keys(parsed).forEach((k) => {
+ if (k === 'pcContainerWidth') return;
+ const group = parsed[k];
+ const pc = buildPcConfigFromGroup(group);
+ if (pc) {
+ byGroup[k] = {
+ pcTableColumnOrder: pc.order ? (() => {
+ const valid = pc.order.filter((id) => NON_FROZEN_COLUMN_IDS.includes(id));
+ const missing = NON_FROZEN_COLUMN_IDS.filter((id) => !valid.includes(id));
+ return [...valid, ...missing];
+ })() : null,
+ pcTableColumnVisibility: pc.visibility,
+ pcTableColumns: Object.keys(pc.sizing).length ? pc.sizing : null,
+ };
+ }
});
+ return byGroup;
+ };
+
+ const [configByGroup, setConfigByGroup] = useState(getInitialConfigByGroup);
+
+ const currentGroupPc = configByGroup[groupKey];
+ const defaultPc = getDefaultPcGroupConfig();
+ const columnOrder = (() => {
+ const order = currentGroupPc?.pcTableColumnOrder ?? defaultPc.order;
+ if (!Array.isArray(order) || order.length === 0) return [...NON_FROZEN_COLUMN_IDS];
+ const valid = order.filter((id) => NON_FROZEN_COLUMN_IDS.includes(id));
+ const missing = NON_FROZEN_COLUMN_IDS.filter((id) => !valid.includes(id));
+ return [...valid, ...missing];
+ })();
+ const columnVisibility = (() => {
+ const vis = currentGroupPc?.pcTableColumnVisibility ?? null;
+ if (vis && typeof vis === 'object' && Object.keys(vis).length > 0) return vis;
+ const allVisible = {};
+ NON_FROZEN_COLUMN_IDS.forEach((id) => { allVisible[id] = true; });
return allVisible;
- });
+ })();
+ const columnSizing = (() => {
+ const s = currentGroupPc?.pcTableColumns;
+ if (s && typeof s === 'object') {
+ const out = Object.fromEntries(Object.entries(s).filter(([, v]) => Number.isFinite(v)));
+ if (out.actions) {
+ const { actions, ...rest } = out;
+ return rest;
+ }
+ return out;
+ }
+ return {};
+ })();
+
+ const persistPcGroupConfig = (updates) => {
+ if (typeof window === 'undefined') return;
+ try {
+ const raw = window.localStorage.getItem('customSettings');
+ const parsed = raw ? JSON.parse(raw) : {};
+ const group = parsed[groupKey] && typeof parsed[groupKey] === 'object' ? { ...parsed[groupKey] } : {};
+ if (updates.pcTableColumnOrder !== undefined) group.pcTableColumnOrder = updates.pcTableColumnOrder;
+ if (updates.pcTableColumnVisibility !== undefined) group.pcTableColumnVisibility = updates.pcTableColumnVisibility;
+ if (updates.pcTableColumns !== undefined) group.pcTableColumns = updates.pcTableColumns;
+ parsed[groupKey] = group;
+ window.localStorage.setItem('customSettings', JSON.stringify(parsed));
+ setConfigByGroup((prev) => ({ ...prev, [groupKey]: { ...prev[groupKey], ...updates } }));
+ onCustomSettingsChange?.();
+ } catch { }
+ };
+
+ const setColumnOrder = (nextOrderOrUpdater) => {
+ const next = typeof nextOrderOrUpdater === 'function'
+ ? nextOrderOrUpdater(columnOrder)
+ : nextOrderOrUpdater;
+ persistPcGroupConfig({ pcTableColumnOrder: next });
+ };
+ const setColumnVisibility = (nextOrUpdater) => {
+ const next = typeof nextOrUpdater === 'function'
+ ? nextOrUpdater(columnVisibility)
+ : nextOrUpdater;
+ persistPcGroupConfig({ pcTableColumnVisibility: next });
+ };
+ const setColumnSizing = (nextOrUpdater) => {
+ const next = typeof nextOrUpdater === 'function'
+ ? nextOrUpdater(columnSizing)
+ : nextOrUpdater;
+ const { actions, ...rest } = next || {};
+ persistPcGroupConfig({ pcTableColumns: rest || {} });
+ };
const [settingModalOpen, setSettingModalOpen] = useState(false);
const [resetConfirmOpen, setResetConfirmOpen] = useState(false);
const handleResetSizing = () => {
setColumnSizing({});
- persistColumnSizing({});
setResetConfirmOpen(false);
};
const handleResetColumnOrder = () => {
- const defaultOrder = [...NON_FROZEN_COLUMN_IDS];
- setColumnOrder(defaultOrder);
- persistColumnOrder(defaultOrder);
+ setColumnOrder([...NON_FROZEN_COLUMN_IDS]);
};
const handleResetColumnVisibility = () => {
@@ -294,14 +323,9 @@ export default function PcFundTable({
allVisible[id] = true;
});
setColumnVisibility(allVisible);
- persistColumnVisibility(allVisible);
};
const handleToggleColumnVisibility = (columnId, visible) => {
- setColumnVisibility((prev = {}) => {
- const next = { ...prev, [columnId]: visible };
- persistColumnVisibility(next);
- return next;
- });
+ setColumnVisibility((prev = {}) => ({ ...prev, [columnId]: visible }));
};
const onRemoveFundRef = useRef(onRemoveFund);
const onToggleFavoriteRef = useRef(onToggleFavorite);
@@ -350,6 +374,7 @@ export default function PcFundTable({
onRemoveFromGroupRef.current?.(original);
}}
title="从小分组移除"
+ style={{ backgroundColor: 'transparent'}}
>
@@ -676,7 +701,6 @@ export default function PcFundTable({
setColumnSizing((prev) => {
const next = typeof updater === 'function' ? updater(prev) : updater;
const { actions, ...rest } = next || {};
- persistColumnSizing(rest || {});
return rest || {};
});
},
@@ -686,18 +710,10 @@ export default function PcFundTable({
columnVisibility,
},
onColumnOrderChange: (updater) => {
- setColumnOrder((prev) => {
- const next = typeof updater === 'function' ? updater(prev) : prev;
- persistColumnOrder(next);
- return next;
- });
+ setColumnOrder(updater);
},
onColumnVisibilityChange: (updater) => {
- setColumnVisibility((prev = {}) => {
- const next = typeof updater === 'function' ? updater(prev) : (updater || {});
- persistColumnVisibility(next);
- return next;
- });
+ setColumnVisibility(updater);
},
initialState: {
columnPinning: {
@@ -927,7 +943,6 @@ export default function PcFundTable({
columns={columnOrder.map((id) => ({ id, header: COLUMN_HEADERS[id] ?? id }))}
onColumnReorder={(newOrder) => {
setColumnOrder(newOrder);
- persistColumnOrder(newOrder);
}}
columnVisibility={columnVisibility}
onToggleColumnVisibility={handleToggleColumnVisibility}
diff --git a/app/globals.css b/app/globals.css
index 4069e5d..b113b7e 100644
--- a/app/globals.css
+++ b/app/globals.css
@@ -1900,7 +1900,7 @@ input[type="number"] {
.mobile-setting-drawer {
width: 100%;
- max-height: 75vh;
+ max-height: 90vh;
display: flex;
flex-direction: column;
border-radius: 20px 20px 0 0;
diff --git a/app/page.jsx b/app/page.jsx
index f787693..5f363ea 100644
--- a/app/page.jsx
+++ b/app/page.jsx
@@ -1751,15 +1751,44 @@ export default function HomePage() {
setGroups(next);
storageHelper.setItem('groups', JSON.stringify(next));
if (currentTab === id) setCurrentTab('all');
+ try {
+ const raw = window.localStorage.getItem('customSettings');
+ const parsed = raw ? JSON.parse(raw) : {};
+ if (parsed && typeof parsed === 'object' && parsed[id] !== undefined) {
+ delete parsed[id];
+ window.localStorage.setItem('customSettings', JSON.stringify(parsed));
+ triggerCustomSettingsSync();
+ }
+ } catch { }
};
const handleUpdateGroups = (newGroups) => {
+ const removedIds = groups.filter((g) => !newGroups.find((ng) => ng.id === g.id)).map((g) => g.id);
setGroups(newGroups);
storageHelper.setItem('groups', JSON.stringify(newGroups));
// 如果当前选中的分组被删除了,切换回“全部”
if (currentTab !== 'all' && currentTab !== 'fav' && !newGroups.find(g => g.id === currentTab)) {
setCurrentTab('all');
}
+ if (removedIds.length > 0) {
+ try {
+ const raw = window.localStorage.getItem('customSettings');
+ const parsed = raw ? JSON.parse(raw) : {};
+ if (parsed && typeof parsed === 'object') {
+ let changed = false;
+ removedIds.forEach((groupId) => {
+ if (parsed[groupId] !== undefined) {
+ delete parsed[groupId];
+ changed = true;
+ }
+ });
+ if (changed) {
+ window.localStorage.setItem('customSettings', JSON.stringify(parsed));
+ triggerCustomSettingsSync();
+ }
+ }
+ } catch { }
+ }
};
const handleAddFundsToGroup = (codes) => {
@@ -3906,7 +3935,7 @@ export default function HomePage() {
style={{
width: '100%',
height: '48px',
- border: '2px dashed rgba(255,255,255,0.1)',
+ border: '2px dashed var(--border)',
background: 'transparent',
borderRadius: '12px',
color: 'var(--muted)',
@@ -3926,7 +3955,7 @@ export default function HomePage() {
e.currentTarget.style.background = 'rgba(34, 211, 238, 0.05)';
}}
onMouseLeave={(e) => {
- e.currentTarget.style.borderColor = 'rgba(255,255,255,0.1)';
+ e.currentTarget.style.borderColor = 'var(--border)';
e.currentTarget.style.color = 'var(--muted)';
e.currentTarget.style.background = 'transparent';
}}