diff --git a/SOLECA794/go.mod b/SOLECA794/go.mod new file mode 100644 index 0000000..2451df2 --- /dev/null +++ b/SOLECA794/go.mod @@ -0,0 +1,41 @@ +module awesomeProject + +go 1.23.1 + +require ( + github.com/gin-gonic/gin v1.10.0 + gorm.io/driver/mysql v1.5.7 + gorm.io/gorm v1.25.12 +) + +require ( + github.com/bytedance/sonic v1.11.6 // indirect + github.com/bytedance/sonic/loader v0.1.1 // indirect + github.com/cloudwego/base64x v0.1.4 // indirect + github.com/cloudwego/iasm v0.2.0 // indirect + github.com/gabriel-vasile/mimetype v1.4.3 // 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.20.0 // indirect + github.com/go-sql-driver/mysql v1.7.0 // indirect + github.com/goccy/go-json v0.10.2 // 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.7 // 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.2 // indirect + github.com/twitchyliquid64/golang-asm v0.15.1 // indirect + github.com/ugorji/go/codec v1.2.12 // indirect + golang.org/x/arch v0.8.0 // indirect + golang.org/x/crypto v0.23.0 // indirect + golang.org/x/net v0.25.0 // indirect + golang.org/x/sys v0.20.0 // indirect + golang.org/x/text v0.15.0 // indirect + google.golang.org/protobuf v1.34.1 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/SOLECA794/main.go b/SOLECA794/main.go new file mode 100644 index 0000000..27d7a7b --- /dev/null +++ b/SOLECA794/main.go @@ -0,0 +1,450 @@ +package main + +import ( + "fmt" + "github.com/gin-gonic/gin" + "gorm.io/driver/mysql" + "gorm.io/gorm" + "io" + "net/http" + "strconv" + "time" +) + +type User struct { + ID int + Name string + Pass string + Email string + Identy int +} +type Question struct { + ID int + Content string + From string + Time time.Time +} +type Answer struct { + ID int + Content string + From string + Quesid int + Agree int +} + +var UserNow User + +func IsLog(c *gin.Context) { + if UserNow.Name == "" { + c.Redirect(http.StatusFound, "/") + c.Abort() + } else { + c.Next() + } +} +func main() { + r := gin.Default() + + dsn := "root:794ASMIN@soleca@tcp(127.0.0.1:3306)/my_database?charset=utf8mb4&parseTime=True&loc=Local" + db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{}) + if err != nil { + panic("connecting filed !!!") + } + db.AutoMigrate(&User{}, &Question{}, &Answer{}) + + r.LoadHTMLGlob("templates/*") + r.GET("/", func(c *gin.Context) { + UserNow.Name = "" + c.HTML(http.StatusOK, "index.tmpl", nil) + }) + r.POST("/login", func(c *gin.Context) { + username := c.PostForm("username") + password := c.PostForm("password") + var userLog User + err := db.Where("name = ? ", username).First(&userLog).Error + if err == gorm.ErrRecordNotFound { + c.HTML(http.StatusOK, "index.tmpl", gin.H{ + "message": "登录失败!你还没有注册", + "message2": "没有用户?现在注册一个▼ ▼ ▼", + "v": 0, + }) + + } else { + if password != userLog.Pass { + c.HTML(http.StatusOK, "index.tmpl", gin.H{ + "message": "您输入的密码不正确", + "v": 1, + }) + + } else { + UserNow = userLog + c.Redirect(http.StatusFound, "/home") + } + } + }) + r.GET("/signup", func(c *gin.Context) { + c.HTML(http.StatusOK, "signup.tmpl", gin.H{}) + }) + r.POST("/signup", func(c *gin.Context) { + username := c.PostForm("username") + password := c.PostForm("password") + email := c.PostForm("email") + submission := c.PostForm("submission") + var userSign User + er := db.Where("email = ? ", email).First(&userSign).Error + err := db.Where("name = ? ", username).First(&userSign).Error + if err == gorm.ErrRecordNotFound && er == gorm.ErrRecordNotFound { + if submission == "123321" { + userSign = User{Name: username, Pass: password, Email: email, Identy: 0} + db.Create(&userSign) + //c.SetCookie("message", "管理员注册成功!", 3600, "/", "localhost", false, true) + c.Redirect(http.StatusFound, "/") + } else { + userSign = User{Name: username, Pass: password, Email: email, Identy: 1} + db.Create(&userSign) + + c.Redirect(http.StatusFound, "/") + } + } else { + var text string + if er != gorm.ErrRecordNotFound { + text = "该邮箱已经注册过了,请更换其他邮箱" + c.HTML(http.StatusOK, "signup.tmpl", gin.H{ + "text": text, + }) + } else { + text = "用户名已被使用,请更换其他用户名" + c.HTML(http.StatusOK, "signup.tmpl", gin.H{ + "text": text, + }) + } + + } + }) + r.GET("/reset", IsLog, func(c *gin.Context) { + c.HTML(http.StatusOK, "reset.tmpl", nil) + + }) + r.POST("/reset", IsLog, func(c *gin.Context) { + pass := c.PostForm("pass") + email := c.PostForm("email") + if UserNow.Email != email { + c.HTML(http.StatusOK, "reset.tmpl", gin.H{ + "message": "邮箱错误!", + }) + } else { + UserNow.Pass = pass + db.Save(&UserNow) + c.HTML(http.StatusOK, "reset.tmpl", gin.H{ + "message": "修改成功!", + }) + } + }) + + //---------------------------------------------------------------------------- + + r.GET("/home", IsLog, func(c *gin.Context) { + if UserNow.Name == "" { + c.Redirect(http.StatusFound, "/") + } + v := UserNow.Identy + var questions []Question + db.Find(&questions) + //if err != nil { + // fmt.Println("this") + // c.JSON(http.StatusBadRequest, gin.H{"error": "NO QUESTIONS"}) + //} + c.HTML(http.StatusOK, "home.tmpl", gin.H{ + "Name": UserNow.Name, + "V": v, + "K": 1, + "questions": questions, + "User": UserNow.Name, + }) + }) + home := r.Group("/home") + { + home.POST("/new", IsLog, func(c *gin.Context) { + new1 := c.PostForm("new") + var NewQuestion Question = Question{Content: new1, From: UserNow.Name, Time: time.Now()} + err := db.Create(&NewQuestion).Error + if err != nil { + c.JSON(http.StatusBadRequest, gin.H{"error": "failed"}) + } + c.Redirect(http.StatusFound, "/home/all") + }) + home.GET("/manage", IsLog, func(c *gin.Context) { + if UserNow.Identy == 0 { + + v := UserNow.Identy + var questionss []Question + err := db.Find(&questionss).Error + if err != nil { + fmt.Println("this") + c.JSON(http.StatusBadRequest, gin.H{"error": "NO QUESTIONS"}) + } + c.HTML(http.StatusOK, "home.tmpl", gin.H{ + "Name": UserNow.Name, + "V": v, + "K": 0, + "questions": questionss, + }) + } + }) + home.GET("/manage/users", IsLog, func(c *gin.Context) { + if UserNow.Identy == 0 { + var users []User + err := db.Find(&users).Error + if err != nil { + fmt.Println("this") + c.JSON(http.StatusBadRequest, gin.H{"error": "NO USERS"}) + } + c.HTML(http.StatusOK, "users.tmpl", gin.H{ + "User": users, + }) + } + }) + home.POST("/search", IsLog, func(c *gin.Context) { + username := c.PostForm("username") + var Q []Question + err := db.Where("`from` = ? ", username).Find(&Q).Error + if err == gorm.ErrRecordNotFound { + c.JSON(http.StatusBadRequest, gin.H{"error": "NOT FOUND"}) + } + c.HTML(http.StatusOK, "search.tmpl", gin.H{ + "Name": username, + "Q": Q, + "U": UserNow.Name, + "I": UserNow.Identy, + }) + + }) + home.GET("/all", IsLog, func(c *gin.Context) { + v := UserNow.Identy + var questions []Question + err := db.Find(&questions).Error + if err != nil { + c.JSON(http.StatusBadRequest, gin.H{"error": "NO QUESTIONS"}) + } + c.HTML(http.StatusOK, "home.tmpl", gin.H{ + "Name": UserNow.Name, + "V": v, + "K": 1, + "questions": questions, + "User": UserNow.Name, + }) + }) + home.GET("/my", IsLog, func(c *gin.Context) { + var questions []Question + db.Where("`from` = ?", UserNow.Name).Find(&questions) + //if err != nil { + // c.JSON(http.StatusBadRequest, gin.H{"error": "NO QUESTIONS"}) + //} + c.HTML(http.StatusOK, "showmy.tmpl", gin.H{ + "questions": questions, + }) + + }) + home.POST("/:id/answer", IsLog, func(c *gin.Context) { + QuesId := c.Param("id") + Id, _ := strconv.Atoi(QuesId) + answer := c.PostForm("answer") + + var ans Answer = Answer{Content: answer, From: UserNow.Name, Quesid: Id, Agree: 0} + db.Create(&ans) + + c.Redirect(http.StatusFound, "/home/all") + }) + home.GET("/:id/answer", IsLog, func(c *gin.Context) { + QuesId := c.Param("id") + var ans []Answer + db.Where(" quesid = ?", QuesId).Find(&ans) + var question Question + db.Where(" id = ?", QuesId).First(&question) + fro := question.From + content := question.Content + tim := question.Time + c.HTML(http.StatusOK, "showanswer.tmpl", gin.H{ + "Content": content, + "Fro": fro, + "Ans": ans, + "Time": tim, + "User": UserNow.Name, + "Identy": UserNow.Identy, + }) + }) + home.GET("/:id/put", IsLog, func(c *gin.Context) { + QuesId := c.Param("id") + + var question Question + db.Where(" id = ?", QuesId).First(&question) + + c.HTML(http.StatusOK, "change.tmpl", gin.H{ + "Content": question.Content, + "Fro": question.From, + "Time": question.Time, + "ID": question.ID, + }) + }) + home.POST("/:id/put", IsLog, func(c *gin.Context) { + QuesId := c.Param("id") + change := c.PostForm("change") + var question Question + db.Where(" id = ?", QuesId).First(&question) + if change != "" { + question.Content = change + } + db.Save(&question) + c.HTML(http.StatusOK, "change.tmpl", gin.H{ + "Content": question.Content, + "Fro": question.From, + "Time": question.Time, + "ID": question.ID, + "Response": "修改成功!", + }) + }) + home.DELETE("/question/delete", IsLog, func(c *gin.Context) { + body, _ := io.ReadAll(c.Request.Body) + // 将字符串转换为数值 + receive, _ := strconv.Atoi(string(body)) + db.Where("id = ?", receive).Delete(&Question{}) + }) + home.DELETE("/answer/delete", IsLog, func(c *gin.Context) { + body, _ := io.ReadAll(c.Request.Body) + // 将字符串转换为数值 + receive, _ := strconv.Atoi(string(body)) + db.Where("id = ?", receive).Delete(&Answer{}) + }) + home.DELETE("/user/delete", IsLog, func(c *gin.Context) { + body, _ := io.ReadAll(c.Request.Body) + // 将字符串转换为数值 + receive, _ := strconv.Atoi(string(body)) + db.Where("id = ?", receive).Delete(&User{}) + }) + home.POST("/answer/agree", IsLog, func(c *gin.Context) { + body, _ := io.ReadAll(c.Request.Body) + receive, _ := strconv.Atoi(string(body)) + var answer Answer + db.Where("id = ?", receive).First(&answer) + answer.Agree = answer.Agree + 1 + db.Save(&answer) + id := strconv.Itoa(answer.Quesid) + id = "/home/" + id + "/answer" + c.Redirect(http.StatusFound, id) + + }) + } + r.Run(":8080") +} + +/* + +c.Request.URL.Path="/b" +r.HandleContext(c) + + + + +//cookie重定向 +c.SetCookie("message", "注册成功!", 3600, "/", "", false, true) +c.Redirect(http.StatusFound, "/") +router.GET("/", func(c *gin.Context) { + // 获取 cookie 中的消息 + message, err := c.Cookie("message") + if err != nil { + message = "" + } + + c.HTML(http.StatusOK, "hello.tmpl", gin.H{ + "message1": message, + }) + }) + + + + +package controllers + +import ( + "net/http" + "github.com/gin-gonic/gin" + "gorm.io/gorm" + "myapp/models" + "golang.org/x/crypto/bcrypt" +) + +var db *gorm.DB + +func init() { + var err error + db, err = gorm.Open(sqlite.Open("test.db"), &gorm.Config{}) + if err != nil { + panic("failed to connect database") + } +} + +func ShowLoginPage(c *gin.Context) { + c.HTML(http.StatusOK, "login.html", gin.H{ + "title": "Login", + }) +} + +func PerformLogin(c *gin.Context) { + var user models.User + username := c.PostForm("username") + password := c.PostForm("password") + + if err := db.Where("username = ?", username).First(&user).Error; err != nil { + c.HTML(http.StatusUnauthorized, "login.html", gin.H{ + "ErrorTitle": "Login Failed", + "ErrorMessage": "Invalid credentials provided", + }) + return + } + + if err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(password)); err != nil { + c.HTML(http.StatusUnauthorized, "login.html", gin.H{ + "ErrorTitle": "Login Failed", + "ErrorMessage": "Invalid credentials provided", + }) + return + } + + c.HTML(http.StatusOK, "login.html", gin.H{ + "title": "Login Successful", + }) +} + + + + + + + + + + {{ .title }} + + +

{{ .title }}

+ {{ if .ErrorTitle }} +

{{ .ErrorTitle }}

+

{{ .ErrorMessage }}

+ {{ end }} +
+ + +
+ + +
+ +
+ + + + + + + +*/ diff --git a/SOLECA794/t.txt b/SOLECA794/t.txt new file mode 100644 index 0000000..cf72489 --- /dev/null +++ b/SOLECA794/t.txt @@ -0,0 +1 @@ +哈哈哈道爷我commit了 \ No newline at end of file diff --git a/SOLECA794/templates/change.tmpl b/SOLECA794/templates/change.tmpl new file mode 100644 index 0000000..a1e0f98 --- /dev/null +++ b/SOLECA794/templates/change.tmpl @@ -0,0 +1,42 @@ + + + + + Answers + + + + +

▶ 问题: "{{ .Content }}"

+

|  Answered by :   < {{ .Fro }} >

+
| {{ .Time }}
+
+ +
+

+
+ + + +
+

{{ .Response }}

+ + diff --git a/SOLECA794/templates/home.tmpl b/SOLECA794/templates/home.tmpl new file mode 100644 index 0000000..52b3c58 --- /dev/null +++ b/SOLECA794/templates/home.tmpl @@ -0,0 +1,132 @@ + + + + + + ☺欢迎来到杭电问答平台! + + + + + +

☺ {{.Name}} ,欢迎来到杭电问答平台!

+
+ + +
+

/

+ +

+

查看问题:

+
+ +
+

  

+
+ +
+
+ +
+
+ + +
+
+
+ + +

  

+
+
+ +
+{{if .V}}
+

权限申请:

+ +{{else}}
+ 您是管理员: +
+ +
+ +
+ +
+ +{{end}} + +
+

问题列表

+{{ $u:=.User }} + + + \ No newline at end of file diff --git a/SOLECA794/templates/index.tmpl b/SOLECA794/templates/index.tmpl new file mode 100644 index 0000000..8c05b60 --- /dev/null +++ b/SOLECA794/templates/index.tmpl @@ -0,0 +1,43 @@ + + + + + + ☺这是一个问答平台 + + + +

☺杭电问答平台

+

未完待续☹

+

备忘:

+

*密码错误提醒*|*忘记密码*|*未注册提示*|*注册查重*|*重置密码*|*页面间身份核验*|

+

{{ .message }}

+
+ + +
+ + +
+ +
+
+ +

{{ .message2 }}

+ +{{$v:=.v}} +{{if $v }} +
+

忘记密码?尝试重置

+ +
+{{ end }} + +
+

No account? Try to sign up.

+ +
+ + \ No newline at end of file diff --git a/SOLECA794/templates/reset.tmpl b/SOLECA794/templates/reset.tmpl new file mode 100644 index 0000000..81c4a62 --- /dev/null +++ b/SOLECA794/templates/reset.tmpl @@ -0,0 +1,23 @@ + + + + + Reset + + +

简洁明了的重置界面( )

+{{.message}} +
+
+ + + + + + +
+
+ +
+ + \ No newline at end of file diff --git a/SOLECA794/templates/search.tmpl b/SOLECA794/templates/search.tmpl new file mode 100644 index 0000000..658d7c5 --- /dev/null +++ b/SOLECA794/templates/search.tmpl @@ -0,0 +1,55 @@ + + + + + Search + + + + +{{ $u := .U }} +{{ $i := .I }} +

▶ "{{ .Name }}"的提问

+
+ +
+
+ {{ range .Q }} +

| ▪   

“{{ .Content }}”  

+ {{ if eq 0 $i}} + + {{else}} + {{ if eq .From $u}} + +
+ +
+ {{end}} + + {{end}} + +

+ {{else}} +
  • 没有回答
  • + {{end}} + + \ No newline at end of file diff --git a/SOLECA794/templates/showanswer.tmpl b/SOLECA794/templates/showanswer.tmpl new file mode 100644 index 0000000..e34da7b --- /dev/null +++ b/SOLECA794/templates/showanswer.tmpl @@ -0,0 +1,82 @@ + + + + + Answers + + + + +

    ▶ "{{ .Content }}"

    +

    |  Answered by :   < {{ .Fro }} >

    +
    | {{ .Time }}
    +
    + +
    +

    + {{ $u :=.User}} + {{ $i :=.Identy }} + {{ range .Ans }} +

    | ▪   

    <{{ .From }}> :  

    + + + {{ if eq 0 $i}} + + {{else}} + {{ if eq .From $u}} + + {{end}} + {{end}} + +

    + {{else}} +
  • 没有回答
  • + {{end}} + + diff --git a/SOLECA794/templates/showmy.tmpl b/SOLECA794/templates/showmy.tmpl new file mode 100644 index 0000000..1e72285 --- /dev/null +++ b/SOLECA794/templates/showmy.tmpl @@ -0,0 +1,57 @@ + + + + + 我的问题 + + + + +
    +

    问题列表

    + +
    + + + \ No newline at end of file diff --git a/SOLECA794/templates/signup.tmpl b/SOLECA794/templates/signup.tmpl new file mode 100644 index 0000000..d9fd1e4 --- /dev/null +++ b/SOLECA794/templates/signup.tmpl @@ -0,0 +1,43 @@ + + + + + signing up.... + + + + +

    用户注册

    +

    备注:

    +

    *用户名查重*|*邮箱作为识别标志*|*社区管理员注册*|*邮箱查重*

    +

    {{ .text }}

    +
    + + +

    (必填)

    +
    + + +

    (必填)

    +
    + 邮箱: + +

    (必填)

    +

    +

          

    + +

    + + + + +
    +

    {{ .message }}

    + + \ No newline at end of file diff --git a/SOLECA794/templates/users.tmpl b/SOLECA794/templates/users.tmpl new file mode 100644 index 0000000..59148f6 --- /dev/null +++ b/SOLECA794/templates/users.tmpl @@ -0,0 +1,39 @@ + + + + + Users + + + + +

    ! 用户管理 !

    +
    + +
    +
    + {{ range .User }} +
  • 用户: <{{.Name}}> : {{ .Email }}
  • + +
    + {{end}} + + \ No newline at end of file