项目结构:
项目结构如下:
beego 默认会解析当前应用下的 conf/app.conf 文件。
通过这个文件你可以初始化很多 beego 的默认参数:
1.conf
app.conf
这个目录做一些配置,项目名称、不同运行环境端口、数据库用户名、密码、端口,开启调试等
appname = myapp
httpport = 8080
runmode = dev
1.上面这些参数会替换 beego 默认的一些参数,beego默认的参数请参考链接beego系统默认参数
2.也可以在配置文件中配置应用需要用的一些配置信息,例如:
mysqluser = "root"
mysqlpass = "rootpass"
就可以通过如下的方式获取设置的配置信息:
beego.AppConfig.String("mysqluser")
beego.AppConfig.String("mysqlpass")
3.解析的时候优先解析 runmode 下的配置,然后解析默认的配置
4.INI 格式配置支持 include 方式,引用多个配置文件,例如:
appname = myapp
httpport = 8080
runmode = dev
include "app2.conf"
2.routers
router.go
package routers
import (
"github.com/astaxie/beego"
"myapp1/controllers"
)
func init() {
beego.Router("/register", &controllers.MainController{}, "get:ShowRegister;post:HandleRegister")
beego.Router("/login", &controllers.LoginController{}, "get:ShowLogin;post:HandleLogin")
beego.Router("/updatepassword", &controllers.MainController{}, "get:ShowUpdatePassword;post:HandleUpdatePassword")
}
路由包里面我们看到执行了路由注册 beego.Router
, 这个函数的功能是映射 URL 到 controller,第一个参数是 URL (用户请求的地址),如果我们注册的有"/"
,也就是我们访问的不带任何参数的 URL,第二个参数是对应的 Controller
,也就是我们即将把请求分发到那个控制器来执行相应的逻辑,例如:
beego.Router("/register", &controllers.MainController{}, "get:ShowRegister;post:HandleRegister")
这样用户就可以通过访问 /register 去执行 MainController 的逻辑。这就是我们所谓的路由
3.controllers
register.go
package controllers
import (
"github.com/astaxie/beego"
"log"
"myapp1/models"
"strings"
"time"
)
type MainController struct {
beego.Controller
}
//register展示页面
func (r *MainController) ShowRegister() {
r.TplName = "register.html"
}
//register获取数据页面
func (r *MainController) HandleRegister() {
//获取浏览器传递的值,并去除两边的空格
Name := strings.TrimSpace(r.GetString("username"))
Password := strings.TrimSpace(r.GetString("password"))
Email := strings.TrimSpace(r.GetString("email"))
//数据处理
if Name == "" || Password == "" || Email == "" {
beego.Info("用户名或密码或邮箱不能为空")
r.Data["errmsg"] = "用户名或密码或邮箱不能为空"
r.TplName = "register.html"
return
}
//判断用户邮箱是否已经注册过
_, ok := captchaMap[Email]
if ok {
beego.Info("邮箱已存在")
r.Data["errmsg"] = "邮箱已存在"
r.TplName = "register.html"
return
}
if err := models.Save(Name, Password, Email); err != nil {
log.Println("插入数据失败")
}
captcha := sendEmail(Email)
captchaMap[Email] = captcha //将验证码和对应的邮箱存入map
intCaptcha, _ := r.GetInt("captcha")
//检验验证码是否正确
if intCaptcha == captcha { //判断验证码是否正确
r.Ctx.WriteString("注册成功")
time.Sleep(1 * time.Second)
//注册成功返回登陆页面
r.Redirect("login", 302)
} else {
r.Ctx.WriteString("验证码错误")
return
}
}
login.go
package controllers
import (
"github.com/astaxie/beego"
"myapp1/models"
"strings"
"time"
)
type LoginController struct {
beego.Controller
}
//login展示页面
func (L *LoginController) ShowLogin() {
L.TplName = "login.html"
}
//login获取数据页面
func (L *LoginController) HandleLogin() {
//获取浏览器传递的值,并除去两边的空格
Name := strings.TrimSpace(L.GetString("name"))
Password := strings.TrimSpace(L.GetString("password"))
beego.Info("账号:", Name, "密码:", Password)
//数据处理
if Name == "" || Password == "" {
beego.Info("登陆失败")
L.TplName = "login.html"
L.Data["errmsg"] = "登陆失败"
return
}
var user models.Users
//判断用户名是否存在
user.Name = Name
err := models.ReadName(Name)
if err != nil {
beego.Info("用户名不存在")
L.TplName = "login.html"
L.Data["errmsg"] = "用户名不存在"
return
}
//判断密码是不是正确
if user.Password != Password {
beego.Info("密码错误")
time.Sleep(2 * time.Second)
L.TplName = "login.html"
L.Data["errmsg"] = "密码错误"
return
}
L.Ctx.WriteString("登录成功")
}
updatepassword.go
package controllers
import (
"fmt"
"github.com/astaxie/beego"
"myapp1/models"
"strconv"
"strings"
"time"
)
//改密码展示页面
func (m *MainController) ShowUpdatePassword() {
m.TplName = "updatepassword.html"
}
//改密码获取数据页面
func (m *MainController) HandleUpdatePassword() {
//获取浏览器传递的值
Name := m.GetString("name")
Password := m.GetString("password")
Email := m.GetString("email")
fmt.Println(Name, Password, Email)
//数据处理
if Name == "" || Password == "" || Email == "" {
beego.Info("用户名或密码或邮箱不能为空")
m.Data["errmsg"] = "用户名或密码或邮箱不能为空"
m.TplName = "updatepassword.html"
return
}
if models.Read(Email) != nil {
beego.Info("用户不存在")
m.TplName = "updatepassword.html"
m.Data["errmsg"] = "用户不存在"
return
}
captcha := sendEmail(Email)
captchaMap[Email] = captcha //将验证码和对应的邮箱存入map
strCaptcha := strings.TrimSpace(m.GetString("captcha"))
intCaptcha, _ := strconv.Atoi(strCaptcha)
//检验验证码是否正确
if intCaptcha == captcha { //判断验证码是否正确
err := models.Update(Password) //更新密码
if err == nil {
beego.Info("更新密码成功")
m.Ctx.WriteString("更新密码成功")
time.Sleep(1 * time.Second)
m.Redirect("login", 302) //修改密码成功返回登陆页面
} else {
beego.Info("更新密码失败")
m.TplName = "updatepassword.html"
m.Data["errmsg"] = "更新密码失败"
return
}
}
}
notification.go
package controllers
import (
"fmt"
"log"
"math/rand"
"net/smtp"
"time"
)
//定义一个map存放邮箱号和对应的验证码
var captchaMap = make(map[string]int)
//发送验证码邮件
func sendEmail(email string) int {
auth := smtp.PlainAuth("", "[email protected]", "happy1314WyJ", "smtp.163.com")
to := []string{email}
//生成随机验证码
rand.Seed(time.Now().Unix())
captcha := rand.Intn(10000)
str := fmt.Sprintf("From:[email protected]\r\nTo:,%s,\r\nSubject:verifycode\r\n\r\n,%d,\r\n", email, captcha)
msg := []byte(str)
err := smtp.SendMail("smtp.163.com:25", auth, "[email protected]", to, msg)
if err != nil {
log.Println("邮件发送失败")
}
return captcha
}
上面的代码显示首先我们声明了一个控制器 MainController
,这个控制器里面内嵌了 beego.Controller
,这就是 Go 的嵌入方式,也就是 MainController
自动拥有了所有 beego.Controller
的方法。
而 beego.Controller
拥有很多方法,其中包括 Init、Prepare、Post、Get、Delete、Head
等方法。如果浏览器的是 GET 请求,那么默认就会执行 MainController
下的 Get 方法。
controllers
里面的代码是需要执行的逻辑
我们也可以通过各种方式获取数据,然后赋值到 this.Data 中
,这是一个用来存储输出数据的 map,可以赋值任意类型的值,然后需要去渲染的模板,this.TplName
就是需要渲染的模板
4.models
model 层一般用来做数据库操作,我们会在 Model 里面处理一些数据读取
package models
import (
"github.com/astaxie/beego/orm"
_ "github.com/go-sql-driver/mysql"
)
//用户信息
type Users struct {
Name string
Email string `orm:"pk"` //设置为主键
Password string
}
func init() {
// 参数1 driverName
// 参数2 数据库类型
// 这个用来设置 driverName 对应的数据库类型
// mysql / sqlite3 / postgres 这三种是默认已经注册过的,所以可以无需设置
_ = orm.RegisterDriver("mysql", orm.DRMySQL)
//ORM 必须注册一个别名为 default 的数据库,作为默认使用。
// 参数1 数据库的别名,用来在 ORM 中切换数据库使用
// 参数2 driverName
_ = orm.RegisterDataBase("default", "mysql", "root:@tcp(localhost:3306)/test")
//将你定义的 Model 进行注册,最佳设计是有单独的 models.go 文件,在他的 init 函数中进行注册
orm.RegisterModel(new(Users))
//参数1 means table's alias name. default is "default".
//参数2 means run next sql if the current is error.
//参数3 means show all info when running command or not.
//生成表,第二个false要是改成true就会强制更新表,数据全部丢失
_ = orm.RunSyncdb("default", false, true)
}
func Read(email string) error {
o := orm.NewOrm()
//获取查询对象
var user Users
//判断邮箱是否存在
user.Email = email
err := o.Read(&user, "email") //查询
return err
}
func ReadName(name string) error {
o := orm.NewOrm()
//获取查询对象
var user Users
err := o.Read(&user, "name") //查询
return err
}
func Save(userName, password, email string) error {
o := orm.NewOrm() // NewOrm 的同时会执行 orm.BootStrap (整个 app 只执行一次),用以验证模型之间的定义并缓存
//获取插入对象
user := Users{}
//插入数值
user.Name = userName
user.Password = password
user.Email = email
_, err := o.Insert(&user)
return err
}
func Update(password string) error {
o := orm.NewOrm() // NewOrm 的同时会执行 orm.BootStrap (整个 app 只执行一次),用以验证模型之间的定义并缓存
//获取插入对象
user := Users{}
_, err := o.Update(&user, "password")
return err
}
5.views
略
6.main.go
package main
import (
"github.com/astaxie/beego"
"github.com/astaxie/beego/logs"
_ "myapp1/routers"
)
func main() {
//logger := logs.NewLogger(1000)
//logs.NewConsole()
//logger.Info("哈哈")
beego.Run()
}