live-forum/.kiro/specs/post-reply-interval/tasks.md
2026-03-24 11:27:37 +08:00

163 lines
9.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 实施计划:发帖和回复时间间隔
## 概述
基于设计文档,分数据库、后端服务、管理端 API、管理端前端、小程序前端五个部分实施。后端先创建数据表和实体再实现间隔校验服务最后前端对接倒计时逻辑。
## 任务
- [x] 1. 数据库变更与后端实体创建
- [x] 1.1 创建数据库迁移脚本
-`server/webapi/数据库脚本/` 下创建 `v1.2.0_post_reply_intervals.sql`
- 创建 `T_PostReplyIntervals` 表,包含 Id、CertificationTypeId唯一索引、PostInterval、ReplyInterval、CreatedAt、UpdatedAt 字段
- 添加外键约束关联 `T_CertificationTypes(Id)`
- _需求: 6.1_
- [x] 1.2 创建 T_PostReplyIntervals 实体类
-`LiveForum.Model/Model/` 下创建 `T_PostReplyIntervals.cs`
- 包含 Id自增主键、CertificationTypeId、PostInterval默认0、ReplyInterval默认0、CreatedAt、UpdatedAt
- 使用 FreeSql 特性标注(`[Column]`、`[JsonProperty]` 等),参考现有实体风格
- _需求: 6.1_
- [x] 2. 后端:间隔校验服务实现
- [x] 2.1 创建 IPostReplyIntervalService 接口和 PostReplyIntervalService 实现
-`LiveForum.IService` 中创建 `IPostReplyIntervalService.cs`
-`LiveForum.Service` 中创建 `PostReplyIntervalService.cs`
- 实现 `GetPostIntervalAsync(long userId)`:查询用户认证等级 → 查询对应 PostInterval 配置,未配置返回 0
- 实现 `GetReplyIntervalAsync(long userId)`:同上,返回 ReplyInterval
- 实现 `GetLastPostTimeAsync(long userId)`:查询用户最近一次成功发帖时间
- 实现 `GetLastCommentTimeAsync(long userId)`:查询用户最近一次成功回复时间
- 实现 `CheckPostIntervalAsync(long userId)`:校验发帖间隔,返回 null通过或剩余秒数
- 实现 `CheckReplyIntervalAsync(long userId)`:校验回复间隔,返回 null通过或剩余秒数
- _需求: 2.1, 2.2, 2.3, 2.4, 2.5, 3.1, 3.2, 3.3, 3.4, 3.5_
- [ ]* 2.2 编写属性测试:发帖间隔校验正确性
- **Property 3: 发帖间隔校验正确性**
- 使用 FsCheck.Xunit 生成随机 PostInterval含 0和随机最近发帖时间
- 验证 CheckPostIntervalAsync 返回值PostInterval=0 或 elapsed>=PostInterval 或从未发帖时返回 null否则返回 ceil(PostInterval - elapsed)
- **验证: 需求 2.3, 2.4**
- [ ]* 2.3 编写属性测试:回复间隔校验正确性
- **Property 4: 回复间隔校验正确性**
- 使用 FsCheck.Xunit 生成随机 ReplyInterval含 0和随机最近回复时间
- 验证 CheckReplyIntervalAsync 返回值ReplyInterval=0 或 elapsed>=ReplyInterval 或从未回复时返回 null否则返回 ceil(ReplyInterval - elapsed)
- **验证: 需求 3.3, 3.4**
- [ ]* 2.4 编写属性测试:未配置认证等级默认返回 0
- **Property 2: 未配置认证等级默认返回 0**
- 生成随机不存在的认证等级 ID 或 CertifiedType 为 null/0 的用户
- 验证 GetPostIntervalAsync 和 GetReplyIntervalAsync 均返回 0
- **验证: 需求 1.5, 2.5, 3.5, 6.5**
- [x] 3. 后端:修改发帖和回复接口集成间隔校验
- [x] 3.1 修改 PostsService.PublishPosts 增加发帖间隔校验
- 在现有认证检查之后、敏感词过滤之前,调用 `CheckPostIntervalAsync`
- 校验不通过时返回错误信息「发帖过于频繁,请等待 {remainingSeconds} 秒后再试」
- _需求: 2.1, 2.2, 2.3_
- [x] 3.2 修改 PublishPostsRespDto 新增 PostInterval 字段
-`PublishPostsRespDto` 中新增 `public int PostInterval { get; set; }`
- 在 PublishPosts 成功返回时调用 `GetPostIntervalAsync` 赋值
- _需求: 6.4_
- [x] 3.3 修改 PostCommentsService.PublishPostComments 增加回复间隔校验
- 在帖子存在性检查和回复权限检查之后,调用 `CheckReplyIntervalAsync`
- 校验不通过时返回错误信息「回复过于频繁,请等待 {remainingSeconds} 秒后再试」
- _需求: 3.1, 3.2, 3.3_
- [x] 3.4 修改 PublishPostCommentsRespDto 新增 ReplyInterval 字段
-`PublishPostCommentsRespDto` 中新增 `public int ReplyInterval { get; set; }`
- 在 PublishPostComments 成功返回时调用 `GetReplyIntervalAsync` 赋值
- _需求: 6.4_
- [ ]* 3.5 编写属性测试:成功响应包含正确的间隔值
- **Property 5: 成功响应包含正确的间隔值**
- 生成随机用户和认证等级配置,验证发帖/回复成功响应中的间隔字段与配置值一致
- **验证: 需求 6.4**
- [x] 4. 检查点 - 后端小程序 API 完成
- 确保所有测试通过,如有疑问请向用户确认。
- [x] 5. 管理端后端 API 实现
- [x] 5.1 创建管理端实体和 DTO
-`ZR.LiveForum.Model/Liveforum/` 下创建 `T_PostReplyIntervals.cs` 实体
- 创建 `Dto/T_PostReplyIntervalsDto.cs`,包含 Id、CertificationTypeId、CertificationTypeName、PostInterval、ReplyInterval
- 创建 `Dto/T_PostReplyIntervalsQueryDto.cs`,继承 PagerInfo
- _需求: 6.2, 6.3_
- [x] 5.2 创建管理端 Service
- 创建 `IT_PostReplyIntervalsService.cs` 接口和 `T_PostReplyIntervalsService.cs` 实现
- 实现 `GetList`:关联查询 T_CertificationTypes 获取认证等级名称未配置间隔的等级也需展示PostInterval/ReplyInterval 显示为 0
- 实现 `AddOrUpdate`:新增或修改间隔配置,校验间隔值不能为负数,校验认证等级存在性
- _需求: 1.1, 1.2, 1.3, 1.4, 6.2, 6.3_
- [x] 5.3 创建管理端 Controller
- 创建 `T_PostReplyIntervalsController.cs`,路由 `liveforum/tpostreplyintervals`
- 实现 `GET list` 接口(权限 `tpostreplyintervals:list`
- 实现 `PUT` 接口(权限 `tpostreplyintervals:edit`
- _需求: 6.2, 6.3_
- [ ]* 5.4 编写属性测试:间隔配置保存 Round-Trip
- **Property 1: 间隔配置保存 Round-Trip**
- 生成随机认证等级 ID 和随机非负整数的 PostInterval/ReplyInterval验证保存→查询的 round-trip 一致性
- **验证: 需求 1.3**
- [x] 6. 检查点 - 管理端后端 API 完成
- 确保所有测试通过,如有疑问请向用户确认。
- [x] 7. 管理端前端页面实现
- [x] 7.1 创建时间间隔配置页面
- 在 ZR.Vue 中创建间隔配置页面组件
- 以列表形式展示所有认证等级对应的间隔配置
- 每行显示认证等级名称、发帖间隔(秒)、回复间隔(秒)
- 提供编辑功能,支持修改 PostInterval 和 ReplyInterval
- 保存时校验间隔值最小为 0
- _需求: 1.1, 1.2, 1.3, 1.4_
- [x] 7.2 配置路由和菜单
- 添加时间间隔配置菜单项
- 配置页面路由
- _需求: 1.1_
- [x] 8. 检查点 - 管理端前端完成
- 确保页面功能正常,如有疑问请向用户确认。
- [x] 9. 小程序前端:发帖页倒计时逻辑
- [x] 9.1 修改 post-page.vue 添加发帖倒计时
- 在 data 中新增 `postCountdown`(剩余秒数)和 `countdownTimer`(定时器引用)
- 实现 `startPostCountdown(seconds)` 方法:启动每秒递减的倒计时
- 修改 `handlePublish` 方法:倒计时期间禁止发帖;发帖成功后从响应中读取 `postInterval` 并启动倒计时
- 处理后端返回间隔错误时:弹出系统提示显示剩余秒数,解析并更新本地倒计时
- 页面销毁时清除定时器
- _需求: 4.1, 4.2, 4.3, 4.4_
- [x] 9.2 修改发布按钮状态
- 倒计时期间:按钮禁用(降低透明度),文案显示「请等待 X 秒」
- 倒计时结束:恢复按钮为可用状态,文案恢复为「立即发布」
- _需求: 4.2, 4.3_
- [x] 10. 小程序前端:帖子详情页回复倒计时逻辑
- [x] 10.1 修改 post-details-page.vue 添加回复倒计时
- 在 data 中新增 `replyCountdown`(剩余秒数)和 `replyCountdownTimer`(定时器引用)
- 实现 `startReplyCountdown(seconds)` 方法:启动每秒递减的倒计时
- 修改回复提交方法:倒计时期间禁止回复;回复成功后从响应中读取 `replyInterval` 并启动倒计时
- 处理后端返回间隔错误时:弹出系统提示显示剩余秒数,解析并更新本地倒计时
- 页面销毁时清除定时器
- _需求: 5.1, 5.2, 5.3, 5.4_
- [x] 10.2 修改评论输入区域状态
- 倒计时期间:显示「请等待 X 秒后再回复」提示文字,提交按钮禁用
- 倒计时结束:恢复为正常可输入可提交状态
- _需求: 5.2, 5.3_
- [x] 11. 最终检查点 - 全部变更验证
- 确保所有测试通过,如有疑问请向用户确认。
## 备注
- 标记 `*` 的子任务为可选属性测试任务,可跳过以加快 MVP 进度
- 每个任务引用了具体的需求编号以便追溯
- 检查点确保增量验证
- 属性测试使用 FsCheck.Xunit每个属性至少 100 次迭代
- 发帖/回复成功响应中直接返回间隔秒数(而非通过 GetAppConfig避免缓存问题