* Date: 2018-4-3
*/
namespace app\admin\controller;
use think\Page;
use think\Verify;
use think\Db;
use think\db\Query;
use think\Session;
use app\admin\model\AuthRole;
use app\admin\logic\AjaxLogic;
class Admin extends Base {
private $admin_info = [];
public function _initialize() {
parent::_initialize();
$this->admin_info = session('?admin_info') ? session('admin_info') : [];
$this->assign('admin_info', $this->admin_info);
}
public function index()
{
$list = array();
$keywords = input('keywords/s');
$keywords = addslashes(trim($keywords));
$condition = array();
if (!empty($keywords)) {
$condition['a.user_name|a.true_name'] = array('LIKE', "%{$keywords}%");
}
/*权限控制 by 小虎哥*/
if (0 < intval($this->admin_info['role_id'])) {
$condition['a.admin_id|a.parent_id'] = $this->admin_info['admin_id'];
} else {
if (!empty($this->admin_info['parent_id'])) {
$condition['a.admin_id|a.parent_id'] = $this->admin_info['admin_id'];
}
}
/*--end*/
/**
* 数据查询
*/
$count = DB::name('admin')->alias('a')->where($condition)->count();// 查询满足要求的总记录数
$Page = new Page($count, config('paginate.list_rows'));// 实例化分页类 传入总记录数和每页显示的记录数
$list = DB::name('admin')->field('a.*, b.name AS role_name')
->alias('a')
->join('__AUTH_ROLE__ b', 'a.role_id = b.id', 'LEFT')
->where($condition)
->order('a.admin_id asc')
->limit($Page->firstRow.','.$Page->listRows)
->select();
$locklist = tpSetting('adminlogin');
foreach ($list as $key => $val) {
if (0 >= intval($val['role_id'])) {
$val['role_name'] = !empty($val['parent_id']) ? '超级管理员' : '创始人';
}
// 是否被锁定
$login_lock_key = 'adminlogin_'.md5('login_lock_'.$val['user_name'].clientIP()); // 是否被锁定
$val['is_locklogin'] = !empty($locklist[$login_lock_key]) ? 1 : 0;
$list[$key] = $val;
}
$show = $Page->show();// 分页显示输出
$this->assign('page',$show);// 赋值分页输出
$this->assign('list',$list);// 赋值数据集
$this->assign('pager',$Page);// 赋值分页集
// 第三方扫码绑定与解绑
$wxlist = [];
$thirdata = login_third_type();
if ('EyouGzhLogin' == $thirdata['type']) {
$wxlist = Db::name('admin_wxlogin')->where(['type'=>1])->getAllWithIndex('admin_id');
} else if ('WechatLogin' == $thirdata['type']) {
$wxlist = Db::name('admin_wxlogin')->where(['type'=>2])->getAllWithIndex('admin_id');
}
$this->assign('wxlist', $wxlist);
$this->assign('thirdata', $thirdata);
/*第一次同步CMS用户的栏目ID到权限组里*/
$this->syn_built_auth_role();
/*--end*/
return $this->fetch();
}
/*
* 管理员登陆
*/
public function login()
{
if (session('?admin_id') && session('admin_id') > 0) {
$web_adminbasefile = tpCache('global.web_adminbasefile');
$web_adminbasefile = !empty($web_adminbasefile) ? $web_adminbasefile : $this->root_dir.'/login.php';
if (stristr($web_adminbasefile, 'index.php')) {
$baseFile = explode('/', request()->baseFile());
$web_adminbasefile = end($baseFile);
$web_adminbasefile = $this->root_dir.'/'.$web_adminbasefile;
}
$this->success("您已登录", $web_adminbasefile);
}
$is_vertify = 1; // 默认开启验证码
$admin_login_captcha = config('captcha.admin_login');
if (!function_exists('imagettftext') || empty($admin_login_captcha['is_on'])) {
$is_vertify = 0; // 函数不存在,不符合开启的条件
} else if (is_file('./data/conf/admin_vertify.txt')) {
$is_exist = @file_get_contents('./data/conf/admin_vertify.txt');
if ($is_exist !== false && empty($is_exist)) {
$is_vertify = 0;
}
}
$this->assign('is_vertify', $is_vertify);
/*----------------微信扫码登录 start---------------*/
$login_type = 1; //仅账号密码登录 2-账号密码登录&微信扫码登录 3-仅微信扫码登录
$thirdata = login_third_type();
$third_login = !empty($thirdata['type']) ? $thirdata['type'] : '';
if ('EyouGzhLogin' == $third_login) {
if (empty($thirdata['data']['force'])){
$login_type = 2; //2-账号密码登录&微信扫码登录
} else {
$login_type = 3; //仅微信扫码登录
}
} else if ('WechatLogin' == $third_login) {
if (empty($thirdata['data']['security_wechat_forcelogin'])) {
$login_type = 2; //2-账号密码登录&微信扫码登录
} else {
$login_type = 3; //仅微信扫码登录
}
}
$this->assign('login_type', $login_type);
$this->assign('third_login', $third_login);
/*----------------微信扫码登录 end---------------*/
if (IS_POST) {
if (!in_array($login_type, [1,2])) {
$this->error('强制扫码,不支持普通登录!');
}
$post = input('post.');
if (!function_exists('session_start')) {
$this->error('请联系空间商,开启php的session扩展!');
}
if (!testWriteAble(ROOT_PATH.config('session.path').'/')) {
$this->error('请仔细检查以下问题:
1、磁盘空间大小是否100%;
2、站点目录权限是否为755;
3、站点所有目录的权限,禁止用root:root ;
4、如还没解决,请点击:查看教程');
}
if (1 == $is_vertify) {
$verify = new Verify();
if (!$verify->check(input('post.vertify'), "admin_login")) {
$this->error('验证码错误');
}
}
$is_clicap = 0; // 默认关闭文字验证码
if (is_dir('./weapp/Clicap/')) {
$ClicapRow = model('Weapp')->getWeappList('Clicap');
if (!empty($ClicapRow['status']) && 1 == $ClicapRow['status']) {
if (!empty($ClicapRow['data']) && $ClicapRow['data']['captcha']['admin_login']['is_on'] == 1) {
$clicaptcha_info = input('post.clicaptcha-submit-info');
$clicaptcha = new \weapp\Clicap\vendor\Clicaptcha;
if (empty($clicaptcha_info) || !$clicaptcha->check($clicaptcha_info, false)) {
$this->error('文字点击验证错误!');
}
}
}
}
$admin_count = 0;
$user_name = input('post.user_name/s');
$password = input('post.password/s');
/*---------登录错误次数的限制 start----------*/
$globalConfing = tpCache('global');
$web_login_lockopen = 0; // 是否开启登录失败锁定
if (!isset($globalConfing['web_login_lockopen']) || !empty($globalConfing['web_login_lockopen'])) {
$web_login_lockopen = 1;
$admin_count = Db::name('admin')->where(['user_name'=>$user_name])->count();
if (!empty($admin_count)) {
$loginErrtotal = !empty($globalConfing['web_login_errtotal']) ? intval($globalConfing['web_login_errtotal']) : config('login_errtotal'); // 登录错误最大次数
$loginErrexpire = !empty($globalConfing['web_login_errexpire']) ? intval($globalConfing['web_login_errexpire']) : config('login_errexpire'); // 登录错误最大限制时间
$clientIP = clientIP();
$login_errnum_key = 'adminlogin_'.md5('login_errnum_'.$user_name.$clientIP);
$login_errtime_key = 'adminlogin_'.md5('login_errtime_'.$user_name.$clientIP);
$login_lock_key = 'adminlogin_'.md5('login_lock_'.$user_name.$clientIP); // 是否被锁定
$loginErrnum = (int)tpSetting('adminlogin.'.$login_errnum_key); // 登录错误次数
$loginErrtime = tpSetting('adminlogin.'.$login_errtime_key); // 最后一次登录错误时间
if ($loginErrnum >= $loginErrtotal) {
if (getTime() < $loginErrtime + $loginErrexpire) {
adminLog("登录失败(已被锁定,登录错误超限{$loginErrtotal}次)");
$surplus_time = ($loginErrtime + $loginErrexpire) - getTime();
if ($surplus_time <= 0) {
$surplus_time = 1;
}
$this->error("多次登录失败,距离解锁还有".ceil($surplus_time/60)."分钟!");
} else {
// 重置登录错误次数
$loginErrnum = $loginErrtime = $login_lock = 0;
tpSetting('adminlogin', [$login_errnum_key => $loginErrnum]);
tpSetting('adminlogin', [$login_errtime_key => $loginErrtime]);
tpSetting('adminlogin', [$login_lock_key => $login_lock]);
}
}
}
}
/*---------登录错误次数的限制 end----------*/
if (!empty($user_name) && !empty($password)) {
$condition['user_name'] = $user_name;
$admin_info = Db::name('admin')->where($condition)->find();
if (!empty($admin_info)) {
/*等保密码复杂度验证 start*/
if (is_dir('./weapp/Equal/')) {
$equal_privkey = input('post.equal_privkey/s');
$equalLogic = new \weapp\Equal\logic\EqualLogic;
$equalLogic->loginLogic($password, $equal_privkey);
}
/*等保密码复杂度验证 end*/
$entry = pwd_encry_type($admin_info['password']);
$encry_password = func_encrypt($password, true, $entry);
if ($admin_info['password'] == $encry_password) {
if ($admin_info['status'] == 0) {
adminLog('登录失败(用户名被禁用)');
$this->error('用户名被禁用!');
}
$admin_info = adminLoginAfter($admin_info['admin_id'], $this->session_id);
// 检查密码复杂度
session('admin_login_pwdlevel', checkPasswordLevel($password));
adminLog('后台登录');
$url = session('from_url') ? session('from_url') : $this->request->baseFile();
session('isset_author', null); // 内置勿动
// 同步追加一个后台管理员到会员用户表
$isFounder = !empty($admin_info['parent_id']) ? 0 : 1;
$this->syn_users_login($admin_info, $isFounder);
$this->success('登录成功', $url);
}
}
}
/*----------记录登录错误次数 start-----------*/
if (!empty($admin_count) && !empty($web_login_lockopen)) {
$login_errnum = $loginErrnum + 1;
$login_num = $loginErrtotal - $login_errnum;
tpSetting('adminlogin', [$login_errnum_key=>$login_errnum]);
tpSetting('adminlogin', [$login_errtime_key=>getTime()]);
if ($login_num > 0) {
$this->error("用户名或密码错误,您还可以尝试[{$login_num}]次!");
} else {
tpSetting('adminlogin', [$login_lock_key => 1]);
$this->error("登录错误超限{$loginErrtotal}次,账号将被锁定".ceil($loginErrexpire/60)."分钟!");
}
}
/*----------记录登录错误次数 end-----------*/
adminLog("登录失败({$user_name})");
$this->error("用户名或密码错误!");
}
$ajaxLogic = new AjaxLogic;
$ajaxLogic->login_handle();
// 仅微信扫码登录
// if ('WechatLogin' == $third_login && 3 == $login_type) {
// $this->wechatLogin();
// }
$this->global = tpCache('global');
$this->assign('global', $this->global);
$this->assign('time', getTime());
/*等保密码复杂度验证 start*/
$pwdJsCode = '';
if (is_dir('./weapp/Equal/')) {
$equalLogic = new \weapp\Equal\logic\EqualLogic;
$pwdJsCode = $equalLogic->pwdJsCode();
}
if ('close' == $pwdJsCode) {
$pwdJsCode = '';
}
$this->assign('pwdJsCode', $pwdJsCode);
/*等保密码复杂度验证 end*/
session('admin_info', null);
$viewfile = 'admin/login';
if (2 <= $this->php_servicemeal) {
$viewfile = 'admin/login_zy';
}
$web_theme_login_tplname = empty($this->globalConfig['web_theme_login_tplname']) ? '' : $this->globalConfig['web_theme_login_tplname'];
if (!empty($web_theme_login_tplname) && file_exists("application/admin/template/theme/{$web_theme_login_tplname}")) {
$login_tplname = str_ireplace('.htm', '', $web_theme_login_tplname);
$viewfile = "theme/{$login_tplname}";
}
if (is_dir('./weapp/Mbackend/') && isMobile()) {
$viewfile = 'weapp/Mbackend/template/admin/login_m.htm';
if (2 <= $this->php_servicemeal) {
$viewfile = 'weapp/Mbackend/template/admin/login_zy_m.htm';
}
// 是否配置微信公众号登录信息
$wechat = tpSetting("OpenMinicode.conf_wechat") ? json_decode(tpSetting("OpenMinicode.conf_wechat"), true) : [];
$this->assign('wechat', $wechat);
return $this->fetch("{$viewfile}");
} else {
return $this->fetch(":{$viewfile}");
}
}
// 后台管理插件(手机版)--微信公众号登录
public function ajax_admin_wechat_login()
{
if (is_dir('./weapp/Mbackend/') && isMobile()) {
// 调用逻辑层
$mbackendLogic = new \weapp\Mbackend\logic\MbackendLogic;
$url = $mbackendLogic->ajaxAdminWechatLogin();
$this->success('授权成功', $url);
} else {
$this->error('请先安装后台管理插件(手机版)');
}
}
// 后台管理插件(手机版)--获取微信登录用户信息
public function get_admin_wechat_users()
{
if (is_dir('./weapp/Mbackend/') && isMobile()) {
// 调用逻辑层
$mbackendLogic = new \weapp\Mbackend\logic\MbackendLogic;
$we_user = $mbackendLogic->getAdminWechatUsers();
$admin_info = adminLoginAfter($we_user['admin_id'], session_id());
if (!empty($admin_info)) {
adminLog('微信授权登录成功');
$this->success('登录成功', weapp_url('Mbackend/Mbackend/index'));
} else {
$this->success('404:您没有操作权限,请联系超级管理员分配权限');
}
} else {
$this->error('请先安装后台管理插件(手机版)');
}
}
private function wechatLogin()
{
$url = url('Admin/wechat_login', [], true, true);
$url = preg_replace('/^http(s?)/i', $this->request->scheme(), $url);
$this->redirect($url);
exit;
}
/**
* 解除锁定登录
* @return [type] [description]
*/
public function ajax_unlock_login()
{
$admin_id = input('param.id/d');
if (!empty($admin_id) && IS_POST) {
if (!empty($this->admin_info['parent_id']) || -1 != $this->admin_info['role_id']) {
$this->error('该功能仅限于创始人操作!');
}
$clientIP = clientIP();
$user_name = Db::name('admin')->where(['admin_id'=>$admin_id])->value('user_name');
$login_errnum_key = 'adminlogin_'.md5('login_errnum_'.$user_name.$clientIP);
$login_errtime_key = 'adminlogin_'.md5('login_errtime_'.$user_name.$clientIP);
$login_lock_key = 'adminlogin_'.md5('login_lock_'.$user_name.$clientIP); // 是否被锁定
tpSetting('adminlogin', [$login_errnum_key => 0]);
tpSetting('adminlogin', [$login_errtime_key => 0]);
tpSetting('adminlogin', [$login_lock_key => 0]);
adminLog('解除锁定:'.$user_name);
$this->success('操作成功');
}
$this->error('操作失败');
}
/**
* 验证码获取
*/
public function vertify()
{
/*验证码插件开关*/
$admin_login_captcha = config('captcha.admin_login');
$config = (!empty($admin_login_captcha['is_on']) && !empty($admin_login_captcha['config'])) ? $admin_login_captcha['config'] : config('captcha.default');
/*--end*/
ob_clean(); // 清空缓存,才能显示验证码
$Verify = new Verify($config);
$Verify->entry('admin_login');
exit();
}
/**
* 退出登陆
*/
public function logout()
{
adminLog('安全退出');
session_unset();
// session_destroy();
session::clear();
cookie('admin-treeClicked', null); // 清除并恢复栏目列表的展开方式
cookie('admin-treeClicked-1649642233', null); // 清除并恢复内容管理的展开方式
$this->success("安全退出", request()->baseFile());
}
/**
* 新增管理员时,检测用户名是否与前台用户名相同
*/
public function ajax_add_user_name()
{
if (IS_AJAX_POST) {
$user_name = input('post.user_name/s');
if (Db::name('admin')->where("user_name", $user_name)->count()) {
$this->error("此用户名已被注册,请更换!");
}
$row = Db::name('users')->field('users_id')->where([
'username' => $user_name,
'lang' => $this->admin_lang,
])->find();
if (!empty($row)) {
$this->error('已有相同会员名,将其转为系统账号?');
} else {
$this->success('会员名不存在,无需提示!');
}
}
}
/**
* 新增管理员
*/
public function admin_add()
{
$this->language_access(); // 多语言功能操作权限
if (IS_POST) {
$data = input('post.');
if (0 < $this->admin_info['role_id']) {
$this->error("超级管理员才能操作!");
}
if (empty($data['password']) || !trim($data['password'])) {
$this->error("用户密码不能为空!", null, ['input_name'=>'password']);
} else {
/*等保密码复杂度验证 start*/
if (is_dir('./weapp/Equal/')) {
$equalLogic = new \weapp\Equal\logic\EqualLogic;
$eqData = $equalLogic->pwdValidate($data['password']);
if (isset($eqData['code']) && empty($eqData['code'])) {
$this->error($eqData['msg']);
}
}
/*等保密码复杂度验证 end*/
}
$data['user_name'] = trim($data['user_name']);
$data['password'] = func_encrypt($data['password'], true, pwd_encry_type('bcrypt'));
$data['role_id'] = intval($data['role_id']);
$data['parent_id'] = $this->admin_info['admin_id'];
$data['add_time'] = getTime();
if (empty($data['pen_name'])) {
$data['pen_name'] = '小编';
}
// 处理数据验证
$error = handleEyouDataValidate('user_name', '__token_admin_add__', $data, '用户名不能为空!');
if (!empty($error)) $this->error($error);
if (Db::name('admin')->where(['user_name'=>$data['user_name']])->count()) {
$this->error("此用户名已被注册,请更换", url('Admin/admin_add'), ['input_name'=>'user_name']);
} else {
$admin_id = Db::name('admin')->insertGetId($data);
if ($admin_id !== false) {
adminLog('新增管理员:'.$data['user_name']);
/*同步追加一个后台管理员到会员用户表*/
try {
$usersInfo = Db::name('users')->field('users_id')->where([
'username' => $data['user_name'],
'lang' => $this->admin_lang,
])->find();
if (!empty($usersInfo)) {
$r = Db::name('users')->where(['users_id'=>$usersInfo['users_id']])->update([
'nickname' => $data['user_name'],
'admin_id' => $admin_id,
'is_activation' => 1,
'is_lock' => 0,
'is_del' => 0,
'update_time' => getTime(),
]);
if ($r !== false) {
$users_id = $usersInfo['users_id'];
}
} else {
// 获取要添加的用户名
$username = $this->GetUserName($data['user_name']);
$password = getTime();
$password = func_encrypt($password, false, pwd_encry_type('bcrypt'));
$AddData = [
'username' => $username,
'nickname' => $username,
'password' => $password,
'level' => 1,
'lang' => $this->admin_lang,
'reg_time' => getTime(),
'head_pic' => ROOT_DIR . '/public/static/common/images/dfboy.png',
'register_place' => 1,
'admin_id' => $admin_id,
];
$users_id = Db::name('users')->insertGetId($AddData);
}
if ($users_id !== false) {
Db::name('admin')->where(['admin_id'=>$admin_id])->update([
'syn_users_id' => intval($users_id),
'update_time' => getTime(),
]);
}
} catch (\Exception $e) {}
/* END */
$this->success("操作成功", url('Admin/index'));
} else {
$this->error("操作失败");
}
}
}
// 权限组
$admin_role_list = model('AuthRole')->getRoleAll();
$this->assign('admin_role_list', $admin_role_list);
// 模块组
$modules = getAllMenu();
$this->assign('modules', $modules);
// 权限集
$auth_rules = get_auth_rule(['is_modules'=>1]);
$auth_rule_list = group_same_key($auth_rules, 'menu_id');
foreach ($auth_rule_list as $key => $val) {
if (is_array($val)) {
$sort_order = [];
foreach ($val as $_k => $_v) {
$sort_order[$_k] = $_v['sort_order'];
}
array_multisort($sort_order, SORT_ASC, $val);
$auth_rule_list[$key] = $val;
}
}
$this->assign('auth_rule_list', $auth_rule_list);
// 栏目
$arctype_list = Db::name('arctype')->where([
'is_del' => 0,
])->order("grade desc")->select();
$arctype_p_html = $arctype_child_html = "";
$arctype_all = list_to_tree($arctype_list);
foreach ($arctype_all as $key => $arctype) {
if (!empty($arctype['children'])) {
if ($key > 0) {
$arctype_p_html .= '';
} else {
$arctype_p_html .= '';
}
$arctype_child_html .= '