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