func adminSetPostState(w http.ResponseWriter, r *http.Request, state int) { id, ok := util.ParamID(w, r, "id") if !ok { return } p := &models.Post{ID: id} if err := db.Select(p); err != nil { logs.Error("adminSetPostState:", err) util.RenderJSON(w, http.StatusInternalServerError, nil, nil) return } // 不可能存在状态值为0的文章,出现此值,表明数据库没有该条记录 if p.State == models.PostStateAll { util.RenderJSON(w, http.StatusNotFound, nil, nil) return } p = &models.Post{ID: id, State: state} if _, err := db.Update(p); err != nil { logs.Error("adminSetPostState:", err) util.RenderJSON(w, http.StatusInternalServerError, nil, nil) return } if err := stats.UpdatePostsSize(); err != nil { logs.Error("admin.adminSetPostState:", err) } lastUpdated() util.RenderJSON(w, http.StatusCreated, "{}", nil) }
// @api delete /admin/api/posts/{id} 删除文章 // @apiGroup admin // // @apiRequest json // @apiHeader Authorization xxx // // @apiSuccess 204 no content func adminDeletePost(w http.ResponseWriter, r *http.Request) { id, ok := util.ParamID(w, r, "id") if !ok { return } tx, err := db.Begin() if err != nil { logs.Error("deletePost:", err) util.RenderJSON(w, http.StatusInternalServerError, nil, nil) tx.Rollback() return } // 删除文章 sql := "DELETE FROM #posts WHERE {id}=?" if _, err := tx.Exec(true, sql, id); err != nil { logs.Error("deletePost:", err) util.RenderJSON(w, http.StatusInternalServerError, nil, nil) tx.Rollback() return } // 删除评论 sql = "DELETE FROM #comments WHERE {postID}=?" if _, err := tx.Exec(true, sql, id); err != nil { logs.Error("deletePost:", err) util.RenderJSON(w, http.StatusInternalServerError, nil, nil) tx.Rollback() return } //删除关联数据 sql = "DELETE FROM #relationships WHERE {postID}=?" if _, err := tx.Exec(true, sql, id); err != nil { logs.Error("deletePost:", err) util.RenderJSON(w, http.StatusInternalServerError, nil, nil) tx.Rollback() return } if err := tx.Commit(); err != nil { tx.Rollback() logs.Error("deletePost:", err) util.RenderJSON(w, http.StatusInternalServerError, nil, nil) return } if err := stats.UpdatePostsSize(); err != nil { logs.Error("admin.adminDeletePost:", err) } lastUpdated() util.RenderJSON(w, http.StatusNoContent, nil, nil) }
// @api put /admin/api/tags/{id} 修改某id的标签内容 // @apiParam id int 需要修改的标签id // @apiGroup admin // // @apiRequest json // @apiHeader Authorization xxx // @apiParam name string 唯一名称 // @apiParam title string 显示的标题 // @apiParam description string 描述信息,可以是html // @apiExample json // { // "name": "tag-1", // "title":"标签1", // "description": "<h1>desc</h1>" // } // // @apiSuccess 204 no content // // @apiError 400 bad request // @apiParam message string 错误信息 // @apiParam detail array 说细的错误信息,用于描述哪个字段有错 // @apiExample json // { // "message": "格式错误", // "detail":[ // {"title":"不能包含特殊字符"}, // {"name": "已经存在同名"} // ] // } func adminPutTag(w http.ResponseWriter, r *http.Request) { t := &models.Tag{} if !util.ReadJSON(w, r, t) { return } // 检测是否为空 errs := &util.ErrorResult{Message: "格式错误", Detail: map[string]string{}} if len(t.Name) == 0 { errs.Add("name", "不能为空") } if len(t.Title) == 0 { errs.Add("title", "不能为空") } if errs.HasErrors() { util.RenderJSON(w, http.StatusBadRequest, errs, nil) return } var ok bool t.ID, ok = util.ParamID(w, r, "id") if !ok { return } // 检测是否存在同名 titleExists, nameExists, err := tagIsExists(t) if err != nil { logs.Error("adminPutTag:", err) util.RenderJSON(w, http.StatusInternalServerError, nil, nil) return } if titleExists { errs.Add("title", "与已有标签同名") } if nameExists { errs.Add("name", "与已有标签同名") } if errs.HasErrors() { util.RenderJSON(w, http.StatusBadRequest, errs, nil) return } if _, err := db.Update(t); err != nil { logs.Error("adminPutTag:", err) util.RenderJSON(w, http.StatusInternalServerError, nil, nil) return } lastUpdated() util.RenderJSON(w, http.StatusNoContent, nil, nil) }
// @api get /admin/api/posts/{id} 获取某一篇文章的详细内容 // @apiGroup admin // // @apiRequest json // @apiHeader Authorization xxx // // @apiSuccess 200 OK // @apiParam id int id值 // @apiParam name string 唯一名称,可以为空 // @apiParam title string 标题 // @apiParam summary string 文章摘要 // @apiParam content string 文章内容 // @apiParam state int 状态 // @apiParam order int 排序 // @apiParam created int 创建时间 // @apiParam modified int 修改时间 // @apiParam template string 所使用的模板 // @apiParam allowPing bool 允许ping // @apiParam allowComment bool 允许评论 // @apiParam tags array 关联的标签。 func adminGetPost(w http.ResponseWriter, r *http.Request) { id, ok := util.ParamID(w, r, "id") if !ok { return } p := &models.Post{ID: id} if err := db.Select(p); err != nil { logs.Error("adminGetPost:", err) util.RenderJSON(w, http.StatusInternalServerError, nil, nil) return } tags, err := getPostTags(id) if err != nil { logs.Error("adminGetPost:", err) util.RenderJSON(w, http.StatusInternalServerError, nil, nil) return } obj := &struct { ID int64 `json:"id"` Name string `json:"name"` Title string `json:"title"` Summary string `json:"summary"` Content string `json:"content"` State int `json:"state"` Order int `json:"order"` Created int64 `json:"created"` Modified int64 `json:"modified"` Template string `json:"template"` AllowPing bool `json:"allowPing"` AllowComment bool `json:"allowComment"` Tags []*models.Tag `json:"tags"` }{ ID: p.ID, Name: p.Name, Title: p.Title, Summary: p.Summary, Content: p.Content, State: p.State, Order: p.Order, Created: p.Created, Modified: p.Modified, Template: p.Template, AllowPing: p.AllowPing, AllowComment: p.AllowComment, Tags: tags, } util.RenderJSON(w, http.StatusOK, obj, nil) }
// @api get /admin/api/tags/{id} 获取指定id的标签内容 // @apiParam id int 标签的id // @apiGroup admin // // @apiSuccess 200 OK // @apiParam id int 标签的id // @apiParam name string 标签的唯一名称,可能为空 // @apiParam title string 标签名称 // @apiParam description string 对标签的详细描述 func adminGetTag(w http.ResponseWriter, r *http.Request) { id, ok := util.ParamID(w, r, "id") if !ok { return } t := &models.Tag{ID: id} if err := db.Select(t); err != nil { logs.Error("adminGetTag:", err) util.RenderJSON(w, http.StatusInternalServerError, nil, nil) return } util.RenderJSON(w, http.StatusOK, t, nil) }
// @api delete /admin/api/comments/{id} 删除某条评论 // @apiParam id int 评论的id值 // @apiGroup admin // // @apiSuccess 204 no content func adminDeleteComment(w http.ResponseWriter, r *http.Request) { id, ok := util.ParamID(w, r, "id") if !ok { return } c := &models.Comment{ID: id} if _, err := db.Delete(c); err != nil { logs.Error("adminDeleteComment:", err) util.RenderJSON(w, http.StatusInternalServerError, nil, nil) return } if err := stats.UpdateCommentsSize(); err != nil { logs.Error("admin.adminDeleteComment:", err) } lastUpdated() util.RenderJSON(w, http.StatusNoContent, nil, nil) }
// @api put /admin/api/comments/{id} 修改评论,只能修改管理员发布的评论 // @apiParam id int 需要修改的评论id // @apiGroup admin // // @apiRequest json // @apiParam content string 新的评论内容 // @apiExample json // { "content", "content..." } // // @apiSuccess 200 ok func adminPutComment(w http.ResponseWriter, r *http.Request) { id, ok := util.ParamID(w, r, "id") if !ok { return } c := &models.Comment{ID: id} cnt, err := db.Count(c) if err != nil { logs.Error("putComment:", err) util.RenderJSON(w, http.StatusInternalServerError, nil, nil) return } if cnt == 0 { util.RenderJSON(w, http.StatusNotFound, nil, nil) return } ct := &struct { Content string `json:"content"` }{} if !util.ReadJSON(w, r, ct) { return } c.Content = ct.Content if _, err = db.Update(c); err != nil { logs.Error("putComment", err) util.RenderJSON(w, http.StatusInternalServerError, nil, nil) return } if err := stats.UpdateCommentsSize(); err != nil { logs.Error("admin.adminPutComment:", err) } lastUpdated() util.RenderJSON(w, http.StatusNoContent, nil, nil) }
// @api delete /admin/api/tags/{id} 删除该id的标签,也将被从relationships表中删除。 // @apiParam id int 需要删除的标签id // @apiGroup admin // // @apiRequest json // @apiHeader Authorization xxx // // @apiSuccess 204 no content func adminDeleteTag(w http.ResponseWriter, r *http.Request) { id, ok := util.ParamID(w, r, "id") if !ok { return } tx, err := db.Begin() if err != nil { logs.Error("adminDeleteMeta:", err) util.RenderJSON(w, http.StatusInternalServerError, nil, nil) return } if _, err := tx.Delete(&models.Tag{ID: id}); err != nil { logs.Error("adminDeleteMeta:", err) util.RenderJSON(w, http.StatusInternalServerError, nil, nil) return } // 删除与之对应的关联数据。 sql := "DELETE FROM #relationships WHERE {tagID}=?" if _, err := tx.Exec(true, sql, id); err != nil { logs.Error("adminDeleteMeta:", err) util.RenderJSON(w, http.StatusInternalServerError, nil, nil) return } if err := tx.Commit(); err != nil { logs.Error("adminDeleteMeta:", err) tx.Rollback() util.RenderJSON(w, http.StatusInternalServerError, nil, nil) return } lastUpdated() util.RenderJSON(w, http.StatusNoContent, nil, nil) }
// @api get /api/posts/{id}/comments // @apiQuery page int 页码 // @apiGroup front // // @apiSuccess 200 OK // @apiParam comments array 当前页的评论 func frontGetPostComments(w http.ResponseWriter, r *http.Request) { id, ok := util.ParamID(w, r, "id") if !ok { return } p := &models.Post{ID: id} if err := db.Select(p); err != nil { logs.Error("frontGetPostComments:", err) util.RenderJSON(w, http.StatusInternalServerError, nil, nil) return } if p.State != models.PostStatePublished { util.RenderJSON(w, http.StatusNotFound, nil, nil) return } sql := db.Where("{postID}=?", id). And("{state}=?", models.CommentStateApproved). Table("#comments") var page int if page, ok = util.QueryInt(w, r, "page", 0); !ok { return } sql.Limit(opt.PageSize, page*opt.PageSize) maps, err := sql.SelectMap(true, "*") if err != nil { logs.Error("frontGetComments:", err) util.RenderJSON(w, http.StatusInternalServerError, nil, nil) return } util.RenderJSON(w, http.StatusOK, map[string]interface{}{"comments": maps}, nil) }
// @api put /admin/api/posts/{id} 修改文章 // @apiGroup admin // // @apiRequest json // @apiHeader Authorization xxx // @apiParam name string 唯一名称,可以为空 // @apiParam title string 标题 // @apiParam summary string 文章摘要 // @apiParam content string 文章内容 // @apiParam state int 状态 // @apiParam order int 排序 // @apiParam template string 所使用的模板 // @apiParam allowPing bool 允许ping // @apiParam allowComment bool 允许评论 // @apiParam tags array 关联的标签 // // @apiSuccess 200 no content func adminPutPost(w http.ResponseWriter, r *http.Request) { id, ok := util.ParamID(w, r, "id") if !ok { return } p := &struct { Name string `json:"name"` Title string `json:"title"` Summary string `json:"summary"` Content string `json:"content"` State int `json:"state"` Order int `json:"order"` Template string `json:"template"` AllowPing bool `json:"allowPing"` AllowComment bool `json:"allowComment"` Tags []int64 `json:"tags"` }{} if !util.ReadJSON(w, r, p) { return } op := &models.Post{ID: id} if err := db.Select(op); err != nil { logs.Error("adminPutPost-0:", err) util.RenderJSON(w, http.StatusInternalServerError, nil, nil) return } pp := &models.Post{ ID: id, Name: p.Name, Title: p.Title, Summary: p.Summary, Content: p.Content, State: p.State, Order: p.Order, Template: p.Template, AllowPing: p.AllowPing, AllowComment: p.AllowComment, Modified: time.Now().Unix(), Created: op.Created, } // TODO 是否有必要检测标签是否真实存在 tx, err := db.Begin() if err != nil { logs.Error("adminPutPost-1:", err) util.RenderJSON(w, http.StatusInternalServerError, nil, nil) tx.Rollback() return } // 更新文档内容 if _, err := tx.UpdateZero(pp); err != nil { logs.Error("adminPutPost-2:", err) util.RenderJSON(w, http.StatusInternalServerError, nil, nil) tx.Rollback() return } // 删除旧的关联内容 sql := "DELETE FROM #relationships WHERE {postID}=?" if _, err := tx.Exec(true, sql, pp.ID); err != nil { logs.Error("adminPutPost-3:", err) util.RenderJSON(w, http.StatusInternalServerError, nil, nil) tx.Rollback() return } // 添加新的关联 if len(p.Tags) > 0 { rs := make([]interface{}, 0, len(p.Tags)) for _, tag := range p.Tags { rs = append(rs, &models.Relationship{TagID: tag, PostID: pp.ID}) } if err := tx.MultInsert(rs...); err != nil { logs.Error("adminPutPost-4:", err) util.RenderJSON(w, http.StatusInternalServerError, nil, nil) tx.Rollback() return } } if err := tx.Commit(); err != nil { logs.Error("adminPutPost-5:", err) tx.Rollback() return } if err := stats.UpdatePostsSize(); err != nil { logs.Error("admin.adminPutPost:", err) } lastUpdated() util.RenderJSON(w, http.StatusNoContent, nil, nil) }