#账户管理
##登录
效果图如下:
用户输入用户名和密码,点击登录系统按钮,在后台首先在cookie中获取用户登录相关信息,如果获取失败再获取用户的输入,对用户输入的数据进行校验并再数据库中查询用户,如果查询失败,再前台页面显示相应的提示信息,如果输入的用户名和密码正确,会将用户输入的数据做MD5处理,然后将处理之后的结果存入cookie中,并设置cookie的存活时间为一周。
func (self *LoginController) LoginIn() {
//判断用户id是否大于0
if self.userId > 0 {
fmt.Println("==========", beego.URLFor("HomeController.Index"), "=============")
self.redirect(beego.URLFor("HomeController.Index"))
}
beego.ReadFromRequest(&self.Controller)
//判断是否是post方式提交
if self.isPost() {
//获取用户名,并去除两边的空格
username := strings.TrimSpace(self.GetString("username"))
//获取密码并去除两边的空格
password := strings.TrimSpace(self.GetString("password"))
//如果获取到的用户名和密码都不为空
if username != "" && password != "" {
//根据用户名查询对应的管理员
user, err := models.AdminGetByName(username)
fmt.Println(user)
flash := beego.NewFlash()
errorMsg := ""
//如果查询出错或者密码不正确
if err != nil || user.Password != libs.Md5([]byte(password+user.Salt)) {
errorMsg = "帐号或密码错误"
} else if user.Status == -1 {//禁用
errorMsg = "该帐号已禁用"
} else {
//获取用户IP地址
user.LastIp = self.getClientIp()
//登录时间
user.LastLogin = time.Now().Unix()
//更新用户
user.Update()
//将用户ip和用户密码以及密码盐通过|连接
authkey := libs.Md5([]byte(self.getClientIp() + "|" + user.Password + user.Salt))
//创建名为auth的cookie
self.Ctx.SetCookie("auth", strconv.Itoa(user.Id)+"|"+authkey, 7*86400)
self.redirect(beego.URLFor("HomeController.Index"))
}
//将错误提示写入flash,键为error,值为错误提示
flash.Error(errorMsg)
flash.Store(&self.Controller)
self.redirect(beego.URLFor("LoginController.LoginIn"))
}
}
self.TplName = "login/login.html"
}
##用户身份校验
如果某个用户再知道了后台管理系统的网址,在地址栏输入该网址就可以随意访问后台管理系统,此时登录功能便形同虚设,所以鉴于安全角度,应该实现用户身份校验功能。在用户访问后台管理系统的时候,从cookie中取出相应的登录信息,然后根据该信息去数据库中查询数据,如果查询失败,说明用户并没有登录,直接重定向到登录页面,让用户重新登录,如果查询成功则允许用户继续访问,并从数据库中查询出后台管理系统的菜单。
func (self *BaseController) auth() {
//将名为auth的cooki而通过|分割
arr := strings.Split(self.Ctx.GetCookie("auth"), "|")
self.userId = 0
//fmt.Println("arr_length = ", len(arr))
//判断分割之后的结果是否是2
if len(arr) == 2 {
idstr, password := arr[0], arr[1]
//fmt.Println("idstr = ", idstr)
//fmt.Println("password = ", password)
//将id转换为整数
userId, _ := strconv.Atoi(idstr)
//判断id是否大于0
if userId > 0 {
//根据id查询管理员
user, err := models.AdminGetById(userId)
//如果查询没有出错并且从cookie中取出的password和哈希之后的结果相同
if err == nil && password == libs.Md5([]byte(self.getClientIp()+"|"+user.Password+user.Salt)) {
self.userId = user.Id
self.loginName = user.LoginName
self.userName = user.RealName
self.user = user
self.AdminAuth()
}
/*isHasAuth := strings.Contains(self.allowUrl, self.controllerName+"/"+self.actionName)
noAuth := "ajaxsave/ajaxdel/table/loginin/loginout/getnodes/start/show/ajaxapisave"
isNoAuth := strings.Contains(noAuth, self.actionName)
if isHasAuth == false && isNoAuth == false {
self.Ctx.WriteString("没有权限")
self.ajaxMsg("没有权限", MSG_ERR)
return
}*/
}
}
if self.userId == 0 && (self.controllerName != "login" && self.actionName != "loginin") {
self.redirect(beego.URLFor("LoginController.LoginIn"))
}
}
##退出登录
当用户点击退出注销按钮的时候,通过路由找到对应的控制器和方法,将cookie中的用户登录信息设置为空,最后重定向到登录页面。
#后台首页
效果图如下:
当用户登录成功后重定向到后台首页,来到首页先查询数据库,从数据库中查询出后台菜单栏信息,具体分为:权限管理,个人中心,咨询管理等模块。
func (self *BaseController) AdminAuth() {
// 左侧导航栏
//分页查询
result, _ := models.AuthGetList()
list := make([]map[string]interface{}, len(result))
list2 := make([]map[string]interface{}, len(result))
i, j := 0, 0
//遍历查询结果
for _, v := range result {
row := make(map[string]interface{})
//上级id为1且显示
/*
SideMenu1 id Icon AuthName
Pid AuthUrl AuthName Id Icon
*/
if v.Pid == 1 {
row["Id"] = int(v.Id)
row["Icon"] = v.Icon
row["AuthName"] = v.AuthName
list[i] = row
i++
}
//上级id不为1,且显示
if v.Pid != 1{
row["Pid"] = int(v.Pid)
row["AuthUrl"] = v.AuthUrl
row["AuthName"] = v.AuthName
row["Id"] = int(v.Id)
row["Icon"] = v.Icon
list2[j] = row
j++
}
}
self.Data["SideMenu1"] = list[:i] //一级菜单
self.Data["SideMenu2"] = list2[:j] //二级菜单
}
#权限管理
效果图如下:
权限管理模块实现了用户的添加,编辑,删除以及用户列表等功能。
##添加用户
效果图如下:
用户在该页面填写相应的信息,点击立即提交按钮,将添加的信息提交到后台,在后台接收用户输入的数据,并对用户输入的数据进行校验,如果用户输入的数据不合法在前台页面给与相应的提示信息,如果用户输入的数据符合要求,将新添加的用户的密码设置为默认值:george518并存入数据库。
func (self *AdminController) AjaxSave() {
Admin_id, _ := self.GetInt("id")
if Admin_id == 0 {
/*
login_name real_name phone email
*/
Admin := new(models.Admin)
Admin.LoginName = strings.TrimSpace(self.GetString("login_name"))
Admin.RealName = strings.TrimSpace(self.GetString("real_name"))
Admin.Phone = strings.TrimSpace(self.GetString("phone"))
Admin.Email = strings.TrimSpace(self.GetString("email"))
Admin.UpdateTime = time.Now().Unix()
Admin.UpdateId = self.userId
Admin.Status = 1
// 检查登录名是否已经存在
_, err := models.AdminGetByName(Admin.LoginName)
if err == nil {
self.ajaxMsg("登录名已经存在", MSG_ERR)
}
//新增
pwd, salt := libs.Password(4, "")
Admin.Password = pwd
Admin.Salt = salt
Admin.CreateTime = time.Now().Unix()
Admin.CreateId = self.userId
if _, err := models.AdminAdd(Admin); err != nil {
self.ajaxMsg(err.Error(), MSG_ERR)
}
self.ajaxMsg("", MSG_OK)
}
Admin, _ := models.AdminGetById(Admin_id)
//修改
Admin.LoginName = strings.TrimSpace(self.GetString("login_name"))
Admin.RealName = strings.TrimSpace(self.GetString("real_name"))
Admin.Phone = strings.TrimSpace(self.GetString("phone"))
Admin.Email = strings.TrimSpace(self.GetString("email"))
Admin.Id = Admin_id
Admin.UpdateTime = time.Now().Unix()
Admin.UpdateId = self.userId
Admin.UpdateTime = time.Now().Unix()
Admin.UpdateId = self.userId
Admin.Status = 1
resetPwd, _ := self.GetInt("reset_pwd")
if resetPwd == 1 {
pwd, salt := libs.Password(4, "")
Admin.Password = pwd
Admin.Salt = salt
}
if err := Admin.Update(); err != nil {
self.ajaxMsg(err.Error(), MSG_ERR)
}
self.ajaxMsg(strconv.Itoa(resetPwd), MSG_OK)
}
##编辑用户
效果图如下:
当用户点击编辑按钮,将对应的古诗id提交到后台,在后台接收id并根据该id去数据库查询对应的记录,将查询到的信息存入模板数据中,在前台页面显示被编辑的用户的信息,即数据回显。当用户修改信息之后点击立即提交按钮,将数据提交到后台,在后台接收相应的数据并更新数据库,对应的代码同上。
##删除用户
效果图如下:
该页面实现了删除用户的功能,当用户点击删除按钮,页面给与相应的提示,因为一旦删除,数据将不可恢复,如果用户确定删除,将被删除的用户的id提交到后台,在后台接收用户id并查询数据库,如果查询失败,说明数据库中不存在该用户则删除失败,如果查询成功,则将该用户删除。
func (self *AdminController) AjaxDel() {
//获取用户id
Admin_id, _ := self.GetInt("id")
//根据id查询管理员
Admin, _ := models.AdminGetById(Admin_id)
//修改时间
Admin.UpdateTime = time.Now().Unix()
//状态,1-正常 0禁用
Admin.Status = 0
Admin.Id = Admin_id
//判断要删除的用户是不是超级管理员
if Admin_id == 1 {
self.ajaxMsg("超级管理员不允许删除", MSG_ERR)
}
//更新用户
if err := Admin.Update(); err != nil {
self.ajaxMsg(err.Error(), MSG_ERR)
}
self.ajaxMsg("", MSG_OK)
}
#个人中心
效果图如下:
该模块主要实现了个人信息的修改,但用户点击修改资料按钮时,从cookie中获取当前登录用户的id,并根据该id去数据库查询数据,将查询到的数据存入模板数据中,通过渲染将当前用户的个人信息显示在前台页面,在用户修改完信息之后点击立即提交按钮将数据提交到后台,在后台接收数据之后将更新对应的记录。
func (self *UserController) AjaxSave() {
/*
login_name real_name phone email reset_pwd password_old password_new1 password_new2 id
*/
//获取用户id
Admin_id, _ := self.GetInt("id")
//根据id查询管理员
Admin, _ := models.AdminGetById(Admin_id)
//修改
Admin.Id = Admin_id
/*
login_name real_name phone email
*/
Admin.LoginName = strings.TrimSpace(self.GetString("login_name"))
Admin.RealName = strings.TrimSpace(self.GetString("real_name"))
Admin.Phone = strings.TrimSpace(self.GetString("phone"))
Admin.Email = strings.TrimSpace(self.GetString("email"))
resetPwd := self.GetString("reset_pwd")
//resetPwd=1为修改密码,resetPwd=2为不修改
if resetPwd == "1" {
//获取原始密码并去除两边的空格
pwdOld := strings.TrimSpace(self.GetString("password_old"))
//将原始密码和密码盐去哈希
pwdOldMd5 := libs.Md5([]byte(pwdOld + Admin.Salt))
//对比结果
if Admin.Password != pwdOldMd5 {
self.ajaxMsg("旧密码错误", MSG_ERR)
}
//获取新密码并去除两边的空格
pwdNew1 := strings.TrimSpace(self.GetString("password_new1"))
//获取确认密码并去除两边的空格
pwdNew2 := strings.TrimSpace(self.GetString("password_new2"))
//对比两次输入的密码是否一致
if pwdNew1 != pwdNew2 {
self.ajaxMsg("两次密码不一致", MSG_ERR)
}
//返回新密码和密码盐
pwd, salt := libs.Password(4, pwdNew1)
//密码为用户输入的密码和密码盐(随机生成的字符串)的哈希值
Admin.Password = pwd
//密码盐
Admin.Salt = salt
}
//修改时间
Admin.UpdateTime = time.Now().Unix()
//修改者ID
Admin.UpdateId = self.userId
//状态,1-正常 0禁用
Admin.Status = 1
//更新用户
if err := Admin.Update(); err != nil {
self.ajaxMsg(err.Error(), MSG_ERR)
}
self.ajaxMsg("", MSG_OK)
}
#咨询管理
该模块主要实现了古诗的添加,删除,编辑以及列表等功能,对古诗内容实现有效的管理。
##咨询列表
效果图如下:
该页面主要用来展示古诗词的相关信息,在下拉框中可以选择想要现实的分类,例如:选择了国学经典,会将国学经典的id提交到后台,在后台拿到id之后查询属于该id下的古诗词并存入模板数据中,在前台页面显示。
func (self *AdminController) Table() {
//列表
page, err := self.GetInt("page")
if err != nil {
page = 1
}
limit, err := self.GetInt("limit")
fmt.Println("limit = ", limit)
if err != nil {
limit = 5
}
limit = 10
self.pageSize = limit
//查询条件
filters := make([]interface{}, 0)
filters = append(filters, "status", 1)
result, count := models.AdminGetList(page, self.pageSize, filters...)
list := make([]map[string]interface{}, len(result))
for k, v := range result {
/*
<th lay-data="{field:'id', width:80, fixed: true}">ID</th>
<th lay-data="{field:'login_name', width:200}">登录账户</th>
<th lay-data="{field:'real_name', width:150}">真实姓名</th>
<th lay-data="{field:'phone', width:200}">手机号码</th>
<th lay-data="{field:'email', width:200}">电子邮箱</th>
*/
row := make(map[string]interface{})
row["id"] = v.Id
row["login_name"] = v.LoginName
row["real_name"] = v.RealName
row["phone"] = v.Phone
row["email"] = v.Email
list[k] = row
}
self.ajaxList("成功", MSG_OK, count, list)
}
##添加古诗
效果图如下:
该页面主要用于添加古诗词,用户在点击添加按钮时,需要从数据库中查询出古诗的所有分类信息,并将相关信息存入模板数据中,在添加页面回显古诗的分类信息。用户在添加页面填写相应的数据并点击立即提交按钮将数据提交到后台,在后台接收用户输入的数据并将该数据添加到数据库中。
func (self *NewsController) AjaxSave() {
/*
title class_id author keywords pic_url media desc content orderid id
*/
News := new(models.InfoList)
//标题
News.Title = strings.TrimSpace(self.GetString("title"))
//获取所属栏目id
classId, _ := self.GetInt("class_id")
//所属栏目id
News.ClassId = classId
//作者编辑
News.Author = strings.TrimSpace(self.GetString("author"))
//关键词
News.Keywords = strings.TrimSpace(self.GetString("keywords"))
//缩略图片
News.Picurl = strings.TrimSpace(self.GetString("pic_url"))
//诗词音频
News.Media = strings.TrimSpace(self.GetString("media"))
//摘要
News.Desc = strings.TrimSpace(self.GetString("desc"))
//详细内容
News.Content = strings.TrimSpace(self.GetString("content"))
orderid, err := self.GetInt("orderid")
if err != nil {
News.Orderid = orderid
}
id, _ := self.GetInt("id")
//更新时间
News.Updatetime = time.Now().Unix()
//审核状态,1正常,2删除,0未审核
News.Status = 1
//添加
if id == 0 {
News.Posttime = time.Now().Unix()
//插入古诗词
if _, err := models.NewsAdd(News); err != nil {
self.ajaxMsg(err.Error(), MSG_ERR)
}
self.ajaxMsg("", MSG_OK)
}
News.Id = id
//更新古诗词
if err := News.Update(); err != nil {
self.ajaxMsg(err.Error(), MSG_ERR)
}
self.ajaxMsg("", MSG_OK)
}
//古诗词列表
func (self *NewsController) Table() {
//获取页码
page, err := self.GetInt("page")
//出现错误,赋予默认值1
if err != nil {
page = 1
}
//获取查询的数量
limit, err := self.GetInt("limit")
//出现错误,赋予默认值30
if err != nil {
limit = 30
}
//获取分类id
class_id ,_ := self.GetInt("class_id")
self.pageSize = limit
//创建切片,用于存储过滤条件
filters := make([]interface{}, 0)
//追加过滤条件:正常状态
filters = append(filters, "status", 1)
//判断分类id是否大于0
if class_id > 0 {
filters = append(filters, "class_id", class_id)
}
//分页查询古诗词
result, count := models.NewsGetList(page, self.pageSize, filters...)
//创建切片,用于存储查询结果
list := make([]map[string]interface{}, len(result))
//遍历结果
for k, v := range result {
/*
<th lay-data="{field:'id', width:80, fixed: true}">ID</th>
<th lay-data="{field:'title', width:200}">标题</th>
<th lay-data="{field:'class_id', width:80}">分类</th>
<th lay-data="{field:'author', width:80}">作者</th>
<th lay-data="{field:'desc', width:200}">简介</th>
<th lay-data="{field:'posttime', width:100}">时间</th>
*/
row := make(map[string]interface{})
row["id"] = v.Id
row["title"] = v.Title
row["class_id"] = v.ClassId
row["author"] = v.Author
row["desc"] = v.Desc
row["posttime"] = beego.Date(time.Unix(v.Posttime, 0), "Y-m-d")//根据秒数和纳秒,返回Time类型
list[k] = row
}
fmt.Println("list = ", list)
self.ajaxList("成功", MSG_OK, count, list)
}
##编辑古诗
效果图如下:
当用户点击编辑按钮,将被编辑的古诗的id提交到后台,在后台接收用户输入的id查询数据库,将查询出的数据存入模板数据中,在编辑页面回显被编辑的古诗的数据,即从模板数据中取出被编辑的古诗的相关信息展示在编辑页面,当用户修改了相关的信息之后并点击立即提交按钮将古诗的相关的数据提交到后台,在后台接收相关数据并存入数据库中,实现古诗的编辑功能。
func (self *NewsController) Edit() {
self.Data["pageTitle"] = "编辑资讯"
//获取id
id, _ := self.GetInt("id", 0)
//根据id查询古诗词
News, _ := models.NewsGetById(id)
//分页查询分类信息
result, _ := models.ClassGetList()
//创建切片,用于存储分类信息
classList := make([]map[string]interface{}, len(result))
//遍历结果
for k, v := range result {
/*
id class_name
*/
row := make(map[string]interface{})
row["id"] = v.Id//栏目id
row["class_name"] = v.ClassName//栏目名称
classList[k] = row
}
//显示文章详情
/*
title class_id author keywords pic_url media desc content orderid
*/
row := make(map[string]interface{})
row["title"] = News.Title
row["class_id"] = News.ClassId
row["author"] = News.Author
row["keywords"] = News.Keywords
row["pic_url"] = News.Picurl
row["media"] = News.Media
row["desc"] = News.Desc
row["content"] = News.Content
row["orderid"] = News.Orderid
row["id"] = News.Id
//row["posttime"] = beego.Date(time.Unix(News.Posttime, 0), "Y/m/d")
self.Data["news_class"] = classList
self.Data["news"] = row
self.display()
}
##删除古诗
效果图如下:
该页面实现了删除古诗的功能,当用户点击删除按钮,页面给与相应的提示,因为一旦删除,数据将不可恢复,如果用户确定删除,将被删除的古诗的id提交到后台,在后台接收用古诗d并查询数据库,如果查询失败,说明数据库中不存在该古诗则删除失败,如果查询成功,则将该古诗删除。
func (self *NewsController) AjaxDel() {
//获取id
NewsId, _ := self.GetInt("id")
//根据id查询古诗词
News, _ := models.NewsGetById(NewsId)
News.Updatetime = time.Now().Unix()
//状态为2表示删除
News.Status = 2
News.Id = NewsId
//跟新
if err := News.Update(); err != nil {
self.ajaxMsg(err.Error(), MSG_ERR)
}
self.ajaxMsg("", MSG_OK)
}
学院Go语言视频主页