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 统一计算,前端只展示