携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第13天,点击查看活动详情
项目原视频地址:www.bilibili.com/video/BV1VS…
文章详情
和之前一样,需要在 router.go 中配置。
e-book-website/router/router.go
func Router() {
http.HandleFunc("/p/", views.HTML.Detail)
}
通过 common.Template 加载页面
e-book-website/views/post.go
func (*HTMLApi) Detail(w http.ResponseWriter, r *http.Request) {
detail := common.Template.Detail
path := r.URL.Path
pIdStr := strings.TrimPrefix(path, "/p/")
pIdStr = strings.TrimSuffix(pIdStr, ".html")
pid, err := strconv.Atoi(pIdStr)
if err != nil {
detail.WriteError(w, errors.New("不识别此请求路径"))
return
}
// 根据 URL 的 id,获取文章详情
postRes, err := service.GetPostDetail(pid)
if err != nil {
detail.WriteError(w, errors.New("查询出错"))
return
}
detail.WriteData(w, postRes)
}
e-book-website/service/post.go
根据 id,获取文章详情
func GetPostDetail(pid int) (*models.PostRes, error) {
post, err := databases.GetPostById(pid)
}
e-book-website/databases/post.go
func GetPostById(pid int) (*models.Post, error) {
post := &models.Post{}
row := DB.QueryRow("select * from post where pid=?", pid)
if row.Err() != nil {
return post, row.Err()
}
err := row.Scan(
&post.Pid,
&post.Title,
&post.Content,
&post.Markdown,
&post.CategoryId,
&post.UserId,
&post.ViewCount,
&post.Type,
&post.Slug,
&post.CreateAt,
&post.UpdateAt,
)
if err != nil {
return post, row.Err()
}
return post, nil
}
返回的数据中包含分类名称和用户名称,因此需要调用之前写的 GetCategoryNameById 和 GetUserNameById。
func GetPostDetail(pid int) (*models.PostRes, error) {
post, err := databases.GetPostById(pid)
if err != nil {
return nil, err
}
categoryName := databases.GetCategoryNameById(post.CategoryId)
userName := databases.GetUserNameById(post.UserId)
postMore := models.PostMore{
post.Pid,
post.Title,
post.Slug,
template.HTML(post.Content),
post.CategoryId,
categoryName,
post.UserId,
userName,
post.ViewCount,
post.Type,
models.DateDay(post.CreateAt),
models.DateDay(post.UpdateAt),
}
var postRes = &models.PostRes{
config.Cfg.Viewer,
config.Cfg.System,
postMore,
}
return postRes, nil
}
重启,刷新页面。
文章评论
Valine - 一款快速、简洁且高效的无后端评论系统。
注册并且实名认证之后,创建应用。
在设置中,点击应用凭证,填入 config.yaml 中。
重启项目,就可以评论了。
写文章
一样的步骤
渲染 HTML
func Router() {
http.HandleFunc("/writing", views.HTML.Writing)
}
e-book-website/views/Writing.go
func (*HTMLApi) Writing(w http.ResponseWriter, r *http.Request) {
writing := common.Template.Writing
wr := service.Writing()
writing.WriteData(w, wr)
}
e-book-website/service/post.go
func Writing() (wr models.WritingRes) {
wr.Title = config.Cfg.Viewer.Title
wr.CdnURL = config.Cfg.System.CdnURL
category, err := databases.GetAllCategory()
if err != nil {
log.Println(err)
return
}
wr.Categorys = category
return
}
重启项目,刷新页面
发布文章
http.HandleFunc("/api/v1/post", api.API.SaveAndUpdatePost)
在发布之前,应该验证当前用户是否处于登录状态。
e-book-website/utils/jwt.go
func ParseToken(tokenStr string) (*gojwt.Token, *Claims, error) {
claims := &Claims{}
token, err := gojwt.ParseWithClaims(tokenStr, claims, func(t *gojwt.Token) (interface{}, error) {
return jwtKey, nil
})
if err != nil {
return nil, nil, err
}
return token, claims, err
}
token 验证通过之后,拿到用户的 id。
func (*Api) SaveAndUpdatePost(w http.ResponseWriter, r *http.Request) {
token := r.Header.Get("Authorization")
_, claim, err := utils.ParseToken(token)
if err != nil {
log.Println("登录已过期")
return
}
uid := claim.Uid
}
通过 GetRequestJsonParam 方法获取 post 传递过来的参数。将传递过来的参数,通过 DB.Exec 保存在数据库中。
e-book-website/databases/post.go
func SavePost(post *models.Post) {
ret, err := DB.Exec("insert into post "+
"(title,content,markdown,categoryId,userId,viewCount,type,slug,create_at,update_at) "+
"values(?,?,?,?,?,?,?,?,?,?)",
post.Title,
post.Content,
post.Markdown,
post.CategoryId,
post.UserId,
post.ViewCount,
post.Type,
post.Slug,
post.CreateAt,
post.UpdateAt,
)
if err != nil {
log.Println(err)
}
pid, _ := ret.LastInsertId()
post.Pid = int(pid)
}
e-book-website/service/post.go
func SavePost(post *models.Post) {
databases.SavePost(post)
}
e-book-website/api/post.go
func (*Api) SaveAndUpdatePost(w http.ResponseWriter, r *http.Request) {
//获取用户id,判断用户是否登录
token := r.Header.Get("Authorization")
_, claim, err := utils.ParseToken(token)
if err != nil {
log.Println("登录已过期")
return
}
uid := claim.Uid
//POST save
method := r.Method
switch method {
case http.MethodPost:
params := common.GetRequestJsonParam(r)
cId := params["categoryId"].(string)
categoryId, _ := strconv.Atoi(cId)
content := params["content"].(string)
markdown := params["markdown"].(string)
slug := params["slug"].(string)
title := params["title"].(string)
postType := params["type"].(float64)
pType := int(postType)
post := &models.Post{
-1,
title,
slug,
content,
markdown,
categoryId,
uid,
0,
pType,
time.Now(),
time.Now(),
}
service.SavePost(post)
common.Success(w, post)
}
}
重启项目,添加文字内容,点击发布,完美 <( ̄▽ ̄)/咩哈哈
编辑文章
编辑就是根据文章ID获取文章,返回前端 + 用户修改过的内容,根据 ID,重新写入数据库。
http.HandleFunc("/api/v1/post/", api.API.GetPost)
e-book-website/api/post.go
func (*Api) GetPost(w http.ResponseWriter, r *http.Request) {
path := r.URL.Path
pIdStr := strings.TrimPrefix(path, "/api/v1/post/")
pid, err := strconv.Atoi(pIdStr)
if err != nil {
log.Println("不识别此请求路径")
return
}
post, err := databases.GetPostById(pid)
if err != nil {
log.Println(err)
return
}
common.Success(w, post)
}
e-book-website/api/post.go
func (*Api) SaveAndUpdatePost(w http.ResponseWriter, r *http.Request) {
// ....
switch method {
case http.MethodPost:
// ...
case http.MethodPut:
// update
params := common.GetRequestJsonParam(r)
cId := params["categoryId"].(float64)
categoryId := int(cId)
content := params["content"].(string)
markdown := params["markdown"].(string)
slug := params["slug"].(string)
title := params["title"].(string)
postType := params["type"].(float64)
pidFloat := params["pid"].(float64)
pType := int(postType)
pid := int(pidFloat)
post := &models.Post{
pid,
title,
slug,
content,
markdown,
categoryId,
uid,
0,
pType,
time.Now(),
time.Now(),
}
service.UpdatePost(post)
common.Success(w, post)
}
}
e-book-website/service/post.go
func UpdatePost(post *models.Post) {
databases.UpdatePost(post)
}
e-book-website/databases/post.go
func UpdatePost(post *models.Post) {
_, err := DB.Exec("update post set title=?,content=?,markdown=?,categoryId=?,type=?,slug=?,update_at=? where pid=?",
post.Title,
post.Content,
post.Markdown,
post.CategoryId,
post.Type,
post.Slug,
post.UpdateAt,
post.Pid,
)
if err != nil {
log.Println(err)
}
}
一样的操作,重启项目,编辑文章。