Commit ceddb47f authored by Zhu yizheng's avatar Zhu yizheng
Browse files

slice实现

parents
module github.com/zyz/comment
go 1.24.3
require (
github.com/sirupsen/logrus v1.9.3 // indirect
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 // indirect
)
package main
import (
"encoding/json"
"net/http"
"strconv"
"sync"
"github.com/sirupsen/logrus"
)
// Comment 表示单个评论
type Comment struct {
ID int `json:"id"`
Name string `json:"name"`
Comment string `json:"content"`
}
// Response 表示统一的 API 响应格式
type Response struct {
Code int `json:"code"`
Msg string `json:"msg"`
Data interface{} `json:"data"`
}
// GetCommentsResponse 表示获取评论 API 的响应
type GetCommentsResponse struct {
Total int `json:"total"`
Comments []Comment `json:"comments"`
}
// 模拟数据库
var mutex = &sync.RWMutex{}
var comments []Comment
var incrementID int
// getCommentsHandler 处理获取评论的请求
func getCommentsHandler(w http.ResponseWriter, r *http.Request) {
log := logrus.WithFields(logrus.Fields{
"method": r.Method,
"path": r.URL.Path,
})
if r.Method != http.MethodGet {
respondError(w, http.StatusMethodNotAllowed, "方法不被允许", nil, log)
return
}
// 解析分页参数
page, size := parsePaginationParams(r)
log = log.WithFields(logrus.Fields{
"page": page,
"size": size,
})
// 使用读锁读取评论
mutex.RLock()
defer mutex.RUnlock()
// 计算分页
total := len(comments)
var result []Comment
if size == -1 {
result = comments
} else {
start := (page - 1) * size
end := start + size
if start < total {
if end > total {
end = total
}
result = comments[start:end]
}
}
// 准备响应
data := GetCommentsResponse{
Total: total,
Comments: result,
}
respondSuccess(w, data, log)
}
// addCommentHandler 处理添加评论的请求
func addCommentHandler(w http.ResponseWriter, r *http.Request) {
log := logrus.WithFields(logrus.Fields{
"method": r.Method,
"path": r.URL.Path,
})
if r.Method != http.MethodPost {
respondError(w, http.StatusMethodNotAllowed, "方法不被允许", nil, log)
return
}
// 解析请求体
var req struct {
Name string `json:"name"`
Content string `json:"content"`
}
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
respondError(w, http.StatusBadRequest, "无效的请求体", nil, log.WithError(err))
return
}
// 验证输入
if req.Name == "" || req.Content == "" {
respondError(w, http.StatusBadRequest, "姓名和内容为必填项", nil, log)
return
}
// 使用写锁添加评论
mutex.Lock()
defer mutex.Unlock()
incrementID++
newComment := Comment{
ID: incrementID,
Name: req.Name,
Comment: req.Content,
}
comments = append(comments, newComment)
log.WithFields(logrus.Fields{
"comment_id": newComment.ID,
"name": newComment.Name,
}).Info("评论已添加")
respondSuccess(w, newComment, log)
}
// deleteCommentHandler 处理删除评论的请求
func deleteCommentHandler(w http.ResponseWriter, r *http.Request) {
log := logrus.WithFields(logrus.Fields{
"method": r.Method,
"path": r.URL.Path,
})
if r.Method != http.MethodPost {
respondError(w, http.StatusMethodNotAllowed, "方法不被允许", nil, log)
return
}
// 解析评论 ID
idStr := r.URL.Query().Get("id")
id, err := strconv.Atoi(idStr)
if err != nil || id <= 0 {
respondError(w, http.StatusBadRequest, "无效的评论 ID", nil, log.WithError(err))
return
}
// 使用写锁删除评论
mutex.Lock()
defer mutex.Unlock()
found := false
for i, comment := range comments {
if comment.ID == id {
comments = append(comments[:i], comments[i+1:]...)
found = true
break
}
}
if !found {
respondError(w, http.StatusNotFound, "评论不存在", nil, log)
return
}
log.WithFields(logrus.Fields{
"comment_id": id,
}).Info("评论已删除")
respondSuccess(w, nil, log)
}
// parsePaginationParams 解析分页参数
func parsePaginationParams(r *http.Request) (page, size int) {
pageStr := r.URL.Query().Get("page")
sizeStr := r.URL.Query().Get("size")
page, err := strconv.Atoi(pageStr)
if err != nil || page < 1 {
page = 1
}
size, err = strconv.Atoi(sizeStr)
if err != nil || size < -1 || size == 0 {
size = 10
}
return page, size
}
// respondSuccess 发送成功响应
func respondSuccess(w http.ResponseWriter, data interface{}, log *logrus.Entry) {
resp := Response{
Code: 0,
Msg: "成功",
Data: data,
}
sendResponse(w, http.StatusOK, resp, log)
}
// respondError 发送错误响应
func respondError(w http.ResponseWriter, status int, msg string, data interface{}, log *logrus.Entry) {
resp := Response{
Code: status,
Msg: msg,
Data: data,
}
log.WithFields(logrus.Fields{
"status": status,
"msg": msg,
}).Error("请求失败")
sendResponse(w, status, resp, log)
}
// sendResponse 发送 JSON 响应
func sendResponse(w http.ResponseWriter, status int, resp Response, log *logrus.Entry) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(status)
if err := json.NewEncoder(w).Encode(resp); err != nil {
log.WithError(err).Error("发送响应失败")
}
}
package main
import (
"net/http"
"github.com/sirupsen/logrus"
)
func main() {
// 初始化日志
logrus.SetFormatter(&logrus.JSONFormatter{})
logrus.Info("启动服务器...")
// 注册路由
http.HandleFunc("/comment/get", getCommentsHandler)
http.HandleFunc("/comment/add", addCommentHandler)
http.HandleFunc("/comment/delete", deleteCommentHandler)
// 启动服务器
addr := ":8080"
logrus.WithField("address", addr).Info("服务器启动")
if err := http.ListenAndServe(addr, nil); err != nil {
logrus.WithError(err).Fatal("服务器启动失败")
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment