[ADD]用户登陆

This commit is contained in:
viletyy 2019-06-27 11:24:43 +08:00
parent 47726bea75
commit 2907760207
13 changed files with 416 additions and 10 deletions

View File

@ -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()
}

38
controllers/user.go Normal file
View File

@ -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
View File

@ -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"
}

View File

@ -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 {

View File

@ -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
}

View File

@ -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{})
}

88
static/js/sysn.js Normal file
View File

@ -0,0 +1,88 @@
/**
@Namelayui.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);
});

14
syserrors/errors.go Normal file
View File

@ -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
}

22
syserrors/unknow.go Normal file
View File

@ -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
}

83
views/login.html Normal file
View File

@ -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>

61
views/reg.html Normal file
View File

@ -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>