Go語言學習教程:管理員登入功能開發

qfDavie發表於2019-04-04

學習完了資料庫操作的知識以後。本節內容,我們將實現管理員登陸功能,涉及到多個模組的程式碼實現和邏輯處理,以及資料庫表的操作,都將在本節內容中進行實現。

管理員結構體定義

首先我們要定義管理員這個實體的結構體,我們定義為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": "管理員登入成功",}複製程式碼

本節內容,我們開發完成了管理員登陸功能的開發,下節課將繼續進行管理員模組的其他功能的開發。


相關文章