學習完了資料庫操作的知識以後。本節內容,我們將實現管理員登陸功能,涉及到多個模組的程式碼實現和邏輯處理,以及資料庫表的操作,都將在本節內容中進行實現。
管理員結構體定義
首先我們要定義管理員這個實體的結構體,我們定義為Admin:
type Admin struct {
//如果field名稱為Id,而且型別為int64,並沒有定義tag,則會被xorm視為主鍵,並且擁有自增屬性
AdminId int64 `xorm:"pk autoincr" json:"id"` //主鍵 自增
AdminName string `xorm:"varchar(32)" json:"admin_name"`
CreateTime time.Time `xorm:"DateTime" json:"create_time"`
Status int64 `xorm:"default 0" json:"status"`
Avatar string `xorm:"varchar(255)" json:"avatar"`
Pwd string `xorm:"varchar(255)" json:"pwd"` //管理員密碼
CityName string `xorm:"varchar(12)" json:"city_name"` //管理員所在城市名稱
CityId int64 `xorm:"index" json:"city_id"`
City *City `xorm:"- <- ->"` //所對應的城市結構體(基礎表結構體)
}複製程式碼
在Admin結構體定義中,我們通過Tag中的xorm限定來制定各個結構體欄位的型別,使用json來限定在進行JSON資料序列化時定義的json欄位。
管理員控制器定義
我們使用mvc包模式來進行功能開發,在進行了結構體定義以後,我們接著定義控制器。控制器負責來完成我們請求的邏輯流程控制,是我們功能開發的核心樞紐。在本專案中,我們按照模組化的結構進行功能開發,本節內容中的管理員登陸就屬於管理員模組。AdminController定義如下:
type AdminController struct {
//iris框架自動為每個請求都繫結上下文物件
Ctx iris.Context
//admin功能實體
Service service.AdminService
//session物件
Session *sessions.Session
}複製程式碼
在AdminController定義中,包含iris.Context上下文處理物件,用於資料功能處理的管理員模組功能實現AdminService,還有用於session管理的物件。 定義PostLogin方法來處理使用者登陸請求,具體的路由處理解析規則我們前面已經學習過,登陸處理方法定義如下:
//介面:/admin/login
//請求:Post
func (ac *AdminController) PostLogin(context iris.Context) mvc.Result {
......
}複製程式碼
這裡只給出控制器的請求處理的方法定義,具體邏輯,我們後面會詳細講。
管理員資料提供模組定義
在我們實際的開發過程中,我們往往將資料提供服務模組設計成介面,這樣設計的目的是介面定義和具體的功能程式設計實現了分離,有助於我們在不同的實現方案之間進行切換,成本非常小,如下圖:
func NewAdminService(db *xorm.Engine) AdminService {
return &adminSevice{
engine: db,
}
}複製程式碼
當我們需要切換不同的實現時,比如由mysql切換到sqlite,我們只需要修改上述具體的adminService實現就好了,其他都不需要更改,程式碼改動非常小。 具體到本專案中,我們使用的是mysql資料庫,因此我們還需要利用運算元據庫來實現AdminService介面中定義的功能方法,在本專案中的管理員的該模組中,實現類我們定義為adminSevice,定義如下:
/**
* 管理員的服務實現結構體
*/
type adminSevice struct {
engine *xorm.Engine
}複製程式碼
通過使用者名稱和密碼查詢特定的管理員的方法實現:
func (ac *adminSevice) GetByAdminNameAndPassword(username, password string) (model.Admin, bool) {
var admin model.Admin
ac.engine.Where(" user_name = ? and pwd = ? ", username, password).Get(&admin)
return admin, admin.AdminId != 0
}複製程式碼
控制器繫結,路由處理
管理員結構體,控制器和功能邏輯實現了以後,我們需要在程式入口處做控制器繫結,指定我們定義的管理員控制器進行路由處理,具體的繫結操作如下:
//啟用session
sessManager := sessions.New(sessions.Config{
Cookie: "sessioncookie",
Expires: 24 * time.Hour,
})
engine := datasource.NewMysqlEngine()
//管理員模組功能
adminService := service.NewAdminService(engine)
admin := mvc.New(app.Party("/admin"))
admin.Register(
adminService,
sessManager.Start,
)
admin.Handle(new(controller.AdminController))複製程式碼
在上述程式碼中,我們啟用了session,然後通過mvc的Handle方法進行控制器的指定。
登入功能方法解析,資料庫查詢
在繫結好了控制器處理以後,我們就可以來實現具體的控制器登陸方法中的業務邏輯,具體的登陸邏輯主要如下:
讀取請求資料
登陸使用者資料校驗
根據使用者請求資料進行資料庫查詢
結果判斷,返回請求資料
根據上述的邏輯進行編碼實現,完整的登陸方法邏輯實現如下:
func (ac *AdminController) PostLogin(context iris.Context) mvc.Result {
var adminLogin AdminLogin
ac.Ctx.ReadJSON(&adminLogin)
//資料引數檢驗
if adminLogin.UserName == "" || adminLogin.Password == "" {
return mvc.Response{
Object: map[string]interface{}{
"status": "0",
"success": "登入失敗",
"message": "使用者名稱或密碼為空,請重新填寫後嘗試登入",
},
}
}
//根據使用者名稱、密碼到資料庫中查詢對應的管理資訊
admin, exist := ac.Service.GetByAdminNameAndPassword(adminLogin.UserName, adminLogin.Password)
//管理員不存在
if !exist {
return mvc.Response{
Object: map[string]interface{}{
"status": "0",
"success": "登入失敗",
"message": "使用者名稱或者密碼錯誤,請重新登入",
},
}
}
//管理員存在 設定session
userByte, _ := json.Marshal(admin)
ac.Session.Set(ADMIN, userByte)
return mvc.Response{
Object: map[string]interface{}{
"status": "1",
"success": "登入成功",
"message": "管理員登入成功",
},
}
}複製程式碼
需要注意的是,該請求處理方法中,除了包含業務邏輯處理以外,我們還使用了session實現了使用者狀態的儲存。
瀏覽器Post請求
所有的程式碼程式設計部分,我們已經實現。可以通過啟動專案,進行登陸請求除錯。在瀏覽器中輸入使用者名稱和密碼,即可使用開發者工具檢視,我們這裡瀏覽器傳送的Post的登陸請求,攜帶的使用者資料是json格式,如下:
{"user_name":"davie","password":"123"}複製程式碼
在真實的生產環境中,密碼和使用者敏感的資料是要經過加密或者脫敏處理的,這裡我們是案例講解,直接進行傳遞,這一點需要大家注意到與實際生產環境的區別。
登陸資料返回
在controller的PostLogin方法中已經有返回資料。登陸請求的返回資料是json格式,如果登陸成功,會有如下返回格式:
{"status":1,"success":"登入成功","message": "管理員登入成功",}複製程式碼
本節內容,我們開發完成了管理員登陸功能的開發,下節課將繼續進行管理員模組的其他功能的開發。