RPC 函数详情
章节阅读计数
get_chapter_and_count_view(匿名计数)与 count_chapter_view_if_new(登录用户去重计数)
概述
项目有两个阅读计数函数,分别服务匿名用户和登录用户。两者都会同时递增 comics 表的四个维度:view_count(总)、popularity_daily(日)、popularity_weekly(周)、popularity_monthly(月)。
| 函数 | 适用场景 | 去重 |
|---|---|---|
get_chapter_and_count_view | 匿名用户 | 无,每次调用必定 +1 |
count_chapter_view_if_new | 登录用户 | 有,基于冷却时间去重 |
两个函数均为 SECURITY DEFINER,以函数定义者身份执行,绕过 RLS 直接操作 comics 和 chapter_view_logs 表。
get_chapter_and_count_view
该函数暂时没有使用,未来视情况删去或改造
获取章节数据的同时无条件递增漫画阅读量。适用于匿名用户——无法记录 user_id,因此不做去重。
| 属性 | 值 |
|---|---|
| 返回类型 | SETOF chapters(完整章节行) |
| 安全级别 | SECURITY DEFINER |
参数
Prop
Type
执行流程
- 根据
p_chapter_id查出所属comic_id - 递增
comics表的view_count、popularity_daily、popularity_weekly、popularity_monthly各 +1 - 返回该章节的完整行数据
调用示例
val chapter = supabase.postgrest
.rpc("get_chapter_and_count_view") {
parameter("p_chapter_id", chapterId)
}
.decodeSingle<Chapter>()const { data } = await supabase
.rpc('get_chapter_and_count_view', {
p_chapter_id: chapterId,
})count_chapter_view_if_new
登录用户的去重阅读计数。通过 chapter_view_logs 表记录每个用户对每个章节的最近浏览时间,在冷却期内重复访问不计数。
| 属性 | 值 |
|---|---|
| 返回类型 | boolean(true = 计数成功,false = 冷却期内跳过) |
| 安全级别 | SECURITY DEFINER |
参数
Prop
Type
执行流程
- 查询
chapter_view_logs中该用户对该章节的最近浏览时间 - 如果在冷却期内(
viewed_at > now() - cooldown),返回false - 否则,UPSERT
chapter_view_logs记录(ON CONFLICT DO UPDATE) - 递增
comics表的四个维度计数各 +1 - 返回
true
去重表结构
chapter_view_logs 表通过 (user_id, chapter_id) 联合唯一约束实现每用户每章节只保留一条记录:
| 字段 | 类型 | 说明 |
|---|---|---|
user_id | uuid | 用户 ID |
chapter_id | bigint | 章节 ID |
viewed_at | timestamptz | 最近浏览时间 |
调用示例
// 默认 120 秒冷却
val counted = supabase.postgrest
.rpc("count_chapter_view_if_new") {
parameter("p_user_id", userId)
parameter("p_chapter_id", chapterId)
}
.decodeSingle<Boolean>()
// 自定义冷却时间
val counted = supabase.postgrest
.rpc("count_chapter_view_if_new") {
parameter("p_user_id", userId)
parameter("p_chapter_id", chapterId)
parameter("p_cooldown_seconds", 300)
}
.decodeSingle<Boolean>()const { data: counted } = await supabase
.rpc('count_chapter_view_if_new', {
p_user_id: userId,
p_chapter_id: chapterId,
// p_cooldown_seconds: 300 // 可选
})选择策略
客户端根据登录状态选择调用哪个函数:
| 用户状态 | 调用函数 | 原因 |
|---|---|---|
| 未登录 | get_chapter_and_count_view | 无 user_id,无法去重,同时需要返回章节数据 |
| 已登录 | count_chapter_view_if_new | 有 user_id,120 秒冷却去重,防止刷量 |