Skip to content

Commit

Permalink
feat: 获取用户发帖列表/获取板块帖子列表/获取板块置顶帖子/获取首页推荐贴等接口统一为一个接口并新增了随机热度排序
Browse files Browse the repository at this point in the history
  • Loading branch information
nullaqua committed Sep 11, 2024
1 parent d164ce7 commit 3893cc8
Show file tree
Hide file tree
Showing 5 changed files with 160 additions and 304 deletions.
54 changes: 36 additions & 18 deletions src/main/kotlin/subit/database/Posts.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,38 @@ interface Posts
@Serializable
enum class PostListSort
{
/**
* 按照时间从新到旧排序
*/
NEW,
/**
* 按照时间从旧到新排序
*/
OLD,
/**
* 按照浏览量从高到低排序
*/
MORE_VIEW,
/**
* 按照点赞数从高到低排序
*/
MORE_LIKE,
/**
* 按照收藏数从高到低排序
*/
MORE_STAR,
/**
* 按照评论数从高到低排序
*/
MORE_COMMENT,
/**
* 按照热度排序
*/
HOT,
/**
* 按照热度并带一定随机性排序
*/
RANDOM_HOT,
}

/**
Expand Down Expand Up @@ -56,25 +82,23 @@ interface Posts
suspend fun getPostFullBasicInfo(pid: PostId): PostFullBasicInfo?

/**
* 获取用户发布的帖子
* 获得帖子列表
* @param loginUser 当前操作用户, null表示未登录, 返回的帖子应是该用户可见的.
* @param author 作者, null表示所有作者
* @param block 板块, null表示所有板块
* @param top 是否置顶, null表示所有
* @param sortBy 排序方式
*/
suspend fun getUserPosts(
suspend fun getPosts(
loginUser: DatabaseUser? = null,
author: UserId,
sortBy: PostListSort,
begin: Long,
limit: Int,
): Slice<PostFullBasicInfo>

suspend fun getBlockPosts(
block: BlockId,
author: UserId?,
block: BlockId?,
top: Boolean?,
sortBy: PostListSort,
begin: Long,
count: Int
limit: Int
): Slice<PostFullBasicInfo>

suspend fun getBlockTopPosts(block: BlockId, begin: Long, count: Int): Slice<PostFullBasicInfo>
suspend fun searchPosts(
loginUser: DatabaseUser?,
key: String,
Expand All @@ -84,10 +108,4 @@ interface Posts
): Slice<PostFullBasicInfo>

suspend fun addView(pid: PostId)

/**
* 获取首页推荐, 应按照时间/浏览量/点赞等参数随机, 即越新/点赞越高/浏览量越高...随机到的几率越大.
* @param count 推荐数量
*/
suspend fun getRecommendPosts(loginUser: UserId?, count: Int): Slice<PostFullBasicInfo>
}
91 changes: 22 additions & 69 deletions src/main/kotlin/subit/database/memoryImpl/PostsImpl.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ class PostsImpl: Posts, KoinComponent
{
private val map = Collections.synchronizedMap(hashMapOf<PostId, Pair<PostInfo, Boolean>>())
private val blocks: Blocks by inject()
private val permissions: Permissions by inject()
private val likes: Likes by inject()
private val stars: Stars by inject()
private val postVersions: PostVersions by inject()
Expand Down Expand Up @@ -64,6 +63,8 @@ class PostsImpl: Posts, KoinComponent
Posts.PostListSort.MORE_LIKE -> runBlocking { -stars.getStarsCount(it.id) }
Posts.PostListSort.MORE_STAR -> runBlocking { -likes.getLikes(it.id) }
Posts.PostListSort.MORE_COMMENT -> map.values.count { post -> post.first.root == it.id }.toLong()
Posts.PostListSort.HOT -> -getHotScore(it.id).toLong()
Posts.PostListSort.RANDOM_HOT -> -getHotScore(it.id).toLong() + Random().nextInt(100)
}
}

Expand All @@ -74,15 +75,9 @@ class PostsImpl: Posts, KoinComponent
count: Int
): Slice<PostFull>
{
val post = map[pid]?.first ?: return Slice.empty()
val descendants = map.values
.filter { isAncestor(pid, it.first.id) }
.filter { it.first.state == State.NORMAL }
.filter {
val blockFull = blocks.getBlock(it.first.block) ?: return@filter false
val permission = permissions.getPermission(blockFull.id, post.author)
permission >= blockFull.reading
}
.map { it.first }
.map { getPostFull(it.id)!! }
.sortedBy(sortBy(sortBy))
Expand All @@ -98,15 +93,9 @@ class PostsImpl: Posts, KoinComponent
count: Int
): Slice<PostFull>
{
val post = map[pid]?.first ?: return Slice.empty()
val children = map.values
.filter { it.first.parent == pid }
.filter { it.first.state == State.NORMAL }
.filter {
val blockFull = blocks.getBlock(it.first.block) ?: return@filter false
val permission = permissions.getPermission(blockFull.id, post.author)
permission >= blockFull.reading
}
.map { it.first }
.map { getPostFull(it.id)!! }
.sortedBy(sortBy(sortBy))
Expand Down Expand Up @@ -153,69 +142,48 @@ class PostsImpl: Posts, KoinComponent
override suspend fun getPostFullBasicInfo(pid: PostId): PostFullBasicInfo? = getPostFull(pid)?.toPostFullBasicInfo()

@Suppress("ConvertCallChainIntoSequence")
override suspend fun getUserPosts(
override suspend fun getPosts(
loginUser: DatabaseUser?,
author: UserId,
author: UserId?,
block: BlockId?,
top: Boolean?,
sortBy: Posts.PostListSort,
begin: Long,
limit: Int
): Slice<PostFullBasicInfo> =
): Slice<PostFullBasicInfo> = withPermission(loginUser)
{
map.values
.filter { it.first.author == author }
.filter {
(author == null || it.first.author == author)
&& (block == null || it.first.block == block)
&& (top == null || it.second == top)
}
.filter {
val blockFull = blocks.getBlock(it.first.block) ?: return@filter false
val permission = loginUser?.let { permissions.getPermission(blockFull.id, loginUser.id) }
?: PermissionLevel.NORMAL
permission >= blockFull.reading && (it.first.state == State.NORMAL)
getPermission(it.first.block) >= blockFull.reading && (it.first.state == State.NORMAL || loginUser.hasGlobalAdmin())
}
.map { it.first }
.map { getPostFull(it.id)!! }
.map { getPostFull(it.first.id)!! }
.sortedBy(sortBy(sortBy))
.asSequence()
.asSlice(begin, limit)
.map { it.toPostFullBasicInfo() }

@Suppress("ConvertCallChainIntoSequence")
override suspend fun getBlockPosts(
block: BlockId,
sortBy: Posts.PostListSort,
begin: Long,
count: Int
): Slice<PostFullBasicInfo> = map.values
.filter { it.first.block == block }
.map { it.first }
.map { getPostFull(it.id)!! }
.sortedBy(sortBy(sortBy))
.asSequence()
.asSlice(begin, count)
.map { it.toPostFullBasicInfo() }

override suspend fun getBlockTopPosts(block: BlockId, begin: Long, count: Int): Slice<PostFullBasicInfo> =
map.values
.filter { it.first.block == block && it.second }
.map { it.first }
.map { getPostFull(it.id)!! }
.asSequence()
.asSlice(begin, count)
.map { it.toPostFullBasicInfo() }
}

override suspend fun searchPosts(
loginUser: DatabaseUser?,
key: String,
advancedSearchData: AdvancedSearchData,
begin: Long,
count: Int
): Slice<PostFullBasicInfo> =
): Slice<PostFullBasicInfo> = withPermission(loginUser)
{
map.values
.map { it.first }
.map { getPostFull(it.id)!! }
.filter { it.title.contains(key) || it.content.contains(key) }
.filter {
val blockFull = blocks.getBlock(it.block) ?: return@filter false
val permission =
loginUser?.let { permissions.getPermission(blockFull.id, loginUser.id) }
?: PermissionLevel.NORMAL
permission >= blockFull.reading
getPermission(it.block) >= blockFull.reading
}
.filter {
val post = it
Expand All @@ -230,17 +198,18 @@ class PostsImpl: Posts, KoinComponent
else ((post.title.contains(key)) || (post.content.contains(key)))
val lastModifiedConstraint =
if (advancedSearchData.lastModifiedAfter != null)
(post.lastModified >= advancedSearchData.lastModifiedAfter)
(post.lastModified >= advancedSearchData.lastModifiedAfter)
else true
val createTimeConstraint =
if (advancedSearchData.createTime != null)
(post.create >= advancedSearchData.createTime.first && post.create <= advancedSearchData.createTime.second)
(post.create >= advancedSearchData.createTime.first && post.create <= advancedSearchData.createTime.second)
else true
blockConstraint && userConstraint && contentConstraint && lastModifiedConstraint && createTimeConstraint
}
.asSequence()
.asSlice(begin, count)
.map { it.toPostFullBasicInfo() }
}

override suspend fun addView(pid: PostId)
{
Expand All @@ -258,20 +227,4 @@ class PostsImpl: Posts, KoinComponent
val time = (System.currentTimeMillis() - createTime).toDouble() /1000/*s*/ /60/*m*/ /60/*h*/
return (post.view + likesCount * 3 + starsCount * 5 + commentsCount * 2) / time.pow(1.8)
}

@Suppress("ConvertCallChainIntoSequence")
override suspend fun getRecommendPosts(loginUser: UserId?, count: Int): Slice<PostFullBasicInfo> = map.values
.filter { it.first.state == State.NORMAL }
.filter {
val blockFull = blocks.getBlock(it.first.block) ?: return@filter false
val permission = loginUser?.let { permissions.getPermission(blockFull.id, loginUser) }
?: PermissionLevel.NORMAL
permission >= blockFull.reading
}
.sortedByDescending { getHotScore(it.first.id) }
.map { it.first }
.map { getPostFull(it.id)!! }
.map { it.toPostFullBasicInfo() }
.asSequence()
.asSlice(1, count)
}
Loading

0 comments on commit 3893cc8

Please sign in to comment.