feat: 测试关联板块
This commit is contained in:
@@ -34,9 +34,11 @@ import {
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
} from '@/components/ui/dialog';
|
||||
import { CloseIcon, DragIcon, ExitIcon, SettingsIcon, StarIcon, TrashIcon, ResetIcon } from './Icons';
|
||||
import { DragIcon, ExitIcon, SettingsIcon, StarIcon, TrashIcon, ResetIcon } from './Icons';
|
||||
import { fetchRelatedSectors } from '@/app/api/fund';
|
||||
|
||||
const NON_FROZEN_COLUMN_IDS = [
|
||||
'relatedSector',
|
||||
'yesterdayChangePercent',
|
||||
'estimateChangePercent',
|
||||
'totalChangePercent',
|
||||
@@ -47,6 +49,7 @@ const NON_FROZEN_COLUMN_IDS = [
|
||||
'estimateNav',
|
||||
];
|
||||
const COLUMN_HEADERS = {
|
||||
relatedSector: '关联板块',
|
||||
latestNav: '最新净值',
|
||||
estimateNav: '估算净值',
|
||||
yesterdayChangePercent: '昨日涨幅',
|
||||
@@ -282,9 +285,15 @@ export default function PcFundTable({
|
||||
})();
|
||||
const columnVisibility = (() => {
|
||||
const vis = currentGroupPc?.pcTableColumnVisibility ?? null;
|
||||
if (vis && typeof vis === 'object' && Object.keys(vis).length > 0) return vis;
|
||||
if (vis && typeof vis === 'object' && Object.keys(vis).length > 0) {
|
||||
const next = { ...vis };
|
||||
if (next.relatedSector === undefined) next.relatedSector = false;
|
||||
return next;
|
||||
}
|
||||
const allVisible = {};
|
||||
NON_FROZEN_COLUMN_IDS.forEach((id) => { allVisible[id] = true; });
|
||||
// 新增列:默认隐藏(用户可在表格设置中开启)
|
||||
allVisible.relatedSector = false;
|
||||
return allVisible;
|
||||
})();
|
||||
const columnSizing = (() => {
|
||||
@@ -356,6 +365,7 @@ export default function PcFundTable({
|
||||
NON_FROZEN_COLUMN_IDS.forEach((id) => {
|
||||
allVisible[id] = true;
|
||||
});
|
||||
allVisible.relatedSector = false;
|
||||
setColumnVisibility(allVisible);
|
||||
};
|
||||
const handleToggleColumnVisibility = (columnId, visible) => {
|
||||
@@ -443,6 +453,51 @@ export default function PcFundTable({
|
||||
};
|
||||
}, [stickyTop]);
|
||||
|
||||
const relatedSectorEnabled = columnVisibility?.relatedSector !== false;
|
||||
const relatedSectorCacheRef = useRef(new Map());
|
||||
const [relatedSectorByCode, setRelatedSectorByCode] = useState({});
|
||||
|
||||
const fetchRelatedSector = async (code) => fetchRelatedSectors(code);
|
||||
|
||||
const runWithConcurrency = async (items, limit, worker) => {
|
||||
const queue = [...items];
|
||||
const results = [];
|
||||
const runners = Array.from({ length: Math.max(1, limit) }, async () => {
|
||||
while (queue.length) {
|
||||
const item = queue.shift();
|
||||
if (item == null) continue;
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
results.push(await worker(item));
|
||||
}
|
||||
});
|
||||
await Promise.all(runners);
|
||||
return results;
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (!relatedSectorEnabled) return;
|
||||
if (!Array.isArray(data) || data.length === 0) return;
|
||||
|
||||
const codes = Array.from(new Set(data.map((d) => d?.code).filter(Boolean)));
|
||||
const missing = codes.filter((code) => !relatedSectorCacheRef.current.has(code));
|
||||
if (missing.length === 0) return;
|
||||
|
||||
let cancelled = false;
|
||||
(async () => {
|
||||
await runWithConcurrency(missing, 4, async (code) => {
|
||||
const value = await fetchRelatedSector(code);
|
||||
relatedSectorCacheRef.current.set(code, value);
|
||||
if (cancelled) return;
|
||||
setRelatedSectorByCode((prev) => {
|
||||
if (prev[code] === value) return prev;
|
||||
return { ...prev, [code]: value };
|
||||
});
|
||||
});
|
||||
})();
|
||||
|
||||
return () => { cancelled = true; };
|
||||
}, [relatedSectorEnabled, data]);
|
||||
|
||||
useEffect(() => {
|
||||
const tableEl = tableContainerRef.current;
|
||||
const portalEl = portalHeaderRef.current;
|
||||
@@ -563,6 +618,22 @@ export default function PcFundTable({
|
||||
cellClassName: 'name-cell',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'relatedSector',
|
||||
header: '关联板块',
|
||||
size: 180,
|
||||
minSize: 120,
|
||||
cell: (info) => {
|
||||
const original = info.row.original || {};
|
||||
const code = original.code;
|
||||
const value = (code && (relatedSectorByCode?.[code] ?? relatedSectorCacheRef.current.get(code))) || '';
|
||||
return value || '—';
|
||||
},
|
||||
meta: {
|
||||
align: 'right',
|
||||
cellClassName: 'related-sector-cell',
|
||||
},
|
||||
},
|
||||
{
|
||||
accessorKey: 'latestNav',
|
||||
header: '最新净值',
|
||||
@@ -895,7 +966,7 @@ export default function PcFundTable({
|
||||
},
|
||||
},
|
||||
],
|
||||
[currentTab, favorites, refreshing, sortBy, showFullFundName, getFundCardProps, masked],
|
||||
[currentTab, favorites, refreshing, sortBy, showFullFundName, getFundCardProps, masked, relatedSectorByCode],
|
||||
);
|
||||
|
||||
const table = useReactTable({
|
||||
@@ -1125,6 +1196,7 @@ export default function PcFundTable({
|
||||
const columnId = cell.column.id || cell.column.columnDef?.accessorKey;
|
||||
const isNameColumn = columnId === 'fundName';
|
||||
const rightAlignedColumns = new Set([
|
||||
'relatedSector',
|
||||
'latestNav',
|
||||
'estimateNav',
|
||||
'yesterdayChangePercent',
|
||||
|
||||
Reference in New Issue
Block a user