feat: 添加连载已读/完本已读分组,基于canUpdate字段自动分类

This commit is contained in:
HapeLee
2026-06-27 02:27:42 +08:00
parent 389239ca67
commit 4b65d6fc71
6 changed files with 235 additions and 3 deletions
@@ -16,6 +16,8 @@ import io.legado.app.data.dao.CacheDao
import io.legado.app.data.dao.CookieDao
import io.legado.app.data.dao.DictRuleDao
import io.legado.app.data.dao.HighlightRuleDao
import io.legado.app.data.dao.HighlightTagRuleDao
import io.legado.app.data.dao.TagGroupRuleDao
import io.legado.app.data.dao.HomepageCustomSetDao
import io.legado.app.data.dao.HomepageModuleDao
import io.legado.app.data.dao.HttpTTSDao
@@ -42,6 +44,8 @@ import io.legado.app.data.entities.Cache
import io.legado.app.data.entities.Cookie
import io.legado.app.data.entities.DictRule
import io.legado.app.data.entities.HighlightRule
import io.legado.app.data.entities.HighlightTagRule
import io.legado.app.data.entities.TagGroupRule
import io.legado.app.data.entities.HomepageCustomSet
import io.legado.app.data.entities.HomepageModule
import io.legado.app.data.entities.HttpTTS
@@ -75,7 +79,7 @@ val appDb by lazy {
}
@Database(
version = 91,
version = 92,
exportSchema = true,
entities = [Book::class, BookGroup::class, BookSource::class, BookChapter::class,
ReplaceRule::class, SearchBook::class, SearchKeyword::class, Cookie::class,
@@ -84,7 +88,7 @@ val appDb by lazy {
RssStar::class, TxtTocRule::class, ReadRecord::class, HttpTTS::class, Cache::class,
RuleSub::class, DictRule::class, KeyboardAssist::class, Server::class,
SearchContentHistory::class, HomepageModule::class, HomepageCustomSet::class,
HighlightRule::class],
HighlightRule::class, HighlightTagRule::class, TagGroupRule::class],
views = [BookSourcePart::class],
autoMigrations = [
AutoMigration(from = 43, to = 44),
@@ -134,7 +138,8 @@ val appDb by lazy {
AutoMigration(from = 87, to = 88),
AutoMigration(from = 88, to = 89),
AutoMigration(from = 89, to = 90),
AutoMigration(from = 90, to = 91)
AutoMigration(from = 90, to = 91),
AutoMigration(from = 91, to = 92)
]
)
abstract class AppDatabase : RoomDatabase() {
@@ -164,6 +169,8 @@ abstract class AppDatabase : RoomDatabase() {
abstract val homepageModuleDao: HomepageModuleDao
abstract val homepageCustomSetDao: HomepageCustomSetDao
abstract val highlightRuleDao: HighlightRuleDao
abstract val highlightTagRuleDao: HighlightTagRuleDao
abstract val tagGroupRuleDao: TagGroupRuleDao
companion object {
@@ -237,6 +244,20 @@ abstract class AppDatabase : RoomDatabase() {
""".trimIndent()
db.execSQL(insertGroupReadFinished)
@Language("sql")
val insertGroupReadFinishedUpdate = """
insert into book_groups(groupId, groupName, 'order', show)
select ${BookGroup.IdReadFinishedUpdate}, '连载已读', -27, 1
where not exists (select * from book_groups where groupId = ${BookGroup.IdReadFinishedUpdate})
""".trimIndent()
db.execSQL(insertGroupReadFinishedUpdate)
@Language("sql")
val insertGroupReadFinishedComplete = """
insert into book_groups(groupId, groupName, 'order', show)
select ${BookGroup.IdReadFinishedComplete}, '完本已读', -26, 1
where not exists (select * from book_groups where groupId = ${BookGroup.IdReadFinishedComplete})
""".trimIndent()
db.execSQL(insertGroupReadFinishedComplete)
@Language("sql")
val insertBookGroupNetNoneGroupSql = """
insert into book_groups(groupId, groupName, 'order', show)
select ${BookGroup.IdNetNone}, '网络未分组', -7, 1
@@ -48,6 +48,8 @@ interface BookDao {
BookGroup.IdUnread -> flowUnread()
BookGroup.IdReading -> flowReading()
BookGroup.IdReadFinished -> flowReadFinished()
BookGroup.IdReadFinishedUpdate -> flowReadFinishedUpdate()
BookGroup.IdReadFinishedComplete -> flowReadFinishedComplete()
else -> flowByUserGroup(groupId)
}.map { list ->
list.filterNot { it.isNotShelf }
@@ -68,6 +70,8 @@ interface BookDao {
BookGroup.IdUnread -> flowBookShelfUnread()
BookGroup.IdReading -> flowBookShelfReading()
BookGroup.IdReadFinished -> flowBookShelfReadFinished()
BookGroup.IdReadFinishedUpdate -> flowBookShelfReadFinishedUpdate()
BookGroup.IdReadFinishedComplete -> flowBookShelfReadFinishedComplete()
else -> flowBookShelfByUserGroup(groupId)
}.map { list ->
list.filterNot { it.isNotShelf }
@@ -123,6 +127,9 @@ interface BookDao {
@Query("SELECT * FROM books order by durChapterTime desc")
fun flowAll(): Flow<List<Book>>
@Query("SELECT * FROM books")
suspend fun getAll(): List<Book>
@Query(
"""
SELECT
@@ -485,6 +492,80 @@ interface BookDao {
)
fun flowBookShelfReadFinished(): Flow<List<BookShelfItem>>
@Query(
"""SELECT * FROM books WHERE totalChapterNum > 0 AND durChapterIndex >= totalChapterNum - 1 AND canUpdate = 1"""
)
fun flowReadFinishedUpdate(): Flow<List<Book>>
@Query(
"""
SELECT
bookUrl,
name,
author,
origin,
originName,
coverUrl,
customCoverUrl,
durChapterTitle,
durChapterTime,
durChapterPos,
latestChapterTitle,
latestChapterTime,
lastCheckCount,
totalChapterNum,
durChapterIndex,
type,
`group`,
`order`,
canUpdate,
ifnull(customIntro, intro) as intro,
kind,
wordCount
FROM books
WHERE totalChapterNum > 0 AND durChapterIndex >= totalChapterNum - 1 AND canUpdate = 1
AND $PUBLIC_BOOK_FILTER
"""
)
fun flowBookShelfReadFinishedUpdate(): Flow<List<BookShelfItem>>
@Query(
"""SELECT * FROM books WHERE totalChapterNum > 0 AND durChapterIndex >= totalChapterNum - 1 AND canUpdate = 0"""
)
fun flowReadFinishedComplete(): Flow<List<Book>>
@Query(
"""
SELECT
bookUrl,
name,
author,
origin,
originName,
coverUrl,
customCoverUrl,
durChapterTitle,
durChapterTime,
durChapterPos,
latestChapterTitle,
latestChapterTime,
lastCheckCount,
totalChapterNum,
durChapterIndex,
type,
`group`,
`order`,
canUpdate,
ifnull(customIntro, intro) as intro,
kind,
wordCount
FROM books
WHERE totalChapterNum > 0 AND durChapterIndex >= totalChapterNum - 1 AND canUpdate = 0
AND $PUBLIC_BOOK_FILTER
"""
)
fun flowBookShelfReadFinishedComplete(): Flow<List<BookShelfItem>>
@Query("""SELECT * FROM books WHERE totalChapterNum > 0 AND durChapterIndex > 0 AND durChapterIndex < totalChapterNum - 1""")
fun flowReading(): Flow<List<Book>>
@@ -728,6 +809,8 @@ interface BookDao {
UNION ALL SELECT ${BookGroup.IdUnread}, COUNT(*) FROM books WHERE durChapterIndex = 0 AND durChapterPos = 0 AND $PUBLIC_BOOK_FILTER
UNION ALL SELECT ${BookGroup.IdReading}, COUNT(*) FROM books WHERE totalChapterNum > 0 AND durChapterIndex > 0 AND durChapterIndex < totalChapterNum - 1 AND $PUBLIC_BOOK_FILTER
UNION ALL SELECT ${BookGroup.IdReadFinished}, COUNT(*) FROM books WHERE totalChapterNum > 0 AND durChapterIndex >= totalChapterNum - 1 AND $PUBLIC_BOOK_FILTER
UNION ALL SELECT ${BookGroup.IdReadFinishedUpdate}, COUNT(*) FROM books WHERE totalChapterNum > 0 AND durChapterIndex >= totalChapterNum - 1 AND canUpdate = 1 AND $PUBLIC_BOOK_FILTER
UNION ALL SELECT ${BookGroup.IdReadFinishedComplete}, COUNT(*) FROM books WHERE totalChapterNum > 0 AND durChapterIndex >= totalChapterNum - 1 AND canUpdate = 0 AND $PUBLIC_BOOK_FILTER
"""
)
fun flowSystemGroupCounts(): Flow<List<GroupBookCount>>
@@ -755,6 +838,8 @@ interface BookDao {
BookGroup.IdUnread -> flowBookShelfUnreadPreview()
BookGroup.IdReading -> flowBookShelfReadingPreview()
BookGroup.IdReadFinished -> flowBookShelfReadFinishedPreview()
BookGroup.IdReadFinishedUpdate -> flowBookShelfReadFinishedUpdatePreview()
BookGroup.IdReadFinishedComplete -> flowBookShelfReadFinishedCompletePreview()
else -> flowBookShelfPreviewByUserGroup(groupId)
}.map { list ->
list.filterNot { it.isNotShelf }
@@ -968,6 +1053,40 @@ interface BookDao {
)
fun flowBookShelfReadFinishedPreview(): Flow<List<BookShelfItem>>
@Query(
"""
SELECT bookUrl, name, author, origin, originName,
coverUrl, customCoverUrl, durChapterTitle, durChapterTime,
durChapterPos, latestChapterTitle, latestChapterTime,
lastCheckCount, totalChapterNum, durChapterIndex,
type, `group`, `order`, canUpdate,
ifnull(customIntro, intro) as intro, kind, wordCount
FROM books
WHERE totalChapterNum > 0 AND durChapterIndex >= totalChapterNum - 1 AND canUpdate = 1
AND $PUBLIC_BOOK_FILTER
ORDER BY durChapterTime DESC
LIMIT 10
"""
)
fun flowBookShelfReadFinishedUpdatePreview(): Flow<List<BookShelfItem>>
@Query(
"""
SELECT bookUrl, name, author, origin, originName,
coverUrl, customCoverUrl, durChapterTitle, durChapterTime,
durChapterPos, latestChapterTitle, latestChapterTime,
lastCheckCount, totalChapterNum, durChapterIndex,
type, `group`, `order`, canUpdate,
ifnull(customIntro, intro) as intro, kind, wordCount
FROM books
WHERE totalChapterNum > 0 AND durChapterIndex >= totalChapterNum - 1 AND canUpdate = 0
AND $PUBLIC_BOOK_FILTER
ORDER BY durChapterTime DESC
LIMIT 10
"""
)
fun flowBookShelfReadFinishedCompletePreview(): Flow<List<BookShelfItem>>
@Query(
"""
SELECT bookUrl, name, author, origin, originName,
@@ -80,6 +80,20 @@ interface BookGroupDao {
AND durChapterPos != 0
AND (`group` = 0 or (const.sumPrivateGroupId & `group`) = 0)
))
or (groupId = ${BookGroup.IdReadFinishedUpdate} and exists (
SELECT 1 FROM books
WHERE totalChapterNum > 0
AND durChapterIndex >= totalChapterNum - 1
AND canUpdate = 1
AND (`group` = 0 or (const.sumPrivateGroupId & `group`) = 0)
))
or (groupId = ${BookGroup.IdReadFinishedComplete} and exists (
SELECT 1 FROM books
WHERE totalChapterNum > 0
AND durChapterIndex >= totalChapterNum - 1
AND canUpdate = 0
AND (`group` = 0 or (const.sumPrivateGroupId & `group`) = 0)
))
or (groupId = ${BookGroup.IdError} and exists (
select 1 from books
@@ -41,6 +41,8 @@ data class BookGroup(
const val IdReading = -20L
const val IdUnread = -21L
const val IdReadFinished = -22L
const val IdReadFinishedUpdate = -23L
const val IdReadFinishedComplete = -24L
}
data class GroupNameInfo(
@@ -61,6 +63,8 @@ data class BookGroup(
IdReading -> GroupNameInfo(groupName, context.getString(R.string.is_reading))
IdUnread -> GroupNameInfo(groupName, context.getString(R.string.is_unread))
IdReadFinished -> GroupNameInfo(groupName, context.getString(R.string.is_read_finished))
IdReadFinishedUpdate -> GroupNameInfo(groupName, context.getString(R.string.is_read_finished_update))
IdReadFinishedComplete -> GroupNameInfo(groupName, context.getString(R.string.is_read_finished_complete))
else -> GroupNameInfo(groupName)
}
}
@@ -660,6 +660,7 @@
<string name="footer_font_size">页脚字号</string>
<string name="select_image">选择图片</string>
<string name="group_manage">分组管理</string>
<string name="group_add">新建分组</string>
<string name="group_select">分组选择</string>
<string name="group_edit">编辑分组</string>
<string name="move_to_group">移入分组</string>
@@ -1670,6 +1671,8 @@
<string name="is_reading">在读</string>
<string name="is_unread">未读</string>
<string name="is_read_finished">已读</string>
<string name="is_read_finished_update">连载已读</string>
<string name="is_read_finished_complete">完本已读</string>
<string name="manga">漫画</string>
<string name="noval">小说</string>
<string name="cover_show_shadow">显示字体阴影</string>
@@ -1947,4 +1950,38 @@
<string name="eye_protection_schedule_summary">仅在配置的时间段内生效</string>
<string name="eye_protection_start_time">开始时间</string>
<string name="eye_protection_end_time">结束时间</string>
<!-- 标签规则 -->
<string name="highlight_tag_config">标签规则</string>
<string name="import_highlight_tag_rule">导入标签规则</string>
<string name="highlight_tag_title">标题</string>
<string name="highlight_tag_pattern">匹配规则</string>
<string name="highlight_tag_empty_hint">暂无醒目标签规则。添加规则可在书籍信息页面突出显示特定标签。</string>
<string name="highlight_tag_add_rule">添加规则</string>
<string name="highlight_tag_edit_rule">编辑规则</string>
<string name="highlight_tag_title_hint">标题(可选)</string>
<string name="highlight_tag_pattern_hint">正则表达式(如 (\\d+)字)</string>
<string name="highlight_tag_display_mode">显示模式</string>
<string name="highlight_tag_mode_horizontal">水平</string>
<string name="highlight_tag_mode_vertical">竖向</string>
<string name="highlight_tag_test_area">测试</string>
<string name="highlight_tag_test_input_hint">输入测试文本</string>
<string name="highlight_tag_test_button">测试匹配</string>
<string name="highlight_tag_test_match">匹配:%1$s</string>
<string name="highlight_tag_test_match_vertical">匹配:%1$s | %2$s</string>
<string name="highlight_tag_test_no_match">未匹配</string>
<string name="highlight_tag_test_error">错误:%1$s</string>
<!-- 标签分组规则 -->
<string name="tag_group_tab_highlight">醒目标签</string>
<string name="tag_group_tab_group">标签分组</string>
<string name="tag_group_add_rule">新建标签分组</string>
<string name="tag_group_edit_rule">编辑分组规则</string>
<string name="tag_group_name">分组名称</string>
<string name="tag_group_pattern">匹配规则(匹配书籍标签)</string>
<string name="tag_group_empty_hint">暂无标签分组规则。添加规则可根据书籍标签自动分组。</string>
<string name="tag_group_sync">同步标签分组</string>
<string name="tag_group_rules">标签分组规则</string>
<string name="tag_group_sync_complete">分组同步完成</string>
<string name="import_tag_group_rule">导入分组规则</string>
</resources>
+37
View File
@@ -686,6 +686,7 @@
<string name="footer_font_size">Footer Font Size</string>
<string name="select_image">Select a picture</string>
<string name="group_manage">Group Management</string>
<string name="group_add">New Group</string>
<string name="group_select">Group selection</string>
<string name="group_edit">Group editing</string>
<string name="move_to_group">Move to group</string>
@@ -1707,6 +1708,8 @@
<string name="is_reading">Reading</string>
<string name="is_unread">Unread</string>
<string name="is_read_finished">Finished</string>
<string name="is_read_finished_update">Finished (Serial)</string>
<string name="is_read_finished_complete">Finished (Completed)</string>
<string name="manga">Manga</string>
<string name="noval">Novel</string>
<string name="cover_show_shadow">Show Font Shadow</string>
@@ -1956,4 +1959,38 @@
<string name="eye_protection_schedule_summary">Only apply during the configured time range</string>
<string name="eye_protection_start_time">Start Time</string>
<string name="eye_protection_end_time">End Time</string>
<!-- Tag Rules -->
<string name="highlight_tag_config">Tag Rules</string>
<string name="import_highlight_tag_rule">Import Tag Rules</string>
<string name="highlight_tag_title">Title</string>
<string name="highlight_tag_pattern">Pattern</string>
<string name="highlight_tag_empty_hint">No highlight tag rules configured. Add rules to highlight specific tags on the book info screen.</string>
<string name="highlight_tag_add_rule">Add Rule</string>
<string name="highlight_tag_edit_rule">Edit Rule</string>
<string name="highlight_tag_title_hint">Title (optional)</string>
<string name="highlight_tag_pattern_hint">Regex pattern (e.g. (\\d+)字)</string>
<string name="highlight_tag_display_mode">Display Mode</string>
<string name="highlight_tag_mode_horizontal">Horizontal</string>
<string name="highlight_tag_mode_vertical">Vertical</string>
<string name="highlight_tag_test_area">Test</string>
<string name="highlight_tag_test_input_hint">Enter test text</string>
<string name="highlight_tag_test_button">Test Match</string>
<string name="highlight_tag_test_match">Matched: %1$s</string>
<string name="highlight_tag_test_match_vertical">Matched: %1$s | %2$s</string>
<string name="highlight_tag_test_no_match">No match</string>
<string name="highlight_tag_test_error">Error: %1$s</string>
<!-- Tag Group Rules -->
<string name="tag_group_tab_highlight">Highlight</string>
<string name="tag_group_tab_group">Group</string>
<string name="tag_group_add_rule">New Tag Group</string>
<string name="tag_group_edit_rule">Edit Group Rule</string>
<string name="tag_group_name">Group Name</string>
<string name="tag_group_pattern">Pattern (matches kind tags)</string>
<string name="tag_group_empty_hint">No tag group rules configured. Add rules to auto-group books by their kind tags.</string>
<string name="tag_group_sync">Sync Tag Groups</string>
<string name="tag_group_rules">Tag Group Rules</string>
<string name="tag_group_sync_complete">Group sync complete</string>
<string name="import_tag_group_rule">Import Tag Group Rules</string>
</resources>