An overview,
The book system framework is shown as follows:
File content is continuously updated inGitHubOn, you can check by yourself.
This article mainly introduces: reviews and readingsIn thecomments
Second, the commentary
Train of thought
1. Comments on the article
2. Responses to comments
3. Tree your data
Database design
Parent_id points to the parent comment ID, which defaults to 0 if it is an article comment.
code
1. Because comments are tree-like structures, nesting of tree data is done in the micro-service part.
action.proto
syntax = "proto3";
package action;
option go_package = "action";
message Request {
string ping = 1;
}
message Response {
bool ok = 1;
string message = 2;
}
message CommentReq{
int64 Id = 1;
int64 ParentId = 2;
int64 BookContentId = 3;
string Comment = 4;
int64 CommentByUserId = 5;
string CommentByNickname = 6;
int64 CommentToUserId = 7;
string CommentToNickname = 8;
}
message CommentResp{
int64 Id = 1;
int64 ParentId = 2;
int64 BookContentId = 3;
string Comment = 4;
int64 CommentByUserId = 5;
string CommentByNickname = 6;
int64 CommentToUserId = 7;
string CommentToNickname = 8;
}
message CommentsNodeResp{
CommentResp Comments = 1;
repeated CommentsNodeResp CommentsNode = 2;
}
message CommentsTreeResp{
repeated CommentsNodeResp CommentsTree = 1;
}
service Action {
//Comments
rpc GetCommentsByBookContentId(CommentReq) returns(CommentsTreeResp);
rpc CreateComment(CommentReq) returns(Response);
rpc UpdateComment(CommentReq) returns(Response);
rpc DeleteComment(CommentReq) returns(Response);
}
Copy the code
2. Combine database data into tree data in logical code
getcommentsbybookcontentidlogic.go
// Comments
func (l *GetCommentsByBookContentIdLogic) GetCommentsByBookContentId(in *action.CommentReq) (*action.CommentsTreeResp, error) {
comments, err := l.svcCtx.CommentModel.FindCommentsByBookContentId(in.BookContentId)
iferr ! =nil {
return nil, err
}
fmt.Println("comments", comments)
f := func(cs []*model.Comment) *action.CommentsTreeResp {
/ / tree structure
var res = action.CommentsTreeResp{
CommentsTree: make([]*action.CommentsNodeResp, 0),}for i := 0; i < len(cs); i++ {
if cs[i].ParentId == 0 {
res.CommentsTree = append(res.CommentsTree, &action.CommentsNodeResp{
Comments: &action.CommentResp{
Id: cs[i].Id,
ParentId: cs[i].ParentId,
BookContentId: cs[i].BookContentId,
Comment: cs[i].Comment,
CommentByUserId: cs[i].CommentByUserId,
CommentByNickname: cs[i].CommentByNickname,
CommentToUserId: cs[i].CommentToUserId,
CommentToNickname: cs[i].CommentToNickname,
},
})
} else {
node := FindCommentNodeByParentId(res.CommentsTree, cs[i].ParentId)
ifnode ! =nil {
node.CommentsNode = append(node.CommentsNode, &action.CommentsNodeResp{
Comments: &action.CommentResp{
Id: cs[i].Id,
ParentId: cs[i].ParentId,
BookContentId: cs[i].BookContentId,
Comment: cs[i].Comment,
CommentByUserId: cs[i].CommentByUserId,
CommentByNickname: cs[i].CommentByNickname,
CommentToUserId: cs[i].CommentToUserId,
CommentToNickname: cs[i].CommentToNickname,
},
})
}
}
}
return &res
}
return f(comments), nil
}
// Find the node corresponding to the id
func FindCommentNodeByParentId(res []*action.CommentsNodeResp, id int64) *action.CommentsNodeResp {
for i := 0; i < len(res); i++ {
if id == res[i].Comments.Id {
return res[i]
} else {
ifr := FindCommentNodeByParentId(res[i].CommentsNode, id); r ! =nil {
return r
}
}
}
return nil
}
Copy the code
3. When doing the front end, I found that comments generally only have two levels of father and son, so I combined all the replies to comments into sub-levels in WebApi. – -! There is bitter can not speak out.
get_comment_handler.go
package action
import (
"WebApi/Pb/action"
"WebApi/Svc"
"context"
"github.com/gin-gonic/gin"
"net/http"
"strconv"
)
func GetCommentsByBookContentIdHandler(c *gin.Context) {
bookContentId, err := strconv.ParseInt(c.Query("bookContentId"), 10.64)
iferr ! =nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
ctx := context.Background()
// Tree structure (comment)
res, err := Svc.SvcContext.Grpc.ActionGrpc.GetCommentsByBookContentId(ctx, &action.CommentReq{
BookContentId: bookContentId,
})
// Tree structure tiling for only parent-child node structure (comments) easy front-end use
tn := func(t *action.CommentsTreeResp) action.CommentsTreeResp {
var tree = action.CommentsTreeResp{}
for i := 0; i < len(t.CommentsTree); i++ {
// Combine the parent node
tree.CommentsTree = append(tree.CommentsTree, &action.CommentsNodeResp{
Comments: t.CommentsTree[i].Comments,
})
// Combine all nodes under the parent node
combChildComment(t.CommentsTree[i].CommentsNode, &tree.CommentsTree[i].CommentsNode)
}
return tree
}
iferr ! =nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
} else {
c.JSON(http.StatusOK, tn(res))
}
}
func combChildComment(src []*action.CommentsNodeResp, dest *[]*action.CommentsNodeResp) {
for i := 0; i < len(src); i++ {
*dest = append(*dest, &action.CommentsNodeResp{
Comments: src[i].Comments,
})
ifsrc[i].CommentsNode ! =nil {
combChildComment(src[i].CommentsNode, dest)
}
}
}
Copy the code
4.POSTman’s results show
{"CommentsTree": [{"Comments": {"Id": 1, "BookContentId": 2, "Comment": "well written. ", "CommentByUserId": 1, "CommentByNickname": "bookshop owner ", "CommentToUserId": 1, "CommentToNickname":" bookshop owner "}, "CommentsNode": [{"Comments": {"Id": 3, "ParentId": 1, "BookContentId": 2, "Comment": "flatterer ", "CommentByUserId": 2, "CommentByNickname": "CommentToUserId": 1, "CommentToNickname": "Bookkeeper"}}, {"Comments": {"Id": 4, "ParentId": 3, "BookContentId": "CommentByUserId": 3, "CommentByNickname": 3, "CommentToUserId": }}]}, {"CommentToNickname": {"Id": 5, "BookContentId": 2, "Comment": "Well written 1. ", "CommentByUserId": 1, "CommentByNickname":" Bookstore owner ", "CommentToUserId": 1, "CommentToNickname": }, "CommentsNode": [{"Comments": {"Id": 8, "ParentId": 5, "BookContentId": 2, "Comment": "Not good ", "CommentByUserId": 4, "CommentByNickname":" King five ", "CommentToUserId": 1, "CommentToNickname": }}, {"Comments": {"Id": 9, "ParentId": 8, "BookContentId": 2, "Comment": "bad ", "CommentByUserId": 4, "CommentByNickname": "CommentToUserId": 4, "CommentToNickname": "CommentToNickname"}}]}, {"Comments": {"Id": 10, "BookContentId": 2, "Comment": "I am the first ", "CommentByUserId": 4, "CommentByNickname":" King five ", "CommentToUserId": }}, {"Comments": {"Id": 11, "BookContentId": 2, "Comment": "2 ", "CommentByUserId": 4, "CommentByNickname": "CommentToUserId": 4, "CommentToNickname": "CommentToNickname"}}, {"Comments": {"Id": 12, "BookContentId": 2, "Comment": "article YYDS. ", "CommentByUserId": 1, "CommentByNickname":" Bookseller ", "CommentToUserId": 1, "CommentToNickname": "Bookshop owner"}}]}Copy the code
5. Front-end results display
Three, Tips,
I have been busy with my work recently, so the update may be slower than before, please bear with me.