@@ -584,6 +584,7 @@ function initBookshelf() {
584584 // 渲染标签过滤器
585585 function renderTagFilter ( container , tags , activeTag ) {
586586 container . innerHTML = '<span class="bookshelf-tag ' + ( activeTag === 'All' ? 'active' : '' ) + '" data-tag="All">All</span>' ;
587+ container . innerHTML += '<span class="bookshelf-tag ' + ( activeTag === 'NoTag' ? 'active' : '' ) + '" data-tag="NoTag">NoTag</span>' ;
587588 tags . forEach ( tag => {
588589 const tagEl = document . createElement ( 'span' ) ;
589590 tagEl . className = 'bookshelf-tag' + ( activeTag === tag ? ' active' : '' ) ;
@@ -616,7 +617,9 @@ function initBookshelf() {
616617 // 检查是否是分组
617618 if ( shelfData . groups && shelfData . groups [ id ] ) {
618619 const group = shelfData . groups [ id ] ;
619- if ( tag !== 'All' && ! groupHasTagInTree ( group , tag ) ) continue ;
620+ if ( tag === 'NoTag' ) {
621+ if ( ! groupHasNoTagInTree ( group ) ) continue ;
622+ } else if ( tag !== 'All' && ! groupHasTagInTree ( group , tag ) ) continue ;
620623
621624 const groupEl = document . createElement ( 'div' ) ;
622625 groupEl . className = 'bookshelf-item group' ;
@@ -641,7 +644,9 @@ function initBookshelf() {
641644 else if ( shelfData . items && shelfData . items . includes ( id ) ) {
642645 const bookInfo = getBookInfo ( id ) ;
643646 if ( ! bookInfo ) continue ;
644- if ( tag !== 'All' && ! bookInfo . tags . includes ( tag ) ) continue ;
647+ if ( tag === 'NoTag' ) {
648+ if ( bookInfo . tags && bookInfo . tags . length > 0 ) continue ;
649+ } else if ( tag !== 'All' && ! bookInfo . tags . includes ( tag ) ) continue ;
645650
646651 const bookEl = document . createElement ( 'div' ) ;
647652 bookEl . className = 'bookshelf-item book' ;
@@ -698,6 +703,20 @@ function initBookshelf() {
698703 return false ;
699704 }
700705
706+ // 检查分组是否包含无标签书籍
707+ function groupHasNoTagInTree ( group ) {
708+ for ( const bookHash of group . items ) {
709+ const bookInfo = getBookInfo ( bookHash ) ;
710+ if ( bookInfo && ( ! bookInfo . tags || bookInfo . tags . length === 0 ) ) return true ;
711+ }
712+ if ( group . groups ) {
713+ for ( const subGroupId in group . groups ) {
714+ if ( groupHasNoTagInTree ( group . groups [ subGroupId ] ) ) return true ;
715+ }
716+ }
717+ return false ;
718+ }
719+
701720 // 渲染分组封面(拼接最多4本书的封面)
702721 function renderGroupCovers ( group ) {
703722 const covers = getGroupCovers ( group , 4 ) ;
@@ -872,7 +891,9 @@ function initBookshelf() {
872891 // 检查是否是子分组
873892 if ( group . groups && group . groups [ id ] ) {
874893 const subGroup = group . groups [ id ] ;
875- if ( tag !== 'All' && ! groupHasTagInTree ( subGroup , tag ) ) continue ;
894+ if ( tag === 'NoTag' ) {
895+ if ( ! groupHasNoTagInTree ( subGroup ) ) continue ;
896+ } else if ( tag !== 'All' && ! groupHasTagInTree ( subGroup , tag ) ) continue ;
876897
877898 const groupEl = document . createElement ( 'div' ) ;
878899 groupEl . className = 'bookshelf-item group' ;
@@ -897,7 +918,9 @@ function initBookshelf() {
897918 else if ( group . items && group . items . includes ( id ) ) {
898919 const bookInfo = getBookInfo ( id ) ;
899920 if ( ! bookInfo ) continue ;
900- if ( tag !== 'All' && ! bookInfo . tags . includes ( tag ) ) continue ;
921+ if ( tag === 'NoTag' ) {
922+ if ( bookInfo . tags && bookInfo . tags . length > 0 ) continue ;
923+ } else if ( tag !== 'All' && ! bookInfo . tags . includes ( tag ) ) continue ;
901924
902925 const bookEl = document . createElement ( 'div' ) ;
903926 bookEl . className = 'bookshelf-item book' ;
0 commit comments