1.包及目录
controller-控制器 放处理函数 handler
dao 涉及数据库访问的内容
router 路由
model 生成后台数据库对应的表的结构体
assets 静态资源
templates 模板文件
2. 实现dao 集成gorm
model.go
package model
import "gorm.io/gorm"
type User struct {
gorm.Model //匿名字段 成员方法 都继承了
Username string `json:"username"`
Password string `json:"password"`
}
dao.go
package dao
import (
"blog/model"
"gorm.io/driver/mysql"
"gorm.io/gorm"
"log"
)
type Manager interface { //定义接口
AddUser(user *model.User)
}
type manager struct {
db *gorm.DB
}
var Mgr Manager //定义接口变量
func init() {
//连接数据库
dsn := "root:root@tcp(127.0.0.1:3306)/blog?charset=utf8mb4&parseTime=True&loc=Local"
//初始化操作数据库
Db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
if err != nil {
log.Fatal("Failed to init db:")
}
//实例化 接口变量
Mgr = &manager{db: Db} //第一个 db 是结构体manager里的, 第二个 Db 是上面初始化的
//创建表 默认users,结构体 user 的复数
Db.AutoMigrate(&model.User{})
}
//manager实现了AddUser方法
//增加记录
func (m *manager) AddUser(user *model.User) {
m.db.Create(user)
}
main.go
package main
import (
"blog/dao"
"blog/model"
)
func main() {
user := model.User{
Username: "张震远",
Password: "654321",
}
dao.Mgr.AddUser(&user)
}
3. 集成Bootstrap创建用户表单
https://getbootstrap.com/docs/5.2/components/navbar/
查找元素
html
<head>
<meta charset="UTF-8">
<title>Title</title>
//引入两个包
<link rel="stylesheet" href="/assets/css/bootstrap.min.css">
<script src="/assets/js/bootstrap.min.js"></script>
</head>
4. 实现控制器和路由
router.go
package router
import (
"blog/controller"
"github.com/gin-gonic/gin"
)
func Start() {
engine := gin.Default()
engine.LoadHTMLGlob("templates/*")
engine.Static("/assets", "./assets")
engine.GET("/index", controller.ListenUser)
engine.POST("/index", controller.AddUser)
engine.Run()
}
controller.go
package controller
import (
"blog/dao"
"blog/model"
"github.com/gin-gonic/gin"
)
//实现添加用户
func AddUser(c *gin.Context) {
username := c.PostForm("username")
password := c.PostForm("password")
user := model.User{
Username: username,
Password: password,
}
dao.Mgr.AddUser(&user)
}
func ListenUser(c *gin.Context) {
c.HTML(200, "index.html", nil)
}
func main() {
router.Start()
}
5. 用户注册
controller
package controller
import (
"blog/dao"
"blog/model"
"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 GoRegister(c *gin.Context) {
c.HTML(200, "register.html", nil)
}
func Index(c *gin.Context) {
c.HTML(200, "index.html", nil)
}
func ListenUser(c *gin.Context) {
c.HTML(200, "userlist.html", nil)
}
dao
package dao
import (
"blog/model"
"gorm.io/driver/mysql"
"gorm.io/gorm"
"log"
)
type Manager interface { //定义接口
Register(user *model.User)
}
type manager struct {
db *gorm.DB
}
var Mgr Manager //定义接口变量
func init() {
//连接数据库
dsn := "root:root@tcp(127.0.0.1:3306)/blog?charset=utf8mb4&parseTime=True&loc=Local"
//初始化操作数据库
Db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
if err != nil {
log.Fatal("Failed to init db:")
}
//实例化 接口变量
Mgr = &manager{db: Db} //第一个 db 是结构体manager里的, 第二个 Db 是上面初始化的
//创建表 默认users,结构体 user 的复数
Db.AutoMigrate(&model.User{})
}
//manager实现了AddUser方法
//注册
func (m *manager) Register(user *model.User) {
m.db.Create(user)
}
router
package router
import (
"blog/controller"
"github.com/gin-gonic/gin"
)
func Start() {
engine := gin.Default()
engine.LoadHTMLGlob("templates/*")
engine.Static("/assets", "./assets")
engine.GET("/register", controller.GoRegister)
engine.POST("/register", controller.Register)
engine.GET("/", controller.Index)
engine.Run()
}
register.html
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<link rel="stylesheet" href="/assets/css/bootstrap.min.css">
<script src="/assets/js/bootstrap.min.js"></script>
</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>
6. 用户登录
dao
type Manager interface { //定义接口
Login(username string) model.User
Register(user *model.User)
}
//登录
func (m *manager) Login(username string) model.User {
var user model.User
m.db.Where("username=?", username).First(&user)
return user
}
controller
func GoLogin(c *gin.Context) {
c.HTML(200, "login.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 {
fmt.Println("密码错误")
c.HTML(200, "login.html", "密码错误")
} else {
fmt.Println("登陆成功")
c.Redirect(301, "/")
}
}
router
engine.GET("/login", controller.GoLogin)
engine.POST("/login", controller.Login)
login.html
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>登录</title>
<link rel="stylesheet" href="/assets/css/bootstrap.min.css">
<script src="/assets/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container">
{{template "header"}}
<form method="post" action="/login">
<p style="background-color: red">{{.}}</p>
<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>
<button type="submit" class="btn btn-primary">登录</button>
</form>
</div>
</body>
</html>
7. 集成markdown编辑器
https://pandao.github.io/editor.md/
下载后 将包引入至项目目录下面 在html页面进行编辑应用
8. 创建博客模型和DAO
创建模型
type Post struct {
gorm.Model //匿名字段 成员方法 都继承了
Title string
Content string `gorm:"type:text"`
Tag string
}
dao
type Manager interface { //定义接口
Login(username string) model.User
Register(user *model.User)
//博客操作
AddPost(post *model.Post) //添加博客文章
GetAllPost() []model.Post //获得所有的博客文章
GetPost(pid int) model.Post //根据id 进行查询单个
}
//创建表 默认users,结构体 user 的复数
Db.AutoMigrate(&model.User{})
Db.AutoMigrate(&model.Post{})
//添加博客文章
func (mgr *manager) AddPost(post *model.Post) {
mgr.db.Create(post)
}
//获得所有的博客文章
func (mgr *manager) GetAllPost() []model.Post {
var posts = make([]model.Post, 10)
mgr.db.Find(&posts)
return posts
}
//根据id 进行查询单个
func (mgr *manager) GetPost(pid int) model.Post {
var post model.Post
mgr.db.First(&post, pid)
return post
}
9. 创建博客控制器和路由
controller
//显示博客列表
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)
}
router
//操作博客
//博客列表
engine.GET("/post_index", controller.GetPostIndex)
//添加博客
engine.POST("/post", controller.AddPost)
//跳转到添加博客页面
engine.GET("/post", controller.GoAddPost)
11. 添加博客
post.html
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="/assets/css/bootstrap.min.css">
<link rel="stylesheet" href="/assets/editormd/css/editormd.min.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-editormd">
<textarea name="content" style="display:none"></textarea>
</div>
<script src="https://cdn.bootcss.com/jquery/1.11.3/jquery.min.js"></script>
<script src="/assets/editormd/editormd.min.js"></script>
<script type="text/javascript">
$(function() {
var editor = editormd("test-editormd", {
width : "100%",
height : 450,
path : "assets/editormd/lib/"
});
});
</script>
</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 type="submit" class="btn btn-primary">添加</button>
</div>
</div>
</form>
</div>
</body>
</html>