Blogger Information
Blog 42
fans 2
comment 0
visits 53936
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
CMS后台管理系统(一) 登陆功能 首页显示 (2019年4月1日)
小明的博客
Original
3059 people have browsed it

今天学习了tp51框架下,构建的cms后台管理系统,主要实现了登陆功能,登陆后对管理员账号权限在左侧菜单的显示。
一、准备

  • 首先要重新下载tp51框架,composer create-project topthink/think cms 5.1.37

  • 配置:

    1. //config下的app。php
    2. // 默认模块名
    3. 'default_module' => 'admins',
    4. // 禁止访问模块
    5. 'deny_module_list' => ['common'],
    6. // 默认控制器名
    7. 'default_controller' => 'Home',
    8. // 默认操作名
    9. 'default_action' => 'index',
    10. //config下的database.php
    11. // 数据库类型
    12. 'type' => 'mysql',
    13. // 服务器地址
    14. 'hostname' => 'localhost',
    15. // 数据库名
    16. 'database' => 'ouyang',
    17. // 用户名
    18. 'username' => 'root',
    19. // 密码
    20. 'password' => 'root',
    21. //config下的template.php
    22. // 模板后缀
    23. 'view_suffix' => 'php',
    24. //public下的.htaccess index.php 后面加上问号 就可以省去入口文件
    25. RewriteRule ^(.*)$ index.php?/$1 [QSA,PT,L]

    二、 页面登陆

  • 创建account控制器下的login方法 , 引入框架Controller类,引入自定义的数据库查询类use Util\Sysdb
  • login 方法用来渲染前端登陆页面
    1. class Account extends Controller
    2. {
    3. //后台登陆页面
    4. //2、页面文件不能再继承公共的权限控制类BaseAdmin类,
    5. //因为这是登陆页面,肯定没有登陆,那么BaseAdmin肯定让他跳转当前页面,造成无限循环
    6. //3、页面需要显示登陆用户名 密码 验证码
    7. //4、验证使用tp51自带的验证码插件
    8. public function login () {
    9. return $this->fetch();
    10. }
    11. }
  • 创建登陆页面view文件夹下的account文件夹下的login.php,写出前端页面,
  • 这里需要tp下的自带的验证码插件,cms composer require topthink/think-captcha=2.0.2 引用<img src="{:captcha_src()}" id="img">
  • js reloadImg刷新二维码
  • 登陆按钮绑定dologin事件,用来获取用户名 密码 验证码,验证都不为空,然后用ajax方式post到account下的dologin方法下处理
    //提交数据给dologin
    1. function dologin() {
    2. var username = $.trim($('#username').val());
    3. var pwd = $.trim($('#password').val());
    4. var verifycode = $.trim($('#verifycode').val());
    5. //验证输入内容为空
    6. if (username == '') {
    7. layer.alert('请输入用户名', {icon:2});
    8. return;
    9. }
    10. if (pwd == '') {
    11. layer.alert('请输入密码', {icon:2});
    12. return;
    13. }
    14. if (verifycode == '') {
    15. layer.alert('请输入验证码', {icon:2});
    16. return;
    17. }
    18. //通过ajax方式交给后台dologin方法处理数据 并且返回相应的数据
    19. $.post('/index.php/admins/Account/dologin', {'username':username,
    20. 'pwd':pwd, 'verifycode':verifycode}, function (res) {
    21. if (res.code > 0) {
    22. reloadImg();
    23. layer.alert(res.msg, {icon:2});
    24. }else{
    25. layer.msg(res.msg);
    26. setTimeout(function () {
    27. window.location.href='/index.php/admins/Home/index'
    28. }, 1000)
    29. }
    30. },'json');
    31. }
  • 在account.php下新建方法dologin,
  • input方法获取传过来的值,然后验证都不为空,
  • !captcha_check($verifycode)验证验证码是否正确
  • 连接数据库 查询与账号相符的记录,验证账号是否存在,验证账号密码是否一致,验证账号状态,删除密码信息后存入session,
    //5、登陆接口

    1. public function dologin () {
    2. //获取传过来的数据 然后赋给相应的变量
    3. $username = trim(input('username'));
    4. $pwd = trim(input('pwd'));
    5. $verifycode = trim(input('verifycode'));
    6. //验证数据空值,输出错误信息的code和msg
    7. if ($username == '') {
    8. exit(json_encode(array('code'=>1, 'msg'=>'账号不能为空')));
    9. }
    10. if ($pwd == '') {
    11. exit(json_encode(array('code'=>1, 'msg'=>'密码不能为空')));
    12. }
    13. if ($verifycode == '') {
    14. exit(json_encode(array('code'=>1, 'msg'=>'验证码不能为空')));
    15. }
    16. //验证验证码
    17. if (!captcha_check($verifycode)) {
    18. exit(json_encode(array('code'=>1, 'msg'=>'验证码错误')));
    19. }
    20. //验证用户
    21. //连接数据库 引入数据库操作公用文件
    22. $this->db = new Sysdb();
    23. //按照账户查询数据库,不用(账户和密码)一起查询,因为那样的花出错不知谁错
    24. $admin = $this->db->table('admins')->where(array('username'=>$username))->item();
    25. //验证是否有该用户
    26. if (!$admin) {
    27. exit(json_encode(array('code'=>1, 'msg'=>'该用户不存在')));
    28. }
    29. //验证账号密码是否一致
    30. if (md5($admin['username'].$pwd) != $admin['password']) {
    31. exit(json_encode(array('code'=>1, 'msg'=>'密码错误')));
    32. }
    33. //验证账号状态
    34. if ($admin['status'] == 1) {
    35. exit(json_encode(array('code'=>1, 'msg'=>'该账号被禁用')));
    36. }
    37. //为了安全 将密码设为空然后再把用户信息存在session中
    38. $admin['password'] = null;
    39. session('admin', $admin);
    40. exit(json_encode(array('code'=>0, 'msg'=>'登陆成功')));
    41. }

三、后台首页
. 登陆成功后跳转到 Home.php下的index方法,home类需要继承BaseAdmin类
. BaseAdmin验证是否登陆,验证session里面的admin信息有就是登陆了,没有就跳转到登陆页面,所哟登陆页面不要继承BaseAdmin类,如果那样的花就循环跳转

  1. class BaseAdmin extends Controller
  2. {
  3. public function __construct()
  4. {
  5. //Controller类里面就有魔术构造方法 继承调用
  6. parent::__construct();
  7. //1、判断是否登陆
  8. //将session值赋给属性
  9. $this->_admin = session('admin');
  10. if (!$this->_admin) {
  11. header('Location: /index.php/admins/Account/login');
  12. exit;
  13. }
  14. $this->assign('admin', $this->_admin);
  15. }
  16. }

. 新建index方法,链接数据库,查询该账号权限下(这里没有验证权限所有开放所有权限)显示并且可用状态的所有左侧菜单,然后将二级菜单根据上级菜单所属进行分类
. 分类菜单,显示把左侧菜单全部遍历,然后分类是首先看他的父级id的下标,有没有该条记录,一级菜单的父id都是0,但是遍历的菜单记录理下标没有为0的,所有就把作为一级菜单赋给tree变量,然后二级的菜单父级id都有,然后把它的记录付费父记录下的children下,用来调用。
. 查询config表 把杂项查询出来

  1. <?php
  2. /**
  3. * Created by PhpStorm.
  4. * User: apple
  5. * Date: 2020/1/2
  6. * Time: 4:29 PM
  7. */
  8. namespace app\admins\controller;
  9. use think\Controller;
  10. use Util\Sysdb;
  11. class Home extends BaseAdmin
  12. {
  13. // 6、首页和左侧菜单的样式是后台共用的样式
  14. // 7、退出登陆 确认后删除session
  15. // 8、查询左侧菜单 遍历出来 渲染在前端
  16. public function index(){
  17. // $menus = false;
  18. // $role = $this->db->table('admin_groups')->where(array('gid'=>$this->_admin['gid']))->item();
  19. // if($role){
  20. // $role['rights'] = (isset($role['rights']) && $role['rights']) ? json_decode($role['rights'],true) : [];
  21. // }
  22. // if($role['rights']){ mid in('.implode(',',$role['rights']).') and
  23. // 9,查询左侧菜单。 在权限开启的情况下,可以直接把admin去掉,那admin就可以有全部权限了。
  24. // 10,查询出来左侧菜单后,整理菜单分级
  25. $this->db = new Sysdb;
  26. // $where = ' ishidden=0 and status=0';
  27. $where = array('ishidden'=>0, 'status'=>0);
  28. $menus = $this->db->table('admin_menus')->where($where)->cates('mid');
  29. print_r($menus);
  30. $menus && $menus = $this->gettreeitems($menus);
  31. // }
  32. // 11,查询config表,这个是公用的表。 config表的目的,是存放一起零散的信息的。
  33. $site = $this->db->table('config')->where(array('names'=>'site'))->item();
  34. $site && $site['values'] = json_decode($site['values']);
  35. $this->assign('site',$site);
  36. // $this->assign('role',$role);
  37. $this->assign('menus',$menus);
  38. return $this->fetch();
  39. }
  40. // 把菜单分级处理。
  41. private function gettreeitems($items){
  42. $tree = array();
  43. // 循环(菜单数组),查询菜单的数据。
  44. foreach ($items as $item) {
  45. // 循环数组, $item是 数组里的单条数据
  46. // 单条数据,判断父ID,是否存在。
  47. // 存在后,把就把它的父级ID,当做它的下标。
  48. if(isset($items[$item['pid']])){
  49. // 如果是二级或三级,就把它的父级ID,当做它的下标。
  50. $items[$item['pid']]['children'][] = &$items[$item['mid']];
  51. }else{
  52. // 不存在,直接在数组第一层
  53. // 如果是一级,直接在数组第一层
  54. $tree[] = &$items[$item['mid']];
  55. }
  56. }
  57. // 作业:看懂这个返回值
  58. print_r($tree);
  59. return $tree;
  60. }
  61. // 欢迎页面
  62. public function welcome(){
  63. return $this->fetch();
  64. }
  65. }

. 最后新建home下的index前端页面,做好渲染

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title>{$site.values}--后台管理系统</title>
  5. <link rel="stylesheet" type="text/css" href="/static/plugins/layui/css/layui.css">
  6. <script type="text/javascript" src="/static/plugins/layui/layui.js"></script>
  7. <style type="text/css">
  8. .header{width:100%;height: 50px;line-height: 50px;background: #2e6da4;color:#ffffff;}
  9. .title{margin-left: 20px;font-size: 20px;}
  10. .userinfo{float: right;margin-right: 10px;}
  11. .userinfo a{color:#ffffff;}
  12. .menu{width: 200px;background: #333744;position: absolute;}
  13. .main{position: absolute;left: 200px;right: 0px;}
  14. .layui-collapse{border: none;}
  15. .layui-colla-item{border-top: none;}
  16. .layui-colla-title{background: #42485b;color:#ffffff;}
  17. .layui-colla-content{border-top: none;padding: 0px;}
  18. </style>
  19. </head>
  20. <body>
  21. <!--header-->
  22. <div class="header">
  23. <span class="title"><span style="font-size: 20px;">{$site.values}</span>--后台管理系统</span>
  24. <span class="userinfo">{$admin.username} <span><a href="javascript:;" onclick="logout()">退出</a></span></span>
  25. </div>
  26. <!--菜单-->
  27. <div class="menu" id="menu">
  28. <div class="layui-collapse" lay-accordion>
  29. {volist name="menus" id="vo"}
  30. <div class="layui-colla-item">
  31. <h2 class="layui-colla-title">{$vo.title}</h2>
  32. <div class="layui-colla-content{$i==1?' layui-show':''}">
  33. <?php if(isset($vo['children']) && $vo['children']){?>
  34. <ul class="layui-nav layui-nav-tree" lay-filter="test">
  35. {volist name="vo.children" id="cvo"}
  36. <li class="layui-nav-item"><a href="javascript:;" onclick="menuFire(this)" src="/index.php/admins/{$cvo.controller}/{$cvo.method}">{$cvo.title}</a></li>
  37. {/volist}
  38. </ul>
  39. <?php }?>
  40. </div>
  41. </div>
  42. {/volist}
  43. </div>
  44. </div>
  45. <!--主操作页面-->
  46. <div class="main">
  47. <iframe src="/index.php/admins/Home/welcome" onload="resetMainHeight(this)" style="width: 100%;height:100%;" frameborder="0" scrolling="0"></iframe>
  48. </div>
  49. <script>
  50. layui.use(['element','layer'], function(){
  51. var element = layui.element;
  52. $ = layui.jquery;
  53. layer = layui.layer;
  54. resetMenuHeight();
  55. });
  56. // 重新设置菜单容器高度
  57. function resetMenuHeight(){
  58. var height = document.documentElement.clientHeight - 50;
  59. $('#menu').height(height);
  60. }
  61. // 重新设置主操作页面高度
  62. function resetMainHeight(obj){
  63. var height = parent.document.documentElement.clientHeight - 53;
  64. $(obj).parent('div').height(height);
  65. }
  66. // 菜单点击
  67. function menuFire(obj){
  68. // 获取url
  69. var src = $(obj).attr('src');
  70. // 设置iframe的src
  71. $('iframe').attr('src',src);
  72. }
  73. // 退出
  74. function logout(){
  75. layer.confirm('确定要退出吗?', {
  76. icon:3,
  77. btn: ['确定','取消']
  78. }, function(){
  79. $.get('/index.php/admins/account/logout',function(res){
  80. if(res.code>0){
  81. layer.msg(res.msg,{'icon':2});
  82. }else{
  83. layer.msg(res.msg,{'icon':1});
  84. setTimeout(function(){window.location.href="/index.php/admins/account/login";},1000);
  85. }
  86. },'json');
  87. });
  88. }
  89. </script>
  90. </body>
  91. </html>
Correction status:Uncorrected

Teacher's comments:
Statement of this Website
The copyright of this blog article belongs to the blogger. Please specify the address when reprinting! If there is any infringement or violation of the law, please contact admin@php.cn Report processing!
All comments Speak rationally on civilized internet, please comply with News Comment Service Agreement
0 comments