[ADD]用户登陆
This commit is contained in:
parent
47726bea75
commit
2907760207
|
@ -1,25 +1,101 @@
|
|||
package controllers
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"github.com/astaxie/beego"
|
||||
"log"
|
||||
"liteblog/models"
|
||||
)
|
||||
|
||||
const SESSION_USER_KEY = "SESSION_USER_KEY"
|
||||
|
||||
type NestPreparer interface {
|
||||
NestPrepare()
|
||||
}
|
||||
|
||||
type BaseController struct {
|
||||
beego.Controller
|
||||
IsLogin bool // 标识 用户是否登陆
|
||||
User models.User // 登陆的用户
|
||||
}
|
||||
|
||||
func (ctx *BaseController) Prepare() {
|
||||
log.Println("BaseController")
|
||||
// 判断子类是否实现了NestPreparer接口,如果实现了就调用接口方法。
|
||||
// 将页面路径保存到path变量中
|
||||
ctx.Data["Path"] = ctx.Ctx.Request.RequestURI
|
||||
ctx.Data["Username"] = "xxxx"
|
||||
// 记录登陆的状态
|
||||
ctx.IsLogin = false
|
||||
tu := ctx.GetSession(SESSION_USER_KEY)
|
||||
if tu != nil {
|
||||
if u, ok := tu.(models.User); ok {
|
||||
ctx.User = u
|
||||
ctx.Data["User"] = u
|
||||
ctx.IsLogin = true
|
||||
}
|
||||
}
|
||||
ctx.Data["IsLogin"] = ctx.IsLogin
|
||||
|
||||
if app, ok := ctx.AppController.(NestPreparer); ok {
|
||||
app.NestPrepare()
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
//func (ctx *BaseController) MustLogin() {
|
||||
// if !ctx.IsLogin {
|
||||
// ctx.Abort500(syserrors.NoUserError{})
|
||||
// }
|
||||
//}
|
||||
|
||||
func (ctx *BaseController) GetMustString(key string, msg string) string {
|
||||
KeyString := ctx.GetString(key, "")
|
||||
if len(KeyString) == 0 {
|
||||
ctx.Abort500(errors.New(msg))
|
||||
}
|
||||
return KeyString
|
||||
}
|
||||
|
||||
func (ctx *BaseController) Abort500(err error) {
|
||||
ctx.Data["Error"] = err
|
||||
ctx.Abort("500")
|
||||
}
|
||||
|
||||
type H map[string]interface{}
|
||||
|
||||
type ResultJsonValue struct {
|
||||
Code int `json:"code"`
|
||||
Msg string `json:"msg"`
|
||||
Action string `json:"action,omitempty"`
|
||||
Count int `json:"count,omitempty"`
|
||||
Data interface{} `json:"data,omitempty"`
|
||||
}
|
||||
|
||||
func (ctx *BaseController) JSONOk(msg string, actions ...string) {
|
||||
var action string
|
||||
if len(actions) > 0 {
|
||||
action = actions[0]
|
||||
}
|
||||
ctx.Data["json"] = &ResultJsonValue{
|
||||
Code: 0,
|
||||
Msg: msg,
|
||||
Action: action,
|
||||
}
|
||||
ctx.ServeJSON()
|
||||
}
|
||||
|
||||
func (ctx *BaseController) JSONOkH(msg string, maps H) {
|
||||
if maps == nil {
|
||||
maps = H{}
|
||||
}
|
||||
maps["code"] = 0
|
||||
maps["msg"] = msg
|
||||
ctx.Data["json"] = maps
|
||||
ctx.ServeJSON()
|
||||
}
|
||||
|
||||
func (ctx *BaseController) JSONOkData(count int, data interface{}) {
|
||||
ctx.Data["json"] = &ResultJsonValue{
|
||||
Code: 0,
|
||||
Count: count,
|
||||
Msg: "成功!",
|
||||
Data: data,
|
||||
}
|
||||
ctx.ServeJSON()
|
||||
}
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
package controllers
|
||||
|
||||
import (
|
||||
"liteblog/models"
|
||||
"liteblog/syserrors"
|
||||
"log"
|
||||
)
|
||||
|
||||
type UserController struct {
|
||||
BaseController
|
||||
}
|
||||
|
||||
// 登陆页面
|
||||
// @router /login [get]
|
||||
func (c *UserController) Login() {
|
||||
c.TplName = "login.html"
|
||||
}
|
||||
|
||||
// @router /signin [post]
|
||||
func (c *UserController) SignIn() {
|
||||
log.Print("======")
|
||||
// 判断邮箱不能为空
|
||||
email := c.GetMustString("email", "邮箱不能为空")
|
||||
// 判断密码不能为空
|
||||
password := c.GetMustString("password", "密码不能为空")
|
||||
|
||||
var (
|
||||
user models.User
|
||||
err error
|
||||
)
|
||||
|
||||
if user, err = models.QueryUserByEmailAndPassword(email, password); err != nil {
|
||||
c.Abort500(syserrors.NewError("邮箱或密码不对", err))
|
||||
}
|
||||
// 将user保存到session
|
||||
c.SetSession(SESSION_USER_KEY, user)
|
||||
c.JSONOk("登陆成功", "/")
|
||||
}
|
Binary file not shown.
Binary file not shown.
13
main.go
13
main.go
|
@ -1,7 +1,9 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"encoding/gob"
|
||||
"github.com/astaxie/beego"
|
||||
"liteblog/models"
|
||||
_ "liteblog/routers"
|
||||
_ "liteblog/models"
|
||||
"strings"
|
||||
|
@ -9,6 +11,7 @@ import (
|
|||
|
||||
func main() {
|
||||
initTemplate()
|
||||
initSession()
|
||||
beego.Run()
|
||||
}
|
||||
|
||||
|
@ -20,5 +23,15 @@ func initTemplate() {
|
|||
})
|
||||
}
|
||||
|
||||
func initSession() {
|
||||
// beego的session序列号是用gob的方式,因此需要将注册models.User
|
||||
gob.Register(models.User{})
|
||||
// https://beego.me/docs/mvc/controller/session.md
|
||||
beego.BConfig.WebConfig.Session.SessionOn = true
|
||||
beego.BConfig.WebConfig.Session.SessionName = "liteblog-key"
|
||||
beego.BConfig.WebConfig.Session.SessionProvider = "file"
|
||||
beego.BConfig.WebConfig.Session.SessionProviderConfig = "data/session"
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -9,8 +9,9 @@ import (
|
|||
_ "github.com/jinzhu/gorm/dialects/mysql"
|
||||
)
|
||||
|
||||
func init() {
|
||||
db := initDbConnect()
|
||||
var db = initDbConnect()
|
||||
|
||||
func init() {
|
||||
//SetMaxOpenConns用于设置最大打开的连接数
|
||||
//SetMaxIdleConns用于设置闲置的连接数
|
||||
db.DB().SetMaxIdleConns(10)
|
||||
|
@ -39,6 +40,7 @@ func init() {
|
|||
Role: 0,
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func initDbConnect() *gorm.DB {
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package models
|
||||
|
||||
import "github.com/jinzhu/gorm"
|
||||
import (
|
||||
"github.com/jinzhu/gorm"
|
||||
)
|
||||
|
||||
type User struct {
|
||||
gorm.Model
|
||||
|
@ -9,4 +11,9 @@ type User struct {
|
|||
Avatar string
|
||||
Pwd string
|
||||
Role int `gorm:"default:1"` // 0 管理员 1正常用户
|
||||
}
|
||||
}
|
||||
|
||||
func QueryUserByEmailAndPassword(email, password string) (user User, err error) {
|
||||
e := db.Model(&User{}).First(&user, "email = ? and pwd = ?", email, password).Error
|
||||
return user, e
|
||||
}
|
||||
|
|
|
@ -8,5 +8,7 @@ import (
|
|||
func init() {
|
||||
//beego.Router("/", &controllers.IndexController{})
|
||||
beego.ErrorController(&controllers.ErrorController{})
|
||||
beego.Include(&controllers.IndexController{})
|
||||
beego.Include(
|
||||
&controllers.IndexController{},
|
||||
&controllers.UserController{})
|
||||
}
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
/**
|
||||
@Name:layui.sysn
|
||||
*/
|
||||
layui.define(['jquery', 'layer'], function (exports) {
|
||||
var $ = layui.jquery,
|
||||
layer = layui.layer,
|
||||
ajaxObj = {},
|
||||
sysn = {};
|
||||
|
||||
function ajax(url, type, timeout, data, success, error, complete) {
|
||||
var error2 = function (ret) {
|
||||
var msg = ret.responseText || ret.msg||ret;
|
||||
if (ret.status != undefined && ret.status == 0) {
|
||||
msg = "网络异常";
|
||||
}
|
||||
if (!error) {
|
||||
sysn.sayError(msg);
|
||||
} else {
|
||||
error(msg)
|
||||
}
|
||||
};
|
||||
$.ajax({
|
||||
url: url,
|
||||
type: type,
|
||||
timeout: timeout || 5000,
|
||||
data: data,
|
||||
success: function (ret) {
|
||||
if (ret.code == 0) {
|
||||
success(ret)
|
||||
} else {
|
||||
error2(ret)
|
||||
}
|
||||
},
|
||||
error: error2,
|
||||
complete: complete
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
sysn.get = function (url, data) {
|
||||
ajaxObj.url = url;
|
||||
ajaxObj.data = data;
|
||||
ajaxObj.method = "GET";
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
sysn.post = function (url, data) {
|
||||
ajaxObj.url = url;
|
||||
ajaxObj.data = data;
|
||||
ajaxObj.method = "POST";
|
||||
return this;
|
||||
};
|
||||
|
||||
sysn.success = function (success) {
|
||||
ajaxObj.success = success;
|
||||
return this;
|
||||
};
|
||||
|
||||
sysn.error = function (error) {
|
||||
ajaxObj.error = error;
|
||||
return this;
|
||||
};
|
||||
|
||||
sysn.complete = function (complete) {
|
||||
ajaxObj.complete = complete;
|
||||
return this;
|
||||
};
|
||||
|
||||
sysn.run = function () {
|
||||
ajax(ajaxObj.url, ajaxObj.method, ajaxObj.timeout, ajaxObj.data, ajaxObj.success, ajaxObj.error, ajaxObj.complete);
|
||||
};
|
||||
|
||||
sysn.sayOk = function (msg) {
|
||||
layer.msg(msg, {icon: 6});
|
||||
};
|
||||
sysn.sayError = function (msg) {
|
||||
layer.msg(msg, {icon: 5})
|
||||
};
|
||||
|
||||
sysn.setTimeout = function (timeout) {
|
||||
ajaxObj.timeout = timeout;
|
||||
return this;
|
||||
};
|
||||
|
||||
//输出test接口
|
||||
exports('sysn', sysn);
|
||||
});
|
|
@ -0,0 +1,14 @@
|
|||
package syserrors
|
||||
|
||||
type Error interface {
|
||||
Error() string
|
||||
Code() int
|
||||
ReasonError() error
|
||||
}
|
||||
|
||||
func NewError(msg string, err2 error) UnKnowError {
|
||||
err := UnKnowError{}
|
||||
err.msg = msg
|
||||
err.reason = err2
|
||||
return err
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package syserrors
|
||||
|
||||
type UnKnowError struct {
|
||||
msg string
|
||||
reason error
|
||||
}
|
||||
|
||||
func (err UnKnowError) Error() string {
|
||||
if len(err.msg) == 0 {
|
||||
return "未知错误"
|
||||
} else {
|
||||
return err.msg
|
||||
}
|
||||
}
|
||||
|
||||
func (err UnKnowError) Code() int {
|
||||
return 1000
|
||||
}
|
||||
|
||||
func (err UnKnowError) ReasonError() error {
|
||||
return err.reason
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>关于-闲言轻博客</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
{{ template "shares/link.html". }}
|
||||
<style>
|
||||
.layui-form-label {
|
||||
width: 50px;
|
||||
}
|
||||
.layui-input-block {
|
||||
margin-left: 80px;
|
||||
}
|
||||
@media screen and (max-width: 450px) {
|
||||
.layui-form-item .layui-input-inline {
|
||||
margin: 0 0 10px 80px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="lay-blog">
|
||||
{{ template "shares/header.html". }}
|
||||
<div class="container-wrap">
|
||||
<div class="container container-message container-details container-about">
|
||||
<div class="contar-wrap">
|
||||
<div class="item">
|
||||
<div class="item-box">
|
||||
<form class="layui-form" action="">
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">邮箱</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="text" name="email" required lay-verify="required"
|
||||
placeholder="请输入邮箱" autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">密码</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="password" name="password" required lay-verify="required"
|
||||
placeholder="请输入密码"
|
||||
autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-input-block">
|
||||
<button class="layui-btn" lay-submit lay-filter="login">登陆</button>
|
||||
<a href="/reg" class="layui-btn layui-btn-primary">注册用户</a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{ template "shares/footer.html". }}
|
||||
<script>
|
||||
layui.use(['form', 'jquery', 'layer', 'sysn'], function () {
|
||||
var form = layui.form,
|
||||
sysn = layui.sysn,
|
||||
$ = layui.jquery,
|
||||
layer = layui.layer;
|
||||
//监听提交
|
||||
form.on('submit(login)', function (formData) {
|
||||
sysn.post("/signin", formData.field)
|
||||
// .setTimeout(5000)
|
||||
.success(function (data) {
|
||||
layer.msg(data.msg);
|
||||
if (data.action) {
|
||||
setTimeout(function () {
|
||||
window.location.href = data.action;
|
||||
}, 300)
|
||||
}
|
||||
}).run();
|
||||
return false;
|
||||
});
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,61 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>关于-闲言轻博客</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
{{ template "shares/link.html". }}
|
||||
</head>
|
||||
<body class="lay-blog">
|
||||
{{ template "shares/header.html". }}
|
||||
<div class="container-wrap">
|
||||
<div class="container container-message container-details container-about">
|
||||
<div class="contar-wrap">
|
||||
<div class="item">
|
||||
<div class="item-box">
|
||||
<form class="layui-form" action="">
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">昵称</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="text" name="name" required lay-verify="required"
|
||||
placeholder="请输入用户名" autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">邮箱</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="text" name="email" required lay-verify="required"
|
||||
placeholder="请输入邮箱" autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">密码</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="password" name="password" required lay-verify="required"
|
||||
placeholder="请输入密码"
|
||||
autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">确认密码</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="password2" name="password2" required lay-verify="required"
|
||||
placeholder="请输入密码"
|
||||
autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-input-block">
|
||||
<button class="layui-btn" lay-submit lay-filter="reg">注册</button>
|
||||
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{ template "shares/footer.html". }}
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue