項目結構:
項目結構如下:
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()
}