这篇文章上次修改于 902 天前,可能其部分内容已经发生变化,如有疑问可询问作者。
1 效果
2 概要设计
评论有两类,一种是针对文章的评论,另一种是针对评论的评论,也就是评论回复。第一种评论称为一级评论,第二种评论称为二级评论,包括所有针对评论的回复,无论之间进行了多少次来回。
3 详细设计
3.1 DB
remark 表,描述评论信息。
字段名 | 类型 | 备注 |
---|---|---|
id | bigint(20) unsigned | 自增 |
article_id | bigint(20) unsigned | 文章 ID |
nickname | varchar(64) | 评论者昵称 |
content | text | 评论内容 |
init_remark_id | bigint(20) unsigned | 被回复的最初评论 ID |
nickname_replied | varchar(64) | 被评论者昵称 |
created_time | datetime | 创建时间 |
updated_time | datetime | 更新时间,更新记录时自动更新 |
3.2 API
3.2.1. 创建评论
(1) 接口描述
本接口 (CreateRemark) 用于创建一条评论。
(2) 输入参数
参数名称 | 必选 | 类型 | 描述 |
---|---|---|---|
ArticleId | 是 | Integer | 文章 ID。 |
Nickname | 是 | String | 评论者昵称。 |
Content | 是 | String | 评论内容。 |
InitRemarkId | 否 | Integer | 被回复的最初评论 ID。 |
NicknameReplied | 否 | String | 被回复者昵称。 |
(3) 输出参数
参数名称 | 类型 | 描述 |
---|---|---|
RemarkId | Integer | 评论 ID。 |
RequestId | String | 唯一请求 ID。 |
3.2.2. 查询评论
(1) 接口描述
本接口 (DescribeRemarks) 用于查询评论。
(2) 输入参数
参数名称 | 必选 | 类型 | 描述 |
---|---|---|---|
ArticleId | 否 | Integer | 文章 ID。 |
Offset | 否 | Integer | 偏移量。 |
Limit | 否 | Integer | 返回数量。 |
(3) 输出参数
参数名称 | 类型 | 描述 |
---|---|---|
Total | Integer | 符合条件的评论数量。 |
RemarkSet | Array of RemarkInfo | 评论详细信息列表。 |
RequestId | String | 唯一请求 ID。 |
RemarkInfo
参数名称 | 类型 | 描述 |
---|---|---|
Remark | Remark | 评论详细信息。 |
ReplySet | Array of Remark | 评论回复详细信息列表。 |
Remark
参数名称 | 类型 | 描述 |
---|---|---|
RemarkId | Integer | 评论 ID。 |
Nickname | String | 评论者昵称。 |
Content | String | 评论内容。 |
InitRemarkId | Integer | 被回复的最初的评论 ID。 |
NicknameReplied | String | 被回复者昵称。 |
CreatedTime | Timestamp | 评论创建时间。 |
3.3 前端渲染
- 利用 v-for 标签列出所有一级评论。
- 在每个一级评论后面再利用 v-for 标签列出对应的所有二级评论。
<!-- 列出类评论-->
<el-row>
<el-col
v-for="item in this.remarkSet"
:key="item.Remark.RemarkId"
style="padding: 3px"
>
<el-card class="back"
:body-style="{height: '50px', padding: '0px', textAlign: 'center'}"
style="position: relative"
shadow="always"
>
<div class="remark-content">
<div class="in-remark-content">
{{formatTime(item.Remark.CreatedTime)}}
{{item.Remark.Nickname}}
{{item.Remark.Content}}
<a :href="'#'" @click="handleReplyRemark(item.Remark)">回复</a>
<a :href="'#'" @click="handleUpdateRemark(item.Remark)" v-show="adminLogin">修改</a>
<a :href="'#'" @click="handleDeleteRemark(item.Remark.RemarkId)" v-show="adminLogin">删除</a>
</div>
</div>
<!-- 列出类回复-->
<el-row>
<el-col class="back"
v-for="reply in item.ReplySet"
:key="reply.RemarkId"
style="padding-left: 20px"
>
<el-card
:body-style="{height: '50px', padding: '0px', textAlign: 'right'}"
style="position: relative"
shadow="always"
>
<div class="remark-content">
<div class="in-remark-content">
{{formatTime(reply.CreatedTime)}}
{{reply.Nickname}}@{{reply.NicknameReplied}}
{{reply.Content}}
<a :href="'#'" @click="handleReplyRemark(reply)">回复</a>
<a :href="'#'" @click="handleUpdateRemark(reply)" v-show="adminLogin">修改</a>
<a :href="'#'" @click="handleDeleteRemark(reply.RemarkId)" v-show="adminLogin">删除</a>
</div>
</div>
</el-card>
</el-col>
</el-row>
</el-card>
</el-col>
</el-row>
4 待完善
- 保存用户身份,用户只需要第一次评论时输入昵称
- 保存用户邮箱,评论后邮件通知
参考
http://hbnnforever.cn/article/commentformysite.html#idcomment
没有评论