From 181b7297aed6ed684175faaadb36091e59d02971 Mon Sep 17 00:00:00 2001 From: Rrrrr226 <1789698945@qq.com> Date: Sat, 5 Oct 2024 16:47:50 +0800 Subject: [PATCH] feat:finish task --- .../Account_System/forum/answer/answer.go | 1 + .../Account_System/forum/create/create.go | 36 +++++ .../forum/distribute/distribute.go | 58 +++++++++ .../Account_System/forum/initial/initial.go | 34 +++++ Rrrrr226/Account_System/forum/login/login.go | 103 +++++++++++++++ .../Account_System/forum/readall/readall.go | 37 ++++++ Rrrrr226/Forum/AI/AI.go | 30 +++++ Rrrrr226/Forum/InitDB/InitDB.go | 20 +++ Rrrrr226/Forum/Login/Login.go | 37 ++++++ Rrrrr226/Forum/Middleware/Middleware.go | 34 +++++ Rrrrr226/Forum/Models/Models.go | 25 ++++ Rrrrr226/Forum/Register/Register.go | 32 +++++ Rrrrr226/Forum/Token/Token.go | 59 +++++++++ Rrrrr226/Forum/createAnswer/createAnswer.go | 51 ++++++++ .../Forum/createQuestion/createQuestion.go | 50 +++++++ Rrrrr226/Forum/getQuestion/getQuestion.go | 31 +++++ Rrrrr226/Forum/getQuestions/getQuestions.go | 19 +++ Rrrrr226/Forum/main.go | 39 ++++++ .../Forum/updateQuestion/updateQuestion.go | 43 ++++++ Rrrrr226/README.md | Bin 0 -> 16 bytes Rrrrr226/dockerfile/image | 29 +++++ Rrrrr226/dockerfile/net.go | 35 +++++ Rrrrr226/go.mod | 42 ++++++ Rrrrr226/go.sum | 123 ++++++++++++++++++ 24 files changed, 968 insertions(+) create mode 100644 Rrrrr226/Account_System/forum/answer/answer.go create mode 100644 Rrrrr226/Account_System/forum/create/create.go create mode 100644 Rrrrr226/Account_System/forum/distribute/distribute.go create mode 100644 Rrrrr226/Account_System/forum/initial/initial.go create mode 100644 Rrrrr226/Account_System/forum/login/login.go create mode 100644 Rrrrr226/Account_System/forum/readall/readall.go create mode 100644 Rrrrr226/Forum/AI/AI.go create mode 100644 Rrrrr226/Forum/InitDB/InitDB.go create mode 100644 Rrrrr226/Forum/Login/Login.go create mode 100644 Rrrrr226/Forum/Middleware/Middleware.go create mode 100644 Rrrrr226/Forum/Models/Models.go create mode 100644 Rrrrr226/Forum/Register/Register.go create mode 100644 Rrrrr226/Forum/Token/Token.go create mode 100644 Rrrrr226/Forum/createAnswer/createAnswer.go create mode 100644 Rrrrr226/Forum/createQuestion/createQuestion.go create mode 100644 Rrrrr226/Forum/getQuestion/getQuestion.go create mode 100644 Rrrrr226/Forum/getQuestions/getQuestions.go create mode 100644 Rrrrr226/Forum/main.go create mode 100644 Rrrrr226/Forum/updateQuestion/updateQuestion.go create mode 100644 Rrrrr226/README.md create mode 100644 Rrrrr226/dockerfile/image create mode 100644 Rrrrr226/dockerfile/net.go create mode 100644 Rrrrr226/go.mod create mode 100644 Rrrrr226/go.sum diff --git a/Rrrrr226/Account_System/forum/answer/answer.go b/Rrrrr226/Account_System/forum/answer/answer.go new file mode 100644 index 0000000..1c3ccb6 --- /dev/null +++ b/Rrrrr226/Account_System/forum/answer/answer.go @@ -0,0 +1 @@ +package answer diff --git a/Rrrrr226/Account_System/forum/create/create.go b/Rrrrr226/Account_System/forum/create/create.go new file mode 100644 index 0000000..85b848f --- /dev/null +++ b/Rrrrr226/Account_System/forum/create/create.go @@ -0,0 +1,36 @@ +package create + +import ( + "github.com/gin-gonic/gin" + "goexample/Account_System/forum/initial" + "net/http" +) + +func Create(c *gin.Context) { + if c.Request.Method != "POST" { + c.AbortWithStatusJSON(http.StatusMethodNotAllowed, gin.H{"error": "Method not allowed"}) + return + } + //Bind方法解析表单数据到结构体 + var newQuestion initial.Question + if err := c.Bind(&newQuestion.QuestionInfo); err != nil { + c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid request body"}) + return + } + + newQuestion.QuestionInfo.Content = c.PostForm("question") + if newQuestion.QuestionInfo.Content == "" { + c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Question is required"}) + return + } + + newQuestion.QuestionInfo.UserName = c.PostForm("username") + + result := initial.Dbq.Create(&newQuestion) + if result.Error != nil { + c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": result.Error.Error()}) + return + } + + c.JSON(http.StatusOK, gin.H{"message": "Your Question successfully created"}) +} diff --git a/Rrrrr226/Account_System/forum/distribute/distribute.go b/Rrrrr226/Account_System/forum/distribute/distribute.go new file mode 100644 index 0000000..52dc8a9 --- /dev/null +++ b/Rrrrr226/Account_System/forum/distribute/distribute.go @@ -0,0 +1,58 @@ +package distribute + +import ( + "fmt" + "github.com/gin-gonic/gin" + "goexample/Account_System/forum/initial" + "goexample/Account_System/forum/readall" +) + +/*func Tosql() *gorm.DB { + db, err := gorm.Open("mysql", "root:123456789@tcp(127.0.0.1:3306)/dbquestion?charset=utf8&parseTime=True&loc=Local") + if err != nil { + panic(err) + } + return db +}*/ + +func Finduser(Username string) (*initial.QuestionInfo, error) { + db := initial.Dbq + var user initial.QuestionInfo + err := db.Where("username=?", Username).First(&user).Error + if err != nil { + return nil, err + } + if user.UserName != "" { + return &user, nil + } + return nil, fmt.Errorf("user not found") +} + +func FindQuestion(Username string) *initial.Question { + db := initial.Dbq + var question initial.Question + db.Where("username=?", Username).First(&question) + return &question +} + +func Distribute(c *gin.Context) { + username := c.Param("username") + if user, _ := Finduser(username); user != nil { + readall.GetAllQuestions() + + c.JSON(200, gin.H{ + "user": "found", + "username": username, + "question": readall.GetAllQuestions(), + }) + + c.JSON(200, gin.H{ + "question": FindQuestion(username), + }) + + return + } + + c.JSON(200, gin.H{"message": "User not found:" + username}) + +} diff --git a/Rrrrr226/Account_System/forum/initial/initial.go b/Rrrrr226/Account_System/forum/initial/initial.go new file mode 100644 index 0000000..e186559 --- /dev/null +++ b/Rrrrr226/Account_System/forum/initial/initial.go @@ -0,0 +1,34 @@ +package initial + +import ( + _ "github.com/go-sql-driver/mysql" + "github.com/jinzhu/gorm" +) + +var Dbq *gorm.DB + +type Question struct { + gorm.Model + QuestionInfo QuestionInfo + AnswerInfo AnswerInfo +} + +type QuestionInfo struct { + Content string + UserName string +} + +type AnswerInfo struct { + Content string + UserName string +} + +func Initial() error { + var err error + Dbq, err = gorm.Open("mysql", "root:123456789@tcp(127.0.0.1:3306)/dbquestion?charset=utf8&parseTime=True&loc=Local") + if err != nil { + return err + } + Dbq.AutoMigrate(&Question{}) + return nil +} diff --git a/Rrrrr226/Account_System/forum/login/login.go b/Rrrrr226/Account_System/forum/login/login.go new file mode 100644 index 0000000..1104ea8 --- /dev/null +++ b/Rrrrr226/Account_System/forum/login/login.go @@ -0,0 +1,103 @@ +package login + +import ( + "fmt" + "github.com/gin-gonic/gin" + "github.com/jinzhu/gorm" + _ "github.com/jinzhu/gorm/dialects/mysql" + "net/http" +) + +type User struct { + gorm.Model + Username string + Password string +} + +var db *gorm.DB + +/*func InitDB() { + var err error + db, err = gorm.Open("mysql", "user:password@tcp(127.0.0.1:24306)/main_db?charset=utf8&parseTime=True&loc=Local") + if err != nil { + panic(err) + } + db.AutoMigrate(&User{}) + /*u0 := User{Username: "Admin", Password: "hdu123"} + result := db.Create(&u0) + if result.Error != nil { + fmt.Println(result.Error) + } else { + fmt.Printf("User created with ID: %v\n", u0.ID) + } +}*/ + +// 检查是否匹配 +func findUser(Username string) *User { + var user User + db.Where("username=?", Username).First(&user) + if user.Username != "" { + return &user + } + return nil +} + +func authenticate(Username, Password string) bool { + user := findUser(Username) + return user != nil && user.Password == Password +} + +func LoginHandler(c *gin.Context) { + if c.Request.Method != "POST" { + c.AbortWithStatusJSON(http.StatusMethodNotAllowed, gin.H{"error": "Method not allowed"}) + return + } + username := c.PostForm("Username") + password := c.PostForm("Password") + if username == "" || password == "" { + c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Username or password is empty"}) + return + } + if authenticate(username, password) { + //http.Redirect(w, r, "/forum/:username", http.StatusFound) + _, _ = fmt.Println("Welcome to forum!") + //c.Redirect(http.StatusFound, "/forum/"+username) + } else { + c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid username or password"}) + } +} + +/*func sayHello(w http.ResponseWriter, r *http.Request) { + b, err := ioutil.ReadFile("./Hello.txt") + if err != nil { + //成功 + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + fmt.Fprintln(w, string(b)) +}*/ + +func Registerhandler(c *gin.Context) { + if c.Request.Method != "POST" { + c.AbortWithStatusJSON(http.StatusMethodNotAllowed, gin.H{"error": "Method not allowed"}) + return + } + username := c.PostForm("Username") + password := c.PostForm("Password") + if username == "" || password == "" { + c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Username or password is empty"}) + return + } + if findUser(username) != nil { + c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Username already exists"}) + return + } + + newuser := User{Username: username, Password: password} + result := db.Create(&newuser) + if result.Error != nil { + c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": result.Error.Error()}) + return + } + c.JSON(http.StatusOK, gin.H{"message": "User registered successfully", "username": newuser.Username}) +} diff --git a/Rrrrr226/Account_System/forum/readall/readall.go b/Rrrrr226/Account_System/forum/readall/readall.go new file mode 100644 index 0000000..22b8633 --- /dev/null +++ b/Rrrrr226/Account_System/forum/readall/readall.go @@ -0,0 +1,37 @@ +package readall + +import ( + "github.com/gin-gonic/gin" + "goexample/Account_System/forum/initial" +) + +/*func ReadAll() { +//initial.Init() + + + +ReadAll() func(c *gin.Context) { + id := c.Param("id") + + var questions []initial.Question + if err := initial.Dbq.Find(&questions).Error;err!=nil{ + c.JSON(500,gin.H{"error":err.Error()}) + return + } + c.JSON(200,questions) +}*/ + +func GetAllQuestions() gin.HandlerFunc { + /*db, err := gorm.Open("mysql", "root:123456789@tcp(127.0.0.1:3306)/dbquestion?charset=utf8&parseTime=True&loc=Local") + if err != nil { + panic(err) + }*/ + return func(c *gin.Context) { + var questions []initial.Question + if err := initial.Dbq.Find(&questions).Error; err != nil { + c.JSON(500, gin.H{"error": err.Error()}) + return + } + c.JSON(200, questions) + } +} diff --git a/Rrrrr226/Forum/AI/AI.go b/Rrrrr226/Forum/AI/AI.go new file mode 100644 index 0000000..074d69f --- /dev/null +++ b/Rrrrr226/Forum/AI/AI.go @@ -0,0 +1,30 @@ +package AI + +import ( + "github.com/gin-gonic/gin" + _ "github.com/go-sql-driver/mysql" + "goexample/Forum/InitDB" + "goexample/Forum/Models" + "net/http" +) + +// 假设的AI API响应结构 +type AIResponse struct { + Content string `json:"answer"` +} + +var aiAPIURL = "https://yiyan.baidu.com/" // 替换为你的AI API URL + +func Aiimport(c *gin.Context) { + id := c.Param("id") + result := InitDB.Db.Where("id=?", id).Find(&Models.Question{}) + if result.Error != nil { + if result.RecordNotFound() { + c.JSON(http.StatusNotFound, gin.H{"error": "no questions found with this question_id"}) + } else { + c.JSON(http.StatusInternalServerError, gin.H{"error": "database error"}) + } + return + } + +} diff --git a/Rrrrr226/Forum/InitDB/InitDB.go b/Rrrrr226/Forum/InitDB/InitDB.go new file mode 100644 index 0000000..83c198d --- /dev/null +++ b/Rrrrr226/Forum/InitDB/InitDB.go @@ -0,0 +1,20 @@ +package InitDB + +import ( + _ "github.com/go-sql-driver/mysql" + "github.com/jinzhu/gorm" + "goexample/Forum/Models" + "log" +) + +var Db *gorm.DB + +func InitDB() error { + var err error + Db, err = gorm.Open("mysql", "root:123456789@tcp(127.0.0.1:3306)/dbquestion?charset=utf8&parseTime=True&loc=Local") + if err != nil { + log.Fatal(err) + } + Db.AutoMigrate(&Models.Question{}, &Models.UserLogin{}) + return nil +} diff --git a/Rrrrr226/Forum/Login/Login.go b/Rrrrr226/Forum/Login/Login.go new file mode 100644 index 0000000..fd1ca2d --- /dev/null +++ b/Rrrrr226/Forum/Login/Login.go @@ -0,0 +1,37 @@ +package Login + +import ( + "github.com/gin-gonic/gin" + "goexample/Forum/InitDB" + "goexample/Forum/Models" + "goexample/Forum/Token" + "net/http" +) + +func LoginHandler(c *gin.Context) { + if c.Request.Method != "POST" { + c.JSON(http.StatusMethodNotAllowed, gin.H{"error": "Method not allowed"}) + return + } + + var login Models.UserLogin + if err := c.ShouldBindJSON(&login); err != nil { + c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) + return + } + + var user Models.UserLogin + result := InitDB.Db.Where("username = ? AND password = ?", login.Username, login.Password).First(&user) + if result.Error != nil { + c.JSON(http.StatusUnauthorized, gin.H{"error": "unauthorized"}) + return + } + + token, err := Token.GenerateToken(user.ID, user.Username) + if err != nil { + c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to generate token"}) + return + } + + c.JSON(http.StatusOK, gin.H{"status": "success", "token": token}) +} diff --git a/Rrrrr226/Forum/Middleware/Middleware.go b/Rrrrr226/Forum/Middleware/Middleware.go new file mode 100644 index 0000000..10b6395 --- /dev/null +++ b/Rrrrr226/Forum/Middleware/Middleware.go @@ -0,0 +1,34 @@ +package Middleware + +import ( + "fmt" + "github.com/gin-gonic/gin" + "goexample/Forum/Token" + "net/http" + "strings" +) + +func AuthMiddleware() gin.HandlerFunc { + return func(c *gin.Context) { + token := c.GetHeader("Authorization") + if token == "" { + c.JSON(http.StatusUnauthorized, gin.H{"error": "Authorization token is missing"}) + c.Abort() + return + } + token = strings.Split(token, " ")[1] + + claims, err := Token.ParseToken(token) + if err != nil { + c.JSON(http.StatusUnauthorized, gin.H{"error": "invalid or expired token"}) + c.Abort() + return + } + userIDStr := claims.Id + fmt.Println("User ID from token:", userIDStr) + + // 设置用户 ID 到上下文中,以便后续中间件或处理器使用 + c.Set("userId", userIDStr) + c.Next() + } +} diff --git a/Rrrrr226/Forum/Models/Models.go b/Rrrrr226/Forum/Models/Models.go new file mode 100644 index 0000000..d5998d5 --- /dev/null +++ b/Rrrrr226/Forum/Models/Models.go @@ -0,0 +1,25 @@ +package Models + +import ( + "time" +) + +type Question struct { + ID uint `gorm:"primaryKey;AUTO_INCREMENT"` + UserID uint `gorm:"not null"` + Content string `gorm:"not null"` + Flag bool `gorm:"not null"` // false代表为Question,true代表为Answer + QuestionID uint `gorm:"default:NULL"` + CreatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP"` + UpdatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP"` +} + +type UserLogin struct { + ID uint `gorm:"primaryKey;AUTO_INCREMENT"` + Username string `gorm:"unique;not null"` + Password string `gorm:"size:255;not null"` + Telephone string `gorm:"not null"` + Email string `gorm:"not null"` + CreatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP"` + UpdatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP"` +} diff --git a/Rrrrr226/Forum/Register/Register.go b/Rrrrr226/Forum/Register/Register.go new file mode 100644 index 0000000..6057256 --- /dev/null +++ b/Rrrrr226/Forum/Register/Register.go @@ -0,0 +1,32 @@ +package Register + +import ( + "github.com/gin-gonic/gin" + "goexample/Forum/InitDB" + "goexample/Forum/Models" + "log" + "net/http" +) + +func Registerhandler(c *gin.Context) { + if c.Request.Method != "POST" { + c.AbortWithStatusJSON(http.StatusMethodNotAllowed, gin.H{"error": "Method not allowed"}) + return + } + + var newUser Models.UserLogin + if err := c.ShouldBindJSON(&newUser); err != nil { + c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) + return + } + + result := InitDB.Db.Create(&newUser) + if result.Error != nil { + log.Printf("Error creating user: %v", result.Error) + c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to register user"}) + return + } + + c.JSON(http.StatusOK, gin.H{"status": "success", "user_id": newUser.ID}) + +} diff --git a/Rrrrr226/Forum/Token/Token.go b/Rrrrr226/Forum/Token/Token.go new file mode 100644 index 0000000..e50087a --- /dev/null +++ b/Rrrrr226/Forum/Token/Token.go @@ -0,0 +1,59 @@ +package Token + +import ( + "errors" + "fmt" + "github.com/golang-jwt/jwt" + "strconv" + "time" +) + +var jwtKey = []byte("") + +// GenerateToken 新建JWT令牌 +func GenerateToken(userID uint, username string) (string, error) { + claims := jwt.StandardClaims{ + ExpiresAt: time.Now().Add(24 * time.Hour).Unix(), // 令牌过期时间 + Id: strconv.Itoa(int(userID)), //转为字符串并设置为Id + Subject: username, //设置用户名 + } + + token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) //使用jwt.NewWithClaims方法,结合签名方法jwt.SigningMethodHS256和声明信息 + signedToken, err := token.SignedString(jwtKey) + if err != nil { + return "", err + } + return signedToken, nil //调用token.SignedString(jwtKey)方法,利用之前定义的密钥对令牌进行签名,并返回签名后的字符串 +} + +// ParseToken 解析JWT令牌 +func ParseToken(tokenString string) (*jwt.StandardClaims, error) { + //接收待解析的JWT令牌字符串 + token, err := jwt.ParseWithClaims(tokenString, &jwt.StandardClaims{}, func(token *jwt.Token) (interface{}, error) { + // 验证令牌的签名方法是否为预期的HS256 + if alg := token.Method.Alg(); alg != jwt.SigningMethodHS256.Alg() { + return nil, fmt.Errorf("unexpected signing method: %v", alg) + } + //调用jwt.Parse方法,尝试解析传入的令牌字符串 + //第二个参数是一个回调函数,用于验证令牌的签名。在此函数中,我们返回之前定义的jwtKey作为验证密钥 + return jwtKey, nil //jwt.Parse方法返回一个*jwt.Token类型的值和一个error。如果解析成功且签名有效,error将为nil + }) + if err != nil { + // 如果解析或签名验证失败,返回错误 + return nil, err + } + + // 检查令牌是否有效 + if !token.Valid { + return nil, errors.New("invalid token: token is not valid") + } + + // 使用类型断言检查token.Claims是否为*jwt.StandardClaims类型 + claims, ok := token.Claims.(*jwt.StandardClaims) + if !ok { + // 如果类型断言失败,返回错误 + return nil, fmt.Errorf("claims verification failed") + } + + return claims, nil +} diff --git a/Rrrrr226/Forum/createAnswer/createAnswer.go b/Rrrrr226/Forum/createAnswer/createAnswer.go new file mode 100644 index 0000000..8d636c7 --- /dev/null +++ b/Rrrrr226/Forum/createAnswer/createAnswer.go @@ -0,0 +1,51 @@ +package createAnswer + +import ( + "github.com/gin-gonic/gin" + "goexample/Forum/InitDB" + "goexample/Forum/Models" + "net/http" + "strconv" +) + +func CreateAnswer(c *gin.Context) { + userIDInterface, exist := c.Get("userId") + if !exist { + c.JSON(http.StatusUnauthorized, gin.H{"error": "user not authenticated"}) + return + } + userIDStr, ok := userIDInterface.(string) + if !ok { + c.JSON(http.StatusInternalServerError, gin.H{"error": "internal server error: user ID type assertion failed"}) + } + + userID, err := strconv.Atoi(userIDStr) + if err != nil { + c.JSON(http.StatusBadRequest, gin.H{"error": "invalid user_id"}) + return + } + + var answer Models.Question + if err := c.ShouldBindJSON(&answer); err != nil { + c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) + return + } + + questionIDStr := c.Param("id") + questionID, err := strconv.Atoi(questionIDStr) + if err != nil { + c.JSON(http.StatusBadRequest, gin.H{"error": "invalid question_id"}) + return + } + + answer.UserID = uint(userID) + answer.QuestionID = uint(questionID) + answer.Flag = true // Assume Flag true for answers + result := InitDB.Db.Create(&answer) + if result.Error != nil { + c.JSON(http.StatusInternalServerError, gin.H{"error": result.Error.Error()}) + return + } + + c.JSON(http.StatusOK, gin.H{"status": "success", "answer": answer}) +} diff --git a/Rrrrr226/Forum/createQuestion/createQuestion.go b/Rrrrr226/Forum/createQuestion/createQuestion.go new file mode 100644 index 0000000..64ef1cb --- /dev/null +++ b/Rrrrr226/Forum/createQuestion/createQuestion.go @@ -0,0 +1,50 @@ +package createQuestion + +import ( + "errors" + "github.com/gin-gonic/gin" + "github.com/jinzhu/gorm" + "goexample/Forum/InitDB" + "goexample/Forum/Models" + "log" + "net/http" + "strconv" +) + +func CreateQuestion(c *gin.Context) { + userIDInterface, exists := c.Get("userId") + if !exists { + c.JSON(http.StatusUnauthorized, gin.H{"error": "user not authenticated"}) + return + } + userIDStr, ok := userIDInterface.(string) + if !ok { + c.JSON(http.StatusInternalServerError, gin.H{"error": "internal server error: user ID type assertion failed"}) + } + + userID, err := strconv.Atoi(userIDStr) + if err != nil { + c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) + } + + var question Models.Question + if err := c.ShouldBindJSON(&question); err != nil { + c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) + return + } + + question.UserID = uint(userID) + result := InitDB.Db.Create(&question) + if result.Error != nil { + log.Printf("Database create error: %v", result.Error) + // 检查是否有记录找不到的错误 + if errors.Is(result.Error, gorm.ErrRecordNotFound) { + c.JSON(http.StatusNotFound, gin.H{"error": "user not found"}) + } else { + c.JSON(http.StatusInternalServerError, gin.H{"error": result.Error.Error()}) + } + return + } + + c.JSON(http.StatusOK, gin.H{"status": "success", "question": question}) +} diff --git a/Rrrrr226/Forum/getQuestion/getQuestion.go b/Rrrrr226/Forum/getQuestion/getQuestion.go new file mode 100644 index 0000000..b28b1cf --- /dev/null +++ b/Rrrrr226/Forum/getQuestion/getQuestion.go @@ -0,0 +1,31 @@ +package getQuestion + +import ( + "github.com/gin-gonic/gin" + _ "github.com/go-sql-driver/mysql" + "goexample/Forum/InitDB" + "goexample/Forum/Models" + "net/http" + "strconv" +) + +func GetQuestion(c *gin.Context) { + questionIDStr := c.Param("id") + questionID, err := strconv.Atoi(questionIDStr) + if err != nil { + c.JSON(http.StatusBadRequest, gin.H{"error": "invalid question_id"}) + return + } + + var questions []Models.Question + result := InitDB.Db.Where("question_id = ?", questionID).Find(&questions) + if result.Error != nil { + if result.RecordNotFound() { + c.JSON(http.StatusNotFound, gin.H{"error": "no questions found with this question_id"}) + } else { + c.JSON(http.StatusInternalServerError, gin.H{"error": "database error"}) + } + return + } + c.JSON(http.StatusOK, gin.H{"status": "success", "question": questions}) +} diff --git a/Rrrrr226/Forum/getQuestions/getQuestions.go b/Rrrrr226/Forum/getQuestions/getQuestions.go new file mode 100644 index 0000000..ee206e1 --- /dev/null +++ b/Rrrrr226/Forum/getQuestions/getQuestions.go @@ -0,0 +1,19 @@ +package getQuestions + +import ( + "github.com/gin-gonic/gin" + "goexample/Forum/InitDB" + "goexample/Forum/Models" + "net/http" +) + +func GetQuestions(c *gin.Context) { + var questions []Models.Question + result := InitDB.Db.Find(&questions) + if result.Error != nil { + c.JSON(http.StatusInternalServerError, gin.H{"error": result.Error.Error()}) + return + } + + c.JSON(http.StatusOK, gin.H{"status": "success", "questions": questions}) +} diff --git a/Rrrrr226/Forum/main.go b/Rrrrr226/Forum/main.go new file mode 100644 index 0000000..9c61fba --- /dev/null +++ b/Rrrrr226/Forum/main.go @@ -0,0 +1,39 @@ +package main + +import ( + "github.com/gin-gonic/gin" + _ "github.com/go-sql-driver/mysql" + "goexample/Forum/InitDB" + "goexample/Forum/Login" + "goexample/Forum/Middleware" + "goexample/Forum/Register" + "goexample/Forum/createAnswer" + "goexample/Forum/createQuestion" + "goexample/Forum/getQuestion" + "goexample/Forum/getQuestions" + "goexample/Forum/updateQuestion" + "log" +) + +func main() { + err := InitDB.InitDB() + if err != nil { + log.Fatal("Failed to initialize database", err) + return + } + r := gin.Default() + + r.POST("/login", Login.LoginHandler) // 登录账号 + r.POST("/register", Register.Registerhandler) // 注册账号 + r.POST("/questions", Middleware.AuthMiddleware(), createQuestion.CreateQuestion) // 提问 + r.POST("/questions/:id/answers", Middleware.AuthMiddleware(), createAnswer.CreateAnswer) // 回答id问题 + //r.POST("/questions/:id/ai", Middleware.AuthMiddleware(), AI.Aiimport) + r.PUT("/questions/:id", Middleware.AuthMiddleware(), updateQuestion.UpdateQuestion) // 更新id问题 + r.GET("/questions", getQuestions.GetQuestions) // 显示所有问题 + r.GET("/questions/:id", getQuestion.GetQuestion) // 显示一个id的问题回答 + + err = r.Run(":6666") + if err != nil { + log.Fatalf("Failed to start server : %v", err) + } +} diff --git a/Rrrrr226/Forum/updateQuestion/updateQuestion.go b/Rrrrr226/Forum/updateQuestion/updateQuestion.go new file mode 100644 index 0000000..716ef93 --- /dev/null +++ b/Rrrrr226/Forum/updateQuestion/updateQuestion.go @@ -0,0 +1,43 @@ +package updateQuestion + +import ( + "github.com/gin-gonic/gin" + "goexample/Forum/InitDB" + "goexample/Forum/Models" + "log" + "net/http" + "strconv" +) + +func UpdateQuestion(c *gin.Context) { + userIDInterface, exist := c.Get("userId") + if !exist { + c.JSON(http.StatusUnauthorized, gin.H{"error": "user not authenticated"}) + return + } + userIDStr, ok := userIDInterface.(string) + if !ok { + c.JSON(http.StatusInternalServerError, gin.H{"error": "internal server error: user ID type assertion failed"}) + } + userID, err := strconv.Atoi(userIDStr) + if err != nil { + c.JSON(http.StatusBadRequest, gin.H{"error": "invalid user_id"}) + return + } + + var question Models.Question + if err := c.ShouldBindJSON(&question); err != nil { + c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) + return + } + + questionIDStr := c.Param("id") + result := InitDB.Db.Model(&question).Where("id=? AND user_id=?", questionIDStr, userID).Updates(&question) + if result.Error != nil { + log.Println(result.Error) + c.JSON(http.StatusInternalServerError, gin.H{"error": result.Error.Error()}) + return + } + + c.JSON(http.StatusOK, gin.H{"status": "success"}) +} diff --git a/Rrrrr226/README.md b/Rrrrr226/README.md new file mode 100644 index 0000000000000000000000000000000000000000..eea7be54a0aa01065f05980725b43cad941dcae6 GIT binary patch literal 16 TcmezWPnki1!4M328Mqh#CoBT% literal 0 HcmV?d00001 diff --git a/Rrrrr226/dockerfile/image b/Rrrrr226/dockerfile/image new file mode 100644 index 0000000..f23659e --- /dev/null +++ b/Rrrrr226/dockerfile/image @@ -0,0 +1,29 @@ +FROM golang:alpine + +# 设置必要的环境变量 +ENV GO111MODULE=on \ + GOPROXY=https://goproxy.cn,direct \ + CGO_ENABLED=0 \ + GOOS=linux \ + GOARCH=amd64 + +# 移动到工作目录:/build (工作目录都是指容器内部的路径,和宿主机隔离) +WORKDIR /build + +# 将代码复制到容器中 +COPY . . + +# 将代码编译成二进制可执行文件app +RUN go build -o app . + +# 移动到用于存放生成的二进制文件的 /dist 目录 +WORKDIR /dist + +# 将二进制文件从 /build 目录复制到这里 +RUN cp /build/app . + +# 声明服务端口 +EXPOSE 8888 + +# 启动容器时运行的命令 +CMD ["/dist/app"] diff --git a/Rrrrr226/dockerfile/net.go b/Rrrrr226/dockerfile/net.go new file mode 100644 index 0000000..4235118 --- /dev/null +++ b/Rrrrr226/dockerfile/net.go @@ -0,0 +1,35 @@ +package main + +import ( + "fmt" + "github.com/gin-gonic/gin" +) + +/*func main() { + http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + w.Write([]byte("Hello,Golang")) + }) + err := http.ListenAndServe(":8888", nil) + if err != nil { + panic(err) + return + } + fmt.Println("Succeed!") +}*/ + +func main() { + router := gin.Default() + + router.GET("/hello", func(c *gin.Context) { + c.JSON(200, gin.H{ + "1": "welcome", + }) + c.String(200, "hello world") + }) + + fmt.Println(router.Run(":8888")) + err := router.Run(":8888") + if err != nil { + fmt.Println(err) + } +} diff --git a/Rrrrr226/go.mod b/Rrrrr226/go.mod new file mode 100644 index 0000000..8f2596c --- /dev/null +++ b/Rrrrr226/go.mod @@ -0,0 +1,42 @@ +module goexample + +go 1.23.1 + +require ( + github.com/gin-gonic/gin v1.10.0 + github.com/go-sql-driver/mysql v1.8.1 + github.com/golang-jwt/jwt v3.2.2+incompatible + github.com/jinzhu/gorm v1.9.16 +) + +require ( + filippo.io/edwards25519 v1.1.0 // indirect + github.com/bytedance/sonic v1.12.3 // indirect + github.com/bytedance/sonic/loader v0.2.0 // indirect + github.com/cloudwego/base64x v0.1.4 // indirect + github.com/cloudwego/iasm v0.2.0 // indirect + github.com/gabriel-vasile/mimetype v1.4.5 // indirect + github.com/gin-contrib/sse v0.1.0 // indirect + github.com/go-playground/locales v0.14.1 // indirect + github.com/go-playground/universal-translator v0.18.1 // indirect + github.com/go-playground/validator/v10 v10.22.1 // indirect + github.com/goccy/go-json v0.10.3 // indirect + github.com/jinzhu/inflection v1.0.0 // indirect + github.com/jinzhu/now v1.1.5 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/klauspost/cpuid/v2 v2.2.8 // indirect + github.com/leodido/go-urn v1.4.0 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/pelletier/go-toml/v2 v2.2.3 // indirect + github.com/twitchyliquid64/golang-asm v0.15.1 // indirect + github.com/ugorji/go/codec v1.2.12 // indirect + golang.org/x/arch v0.10.0 // indirect + golang.org/x/crypto v0.27.0 // indirect + golang.org/x/net v0.29.0 // indirect + golang.org/x/sys v0.25.0 // indirect + golang.org/x/text v0.18.0 // indirect + google.golang.org/protobuf v1.34.2 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/Rrrrr226/go.sum b/Rrrrr226/go.sum new file mode 100644 index 0000000..00d0e23 --- /dev/null +++ b/Rrrrr226/go.sum @@ -0,0 +1,123 @@ +filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= +filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= +github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc= +github.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y= +github.com/bytedance/sonic v1.12.3 h1:W2MGa7RCU1QTeYRTPE3+88mVC0yXmsRQRChiyVocVjU= +github.com/bytedance/sonic v1.12.3/go.mod h1:B8Gt/XvtZ3Fqj+iSKMypzymZxw/FVwgIGKzMzT9r/rk= +github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= +github.com/bytedance/sonic/loader v0.2.0 h1:zNprn+lsIP06C/IqCHs3gPQIvnvpKbbxyXQP1iU4kWM= +github.com/bytedance/sonic/loader v0.2.0/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= +github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y= +github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= +github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg= +github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/denisenkom/go-mssqldb v0.0.0-20191124224453-732737034ffd h1:83Wprp6ROGeiHFAP8WJdI2RoxALQYgdllERc3N5N2DM= +github.com/denisenkom/go-mssqldb v0.0.0-20191124224453-732737034ffd/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= +github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5 h1:Yzb9+7DPaBjB8zlTR87/ElzFsnQfuHnVUVqpZZIcV5Y= +github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0= +github.com/gabriel-vasile/mimetype v1.4.5 h1:J7wGKdGu33ocBOhGy0z653k/lFKLFDPJMG8Gql0kxn4= +github.com/gabriel-vasile/mimetype v1.4.5/go.mod h1:ibHel+/kbxn9x2407k1izTA1S81ku1z/DlgOW2QE0M4= +github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= +github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU= +github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y= +github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= +github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= +github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= +github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= +github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= +github.com/go-playground/validator/v10 v10.22.1 h1:40JcKH+bBNGFczGuoBYgX4I6m/i27HYW8P9FDk5PbgA= +github.com/go-playground/validator/v10 v10.22.1/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= +github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= +github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y= +github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= +github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA= +github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= +github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= +github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= +github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY= +github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= +github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/jinzhu/gorm v1.9.16 h1:+IyIjPEABKRpsu/F8OvDPy9fyQlgsg2luMV2ZIH5i5o= +github.com/jinzhu/gorm v1.9.16/go.mod h1:G3LB3wezTOWM2ITLzPxEXgSkOXAntiLHS7UdBefADcs= +github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= +github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= +github.com/jinzhu/now v1.0.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= +github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= +github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM= +github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= +github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= +github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= +github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= +github.com/lib/pq v1.1.1 h1:sJZmqHoEaY7f+NPP8pgLB/WxulyR3fewgCM2qaSlBb4= +github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-sqlite3 v1.14.0 h1:mLyGNKR8+Vv9CAU7PphKa2hkEqxxhn8i32J6FPj1/QA= +github.com/mattn/go-sqlite3 v1.14.0/go.mod h1:JIl7NbARA7phWnGvh0LKTyg7S9BA+6gx71ShQilpsus= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M= +github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= +github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= +github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= +github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= +golang.org/x/arch v0.10.0 h1:S3huipmSclq3PJMNe76NGwkBR504WFkQ5dhzWzP8ZW8= +golang.org/x/arch v0.10.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= +golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= +golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= +golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= +golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= +golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=