From ecc4ded05285e678a9fd54816bb22b1dcb0e8e04 Mon Sep 17 00:00:00 2001 From: Alex-larget <33240357+Alex-larget@users.noreply.github.com> Date: Fri, 20 Mar 2026 11:05:52 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=8D=E6=9E=84=E7=AB=A0=E8=8A=82=E6=A0=91?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=EF=BC=8C=E6=9B=B4=E6=96=B0=E7=AB=A0=E8=8A=82?= =?UTF-8?q?ID=E5=B1=95=E7=A4=BA=E9=80=BB=E8=BE=91=EF=BC=8C=E7=A7=BB?= =?UTF-8?q?=E9=99=A4=E8=8A=82=E5=BA=8F=E5=8F=B7=E4=BE=9D=E8=B5=96=EF=BC=8C?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E7=AB=A0=E8=8A=82=E8=8C=83=E5=9B=B4=E6=98=BE?= =?UTF-8?q?=E7=A4=BA=E3=80=82=E8=B0=83=E6=95=B4=E5=86=85=E5=AE=B9=E9=A1=B5?= =?UTF-8?q?=E9=9D=A2=E6=A0=91=E6=9E=84=E5=BB=BA=E9=80=BB=E8=BE=91=EF=BC=8C?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=E7=83=AD=E5=BA=A6=E6=8E=92=E5=90=8D=E6=98=A0?= =?UTF-8?q?=E5=B0=84=EF=BC=8C=E6=8F=90=E5=8D=87=E6=95=B0=E6=8D=AE=E5=B1=95?= =?UTF-8?q?=E7=A4=BA=E4=B8=80=E8=87=B4=E6=80=A7=E5=92=8C=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E4=BD=93=E9=AA=8C=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- soul-admin/src/pages/content/ChapterTree.tsx | 59 +++++++------------- soul-admin/src/pages/content/ContentPage.tsx | 17 ++++-- 2 files changed, 33 insertions(+), 43 deletions(-) diff --git a/soul-admin/src/pages/content/ChapterTree.tsx b/soul-admin/src/pages/content/ChapterTree.tsx index 4d2d4b45..5253737b 100644 --- a/soul-admin/src/pages/content/ChapterTree.tsx +++ b/soul-admin/src/pages/content/ChapterTree.tsx @@ -41,26 +41,16 @@ function isPrefacePart(p: PartItem) { } /** 篇内按章数量展示:第1章 ~ 第n章(仅章数,与节数无关) */ -function chapterRangeSubtitle(chapterCount: number): string { - if (chapterCount <= 0) return '暂无章节' - if (chapterCount === 1) return '第1章' - return `第1章 ~ 第${chapterCount}章` -} - -/** 全书节序号:跳过序言篇后从 1 连续编号(与列表拖拽顺序一致) */ -function buildBodySectionOrderMap(parts: PartItem[]): Map { - const m = new Map() - let n = 0 - for (const part of parts) { - if (isPrefacePart(part)) continue - for (const ch of part.chapters) { - for (const s of ch.sections) { - n += 1 - m.set(s.id, n) - } +function sectionIdRangeSubtitle(part: PartItem): string { + const ids: string[] = [] + for (const ch of part.chapters) { + for (const s of ch.sections) { + ids.push(s.id) } } - return m + if (ids.length === 0) return '暂无章节' + if (ids.length === 1) return ids[0] + return `${ids[0]}~${ids[ids.length - 1]}` } function parseDragData(data: string): { type: DragType; id: string } | null { @@ -113,7 +103,7 @@ export function ChapterTree({ const [draggingItem, setDraggingItem] = useState<{ type: DragType; id: string } | null>(null) const [dragOverTarget, setDragOverTarget] = useState<{ type: DragType; id: string } | null>(null) - const bodySectionOrderMap = useMemo(() => buildBodySectionOrderMap(parts), [parts]) + // 章节ID/范围展示由数据本身决定,不再依赖“节序号”重新编号 const isDragging = (type: DragType, id: string) => draggingItem?.type === type && draggingItem?.id === id const isDragOver = (type: DragType, id: string) => dragOverTarget?.type === type && dragOverTarget?.id === id @@ -303,25 +293,16 @@ export function ChapterTree({ parts.slice(0, partIndex).filter((p) => !isPrefacePart(p)).length const sectionTitleLine = (section: SectionItem) => { - const ord = bodySectionOrderMap.get(section.id) - if (ord != null) { - return ( - <> - - {ord}. - - {section.title} - - ) - } return ( - - {section.mid != null && section.mid > 0 ? `${section.mid}. ` : ''} - {section.title} - + <> + + {section.id} + + {section.title} + ) } @@ -439,7 +420,7 @@ export function ChapterTree({

{part.title}

-

{chapterRangeSubtitle(chapterCount)}

+

{sectionIdRangeSubtitle(part)}

{part.title}

-

{chapterRangeSubtitle(chapterCount)}

+

{sectionIdRangeSubtitle(part)}

): Part[] { const partMap = new Map< string, { id: string; title: string; chapters: Map } @@ -157,7 +157,7 @@ function buildTree(sections: SectionListItem[]): Part[] { clickCount: s.clickCount ?? 0, payCount: s.payCount ?? 0, hotScore: s.hotScore ?? 0, - hotRank: s.hotRank ?? 0, + hotRank: hotRankMap.get(s.id) ?? 0, }) } const parts = Array.from(partMap.values()).map((p) => ({ @@ -277,7 +277,16 @@ export function ContentPage() { const [ckbLeadLoading, setCkbLeadLoading] = useState(false) const richEditorRef = useRef(null) - const tree = buildTree(sectionsList) + const hotRankMap = useMemo(() => { + const m = new Map() + rankedSectionsList.forEach((s, idx) => { + // 排名展示从 1 开始,避免出现“第0名” + m.set(s.id, idx + 1) + }) + return m + }, [rankedSectionsList]) + + const tree = buildTree(sectionsList, hotRankMap) const totalSections = sectionsList.length // 内容排行榜:排序与置顶由后端 API 统一计算,前端只展示