开发前的准备
需要集成markdown编辑器
下载地址
需求分析
1.能够实现用户的注册与登录
2.能够编写并保存博客
3.能够对保存的博客进行展示
项目截图
代码
main.go
package mainimport "blog/router"func main() {router.Start()
}
controller.go
package controllerimport ("blog/dao""blog/model""fmt""github.com/gin-gonic/gin"
)func Register(c *gin.Context) {username := c.PostForm("username")password := c.PostForm("password")user := model.User{Username: username,Password: password,}dao.Mgr.Register(&user)c.Redirect(301, "/")
}func Index(c *gin.Context) {c.HTML(200, "index.html", nil)
}func GoRegister(c *gin.Context) {c.HTML(200, "register.html", nil)
}func Login(c *gin.Context) {username := c.PostForm("username")password := c.PostForm("password")fmt.Println(username)u := dao.Mgr.Login(username)if u.Username == "" {c.HTML(200, "login.html", "用户名不存在")} else {if u.Password != password {c.HTML(200, "login.html", "密码错误")} else {c.Redirect(301, "/")}}
}func GoLogin(c *gin.Context) {c.HTML(200, "login.html", nil)
}//操作博客//博客列表
func GetPostIndex(c *gin.Context) {posts := dao.Mgr.GetAllPost()c.HTML(200, "postIndex.html", posts)
}
func AddPost(c *gin.Context) {title := c.PostForm("title")tag := c.PostForm("tag")content := c.PostForm("content")post := model.Post{Title: title,Tag: tag,Content: content,}dao.Mgr.AddPost(&post)c.Redirect(302, "/post_index")
}//跳转到添加博客
func GoAddPost(c *gin.Context) {c.HTML(200, "post.html", nil)
}
dao.go
package daoimport ("blog/model""fmt"_ "github.com/go-sql-driver/mysql""github.com/jmoiron/sqlx""log"
)type Manager interface {Register(user *model.User)Login(username string) model.UserAddPost(post *model.Post)GetAllPost() []model.PostgetPost(topic string) []model.Post
}type manager struct {db *sqlx.DB
}var (Mgr Manager
)func init() {dsn := "root:******@tcp(127.0.0.1:3306)/blog_db"conn, err := sqlx.Open("mysql", dsn)if err != nil {log.Fatal("open database failed,err:", err)return}Mgr = &manager{db: conn,}
}func (m *manager) Register(user *model.User) {sqlStr := "insert into user(Username,Password) values(?,?)"_, err := m.db.Exec(sqlStr, user.Username, user.Password)if err != nil {fmt.Println("add user failed,err:", err)return}
}func (m *manager) Login(username string) model.User {var user []model.Usererr := m.db.Select(&user, "select Username,Password from user where username=?", username)if err != nil {fmt.Println("query username failed,err:", err)}return user[0]
}func (m *manager) AddPost(post *model.Post) {_, err := m.db.Exec("insert into blog(Title,Content,Tag) values (?,?,?)", post.Title, post.Content, post.Tag)if err != nil {fmt.Println("insert into blog failed,err:", err)return}
}func (m *manager) GetAllPost() []model.Post {var posts = make([]model.Post, 10)m.db.Select(&posts, "select * from blog")return posts
}func (m *manager) getPost(title string) []model.Post {var posts []model.Postm.db.Select(&posts, "select * from blog where Topic = ?", title)return posts
}
model.go
package modeltype User struct {Username string `db:"Username"`Password string `db:"Password"`
}
type Post struct {Title string `db:"Title"`Content string `db:"Content"`Tag string `db:"Tag"`
}
header.html
{{define "header"}}
<header class="p-3 bg-dark text-white"><div class="container"><div class="d-flex flex-wrap align-items-center justify-content-center justify-content-lg-start"><a class="navbar-brand" href="#">zyj的博客</a><a href="/" class="d-flex align-items-center mb-2 mb-lg-0 text-white text-decoration-none"><svg class="bi me-2" width="40" height="32" role="img" aria-label="Bootstrap"><use xlink:href="#bootstrap"></use></svg></a><ul class="nav col-12 col-lg-auto me-lg-auto mb-2 justify-content-center mb-md-0"><li><a href="/" class="nav-link px-2 text-secondary">首页</a></li><li><a href="/post" class="nav-link px-2 text-white">博客</a></li></ul><div class="text-end"><a type="button" href="/login" class="btn btn-outline-light me-2">登录</a><a type="button" href="/register" class="btn btn-warning">注册</a></div></div></div>
</header>{{end}}
index.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1.0"><link rel="stylesheet" href="/assets/css/bootstrap.min.css"><link rel="stylesheet" href="/assets/editor/css/editormd.min.css"><script src="/assets/js/bootstrap.min.js"></script><title>Title</title>
</head>
<body><div class="container">{{template "header"}}<div id="test-editor"><textarea style="display:none;">### 关于 Editor.md</textarea></div><script src="https://cdn.bootcss.com/jquery/1.11.3/jquery.min.js"></script><script src="/assets/editor/editormd.min.js"></script><script type="text/javascript">$(function() {var editor = editormd("test-editor", {width : "100%",height : "640",path : "assets/editor/lib/"});});</script></div>
</body>
</html>
post.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width",initial-scale="1.0"><link rel="stylesheet" href="/assets/css/bootstrap.min.css"><link rel="stylesheet" href="/assets/editor/css/editormd.css"><script src="/assets/js/bootstrap.min.js"></script><title>添加博客</title>
</head>
<body><div class="container">{{template "header"}}<form action="/post" method="post"><div class="row"><div class="col-md-8"><div id="test-editor"><textarea style="display: none;" name="context"></textarea></div></div><div class="col-md-4 mt-3"><label for="title" class="form-label">请输入标题</label><input type="text" name="title" class="form-control" id="title"><br><label for="tag" class="form-label">请输入标签</label><input type="text" name="tag" class="form-control" id="tag"><br><button for="submit" class="btn btn-primary">添加</button></div></div></form></div><script src="https://cdn.bootcss.com/jquery/1.11.3/jquery.min.js"></script>
<script src="/assets/editor/editormd.min.js"></script>
<script type="text/javascript">$(function() {var editor = editormd("test-editor", {width : "100%",height : "640",path : "assets/editor/lib/"});});
</script></body>
</html>
postIndex.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><link rel="stylesheet" href="/assets/css/bootstrap.min.css"><title>博客列表</title>
</head>
<body>
<div class="container">{{template "header"}}<div class="row mt-3">{{range $post:=. -}}<div class="col-md-6"><div class="row g-0 border rounded overflow-hidden flex-md-row mb-4 shadow-sm h-md-250 position-relative"><div class="col p-4 d-flex flex-column position-static"><strong class="d-inline-block mb-2 text-primary">分类</strong><h3 class="mb-0">{{$post.Title}}</h3><div class="mb-1 text-muted">Nov 12</div><p class="card-text mb-auto">{{$post.Content}}</p><a href="#" class="stretched-link">...</a></div><div class="col-auto d-none d-lg-block"><svg class="bd-placeholder-img" width="200" height="250" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="Placeholder: Thumbnail" preserveAspectRatio="xMidYMid slice" focusable="false"><title>Placeholder</title><rect width="100%" height="100%" fill="#55595c"></rect><text x="50%" y="50%" fill="#eceeef" dy=".3em">博客封面</text></svg></div></div></div>{{- end}}</div></div></body>
</html>
register.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1.0"><link rel="stylesheet" href="/assets/css/bootstrap.min.css"><script src="/assets/js/bootstrap.min.js"></script><title>注册</title>
</head>
<body>
<div class="container">{{template "header"}}<form method="post" action="/register"><div class="mb-3"><label for="exampleInputEmail1" class="form-label">用户名称</label><input type="text" name="username" class="form-control" id="exampleInputEmail1" aria-describedby="emailHelp"></div><div class="mb-3"><label for="exampleInputPassword1" class="form-label">用户密码</label><input type="password" name="password" class="form-control" id="exampleInputPassword1"></div><div class="mb-3"><label for="exampleInputPassword2" class="form-label">确认密码</label><input type="password" name="password2" class="form-control" id="exampleInputPassword2"></div><button type="submit" class="btn btn-primary">注册</button></form></div>
</body>
</html>