工会后台开发-框架提交-基础设置提交-首页统计提交
This commit is contained in:
@@ -169,6 +169,12 @@ class Guild extends adminApi
|
|||||||
return V(0, "靓号已使用");
|
return V(0, "靓号已使用");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(empty($request['guild_user_mobile'])){
|
||||||
|
return V(0, "请填写会长手机号");
|
||||||
|
}
|
||||||
|
if(empty($request['password'])){
|
||||||
|
return V(0, "请填写后台登录密码");
|
||||||
|
}
|
||||||
Db::startTrans();
|
Db::startTrans();
|
||||||
try {
|
try {
|
||||||
$data = [
|
$data = [
|
||||||
@@ -208,12 +214,31 @@ class Guild extends adminApi
|
|||||||
db::rollback();
|
db::rollback();
|
||||||
return V(0, "加入失败");
|
return V(0, "加入失败");
|
||||||
}
|
}
|
||||||
$reslut = model('api/Tencent')->create_group($user_id,'g'.$res,"Public",$request['guild_logo'],$request['guild_name']);
|
// $reslut = model('api/Tencent')->create_group($user_id,'g'.$res,"Public",$request['guild_logo'],$request['guild_name']);
|
||||||
if ($reslut['code'] ==0 ) {
|
// if ($reslut['code'] ==0 ) {
|
||||||
db::rollback();
|
// db::rollback();
|
||||||
return V(0, $reslut['msg']);
|
// return V(0, $reslut['msg']);
|
||||||
}
|
// }
|
||||||
model('api/Tencent')->send_group_system_notification('g'.$res, $request['guild_name'].'工会群聊创建成功');
|
// model('api/Tencent')->send_group_system_notification('g'.$res, $request['guild_name'].'工会群聊创建成功');
|
||||||
|
|
||||||
|
//新功能
|
||||||
|
//创建基础信息数据
|
||||||
|
$boss_auth = db::name('user_auth')->where('mobile',$user['mobile'])->find();
|
||||||
|
$data = [
|
||||||
|
'guild_id' => $res,
|
||||||
|
'boss_mobile' => $request['guild_user_mobile'] ?? $user['mobile'],
|
||||||
|
'boss_name' => $boss_auth['real_name']?? '',
|
||||||
|
'createtime' => time(),
|
||||||
|
];
|
||||||
|
db::name('vs_guild_data')->insert($data);
|
||||||
|
//创建后台登录账号
|
||||||
|
$data = [
|
||||||
|
'guild_id' => $res,
|
||||||
|
'username' => $request['guild_user_mobile'],
|
||||||
|
'password' => $request['password'],
|
||||||
|
'nickname' => $request['guild_name']."管理员",
|
||||||
|
];
|
||||||
|
model('guildAdmin/Admin')->createAdmin($data);
|
||||||
db::commit();
|
db::commit();
|
||||||
return V(1,"成功", []);
|
return V(1,"成功", []);
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
|
|||||||
625
application/common/controller/GuildAdmin.php
Normal file
625
application/common/controller/GuildAdmin.php
Normal file
@@ -0,0 +1,625 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\common\controller;
|
||||||
|
|
||||||
|
use app\guildAdmin\library\Auth;
|
||||||
|
use think\Config;
|
||||||
|
use think\Controller;
|
||||||
|
use think\Hook;
|
||||||
|
use think\Lang;
|
||||||
|
use think\Loader;
|
||||||
|
use think\Model;
|
||||||
|
use think\Session;
|
||||||
|
use fast\Tree;
|
||||||
|
use think\Validate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 后台控制器基类
|
||||||
|
*/
|
||||||
|
class GuildAdmin extends Controller
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 无需登录的方法,同时也就不需要鉴权了
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $noNeedLogin = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 无需鉴权的方法,但需要登录
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $noNeedRight = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 布局模板
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $layout = 'default';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 权限控制类
|
||||||
|
* @var Auth
|
||||||
|
*/
|
||||||
|
protected $auth = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 模型对象
|
||||||
|
* @var \think\Model
|
||||||
|
*/
|
||||||
|
protected $model = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 快速搜索时执行查找的字段
|
||||||
|
*/
|
||||||
|
protected $searchFields = 'id';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否是关联查询
|
||||||
|
*/
|
||||||
|
protected $relationSearch = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否开启数据限制
|
||||||
|
* 支持auth/personal
|
||||||
|
* 表示按权限判断/仅限个人
|
||||||
|
* 默认为禁用,若启用请务必保证表中存在admin_id字段
|
||||||
|
*/
|
||||||
|
protected $dataLimit = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据限制字段
|
||||||
|
*/
|
||||||
|
protected $dataLimitField = 'admin_id';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据限制开启时自动填充限制字段值
|
||||||
|
*/
|
||||||
|
protected $dataLimitFieldAutoFill = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否开启Validate验证
|
||||||
|
*/
|
||||||
|
protected $modelValidate = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否开启模型场景验证
|
||||||
|
*/
|
||||||
|
protected $modelSceneValidate = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Multi方法可批量修改的字段
|
||||||
|
*/
|
||||||
|
protected $multiFields = 'status';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Selectpage可显示的字段
|
||||||
|
*/
|
||||||
|
protected $selectpageFields = '*';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 前台提交过来,需要排除的字段数据
|
||||||
|
*/
|
||||||
|
protected $excludeFields = "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导入文件首行类型
|
||||||
|
* 支持comment/name
|
||||||
|
* 表示注释或字段名
|
||||||
|
*/
|
||||||
|
protected $importHeadType = 'comment';
|
||||||
|
|
||||||
|
protected $guildId = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 引入后台控制器的traits
|
||||||
|
*/
|
||||||
|
use \app\admin\library\traits\Backend;
|
||||||
|
|
||||||
|
public function _initialize()
|
||||||
|
{
|
||||||
|
$modulename = $this->request->module();
|
||||||
|
$controllername = Loader::parseName($this->request->controller());
|
||||||
|
$actionname = strtolower($this->request->action());
|
||||||
|
$path = '/' .$modulename.'/' .str_replace('.', '/', $controllername) . '/' . $actionname;
|
||||||
|
// 定义是否Addtabs请求
|
||||||
|
!defined('IS_ADDTABS') && define('IS_ADDTABS', (bool)input("addtabs"));
|
||||||
|
|
||||||
|
// 定义是否Dialog请求
|
||||||
|
!defined('IS_DIALOG') && define('IS_DIALOG', (bool)input("dialog"));
|
||||||
|
|
||||||
|
// 定义是否AJAX请求
|
||||||
|
!defined('IS_AJAX') && define('IS_AJAX', $this->request->isAjax());
|
||||||
|
|
||||||
|
// 检测IP是否允许
|
||||||
|
check_ip_allowed();
|
||||||
|
|
||||||
|
$this->auth = Auth::instance();
|
||||||
|
|
||||||
|
// 设置当前请求的URI
|
||||||
|
$this->auth->setRequestUri($path);
|
||||||
|
// 检测是否需要验证登录
|
||||||
|
if (!$this->auth->match($this->noNeedLogin)) {
|
||||||
|
//获取 token
|
||||||
|
//通过头部信息获取authorization0
|
||||||
|
$token = $this->request->server('HTTP_AUTHORIZATION', $this->request->request('token', \think\Cookie::get('token')));
|
||||||
|
//检测是否登录
|
||||||
|
if (!$this->auth->isLogin($token)) {
|
||||||
|
Hook::listen('admin_nologin', $this);
|
||||||
|
$url = Session::get('referer');
|
||||||
|
$url = $url ? $url : $this->request->url();
|
||||||
|
if (in_array($this->request->pathinfo(), ['/', 'index/index'])) {
|
||||||
|
return V(301,"请登录后操作", url('index/login', ['url' => $url]));
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
return V(301,"请登录后操作", url('index/login', ['url' => $url]));
|
||||||
|
}
|
||||||
|
// 判断是否需要验证权限
|
||||||
|
if (!$this->auth->match($this->noNeedRight)) {
|
||||||
|
// 判断控制器和方法是否有对应权限
|
||||||
|
// if (!$this->auth->check($path)) {
|
||||||
|
// Hook::listen('admin_nopermission', $this);
|
||||||
|
// return V(302,"你没有权限访问", url('index/login', []));
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 非选项卡时重定向
|
||||||
|
if (!$this->request->isPost() && !IS_AJAX && !IS_ADDTABS && !IS_DIALOG && input("ref") == 'addtabs') {
|
||||||
|
$url = preg_replace_callback("/([\?|&]+)ref=addtabs(&?)/i", function ($matches) {
|
||||||
|
return $matches[2] == '&' ? $matches[1] : '';
|
||||||
|
}, $this->request->url());
|
||||||
|
if (Config::get('url_domain_deploy')) {
|
||||||
|
if (stripos($url, $this->request->server('SCRIPT_NAME')) === 0) {
|
||||||
|
$url = substr($url, strlen($this->request->server('SCRIPT_NAME')));
|
||||||
|
}
|
||||||
|
$url = url($url, '', false);
|
||||||
|
}
|
||||||
|
$this->redirect('index/index', [], 302, ['referer' => $url]);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置面包屑导航数据
|
||||||
|
$breadcrumb = [];
|
||||||
|
if (!IS_DIALOG && !config('fastadmin.multiplenav') && config('fastadmin.breadcrumb')) {
|
||||||
|
$breadcrumb = $this->auth->getBreadCrumb($path);
|
||||||
|
array_pop($breadcrumb);
|
||||||
|
}
|
||||||
|
$this->view->breadcrumb = $breadcrumb;
|
||||||
|
|
||||||
|
// 如果有使用模板布局
|
||||||
|
if ($this->layout) {
|
||||||
|
$this->view->engine->layout('layout/' . $this->layout);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 语言检测
|
||||||
|
$lang = $this->request->langset();
|
||||||
|
$lang = preg_match("/^([a-zA-Z\-_]{2,10})\$/i", $lang) ? $lang : 'zh-cn';
|
||||||
|
|
||||||
|
$site = Config::get("site");
|
||||||
|
$upload = \app\common\model\Config::upload();
|
||||||
|
|
||||||
|
// 上传信息配置后
|
||||||
|
Hook::listen("upload_config_init", $upload);
|
||||||
|
|
||||||
|
// 配置信息
|
||||||
|
$config = [
|
||||||
|
'site' => array_intersect_key($site, array_flip(['name', 'indexurl', 'cdnurl', 'version', 'timezone', 'languages'])),
|
||||||
|
'upload' => $upload,
|
||||||
|
'modulename' => $modulename,
|
||||||
|
'controllername' => $controllername,
|
||||||
|
'actionname' => $actionname,
|
||||||
|
'jsname' => 'backend/' . str_replace('.', '/', $controllername),
|
||||||
|
'moduleurl' => rtrim(url("/{$modulename}", '', false), '/'),
|
||||||
|
'language' => $lang,
|
||||||
|
'referer' => Session::get("referer")
|
||||||
|
];
|
||||||
|
$config = array_merge($config, Config::get("view_replace_str"));
|
||||||
|
|
||||||
|
Config::set('upload', array_merge(Config::get('upload'), $upload));
|
||||||
|
//记录日志
|
||||||
|
//只记录POST请求的日志
|
||||||
|
if (request()->isPost() && config('myadmin.auto_record_log')) {
|
||||||
|
$this_auth_rule_name = db('auth_rule')->where('name', substr(xss_clean(strip_tags(request()->url())), 0, 1500))->value('title');
|
||||||
|
if(empty($this_auth_rule_name)){
|
||||||
|
$this_auth_rule_name = '未知操作';
|
||||||
|
}
|
||||||
|
\app\guildAdmin\model\AdminLog::record($this_auth_rule_name);
|
||||||
|
}
|
||||||
|
// 配置信息后
|
||||||
|
Hook::listen("config_init", $config);
|
||||||
|
$this->guildId = Session::get('guild_id') ?? 0;
|
||||||
|
//加载当前控制器语言包
|
||||||
|
$this->loadlang($controllername);
|
||||||
|
//渲染站点配置
|
||||||
|
$this->assign('site', $site);
|
||||||
|
//渲染配置信息
|
||||||
|
$this->assign('config', $config);
|
||||||
|
//渲染权限对象
|
||||||
|
$this->assign('auth', $this->auth);
|
||||||
|
//渲染管理员对象
|
||||||
|
$this->assign('admin', Session::get('admin'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加载语言文件
|
||||||
|
* @param string $name
|
||||||
|
*/
|
||||||
|
protected function loadlang($name)
|
||||||
|
{
|
||||||
|
$name = Loader::parseName($name);
|
||||||
|
$name = preg_match("/^([a-zA-Z0-9_\.\/]+)\$/i", $name) ? $name : 'index';
|
||||||
|
$lang = $this->request->langset();
|
||||||
|
$lang = preg_match("/^([a-zA-Z\-_]{2,10})\$/i", $lang) ? $lang : 'zh-cn';
|
||||||
|
Lang::load(APP_PATH . $this->request->module() . '/lang/' . $lang . '/' . str_replace('.', '/', $name) . '.php');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 渲染配置信息
|
||||||
|
* @param mixed $name 键名或数组
|
||||||
|
* @param mixed $value 值
|
||||||
|
*/
|
||||||
|
protected function assignconfig($name, $value = '')
|
||||||
|
{
|
||||||
|
$this->view->config = array_merge($this->view->config ? $this->view->config : [], is_array($name) ? $name : [$name => $value]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成查询所需要的条件,排序方式
|
||||||
|
* @param mixed $searchfields 快速查询的字段
|
||||||
|
* @param boolean $relationSearch 是否关联查询
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
protected function buildparams($searchfields = null, $relationSearch = null)
|
||||||
|
{
|
||||||
|
$searchfields = is_null($searchfields) ? $this->searchFields : $searchfields;
|
||||||
|
$relationSearch = is_null($relationSearch) ? $this->relationSearch : $relationSearch;
|
||||||
|
$search = $this->request->get("search", '');
|
||||||
|
$filter = $this->request->get("filter", '');
|
||||||
|
$op = $this->request->get("op", '', 'trim');
|
||||||
|
$sort = $this->request->get("sort", !empty($this->model) && $this->model->getPk() ? $this->model->getPk() : 'id');
|
||||||
|
$order = $this->request->get("order", "DESC");
|
||||||
|
$offset = max(0, $this->request->get("offset/d", 0));
|
||||||
|
$limit = max(0, $this->request->get("limit/d", 0));
|
||||||
|
$limit = $limit ?: 999999;
|
||||||
|
//新增自动计算页码
|
||||||
|
$page = $limit ? intval($offset / $limit) + 1 : 1;
|
||||||
|
if ($this->request->has("page")) {
|
||||||
|
$page = max(0, $this->request->get("page/d", 1));
|
||||||
|
}
|
||||||
|
$this->request->get([config('paginate.var_page') => $page]);
|
||||||
|
$filter = (array)json_decode($filter, true);
|
||||||
|
$op = (array)json_decode($op, true);
|
||||||
|
$filter = $filter ? $filter : [];
|
||||||
|
$where = [];
|
||||||
|
$alias = [];
|
||||||
|
$bind = [];
|
||||||
|
$name = '';
|
||||||
|
$aliasName = '';
|
||||||
|
if (!empty($this->model) && $relationSearch) {
|
||||||
|
$name = $this->model->getTable();
|
||||||
|
$alias[$name] = Loader::parseName(basename(str_replace('\\', '/', get_class($this->model))));
|
||||||
|
$aliasName = $alias[$name] . '.';
|
||||||
|
}
|
||||||
|
$sortArr = explode(',', $sort);
|
||||||
|
foreach ($sortArr as $index => & $item) {
|
||||||
|
$item = stripos($item, ".") === false ? $aliasName . trim($item) : $item;
|
||||||
|
}
|
||||||
|
unset($item);
|
||||||
|
$sort = implode(',', $sortArr);
|
||||||
|
$adminIds = $this->getDataLimitAdminIds();
|
||||||
|
if (is_array($adminIds)) {
|
||||||
|
$where[] = [$aliasName . $this->dataLimitField, 'in', $adminIds];
|
||||||
|
}
|
||||||
|
if ($search) {
|
||||||
|
$searcharr = is_array($searchfields) ? $searchfields : explode(',', $searchfields);
|
||||||
|
foreach ($searcharr as $k => &$v) {
|
||||||
|
$v = stripos($v, ".") === false ? $aliasName . $v : $v;
|
||||||
|
}
|
||||||
|
unset($v);
|
||||||
|
$where[] = [implode("|", $searcharr), "LIKE", "%{$search}%"];
|
||||||
|
}
|
||||||
|
$index = 0;
|
||||||
|
foreach ($filter as $k => $v) {
|
||||||
|
if (!preg_match('/^[a-zA-Z0-9_\-\.]+$/', $k)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$sym = $op[$k] ?? '=';
|
||||||
|
if (stripos($k, ".") === false) {
|
||||||
|
$k = $aliasName . $k;
|
||||||
|
}
|
||||||
|
$v = !is_array($v) ? trim($v) : $v;
|
||||||
|
$sym = strtoupper($op[$k] ?? $sym);
|
||||||
|
//null和空字符串特殊处理
|
||||||
|
if (!is_array($v)) {
|
||||||
|
if (in_array(strtoupper($v), ['NULL', 'NOT NULL'])) {
|
||||||
|
$sym = strtoupper($v);
|
||||||
|
}
|
||||||
|
if (in_array($v, ['""', "''"])) {
|
||||||
|
$v = '';
|
||||||
|
$sym = '=';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ($sym) {
|
||||||
|
case '=':
|
||||||
|
case '<>':
|
||||||
|
$where[] = [$k, $sym, (string)$v];
|
||||||
|
break;
|
||||||
|
case 'LIKE':
|
||||||
|
case 'NOT LIKE':
|
||||||
|
case 'LIKE %...%':
|
||||||
|
case 'NOT LIKE %...%':
|
||||||
|
$where[] = [$k, trim(str_replace('%...%', '', $sym)), "%{$v}%"];
|
||||||
|
break;
|
||||||
|
case '>':
|
||||||
|
case '>=':
|
||||||
|
case '<':
|
||||||
|
case '<=':
|
||||||
|
$where[] = [$k, $sym, intval($v)];
|
||||||
|
break;
|
||||||
|
case 'FINDIN':
|
||||||
|
case 'FINDINSET':
|
||||||
|
case 'FIND_IN_SET':
|
||||||
|
$v = is_array($v) ? $v : explode(',', str_replace(' ', ',', $v));
|
||||||
|
$findArr = array_values($v);
|
||||||
|
foreach ($findArr as $idx => $item) {
|
||||||
|
$bindName = "item_" . $index . "_" . $idx;
|
||||||
|
$bind[$bindName] = $item;
|
||||||
|
$where[] = "FIND_IN_SET(:{$bindName}, `" . str_replace('.', '`.`', $k) . "`)";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'IN':
|
||||||
|
case 'IN(...)':
|
||||||
|
case 'NOT IN':
|
||||||
|
case 'NOT IN(...)':
|
||||||
|
$where[] = [$k, str_replace('(...)', '', $sym), is_array($v) ? $v : explode(',', $v)];
|
||||||
|
break;
|
||||||
|
case 'BETWEEN':
|
||||||
|
case 'NOT BETWEEN':
|
||||||
|
$arr = array_slice(explode(',', $v), 0, 2);
|
||||||
|
if (stripos($v, ',') === false || !array_filter($arr, function ($v) {
|
||||||
|
return $v != '' && $v !== false && $v !== null;
|
||||||
|
})) {
|
||||||
|
continue 2;
|
||||||
|
}
|
||||||
|
//当出现一边为空时改变操作符
|
||||||
|
if ($arr[0] === '') {
|
||||||
|
$sym = $sym == 'BETWEEN' ? '<=' : '>';
|
||||||
|
$arr = $arr[1];
|
||||||
|
} elseif ($arr[1] === '') {
|
||||||
|
$sym = $sym == 'BETWEEN' ? '>=' : '<';
|
||||||
|
$arr = $arr[0];
|
||||||
|
}
|
||||||
|
$where[] = [$k, $sym, $arr];
|
||||||
|
break;
|
||||||
|
case 'RANGE':
|
||||||
|
case 'NOT RANGE':
|
||||||
|
$v = str_replace(' - ', ',', $v);
|
||||||
|
$arr = array_slice(explode(',', $v), 0, 2);
|
||||||
|
if (stripos($v, ',') === false || !array_filter($arr)) {
|
||||||
|
continue 2;
|
||||||
|
}
|
||||||
|
//当出现一边为空时改变操作符
|
||||||
|
if ($arr[0] === '') {
|
||||||
|
$sym = $sym == 'RANGE' ? '<=' : '>';
|
||||||
|
$arr = $arr[1];
|
||||||
|
} elseif ($arr[1] === '') {
|
||||||
|
$sym = $sym == 'RANGE' ? '>=' : '<';
|
||||||
|
$arr = $arr[0];
|
||||||
|
}
|
||||||
|
$tableArr = explode('.', $k);
|
||||||
|
if (count($tableArr) > 1 && $tableArr[0] != $name && !in_array($tableArr[0], $alias)
|
||||||
|
&& !empty($this->model) && $this->relationSearch) {
|
||||||
|
//修复关联模型下时间无法搜索的BUG
|
||||||
|
$relation = Loader::parseName($tableArr[0], 1, false);
|
||||||
|
$alias[$this->model->$relation()->getTable()] = $tableArr[0];
|
||||||
|
}
|
||||||
|
$where[] = [$k, str_replace('RANGE', 'BETWEEN', $sym) . ' TIME', $arr];
|
||||||
|
break;
|
||||||
|
case 'NULL':
|
||||||
|
case 'IS NULL':
|
||||||
|
case 'NOT NULL':
|
||||||
|
case 'IS NOT NULL':
|
||||||
|
$where[] = [$k, strtolower(str_replace('IS ', '', $sym))];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
$index++;
|
||||||
|
}
|
||||||
|
if (!empty($this->model)) {
|
||||||
|
$this->model->alias($alias);
|
||||||
|
}
|
||||||
|
$model = $this->model;
|
||||||
|
$where = function ($query) use ($where, $alias, $bind, &$model) {
|
||||||
|
if (!empty($model)) {
|
||||||
|
$model->alias($alias);
|
||||||
|
$model->bind($bind);
|
||||||
|
}
|
||||||
|
foreach ($where as $k => $v) {
|
||||||
|
if (is_array($v)) {
|
||||||
|
call_user_func_array([$query, 'where'], $v);
|
||||||
|
} else {
|
||||||
|
$query->where($v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return [$where, $sort, $order, $offset, $limit, $page, $alias, $bind];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取数据限制的管理员ID
|
||||||
|
* 禁用数据限制时返回的是null
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
protected function getDataLimitAdminIds()
|
||||||
|
{
|
||||||
|
if (!$this->dataLimit) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if ($this->auth->isSuperAdmin()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
$adminIds = [];
|
||||||
|
if (in_array($this->dataLimit, ['auth', 'personal'])) {
|
||||||
|
$adminIds = $this->dataLimit == 'auth' ? $this->auth->getChildrenAdminIds(true) : [$this->auth->id];
|
||||||
|
}
|
||||||
|
return $adminIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Selectpage的实现方法
|
||||||
|
*
|
||||||
|
* 当前方法只是一个比较通用的搜索匹配,请按需重载此方法来编写自己的搜索逻辑,$where按自己的需求写即可
|
||||||
|
* 这里示例了所有的参数,所以比较复杂,实现上自己实现只需简单的几行即可
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
protected function selectpage()
|
||||||
|
{
|
||||||
|
//设置过滤方法
|
||||||
|
$this->request->filter(['trim', 'strip_tags', 'htmlspecialchars']);
|
||||||
|
|
||||||
|
//搜索关键词,客户端输入以空格分开,这里接收为数组
|
||||||
|
$word = (array)$this->request->request("q_word/a");
|
||||||
|
//当前页
|
||||||
|
$page = $this->request->request("pageNumber");
|
||||||
|
//分页大小
|
||||||
|
$pagesize = $this->request->request("pageSize");
|
||||||
|
//搜索条件
|
||||||
|
$andor = $this->request->request("andOr", "and", "strtoupper");
|
||||||
|
//排序方式
|
||||||
|
$orderby = (array)$this->request->request("orderBy/a");
|
||||||
|
//显示的字段
|
||||||
|
$field = $this->request->request("showField");
|
||||||
|
//主键
|
||||||
|
$primarykey = $this->request->request("keyField");
|
||||||
|
//主键值
|
||||||
|
$primaryvalue = $this->request->request("keyValue");
|
||||||
|
//搜索字段
|
||||||
|
$searchfield = (array)$this->request->request("searchField/a");
|
||||||
|
//自定义搜索条件
|
||||||
|
$custom = (array)$this->request->request("custom/a");
|
||||||
|
//是否返回树形结构
|
||||||
|
$istree = $this->request->request("isTree", 0);
|
||||||
|
$ishtml = $this->request->request("isHtml", 0);
|
||||||
|
if ($istree) {
|
||||||
|
$word = [];
|
||||||
|
$pagesize = 999999;
|
||||||
|
}
|
||||||
|
$order = [];
|
||||||
|
foreach ($orderby as $k => $v) {
|
||||||
|
$order[$v[0]] = $v[1];
|
||||||
|
}
|
||||||
|
$field = $field ? $field : 'name';
|
||||||
|
|
||||||
|
//如果有primaryvalue,说明当前是初始化传值
|
||||||
|
if ($primaryvalue !== null) {
|
||||||
|
$where = [$primarykey => ['in', $primaryvalue]];
|
||||||
|
$pagesize = 999999;
|
||||||
|
} else {
|
||||||
|
$where = function ($query) use ($word, $andor, $field, $searchfield, $custom) {
|
||||||
|
$logic = $andor == 'AND' ? '&' : '|';
|
||||||
|
$searchfield = is_array($searchfield) ? implode($logic, $searchfield) : $searchfield;
|
||||||
|
$searchfield = str_replace(',', $logic, $searchfield);
|
||||||
|
$word = array_filter(array_unique($word));
|
||||||
|
if (count($word) == 1) {
|
||||||
|
$query->where($searchfield, "like", "%" . reset($word) . "%");
|
||||||
|
} else {
|
||||||
|
$query->where(function ($query) use ($word, $searchfield) {
|
||||||
|
foreach ($word as $index => $item) {
|
||||||
|
$query->whereOr(function ($query) use ($item, $searchfield) {
|
||||||
|
$query->where($searchfield, "like", "%{$item}%");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if ($custom && is_array($custom)) {
|
||||||
|
foreach ($custom as $k => $v) {
|
||||||
|
if (is_array($v) && 2 == count($v)) {
|
||||||
|
$query->where($k, trim($v[0]), $v[1]);
|
||||||
|
} else {
|
||||||
|
$query->where($k, '=', $v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
$adminIds = $this->getDataLimitAdminIds();
|
||||||
|
if (is_array($adminIds)) {
|
||||||
|
$this->model->where($this->dataLimitField, 'in', $adminIds);
|
||||||
|
}
|
||||||
|
$list = [];
|
||||||
|
$total = $this->model->where($where)->count();
|
||||||
|
if ($total > 0) {
|
||||||
|
if (is_array($adminIds)) {
|
||||||
|
$this->model->where($this->dataLimitField, 'in', $adminIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
$fields = is_array($this->selectpageFields) ? $this->selectpageFields : ($this->selectpageFields && $this->selectpageFields != '*' ? explode(',', $this->selectpageFields) : []);
|
||||||
|
|
||||||
|
//如果有primaryvalue,说明当前是初始化传值,按照选择顺序排序
|
||||||
|
if ($primaryvalue !== null && preg_match("/^[a-z0-9_\-]+$/i", $primarykey)) {
|
||||||
|
$primaryvalue = array_unique(is_array($primaryvalue) ? $primaryvalue : explode(',', $primaryvalue));
|
||||||
|
//修复自定义data-primary-key为字符串内容时,给排序字段添加上引号
|
||||||
|
$primaryvalue = array_map(function ($value) {
|
||||||
|
return '\'' . $value . '\'';
|
||||||
|
}, $primaryvalue);
|
||||||
|
|
||||||
|
$primaryvalue = implode(',', $primaryvalue);
|
||||||
|
|
||||||
|
$this->model->orderRaw("FIELD(`{$primarykey}`, {$primaryvalue})");
|
||||||
|
} else {
|
||||||
|
$this->model->order($order);
|
||||||
|
}
|
||||||
|
|
||||||
|
$datalist = $this->model->where($where)
|
||||||
|
->page($page, $pagesize)
|
||||||
|
->select();
|
||||||
|
|
||||||
|
foreach ($datalist as $index => $item) {
|
||||||
|
unset($item['password'], $item['salt']);
|
||||||
|
if ($this->selectpageFields == '*') {
|
||||||
|
$result = [
|
||||||
|
$primarykey => $item[$primarykey] ?? '',
|
||||||
|
$field => $item[$field] ?? '',
|
||||||
|
];
|
||||||
|
} else {
|
||||||
|
$result = array_intersect_key(($item instanceof Model ? $item->toArray() : (array)$item), array_flip($fields));
|
||||||
|
}
|
||||||
|
$result['pid'] = isset($item['pid']) ? $item['pid'] : (isset($item['parent_id']) ? $item['parent_id'] : 0);
|
||||||
|
$result = array_map("htmlentities", $result);
|
||||||
|
$list[] = $result;
|
||||||
|
}
|
||||||
|
if ($istree && !$primaryvalue) {
|
||||||
|
$tree = Tree::instance();
|
||||||
|
$tree->init(collection($list)->toArray(), 'pid');
|
||||||
|
$list = $tree->getTreeList($tree->getTreeArray(0), $field);
|
||||||
|
if (!$ishtml) {
|
||||||
|
foreach ($list as &$item) {
|
||||||
|
$item = str_replace(' ', ' ', $item);
|
||||||
|
}
|
||||||
|
unset($item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//这里一定要返回有list这个字段,total是可选的,如果total<=list的数量,则会隐藏分页按钮
|
||||||
|
return json(['list' => $list, 'total' => $total]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 刷新Token
|
||||||
|
*/
|
||||||
|
protected function token()
|
||||||
|
{
|
||||||
|
$token = $this->request->param('__token__');
|
||||||
|
|
||||||
|
//验证Token
|
||||||
|
if (!Validate::make()->check(['__token__' => $token], ['__token__' => 'require|token'])) {
|
||||||
|
$this->error(__('Token verification error'), '', ['__token__' => $this->request->token()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
//刷新Token
|
||||||
|
$this->request->token();
|
||||||
|
}
|
||||||
|
}
|
||||||
1
application/guildAdmin/common.php
Normal file
1
application/guildAdmin/common.php
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<?php
|
||||||
6
application/guildAdmin/config.php
Normal file
6
application/guildAdmin/config.php
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
//配置文件
|
||||||
|
return [
|
||||||
|
'exception_handle' => '\\app\\adminapi\\library\\ExceptionHandle',
|
||||||
|
];
|
||||||
713
application/guildAdmin/controller/Admin.php
Normal file
713
application/guildAdmin/controller/Admin.php
Normal file
@@ -0,0 +1,713 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\guildAdmin\controller;
|
||||||
|
|
||||||
|
use app\admin\command\Menu;
|
||||||
|
use app\GuildAdmin\model\AuthGroup;
|
||||||
|
use app\GuildAdmin\model\AuthGroupAccess;
|
||||||
|
use app\GuildAdmin\model\AuthRule;
|
||||||
|
use app\common\controller\GuildAdmin;
|
||||||
|
use fast\Random;
|
||||||
|
use fast\Tree;
|
||||||
|
use think\Cache;
|
||||||
|
use think\Db;
|
||||||
|
use think\Exception;
|
||||||
|
use think\Session;
|
||||||
|
use think\Validate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 管理员管理
|
||||||
|
*
|
||||||
|
* @icon fa fa-users
|
||||||
|
* @remark 一个管理员可以有多个角色组,左侧的菜单根据管理员所拥有的权限进行生成
|
||||||
|
*/
|
||||||
|
class Admin extends GuildAdmin
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \app\admin\model\Admin
|
||||||
|
*/
|
||||||
|
protected $model = null;
|
||||||
|
protected $authRuleModel = null;
|
||||||
|
protected $childrenGroupIds = [];
|
||||||
|
protected $childrenAdminIds = [];
|
||||||
|
|
||||||
|
protected $guildId = null;
|
||||||
|
|
||||||
|
public function _initialize()
|
||||||
|
{
|
||||||
|
parent::_initialize();
|
||||||
|
$this->model = model('GuildAdmin/Admin');
|
||||||
|
$this->authRuleModel = model('GuildAdmin/AuthRule');
|
||||||
|
$this->authGroup = model('GuildAdmin/AuthGroup');
|
||||||
|
$this->guildId = Session::get('guild_id');
|
||||||
|
$this->childrenAdminIds = $this->auth->getChildrenAdminIds($this->auth->isSuperAdmin());
|
||||||
|
$this->childrenGroupIds = $this->auth->getChildrenGroupIds($this->auth->isSuperAdmin());
|
||||||
|
$groupList = collection(AuthGroup::where('id', 'in', $this->childrenGroupIds)->where('guild_id', $this->guildId)->select())->toArray();
|
||||||
|
Tree::instance()->init($groupList);
|
||||||
|
$groupdata = [];
|
||||||
|
if ($this->auth->isSuperAdmin()) {
|
||||||
|
$result = Tree::instance()->getTreeList(Tree::instance()->getTreeArray(0));
|
||||||
|
foreach ($result as $k => $v) {
|
||||||
|
$groupdata[$v['id']] = $v['name'];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$result = [];
|
||||||
|
$groups = $this->auth->getGroups();
|
||||||
|
foreach ($groups as $m => $n) {
|
||||||
|
$childlist = Tree::instance()->getTreeList(Tree::instance()->getTreeArray($n['id']));
|
||||||
|
$temp = [];
|
||||||
|
foreach ($childlist as $k => $v) {
|
||||||
|
$temp[$v['id']] = $v['name'];
|
||||||
|
}
|
||||||
|
$result[__($n['name'])] = $temp;
|
||||||
|
}
|
||||||
|
$groupdata = $result;
|
||||||
|
}
|
||||||
|
$this->assignconfig("admin", ['id' => $this->auth->id]);
|
||||||
|
|
||||||
|
$this->childrenGroupIds = $this->auth->getChildrenGroupIds(true);
|
||||||
|
$groupList = collection(AuthGroup::where('id', 'in', $this->childrenGroupIds)->where('guild_id', $this->guildId)->select())->toArray();
|
||||||
|
Tree::instance()->init($groupList);
|
||||||
|
$groupList = [];
|
||||||
|
if ($this->auth->isSuperAdmin()) {
|
||||||
|
$groupList = Tree::instance()->getTreeList(Tree::instance()->getTreeArray(0));
|
||||||
|
} else {
|
||||||
|
$groups = $this->auth->getGroups();
|
||||||
|
$groupIds = [];
|
||||||
|
foreach ($groups as $m => $n) {
|
||||||
|
if (in_array($n['id'], $groupIds) || in_array($n['pid'], $groupIds)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$groupList = array_merge($groupList, Tree::instance()->getTreeList(Tree::instance()->getTreeArray($n['pid'])));
|
||||||
|
foreach ($groupList as $index => $item) {
|
||||||
|
$groupIds[] = $item['id'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$groupName = [];
|
||||||
|
foreach ($groupList as $k => $v) {
|
||||||
|
$groupName[$v['id']] = $v['name'];
|
||||||
|
}
|
||||||
|
$this->grouplist = $groupList;
|
||||||
|
$this->groupdata = $groupName;
|
||||||
|
$this->assignconfig("admin", ['id' => $this->auth->id, 'group_ids' => $this->auth->getGroupIds()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 权限列表
|
||||||
|
*/
|
||||||
|
public function auth_index()
|
||||||
|
{
|
||||||
|
$ruleList = db::name("vs_guild_admin_auth")->field('type,condition,remark,createtime,updatetime', true)->order('weigh DESC,id ASC')->select();
|
||||||
|
foreach ($ruleList as $k => &$v) {
|
||||||
|
$v['title'] = __($v['title']);
|
||||||
|
}
|
||||||
|
unset($v);
|
||||||
|
Tree::instance()->init($ruleList);
|
||||||
|
$ruleList = Tree::instance()->getTreeArray(0);
|
||||||
|
$ruledata = [0 => __('None')];
|
||||||
|
foreach ($ruleList as $k => &$v) {
|
||||||
|
if (!$v['ismenu']) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$ruledata[$v['id']] = $v['title'];
|
||||||
|
unset($v['spacer']);
|
||||||
|
}
|
||||||
|
unset($v);
|
||||||
|
$list = $ruleList;
|
||||||
|
$total = count($ruleList);
|
||||||
|
$result = array("total" => $total, "rows" => $list);
|
||||||
|
return V(1,"菜单规则列表", $result);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 权限添加
|
||||||
|
*/
|
||||||
|
public function auth_add()
|
||||||
|
{
|
||||||
|
if ($this->request->isPost()) {
|
||||||
|
$params = $this->request->post();
|
||||||
|
if ($params) {
|
||||||
|
if (!$params['ismenu'] && !$params['pid']) {
|
||||||
|
return V(0,'非菜单规则节点必须有父级', null);
|
||||||
|
}
|
||||||
|
$result = $this->authRuleModel->validate('app\admin\validate\AuthRule')->save($params);
|
||||||
|
if ($result === false) {
|
||||||
|
return V(0,'操作失败', null);
|
||||||
|
}
|
||||||
|
return V(1,'操作成功', null);
|
||||||
|
}
|
||||||
|
return V(0,'操作失败', null);
|
||||||
|
}
|
||||||
|
return V(0,'操作失败', null);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 权限编辑
|
||||||
|
*/
|
||||||
|
public function auth_edit($ids = NULL)
|
||||||
|
{
|
||||||
|
if ($this->request->isPost()) {
|
||||||
|
$params = $this->request->post();
|
||||||
|
if ($params) {
|
||||||
|
if (!$params['ismenu'] && !$params['pid']) {
|
||||||
|
return V(0,'非菜单规则节点必须有父级', null);
|
||||||
|
}
|
||||||
|
if ($params['pid'] == $params['id']) {
|
||||||
|
return V(0,'父级不能是它自己', null);
|
||||||
|
}
|
||||||
|
if ($params['pid'] != $params['pid']) {
|
||||||
|
$childrenIds = Tree::instance()->init(collection(AuthRule::select())->toArray())->getChildrenIds($params['id']);
|
||||||
|
if (in_array($params['pid'], $childrenIds)) {
|
||||||
|
return V(0,'父组别不能是它的子组别', null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//这里需要针对name做唯一验证
|
||||||
|
$ruleValidate = \think\Loader::validate('app\admin\validate\AuthRule');
|
||||||
|
$ruleValidate->rule([
|
||||||
|
'name' => 'require|unique:AuthRule,name,' . $params['id'],
|
||||||
|
]);
|
||||||
|
$result = $this->authRuleModel->validate('app\admin\validate\AuthRule')->save($params, $params['id']);
|
||||||
|
if ($result === false) {
|
||||||
|
return V(0,'操作失败', null);
|
||||||
|
}
|
||||||
|
return V(1,'操作成功', null);
|
||||||
|
}
|
||||||
|
return V(0,'操作失败', null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 权限详情
|
||||||
|
*/
|
||||||
|
public function auth_detail(){
|
||||||
|
$id = $this->request->param('id');
|
||||||
|
$row = $this->authRuleModel->get($id);
|
||||||
|
if (!$row) {
|
||||||
|
return V(0,'操作失败', null);
|
||||||
|
}
|
||||||
|
return V(1,"详情", $row);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 权限删除
|
||||||
|
*/
|
||||||
|
public function auth_del($ids = "")
|
||||||
|
{
|
||||||
|
$ids = input('ids', '');
|
||||||
|
if ($ids) {
|
||||||
|
$delIds = [];
|
||||||
|
foreach (explode(',', $ids) as $k => $v) {
|
||||||
|
$delIds = array_merge($delIds, Tree::instance()->getChildrenIds($v, true));
|
||||||
|
}
|
||||||
|
$delIds = array_unique($delIds);
|
||||||
|
$count = $this->authRuleModel->where('id', 'in', $delIds)->delete();
|
||||||
|
if ($count) {
|
||||||
|
Cache::rm('__guild_menu__');
|
||||||
|
return V(1,'操作成功', null);return V(1,'操作成功', null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return V(0,'操作失败', null);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* 菜单接口
|
||||||
|
*/
|
||||||
|
public function menus(){
|
||||||
|
$ruleList = Tree::instance()->getTreeArray(0);
|
||||||
|
$ruleList = $this->getTree($ruleList,['title','url','name','icon','extend']);
|
||||||
|
return V(1,"系统菜单接口", $ruleList);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 角色列表
|
||||||
|
*/
|
||||||
|
public function role_index()
|
||||||
|
{
|
||||||
|
$list = $this->grouplist;
|
||||||
|
$total = count($list);
|
||||||
|
$result = array("total" => $total, "list" => $list);
|
||||||
|
return V(1,"角色管理列表", $result);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 角色添加
|
||||||
|
*/
|
||||||
|
public function role_add()
|
||||||
|
{
|
||||||
|
if ($this->request->isPost()) {
|
||||||
|
$params = $this->request->post();
|
||||||
|
$params['rules'] = explode(',', $params['rules']);
|
||||||
|
if (!in_array($params['pid'], $this->childrenGroupIds)) {
|
||||||
|
return V(0,'请选择正确的父角色', null);
|
||||||
|
}
|
||||||
|
$parentmodel = model("guildAdmin/AuthGroup")->get($params['pid']);
|
||||||
|
if (!$parentmodel) {
|
||||||
|
return V(0,'请选择正确的父角色', null);
|
||||||
|
}
|
||||||
|
// 父级别的规则节点
|
||||||
|
$parentrules = explode(',', $parentmodel->rules);
|
||||||
|
// 当前组别的规则节点
|
||||||
|
$currentrules = $this->auth->getRuleIds();
|
||||||
|
$rules = $params['rules'];
|
||||||
|
// 如果父组不是超级管理员则需要过滤规则节点,不能超过父组别的权限
|
||||||
|
$rules = in_array('*', $parentrules) ? $rules : array_intersect($parentrules, $rules);
|
||||||
|
// 如果当前组别不是超级管理员则需要过滤规则节点,不能超当前组别的权限
|
||||||
|
$rules = in_array('*', $currentrules) ? $rules : array_intersect($currentrules, $rules);
|
||||||
|
$params['rules'] = implode(',', $rules);
|
||||||
|
if ($params) {
|
||||||
|
$params['guild_id'] = $this->guildId;
|
||||||
|
$this->authGroup->create($params);
|
||||||
|
return V(1,"成功", null);
|
||||||
|
}
|
||||||
|
return V(0,'操作失败', null);
|
||||||
|
}
|
||||||
|
return V(0,'操作失败', null);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 角色编辑
|
||||||
|
*/
|
||||||
|
public function role_edit($ids = null)
|
||||||
|
{
|
||||||
|
$params = $this->request->post();
|
||||||
|
$id = $params['id'];
|
||||||
|
if (!in_array($id, $this->childrenGroupIds)) {
|
||||||
|
return V(0,'你没有权限访问', null);
|
||||||
|
}
|
||||||
|
$row = $this->authGroup->get(['id' => $id]);
|
||||||
|
if (!$row) {
|
||||||
|
return V(0,'角色不存在', null);
|
||||||
|
}
|
||||||
|
if ($this->request->isPost()) {
|
||||||
|
//父节点不能是非权限内节点
|
||||||
|
if (!in_array($params['pid'], $this->childrenGroupIds)) {
|
||||||
|
return V(0,'请选择正确的父角色', null);
|
||||||
|
}
|
||||||
|
// 父节点不能是它自身的子节点或自己本身
|
||||||
|
if (in_array($params['pid'], Tree::instance()->getChildrenIds($row->id, true))) {
|
||||||
|
return V(0,'父节点不能是它自身的子节点或自己本身', null);
|
||||||
|
}
|
||||||
|
$params['rules'] = explode(',', $params['rules']);
|
||||||
|
|
||||||
|
$parentmodel = model("GuildAdmin/AuthGroup")->get($params['pid']);
|
||||||
|
if (!$parentmodel) {
|
||||||
|
return V(0,'请选择正确的父角色', null);
|
||||||
|
}
|
||||||
|
// 父级别的规则节点
|
||||||
|
$parentrules = explode(',', $parentmodel->rules);
|
||||||
|
// 当前组别的规则节点
|
||||||
|
$currentrules = $this->auth->getRuleIds();
|
||||||
|
$rules = $params['rules'];
|
||||||
|
// 如果父组不是超级管理员则需要过滤规则节点,不能超过父组别的权限
|
||||||
|
$rules = in_array('*', $parentrules) ? $rules : array_intersect($parentrules, $rules);
|
||||||
|
// 如果当前组别不是超级管理员则需要过滤规则节点,不能超当前组别的权限
|
||||||
|
$rules = in_array('*', $currentrules) ? $rules : array_intersect($currentrules, $rules);
|
||||||
|
$params['rules'] = implode(',', $rules);
|
||||||
|
if ($params) {
|
||||||
|
Db::startTrans();
|
||||||
|
try {
|
||||||
|
$row->save($params);
|
||||||
|
$children_auth_groups = model("GuildAdmin/AuthGroup")->all(['id' => ['in', implode(',', (Tree::instance()->getChildrenIds($row->id)))]]);
|
||||||
|
$childparams = [];
|
||||||
|
foreach ($children_auth_groups as $key => $children_auth_group) {
|
||||||
|
$childparams[$key]['id'] = $children_auth_group->id;
|
||||||
|
$childparams[$key]['rules'] = implode(',', array_intersect(explode(',', $children_auth_group->rules), $rules));
|
||||||
|
}
|
||||||
|
model("GuildAdmin/AuthGroup")->saveAll($childparams);
|
||||||
|
Db::commit();
|
||||||
|
return V(1,"成功", null);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
Db::rollback();
|
||||||
|
return V(0,'操作失败', null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return V(0,'操作失败', null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 角色详情
|
||||||
|
*/
|
||||||
|
public function role_detail(){
|
||||||
|
$id =input('id', 0);
|
||||||
|
if (!$id) {
|
||||||
|
return V(0,'参数错误', null);
|
||||||
|
}
|
||||||
|
$row = $this->authGroup->get($id);
|
||||||
|
if (!$row) {
|
||||||
|
return V(0,'数据不存在', null);
|
||||||
|
}
|
||||||
|
return V(1,'成功', $row);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 角色删除
|
||||||
|
*/
|
||||||
|
public function role_del($ids = null)
|
||||||
|
{
|
||||||
|
$ids = $ids ? $ids : $this->request->post("ids");
|
||||||
|
if (!$ids) {
|
||||||
|
return V(0,'参数错误', null);
|
||||||
|
}
|
||||||
|
$ids = explode(',', $ids);
|
||||||
|
$grouplist = $this->auth->getGroups();
|
||||||
|
$group_ids = array_map(function ($group) {
|
||||||
|
return $group['id'];
|
||||||
|
}, $grouplist);
|
||||||
|
// 移除掉当前管理员所在组别
|
||||||
|
$ids = array_diff($ids, $group_ids);
|
||||||
|
|
||||||
|
// 循环判断每一个组别是否可删除
|
||||||
|
$grouplist = $this->authGroup->where('id', 'in', $ids)->select();
|
||||||
|
$groupaccessmodel = model('GuildAdmin/AuthGroupAccess');
|
||||||
|
foreach ($grouplist as $k => $v) {
|
||||||
|
// 当前组别下有管理员
|
||||||
|
$groupone = $groupaccessmodel->get(['group_id' => $v['id']]);
|
||||||
|
if ($groupone) {
|
||||||
|
$ids = array_diff($ids, [$v['id']]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// 当前组别下有子组别
|
||||||
|
$groupone = $this->authGroup->get(['pid' => $v['id']]);
|
||||||
|
if ($groupone) {
|
||||||
|
$ids = array_diff($ids, [$v['id']]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$count = $this->authGroup->where('id', 'in', $ids)->delete();
|
||||||
|
if ($count) {
|
||||||
|
return V(1,'成功', $count);
|
||||||
|
}
|
||||||
|
return V(0,'操作失败', null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 读取角色权限树
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
public function role_tree()
|
||||||
|
{
|
||||||
|
$model = model('GuildAdmin/AuthGroup');
|
||||||
|
$id = $this->request->post("id");
|
||||||
|
$pid = $this->request->post("pid");
|
||||||
|
$parentGroupModel = $model->get($pid);
|
||||||
|
|
||||||
|
$currentGroupModel = null;
|
||||||
|
if ($id) {
|
||||||
|
$currentGroupModel = $model->get($id);
|
||||||
|
}
|
||||||
|
if (($pid || $parentGroupModel) && (!$id || $currentGroupModel)) {
|
||||||
|
$id = $id ? $id : null;
|
||||||
|
$ruleList = collection(model('GuildAdmin/AuthRule')->order('weigh', 'desc')->order('id', 'asc')->select())->toArray();
|
||||||
|
//读取父类角色所有节点列表
|
||||||
|
$parentRuleList = [];
|
||||||
|
if (in_array('*', explode(',', $parentGroupModel->rules))) {
|
||||||
|
$parentRuleList = $ruleList;
|
||||||
|
} else {
|
||||||
|
$parentRuleIds = explode(',', $parentGroupModel->rules);
|
||||||
|
foreach ($ruleList as $k => $v) {
|
||||||
|
if (in_array($v['id'], $parentRuleIds)) {
|
||||||
|
$parentRuleList[] = $v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$ruleTree = new Tree();
|
||||||
|
$groupTree = new Tree();
|
||||||
|
//当前所有正常规则列表
|
||||||
|
$ruleTree->init($parentRuleList);
|
||||||
|
//角色组列表
|
||||||
|
$groupTree->init(collection(model('GuildAdmin/AuthGroup')->where('id', 'in', $this->childrenGroupIds)->select())->toArray());
|
||||||
|
|
||||||
|
//读取当前角色下规则ID集合
|
||||||
|
$adminRuleIds = $this->auth->getRuleIds();
|
||||||
|
//是否是超级管理员
|
||||||
|
$superadmin = $this->auth->isSuperAdmin();
|
||||||
|
//当前拥有的规则ID集合
|
||||||
|
$currentRuleIds = $id ? explode(',', $currentGroupModel->rules) : [];
|
||||||
|
|
||||||
|
if (!$id || !in_array($pid, $this->childrenGroupIds) || !in_array($pid, $groupTree->getChildrenIds($id, true))) {
|
||||||
|
$parentRuleList = $ruleTree->getTreeList($ruleTree->getTreeArray(0), 'name');
|
||||||
|
$hasChildrens = [];
|
||||||
|
foreach ($parentRuleList as $k => $v) {
|
||||||
|
if ($v['haschild']) {
|
||||||
|
$hasChildrens[] = $v['id'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$parentRuleIds = array_map(function ($item) {
|
||||||
|
return $item['id'];
|
||||||
|
}, $parentRuleList);
|
||||||
|
$nodeList = [];
|
||||||
|
foreach ($parentRuleList as $k => $v) {
|
||||||
|
if (!$superadmin && !in_array($v['id'], $adminRuleIds)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ($v['pid'] && !in_array($v['pid'], $parentRuleIds)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$state = array('selected' => in_array($v['id'], $currentRuleIds) && !in_array($v['id'], $hasChildrens));
|
||||||
|
$nodeList[] = array('id' => $v['id'], 'parent' => $v['pid'] ? $v['pid'] : '#', 'text' => __($v['title']), 'type' => 'menu', 'state' => $state);
|
||||||
|
}
|
||||||
|
return V(1,'成功', $nodeList);
|
||||||
|
} else {
|
||||||
|
return V(0,'父组别不能是它的子组别或它自己', null);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return V(0,'角色未找到', null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查看
|
||||||
|
*/
|
||||||
|
public function admin_index()
|
||||||
|
{
|
||||||
|
//设置过滤方法
|
||||||
|
$this->request->filter(['strip_tags', 'trim']);
|
||||||
|
//如果发送的来源是Selectpage,则转发到Selectpage
|
||||||
|
if ($this->request->request('keyField')) {
|
||||||
|
return $this->selectpage();
|
||||||
|
}
|
||||||
|
$childrenGroupIds = $this->childrenGroupIds;
|
||||||
|
$groupName = AuthGroup::where('id', 'in', $childrenGroupIds)
|
||||||
|
->column('id,name');
|
||||||
|
$authGroupList = AuthGroupAccess::where('group_id', 'in', $childrenGroupIds)
|
||||||
|
->field('uid,group_id')
|
||||||
|
->select();
|
||||||
|
|
||||||
|
$adminGroupName = [];
|
||||||
|
foreach ($authGroupList as $k => $v) {
|
||||||
|
if (isset($groupName[$v['group_id']])) {
|
||||||
|
$adminGroupName[$v['uid']][$v['group_id']] = $groupName[$v['group_id']];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$groups = $this->auth->getGroups();
|
||||||
|
foreach ($groups as $m => $n) {
|
||||||
|
$adminGroupName[$this->auth->id][$n['id']] = $n['name'];
|
||||||
|
}
|
||||||
|
list($where, $sort, $order, $offset, $limit) = $this->buildparams();
|
||||||
|
$list = $this->model
|
||||||
|
->where($where)
|
||||||
|
->where('guild_id', $this->guildId)
|
||||||
|
->where('id', 'in', $this->childrenAdminIds)
|
||||||
|
->field(['password', 'salt', 'token'], true)
|
||||||
|
->order($sort, $order)
|
||||||
|
->paginate($limit);
|
||||||
|
|
||||||
|
foreach ($list as $k => &$v) {
|
||||||
|
$groups = isset($adminGroupName[$v['id']]) ? $adminGroupName[$v['id']] : [];
|
||||||
|
$v['groups'] = implode(',', array_keys($groups));
|
||||||
|
$v['groups_text'] = implode(',', array_values($groups));
|
||||||
|
}
|
||||||
|
unset($v);
|
||||||
|
$result = array("total" => $list->total(), "rows" => $list->items());
|
||||||
|
return V(1,"管理员列表", $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 管理员添加
|
||||||
|
* username
|
||||||
|
* email
|
||||||
|
* mobile
|
||||||
|
* nickname
|
||||||
|
* password
|
||||||
|
* status
|
||||||
|
*/
|
||||||
|
public function admin_add()
|
||||||
|
{
|
||||||
|
$params = $this->request->Post();
|
||||||
|
if (empty($params)) {
|
||||||
|
return V(0,"参数错误", []);
|
||||||
|
}
|
||||||
|
if (!Validate::is($params['password'], '\S{6,30}')) {
|
||||||
|
return V(0,"密码长度必须在6-30位之间,不能包含空格", []);
|
||||||
|
}
|
||||||
|
$group = $params['group'];
|
||||||
|
unset($params['group']);
|
||||||
|
unset($params['__token__']);
|
||||||
|
$group = explode(',',$group);
|
||||||
|
if ($params) {
|
||||||
|
Db::startTrans();
|
||||||
|
try {
|
||||||
|
$params['salt'] = Random::alnum();
|
||||||
|
$params['password'] = $this->auth->getEncryptPassword($params['password'], $params['salt']);
|
||||||
|
$params['avatar'] = '/assets/img/avatar.png'; //设置新管理员默认头像。
|
||||||
|
$params['guild_id'] = $this->guildId;
|
||||||
|
$result = $this->model->save($params);
|
||||||
|
if ($result === false) {
|
||||||
|
return V(0,"失败", []);
|
||||||
|
}
|
||||||
|
//过滤不允许的组别,避免越权
|
||||||
|
$group = array_intersect($this->childrenGroupIds, $group);
|
||||||
|
if (!$group) {
|
||||||
|
return V(0,"失败", []);
|
||||||
|
}
|
||||||
|
|
||||||
|
$dataset = [];
|
||||||
|
foreach ($group as $value) {
|
||||||
|
$dataset[] = ['uid' => $this->model->id, 'group_id' => $value];
|
||||||
|
}
|
||||||
|
model('guildAdmin/AuthGroupAccess')->saveAll($dataset);
|
||||||
|
Db::commit();
|
||||||
|
return V(1,"添加成功", []);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
Db::rollback();
|
||||||
|
return V(0,"失败", []);
|
||||||
|
$this->error($e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 管理员编辑
|
||||||
|
*/
|
||||||
|
public function admin_edit($ids = null)
|
||||||
|
{
|
||||||
|
if ($this->request->isPost()) {
|
||||||
|
$params = $this->request->post();
|
||||||
|
$group = $params['group']?? [];
|
||||||
|
unset($params['group']);
|
||||||
|
unset($params['__token__']);
|
||||||
|
if($group){
|
||||||
|
$group = explode(',',$group);
|
||||||
|
}
|
||||||
|
if ($params) {
|
||||||
|
Db::startTrans();
|
||||||
|
try {
|
||||||
|
if ($params['password']) {
|
||||||
|
if (!Validate::is($params['password'], '\S{6,30}')) {
|
||||||
|
return V(0,"密码长度必须在6-30位之间,不能包含空格", []);
|
||||||
|
}
|
||||||
|
$params['salt'] = Random::alnum();
|
||||||
|
$params['password'] = $this->auth->getEncryptPassword($params['password'], $params['salt']);
|
||||||
|
} else {
|
||||||
|
unset($params['password'], $params['salt']);
|
||||||
|
}
|
||||||
|
//这里需要针对username和email做唯一验证
|
||||||
|
$adminValidate = \think\Loader::validate('admin/Admin');
|
||||||
|
$adminValidate->rule([
|
||||||
|
'username' => 'require|regex:\w{3,30}|unique:admin,username,' . $params['id'],
|
||||||
|
'email' => 'require|email|unique:admin,email,' . $params['id'],
|
||||||
|
'mobile' => 'regex:1[3-9]\d{9}|unique:admin,mobile,' . $params['id'],
|
||||||
|
'password' => 'regex:\S{32}',
|
||||||
|
]);
|
||||||
|
$result = $this->model->save($params, $params['id']);
|
||||||
|
if ($result === false) {
|
||||||
|
return V(0,"失败", []);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!empty($group)){
|
||||||
|
// 先移除所有权限
|
||||||
|
model('guildAdmin/AuthGroupAccess')->where('uid', $params['id'])->delete();
|
||||||
|
// 过滤不允许的组别,避免越权
|
||||||
|
$group = array_intersect($this->childrenGroupIds, $group);
|
||||||
|
if (!$group) {
|
||||||
|
return V(0,"失败", []);
|
||||||
|
}
|
||||||
|
|
||||||
|
$dataset = [];
|
||||||
|
foreach ($group as $value) {
|
||||||
|
$dataset[] = ['uid' => $params['id'], 'group_id' => $value];
|
||||||
|
}
|
||||||
|
model('guildAdmin/AuthGroupAccess')->saveAll($dataset);
|
||||||
|
}
|
||||||
|
Db::commit();
|
||||||
|
return V(1,"成功", []);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
Db::rollback();
|
||||||
|
return V(0,"失败", []);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return V(0,"参数错误!", []);
|
||||||
|
}else{
|
||||||
|
return V(0,"参数错误!", []);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* 管理员详情
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public function admin_detail($ids = ""){
|
||||||
|
$id = $this->request->get('id');
|
||||||
|
if (!$id) {
|
||||||
|
return V(0,"未找到记录", []);
|
||||||
|
}
|
||||||
|
if (!in_array($id, $this->childrenAdminIds)) {
|
||||||
|
return V(0,"你没有权限访问", []);
|
||||||
|
}
|
||||||
|
$data = $this->model->where('id',$id)->find();
|
||||||
|
$grouplist = $this->auth->getGroups($id);
|
||||||
|
$groupids = [];
|
||||||
|
foreach ($grouplist as $k => $v) {
|
||||||
|
$groupids[] = $v['id'];
|
||||||
|
}
|
||||||
|
$result = [];
|
||||||
|
$result['row'] = $data;
|
||||||
|
$result['groupids'] = $groupids;
|
||||||
|
return V(1,"管理员详情", $result);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* 管理员状态修改
|
||||||
|
*/
|
||||||
|
public function admin_change_status(){
|
||||||
|
if (!$this->request->isPost()) {
|
||||||
|
return V(0,"失败", []);
|
||||||
|
}
|
||||||
|
$id = $this->request->post("id");
|
||||||
|
if (empty($id)) {
|
||||||
|
return V(0,"失败", []);
|
||||||
|
}
|
||||||
|
if($id==1){
|
||||||
|
return V(0,"超级管理员不能修改状态", []);
|
||||||
|
}
|
||||||
|
$status = $this->request->post("status");
|
||||||
|
$data = [];
|
||||||
|
$data['status'] = $status;
|
||||||
|
$res = Db::name("vs_guild_admin")->where("id",$id)->update($data);
|
||||||
|
if ($res) {
|
||||||
|
return V(1,"成功", []);
|
||||||
|
}else{
|
||||||
|
return V(0,"失败", []);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除
|
||||||
|
*/
|
||||||
|
public function admin_del($ids = "")
|
||||||
|
{
|
||||||
|
if (!$this->request->isPost()) {
|
||||||
|
return V(0,"失败", []);
|
||||||
|
}
|
||||||
|
$ids = $ids ? $ids : $this->request->post("id");
|
||||||
|
if ($ids) {
|
||||||
|
$ids = array_intersect($this->childrenAdminIds, array_filter(explode(',', $ids)));
|
||||||
|
// 避免越权删除管理员
|
||||||
|
$childrenGroupIds = $this->childrenGroupIds;
|
||||||
|
$adminList = $this->model->where('id', 'in', $ids)->where('id', 'in', function ($query) use ($childrenGroupIds) {
|
||||||
|
$query->name('vs_guild_admin_auth_group_access')->where('group_id', 'in', $childrenGroupIds)->field('uid');
|
||||||
|
})->select();
|
||||||
|
if ($adminList) {
|
||||||
|
$deleteIds = [];
|
||||||
|
foreach ($adminList as $k => $v) {
|
||||||
|
$deleteIds[] = $v->id;
|
||||||
|
}
|
||||||
|
$deleteIds = array_values(array_diff($deleteIds, [$this->auth->id]));
|
||||||
|
if ($deleteIds) {
|
||||||
|
Db::startTrans();
|
||||||
|
try {
|
||||||
|
$this->model->destroy($deleteIds);
|
||||||
|
model('guildAdmin/AuthGroupAccess')->where('uid', 'in', $deleteIds)->delete();
|
||||||
|
Db::commit();
|
||||||
|
return V(1,"成功", []);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
Db::rollback();
|
||||||
|
return V(0,"失败", []);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return V(0,"失败", []);
|
||||||
|
}
|
||||||
|
}
|
||||||
220
application/guildAdmin/controller/GuildData.php
Normal file
220
application/guildAdmin/controller/GuildData.php
Normal file
@@ -0,0 +1,220 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\guildAdmin\controller;
|
||||||
|
|
||||||
|
use app\admin\command\Menu;
|
||||||
|
use app\GuildAdmin\model\AuthGroup;
|
||||||
|
use app\GuildAdmin\model\AuthGroupAccess;
|
||||||
|
use app\GuildAdmin\model\AuthRule;
|
||||||
|
use app\common\controller\GuildAdmin;
|
||||||
|
use fast\Random;
|
||||||
|
use fast\Tree;
|
||||||
|
use think\Cache;
|
||||||
|
use think\Db;
|
||||||
|
use think\Exception;
|
||||||
|
use think\Hook;
|
||||||
|
use think\Session;
|
||||||
|
use think\Validate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 管理员管理
|
||||||
|
*
|
||||||
|
* @icon fa fa-users
|
||||||
|
* @remark 一个管理员可以有多个角色组,左侧的菜单根据管理员所拥有的权限进行生成
|
||||||
|
*/
|
||||||
|
class GuildData extends GuildAdmin
|
||||||
|
{
|
||||||
|
|
||||||
|
protected $noNeedLogin = [];
|
||||||
|
protected $noNeedRight = [];
|
||||||
|
protected $layout = '';
|
||||||
|
protected $table_guild_subsidy_config = 'vs_guild_subsidy_config';
|
||||||
|
protected $table_guild_subsidy = 'vs_guild_subsidy';
|
||||||
|
protected $table_guild_user = 'vs_guild_user';
|
||||||
|
protected $table_guild_data = 'vs_guild_data';
|
||||||
|
protected $table_guild = 'vs_guild';
|
||||||
|
public function _initialize()
|
||||||
|
{
|
||||||
|
parent::_initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
//公会资料详情
|
||||||
|
public function guild_data_detail(){
|
||||||
|
$guild_id = input('guild_id',$this->guildId);
|
||||||
|
if(!$guild_id){
|
||||||
|
return V(0,"公会ID不存在");
|
||||||
|
}
|
||||||
|
$guild = Db::name($this->table_guild)->where('id',$guild_id)->find();
|
||||||
|
if(!$guild){
|
||||||
|
return V(0,"公会不存在");
|
||||||
|
}
|
||||||
|
$guild_data = Db::name($this->table_guild_data)->where('guild_id',$guild_id)->find();
|
||||||
|
//公会会长
|
||||||
|
$guild_user = Db::name('user')->where('id',$guild['user_id'])->find();
|
||||||
|
$return_data =[];
|
||||||
|
$return_data ['company']['guild_name'] = $guild['guild_name'] ?? '';
|
||||||
|
$return_data ['company']['company_name'] = $guild_data['company_name'] ?? '';
|
||||||
|
$return_data ['company']['agreement'] = $guild_data['agreement'] ?? '';
|
||||||
|
$return_data ['company']['guild_cover'] = $guild['cover'] ?? '';
|
||||||
|
//负责人信息
|
||||||
|
$return_data ['boss']['boss_name'] = $guild_data['boss_name'] ?? '';
|
||||||
|
$return_data ['boss']['boss_mobile'] = $guild_data['boss_mobile'] ?? '';
|
||||||
|
$return_data ['boss']['boss_user_code'] = $guild_user['user_code'] ?? '';
|
||||||
|
//对公账号
|
||||||
|
$return_data ['bank']['bank_name'] = $guild_data['bank_name'] ?? '';
|
||||||
|
$return_data ['bank']['bank_num'] = $guild_data['bank_num'] ?? '';
|
||||||
|
$return_data ['bank']['bank_img'] = $guild_data['bank_img'] ?? '';
|
||||||
|
//扫描件
|
||||||
|
$return_data ['scan']['business_license_img'] = $guild_data['business_license_img'] ?? '';
|
||||||
|
$return_data ['scan']['id_card_1'] = $guild_data['id_card_1'] ?? '';
|
||||||
|
$return_data ['scan']['id_card_2'] = $guild_data['id_card_2'] ?? '';
|
||||||
|
|
||||||
|
return V(1,"成功", $return_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
//公司信息修改
|
||||||
|
public function company_update(){
|
||||||
|
$guild_id = input('guild_id',$this->guildId);
|
||||||
|
if(!$guild_id){
|
||||||
|
return V(0,"公会ID不存在");
|
||||||
|
}
|
||||||
|
$guild = Db::name($this->table_guild)->where('id',$guild_id)->find();
|
||||||
|
if(!$guild){
|
||||||
|
return V(0,"公会不存在");
|
||||||
|
}
|
||||||
|
$guild_data = Db::name($this->table_guild_data)->where('guild_id',$guild_id)->find();
|
||||||
|
if(!$guild_data){
|
||||||
|
return V(0,"公会资料不存在");
|
||||||
|
}
|
||||||
|
$company_name = input('company_name', '');
|
||||||
|
$agreement = input('agreement', '');
|
||||||
|
$guild_cover = input('guild_cover', '');
|
||||||
|
$data = [
|
||||||
|
'company_name' => $company_name,
|
||||||
|
'agreement' => $agreement
|
||||||
|
];
|
||||||
|
if($guild_cover){
|
||||||
|
db::name($this->table_guild)->where('id',$guild_id)->update(['cover' => $guild_cover]);
|
||||||
|
}
|
||||||
|
$ret = Db::name($this->table_guild_data)->where('guild_id',$guild_id)->update($data);
|
||||||
|
if($ret){
|
||||||
|
return V(1,"修改成功");
|
||||||
|
}else{
|
||||||
|
return V(0,"修改失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//负责人信息修改
|
||||||
|
public function boss_update(){
|
||||||
|
$guild_id = input('guild_id',$this->guildId);
|
||||||
|
if(!$guild_id){
|
||||||
|
return V(0,"公会ID不存在");
|
||||||
|
}
|
||||||
|
$guild = Db::name($this->table_guild)->where('id',$guild_id)->find();
|
||||||
|
if(!$guild){
|
||||||
|
return V(0,"公会不存在");
|
||||||
|
}
|
||||||
|
$guild_data = Db::name($this->table_guild_data)->where('guild_id',$guild_id)->find();
|
||||||
|
if(!$guild_data){
|
||||||
|
return V(0,"公会资料不存在");
|
||||||
|
}
|
||||||
|
$boss_name = input('boss_name', '');
|
||||||
|
$boss_mobile = input('boss_mobile', '');
|
||||||
|
$data = [
|
||||||
|
'boss_name' => $boss_name,
|
||||||
|
'boss_mobile' => $boss_mobile
|
||||||
|
];
|
||||||
|
$ret = Db::name($this->table_guild_data)->where('guild_id',$guild_id)->update($data);
|
||||||
|
if($ret){
|
||||||
|
return V(1,"修改成功");
|
||||||
|
}else{
|
||||||
|
return V(0,"修改失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//对公账号信息修改
|
||||||
|
public function bank_update(){
|
||||||
|
$guild_id = input('guild_id',$this->guildId);
|
||||||
|
if(!$guild_id){
|
||||||
|
return V(0,"公会ID不存在");
|
||||||
|
}
|
||||||
|
$guild = Db::name($this->table_guild)->where('id',$guild_id)->find();
|
||||||
|
if(!$guild){
|
||||||
|
return V(0,"公会不存在");
|
||||||
|
}
|
||||||
|
$guild_data = Db::name($this->table_guild_data)->where('guild_id',$guild_id)->find();
|
||||||
|
if(!$guild_data){
|
||||||
|
return V(0,"公会资料不存在");
|
||||||
|
}
|
||||||
|
$bank_name = input('bank_name', '');
|
||||||
|
$bank_num = input('bank_num', '');
|
||||||
|
$bank_img = input('bank_img', '');
|
||||||
|
$data = [
|
||||||
|
'bank_name' => $bank_name,
|
||||||
|
'bank_num' => $bank_num,
|
||||||
|
'bank_img' => $bank_img
|
||||||
|
];
|
||||||
|
$ret = Db::name($this->table_guild_data)->where('guild_id',$guild_id)->update($data);
|
||||||
|
if($ret){
|
||||||
|
return V(1,"修改成功");
|
||||||
|
}else{
|
||||||
|
return V(0,"修改失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//扫描件信息修改
|
||||||
|
public function scan_update(){
|
||||||
|
$guild_id = input('guild_id',$this->guildId);
|
||||||
|
if(!$guild_id){
|
||||||
|
return V(0,"公会ID不存在");
|
||||||
|
}
|
||||||
|
$guild = Db::name($this->table_guild)->where('id',$guild_id)->find();
|
||||||
|
if(!$guild){
|
||||||
|
return V(0,"公会不存在");
|
||||||
|
}
|
||||||
|
$guild_data = Db::name($this->table_guild_data)->where('guild_id',$guild_id)->find();
|
||||||
|
if(!$guild_data){
|
||||||
|
return V(0,"公会资料不存在");
|
||||||
|
}
|
||||||
|
$business_license_img = input('business_license_img', '');
|
||||||
|
$id_card_1 = input('id_card_1', '');
|
||||||
|
$id_card_2 = input('id_card_2', '');
|
||||||
|
$data = [
|
||||||
|
'business_license_img' => $business_license_img,
|
||||||
|
'id_card_1' => $id_card_1,
|
||||||
|
'id_card_2' => $id_card_2
|
||||||
|
];
|
||||||
|
$ret = Db::name($this->table_guild_data)->where('guild_id',$guild_id)->update($data);
|
||||||
|
if($ret){
|
||||||
|
return V(1,"修改成功");
|
||||||
|
}else{
|
||||||
|
return V(0,"修改失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//后台密码修改
|
||||||
|
public function password_update(){
|
||||||
|
$guild_id = input('guild_id',$this->guildId);
|
||||||
|
if(!$guild_id){
|
||||||
|
return V(0,"公会ID不存在");
|
||||||
|
}
|
||||||
|
$guild_data = Db::name($this->table_guild_data)->where('guild_id',$guild_id)->find();
|
||||||
|
if(!$guild_data){
|
||||||
|
return V(0,"公会资料不存在");
|
||||||
|
}
|
||||||
|
$password = input('password', '');
|
||||||
|
if ($password) {
|
||||||
|
if (!Validate::is($password, '\S{6,30}')) {
|
||||||
|
return V(0,"密码长度必须在6-30位之间,不能包含空格", []);
|
||||||
|
}
|
||||||
|
$params['salt'] = Random::alnum();
|
||||||
|
$params['password'] = $this->auth->getEncryptPassword($password, $params['salt']);
|
||||||
|
}
|
||||||
|
$ret = Db::name('vs_guild_admin')->where('guild_id',$guild_id)->update($params);
|
||||||
|
if($ret){
|
||||||
|
$this->auth->logout();
|
||||||
|
Hook::listen("admin_logout_after", $this->request);
|
||||||
|
return V(1,"修改成功");
|
||||||
|
}else{
|
||||||
|
return V(0,"修改失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
176
application/guildAdmin/controller/Index.php
Normal file
176
application/guildAdmin/controller/Index.php
Normal file
@@ -0,0 +1,176 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\guildAdmin\controller;
|
||||||
|
|
||||||
|
use app\common\controller\GuildAdmin;
|
||||||
|
use think\Config;
|
||||||
|
use think\Db;
|
||||||
|
use think\Hook;
|
||||||
|
use think\Session;
|
||||||
|
use think\Validate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 后台首页
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
class Index extends GuildAdmin
|
||||||
|
{
|
||||||
|
|
||||||
|
protected $noNeedLogin = ['login'];
|
||||||
|
protected $noNeedRight = ['index', 'logout'];
|
||||||
|
protected $layout = '';
|
||||||
|
|
||||||
|
public function _initialize()
|
||||||
|
{
|
||||||
|
parent::_initialize();
|
||||||
|
//移除HTML标签
|
||||||
|
$this->request->filter('trim,strip_tags,htmlspecialchars');
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 后台首页
|
||||||
|
*/
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
$guild_id = $this->guildId;
|
||||||
|
//昨天时间
|
||||||
|
$tday = date("Y-m-d", strtotime("-1 day"));
|
||||||
|
$stime_input = input('search_stime',0);
|
||||||
|
$etime_input = input('search_etime',date("Y-m-d",strtotime($tday)+86400));
|
||||||
|
$stime = $stime_input==0 ? strtotime($tday) : strtotime($stime_input);
|
||||||
|
$etime = strtotime($etime_input);
|
||||||
|
$return_data =[];
|
||||||
|
//基础数据
|
||||||
|
$guild_user = Db::name('vs_guild_user')->where([
|
||||||
|
'guild_id'=>$guild_id,
|
||||||
|
'status'=>1,
|
||||||
|
])->select();
|
||||||
|
$return_data['room_num'] = 0;//房间数量
|
||||||
|
$return_data['user_num'] = 0; //用户数量
|
||||||
|
$rooms = [];
|
||||||
|
foreach ($guild_user as $key => $value) {
|
||||||
|
if($value['quit_time']>0 && $value['quit_time']<$stime && $value['quit_time']>$etime){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if($value['createtime']>$etime){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if($value['createtime']<$stime_input){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(!empty($value['room_id'])){
|
||||||
|
$return_data['room_num']++;
|
||||||
|
$rooms[] = $value['room_id'];
|
||||||
|
}
|
||||||
|
$return_data['user_num']++;
|
||||||
|
}
|
||||||
|
//房间粉丝数
|
||||||
|
$return_data['room_follow'] = 0;
|
||||||
|
$return_data['room_follow_new'] = 0;
|
||||||
|
$follow = Db::name('user_follow')->where([
|
||||||
|
'follow_id'=>['in',$rooms],
|
||||||
|
'type'=>2,
|
||||||
|
'createtime'=>['<',$etime],
|
||||||
|
])->select();
|
||||||
|
foreach ($follow as $key => $value) {
|
||||||
|
$return_data['room_follow']++;
|
||||||
|
if($value['createtime']>=$stime && $value['createtime']<$etime){
|
||||||
|
$return_data['room_follow_new']++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//刷礼物流水
|
||||||
|
$return_data['all_money'] = db::name('vs_give_gift')
|
||||||
|
->whereIn('from_id',$rooms)
|
||||||
|
->where(['from'=>['in',[2,3,6]],'createtime'=>['<',$etime]])
|
||||||
|
->where(['createtime'=>['>',$stime_input]])
|
||||||
|
->sum('total_price');
|
||||||
|
//礼物总分成
|
||||||
|
$return_data['gift_money'] = db::name('vs_user_money_log')->where([
|
||||||
|
'room_id'=>['in',$rooms],
|
||||||
|
'money_type'=>2,
|
||||||
|
'change_type'=>11,
|
||||||
|
'createtime'=>['<',$etime]
|
||||||
|
])->where(['createtime'=>['>',$stime_input]])->sum('change_value');
|
||||||
|
//主持分成
|
||||||
|
$return_data['host_money'] = db::name('vs_user_money_log')->where([
|
||||||
|
'room_id'=>['in',$rooms],
|
||||||
|
'money_type'=>2,
|
||||||
|
'change_type'=>19,
|
||||||
|
'createtime'=>['<',$etime]
|
||||||
|
])->where(['createtime'=>['>',$stime_input]])->sum('change_value');
|
||||||
|
//房主分成
|
||||||
|
$return_data['room_owner_money'] = db::name('vs_user_money_log')->where([
|
||||||
|
'room_id'=>['in',$rooms],
|
||||||
|
'money_type'=>2,
|
||||||
|
'change_type'=>18,
|
||||||
|
'createtime'=>['<',$etime]
|
||||||
|
])->where(['createtime'=>['>',$stime_input]])->sum('change_value');
|
||||||
|
|
||||||
|
return V(1,"后台首页", $return_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 管理员登录
|
||||||
|
*/
|
||||||
|
public function login()
|
||||||
|
{
|
||||||
|
$url = $this->request->get('url', '', 'url_clean');
|
||||||
|
$url = $url ?: 'index/index';
|
||||||
|
if ($this->auth->isLogin()) {
|
||||||
|
return V(0,"已登录", null);
|
||||||
|
}
|
||||||
|
//保持会话有效时长,单位:小时
|
||||||
|
$keeyloginhours = 24;
|
||||||
|
if ($this->request->isPost()) {
|
||||||
|
$username = $this->request->post('username');
|
||||||
|
$password = $this->request->post('password', '', null);
|
||||||
|
$keeplogin = $this->request->post('keeplogin',0);
|
||||||
|
$rule = [
|
||||||
|
'username' => 'require|length:3,30',
|
||||||
|
'password' => 'require|length:3,30',
|
||||||
|
];
|
||||||
|
$data = [
|
||||||
|
'username' => $username,
|
||||||
|
'password' => $password,
|
||||||
|
];
|
||||||
|
$validate = new Validate($rule, [], ['username' => __('Username'), 'password' => __('Password'), 'captcha' => __('Captcha')]);
|
||||||
|
$result = $validate->check($data);
|
||||||
|
if (!$result) {
|
||||||
|
$this->error($validate->getError(), $url, ['token' => $this->request->token()]);
|
||||||
|
}
|
||||||
|
// AdminLog::setTitle(__('Login'));
|
||||||
|
$result = $this->auth->login($username, $password, $keeplogin ? $keeyloginhours * 3600 : 0);
|
||||||
|
if ($result === true) {
|
||||||
|
Hook::listen("admin_login_after", $this->request);
|
||||||
|
$admin = $this->get_admin_info();
|
||||||
|
return V(1,"登录成功", ['__token__' => $this->request->token(), 'admin' => $admin]);
|
||||||
|
} else {
|
||||||
|
return V(0,"用户名或密码错误", null);
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
return V(0,"用户名或密码错误", null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 退出登录
|
||||||
|
*/
|
||||||
|
public function logout()
|
||||||
|
{
|
||||||
|
if ($this->request->isPost()) {
|
||||||
|
$this->auth->logout();
|
||||||
|
Hook::listen("admin_logout_after", $this->request);
|
||||||
|
return V(1,'退出成功', null);
|
||||||
|
}else{
|
||||||
|
return V(0,'操作失败', null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 获取当前登录管理员信息
|
||||||
|
*/
|
||||||
|
public function get_admin_info(){
|
||||||
|
$admin_info = $this->auth->getUserInfo();
|
||||||
|
$admin_info['ruleList'] = $this->auth->getRuleList();
|
||||||
|
return $admin_info;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
102
application/guildAdmin/lang/zh-cn.php
Normal file
102
application/guildAdmin/lang/zh-cn.php
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
'Keep login' => '保持会话',
|
||||||
|
'Username' => '用户名',
|
||||||
|
'User id' => '会员ID',
|
||||||
|
'Nickname' => '昵称',
|
||||||
|
'Password' => '密码',
|
||||||
|
'Sign up' => '注 册',
|
||||||
|
'Sign in' => '登 录',
|
||||||
|
'Sign out' => '退 出',
|
||||||
|
'Guest' => '游客',
|
||||||
|
'Welcome' => '%s,你好!',
|
||||||
|
'Add' => '添加',
|
||||||
|
'Edit' => '编辑',
|
||||||
|
'Delete' => '删除',
|
||||||
|
'Move' => '移动',
|
||||||
|
'Name' => '名称',
|
||||||
|
'Status' => '状态',
|
||||||
|
'Weigh' => '权重',
|
||||||
|
'Operate' => '操作',
|
||||||
|
'Warning' => '温馨提示',
|
||||||
|
'Default' => '默认',
|
||||||
|
'Article' => '文章',
|
||||||
|
'Page' => '单页',
|
||||||
|
'OK' => '确定',
|
||||||
|
'Cancel' => '取消',
|
||||||
|
'Loading' => '加载中',
|
||||||
|
'More' => '更多',
|
||||||
|
'Normal' => '正常',
|
||||||
|
'Hidden' => '隐藏',
|
||||||
|
'Submit' => '提交',
|
||||||
|
'Reset' => '重置',
|
||||||
|
'Execute' => '执行',
|
||||||
|
'Close' => '关闭',
|
||||||
|
'Search' => '搜索',
|
||||||
|
'Refresh' => '刷新',
|
||||||
|
'First' => '首页',
|
||||||
|
'Previous' => '上一页',
|
||||||
|
'Next' => '下一页',
|
||||||
|
'Last' => '末页',
|
||||||
|
'None' => '无',
|
||||||
|
'Home' => '主页',
|
||||||
|
'Online' => '在线',
|
||||||
|
'Logout' => '退出',
|
||||||
|
'Profile' => '个人资料',
|
||||||
|
'Index' => '首页',
|
||||||
|
'Hot' => '热门',
|
||||||
|
'Recommend' => '推荐',
|
||||||
|
'Dashboard' => '控制台',
|
||||||
|
'Code' => '编号',
|
||||||
|
'Message' => '内容',
|
||||||
|
'Line' => '行号',
|
||||||
|
'File' => '文件',
|
||||||
|
'Menu' => '菜单',
|
||||||
|
'Type' => '类型',
|
||||||
|
'Title' => '标题',
|
||||||
|
'Content' => '内容',
|
||||||
|
'Append' => '追加',
|
||||||
|
'Memo' => '备注',
|
||||||
|
'Parent' => '父级',
|
||||||
|
'Params' => '参数',
|
||||||
|
'Permission' => '权限',
|
||||||
|
'Advance search' => '高级搜索',
|
||||||
|
'Check all' => '选中全部',
|
||||||
|
'Expand all' => '展开全部',
|
||||||
|
'Begin time' => '开始时间',
|
||||||
|
'End time' => '结束时间',
|
||||||
|
'Create time' => '创建时间',
|
||||||
|
'Flag' => '标志',
|
||||||
|
'Please login first' => '请登录后操作',
|
||||||
|
'Uploaded successful' => '上传成功',
|
||||||
|
'You can upload up to %d file%s' => '你最多还可以上传%d个文件',
|
||||||
|
'You can choose up to %d file%s' => '你最多还可以选择%d个文件',
|
||||||
|
'Chunk file write error' => '分片写入失败',
|
||||||
|
'Chunk file info error' => '分片文件错误',
|
||||||
|
'Chunk file merge error' => '分片合并错误',
|
||||||
|
'Chunk file disabled' => '未开启分片上传功能',
|
||||||
|
'Cancel upload' => '取消上传',
|
||||||
|
'Upload canceled' => '上传已取消',
|
||||||
|
'No file upload or server upload limit exceeded' => '未上传文件或超出服务器上传限制',
|
||||||
|
'Uploaded file format is limited' => '上传文件格式受限制',
|
||||||
|
'Uploaded file is not a valid image' => '上传文件不是有效的图片文件',
|
||||||
|
'Are you sure you want to cancel this upload?' => '确定取消上传?',
|
||||||
|
'Remove file' => '移除文件',
|
||||||
|
'You can only upload a maximum of %s files' => '你最多允许上传 %s 个文件',
|
||||||
|
'You can\'t upload files of this type' => '不允许上传的文件类型',
|
||||||
|
'Server responded with %s code' => '服务端响应(Code:%s)',
|
||||||
|
'File is too big (%sMiB), Max filesize: %sMiB.' => '当前上传(%sM),最大允许上传文件大小:%sM',
|
||||||
|
'Redirect now' => '立即跳转',
|
||||||
|
'Operation completed' => '操作成功!',
|
||||||
|
'Operation failed' => '操作失败!',
|
||||||
|
'Unknown data format' => '未知的数据格式!',
|
||||||
|
'Network error' => '网络错误!',
|
||||||
|
'Advanced search' => '高级搜索',
|
||||||
|
'Invalid parameters' => '未知参数',
|
||||||
|
'No results were found' => '记录未找到',
|
||||||
|
'Parameter %s can not be empty' => '参数%s不能为空',
|
||||||
|
'You have no permission' => '你没有权限访问',
|
||||||
|
'An unexpected error occurred' => '发生了一个意外错误,程序猿正在紧急处理中',
|
||||||
|
'This page will be re-directed in %s seconds' => '页面将在 %s 秒后自动跳转',
|
||||||
|
];
|
||||||
3
application/guildAdmin/lang/zh-cn/common.php
Normal file
3
application/guildAdmin/lang/zh-cn/common.php
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
return [];
|
||||||
39
application/guildAdmin/lang/zh-cn/user.php
Normal file
39
application/guildAdmin/lang/zh-cn/user.php
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
'User center' => '会员中心',
|
||||||
|
'Register' => '注册',
|
||||||
|
'Login' => '登录',
|
||||||
|
'Sign up successful' => '注册成功',
|
||||||
|
'Username can not be empty' => '用户名不能为空',
|
||||||
|
'Username must be 3 to 30 characters' => '用户名必须3-30个字符',
|
||||||
|
'Username must be 6 to 30 characters' => '用户名必须6-30个字符',
|
||||||
|
'Password can not be empty' => '密码不能为空',
|
||||||
|
'Password must be 6 to 30 characters' => '密码必须6-30个字符',
|
||||||
|
'Mobile is incorrect' => '手机格式不正确',
|
||||||
|
'Username already exist' => '用户名已经存在',
|
||||||
|
'Nickname already exist' => '昵称已经存在',
|
||||||
|
'Email already exist' => '邮箱已经存在',
|
||||||
|
'Mobile already exist' => '手机号已经存在',
|
||||||
|
'Username is incorrect' => '用户名不正确',
|
||||||
|
'Email is incorrect' => '邮箱不正确',
|
||||||
|
'Account is locked' => '账户已经被锁定',
|
||||||
|
'Password is incorrect' => '密码不正确',
|
||||||
|
'Account is incorrect' => '账户不正确',
|
||||||
|
'Account not exist' => '账户不存在',
|
||||||
|
'Account can not be empty' => '账户不能为空',
|
||||||
|
'Username or password is incorrect' => '用户名或密码不正确',
|
||||||
|
'You are not logged in' => '你当前还未登录',
|
||||||
|
'You\'ve logged in, do not login again' => '你已经存在,请不要重复登录',
|
||||||
|
'Profile' => '个人资料',
|
||||||
|
'Verify email' => '邮箱验证',
|
||||||
|
'Change password' => '修改密码',
|
||||||
|
'Captcha is incorrect' => '验证码不正确',
|
||||||
|
'Logged in successful' => '登录成功',
|
||||||
|
'Logout successful' => '退出成功',
|
||||||
|
'Operation failed' => '操作失败',
|
||||||
|
'Invalid parameters' => '参数不正确',
|
||||||
|
'Change password failure' => '修改密码失败',
|
||||||
|
'Change password successful' => '修改密码成功',
|
||||||
|
'Reset password successful' => '重置密码成功',
|
||||||
|
];
|
||||||
617
application/guildAdmin/library/Auth.php
Normal file
617
application/guildAdmin/library/Auth.php
Normal file
@@ -0,0 +1,617 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\guildAdmin\library;
|
||||||
|
|
||||||
|
use app\guildAdmin\model\Admin;
|
||||||
|
use fast\Random;
|
||||||
|
use fast\Tree;
|
||||||
|
use think\Cache;
|
||||||
|
use think\Config;
|
||||||
|
use think\Cookie;
|
||||||
|
use think\Db;
|
||||||
|
use think\Hook;
|
||||||
|
use think\Request;
|
||||||
|
use think\Session;
|
||||||
|
|
||||||
|
class Auth extends \fast\Auth
|
||||||
|
{
|
||||||
|
protected $_error = '';
|
||||||
|
protected $requestUri = '';
|
||||||
|
protected $breadcrumb = [];
|
||||||
|
protected $logined = false; //登录状态
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __get($name)
|
||||||
|
{
|
||||||
|
return Session::get('guild_admin.' . $name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 管理员登录
|
||||||
|
*
|
||||||
|
* @param string $username 用户名
|
||||||
|
* @param string $password 密码
|
||||||
|
* @param int $keeptime 有效时长
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public function login($username, $password, $keeptime = 0)
|
||||||
|
{
|
||||||
|
$admin = Admin::get(['username' => $username]);
|
||||||
|
if (!$admin) {
|
||||||
|
$this->setError('Username is incorrect');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ($admin['status'] == 'hidden') {
|
||||||
|
$this->setError('Admin is forbidden');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (Config::get('fastadmin.login_failure_retry') && $admin->loginfailure >= 10 && time() - $admin->updatetime < 86400) {
|
||||||
|
$this->setError('Please try again after 1 day');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ($admin->password != $this->getEncryptPassword($password, $admin->salt)) {
|
||||||
|
$admin->loginfailure++;
|
||||||
|
$admin->save();
|
||||||
|
$this->setError('Password is incorrect');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$admin->loginfailure = 0;
|
||||||
|
$admin->logintime = time();
|
||||||
|
$admin->loginip = request()->ip();
|
||||||
|
$admin->token = Random::uuid();
|
||||||
|
$admin->save();
|
||||||
|
Session::set("guild_admin", $admin->toArray());
|
||||||
|
Session::set("guild_admin_id", $admin['id']);
|
||||||
|
Session::set("guild_admin.safecode", $this->getEncryptSafecode($admin));
|
||||||
|
Cache::set("guild_admin_" . $admin->token, json_encode($admin->toArray()), 86400);
|
||||||
|
Session::set("guild_id", $admin['guild_id']);
|
||||||
|
$this->keeplogin($admin, $keeptime);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退出登录
|
||||||
|
*/
|
||||||
|
public function logout()
|
||||||
|
{
|
||||||
|
$admin = Admin::get(intval($this->id));
|
||||||
|
if ($admin) {
|
||||||
|
Cache::rm("guild_admin_" . $admin->token);
|
||||||
|
$admin->token = '';
|
||||||
|
$admin->save();
|
||||||
|
}
|
||||||
|
$this->logined = false; //重置登录状态
|
||||||
|
Session::delete("guild_admin");
|
||||||
|
Cookie::delete("guild_keeplogin");
|
||||||
|
Cache::rm("guild_admin_" . $admin->token);
|
||||||
|
setcookie('guild_userinfo', '', $_SERVER['REQUEST_TIME'] - 3600, rtrim(url("/" . request()->module(), '', false), '/'));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自动登录
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public function autologin()
|
||||||
|
{
|
||||||
|
$keeplogin = Cookie::get('guild_keeplogin');
|
||||||
|
if (!$keeplogin) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
list($id, $keeptime, $expiretime, $key) = explode('|', $keeplogin);
|
||||||
|
if ($id && $keeptime && $expiretime && $key && $expiretime > time()) {
|
||||||
|
$admin = Admin::get($id);
|
||||||
|
if (!$admin || !$admin->token) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
//token有变更
|
||||||
|
if ($key != $this->getKeeploginKey($admin, $keeptime, $expiretime)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$ip = request()->ip();
|
||||||
|
//IP有变动
|
||||||
|
if ($admin->loginip != $ip) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Session::set("guild_admin", $admin->toArray());
|
||||||
|
Session::set("guild_admin.safecode", $this->getEncryptSafecode($admin));
|
||||||
|
//刷新自动登录的时效
|
||||||
|
$this->keeplogin($admin, $keeptime);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 刷新保持登录的Cookie
|
||||||
|
*
|
||||||
|
* @param int $keeptime
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
protected function keeplogin($admin, $keeptime = 0)
|
||||||
|
{
|
||||||
|
if ($keeptime) {
|
||||||
|
$expiretime = time() + $keeptime;
|
||||||
|
$key = $this->getKeeploginKey($admin, $keeptime, $expiretime);
|
||||||
|
Cookie::set('guild_keeplogin', implode('|', [$admin['id'], $keeptime, $expiretime, $key]), $keeptime);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取密码加密后的字符串
|
||||||
|
* @param string $password 密码
|
||||||
|
* @param string $salt 密码盐
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getEncryptPassword($password, $salt = '')
|
||||||
|
{
|
||||||
|
return md5(md5($password) . $salt);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取密码加密后的自动登录码
|
||||||
|
* @param string $password 密码
|
||||||
|
* @param string $salt 密码盐
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getEncryptKeeplogin($params, $keeptime)
|
||||||
|
{
|
||||||
|
$expiretime = time() + $keeptime;
|
||||||
|
$key = md5(md5($params['id']) . md5($keeptime) . md5($expiretime) . $params['token'] . config('token.key'));
|
||||||
|
return implode('|', [$this->id, $keeptime, $expiretime, $key]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取自动登录Key
|
||||||
|
* @param $params
|
||||||
|
* @param $keeptime
|
||||||
|
* @param $expiretime
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getKeeploginKey($params, $keeptime, $expiretime)
|
||||||
|
{
|
||||||
|
$key = md5(md5($params['id']) . md5($keeptime) . md5($expiretime) . $params['token'] . config('token.key'));
|
||||||
|
return $key;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取加密后的安全码
|
||||||
|
* @param $params
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getEncryptSafecode($params)
|
||||||
|
{
|
||||||
|
return md5(md5($params['username']) . md5(substr($params['password'], 0, 6)) . config('token.key'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function check($name, $uid = '', $relation = 'or', $mode = 'url')
|
||||||
|
{
|
||||||
|
$uid = $uid ? $uid : $this->id;
|
||||||
|
return parent::check($name, $uid, $relation, $mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检测当前控制器和方法是否匹配传递的数组
|
||||||
|
*
|
||||||
|
* @param array $arr 需要验证权限的数组
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function match($arr = [])
|
||||||
|
{
|
||||||
|
$request = Request::instance();
|
||||||
|
$arr = is_array($arr) ? $arr : explode(',', $arr);
|
||||||
|
if (!$arr) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$arr = array_map('strtolower', $arr);
|
||||||
|
// 是否存在
|
||||||
|
if (in_array(strtolower($request->action()), $arr) || in_array('*', $arr)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 没找到匹配
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检测是否登录
|
||||||
|
*
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public function isLogin($token = null)
|
||||||
|
{
|
||||||
|
if ($this->logined) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
$admin = Session::get('guild_admin');
|
||||||
|
if (!$admin) {
|
||||||
|
$admin = Cache::get("guild_admin_" . $token);
|
||||||
|
$admin = json_decode($admin, true);
|
||||||
|
if($admin){
|
||||||
|
Session::set("guild_admin", $admin);
|
||||||
|
Session::set("guild_admin_id", $admin['id']);
|
||||||
|
// Session::set("admin.safecode", $this->getEncryptSafecode($admin));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!$admin) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$my = Admin::get($admin['id']);
|
||||||
|
if (!$my) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
//校验安全码,可用于判断关键信息发生了变更需要重新登录
|
||||||
|
// if (!isset($admin['safecode']) || $this->getEncryptSafecode($my) !== $admin['safecode']) {
|
||||||
|
// $this->logout();
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
//判断是否同一时间同一账号只能在一个地方登录
|
||||||
|
if (Config::get('fastadmin.login_unique')) {
|
||||||
|
if ($my['token'] != $admin['token']) {
|
||||||
|
$this->logout();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//判断管理员IP是否变动
|
||||||
|
if (Config::get('guild.loginip_check')) {
|
||||||
|
if (!isset($admin['loginip']) || $admin['loginip'] != request()->ip()) {
|
||||||
|
$this->logout();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$this->logined = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取当前请求的URI
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getRequestUri()
|
||||||
|
{
|
||||||
|
return $this->requestUri;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置当前请求的URI
|
||||||
|
* @param string $uri
|
||||||
|
*/
|
||||||
|
public function setRequestUri($uri)
|
||||||
|
{
|
||||||
|
$this->requestUri = $uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getGroups($uid = null)
|
||||||
|
{
|
||||||
|
$uid = is_null($uid) ? $this->id : $uid;
|
||||||
|
// return parent::getGroups($uid);
|
||||||
|
$user_groups = Db::name('vs_guild_admin_auth_group_access')
|
||||||
|
->alias('aga')
|
||||||
|
->join('fa_vs_guild_admin_auth_group ag', 'aga.group_id = ag.id', 'LEFT')
|
||||||
|
->field('aga.uid,aga.group_id,ag.id,ag.pid,ag.name,ag.rules')
|
||||||
|
->where("aga.uid='{$uid}' and ag.status='normal'")
|
||||||
|
->where('ag.guild_id', Session::get('guild_id'))
|
||||||
|
->select();
|
||||||
|
$groups[$uid] = $user_groups ?: [];
|
||||||
|
return $groups[$uid];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getRuleList($uid = null)
|
||||||
|
{
|
||||||
|
$uid = is_null($uid) ? $this->id : $uid;
|
||||||
|
return parent::getRuleList($uid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getUserInfo($uid = null)
|
||||||
|
{
|
||||||
|
$uid = is_null($uid) ? $this->id : $uid;
|
||||||
|
|
||||||
|
return $uid != $this->id ? Admin::get(intval($uid)) : Session::get('guild_admin');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getRuleIds($uid = null)
|
||||||
|
{
|
||||||
|
$uid = is_null($uid) ? $this->id : $uid;
|
||||||
|
// return parent::getRuleIds($uid);
|
||||||
|
// 执行查询
|
||||||
|
$user_groups = Db::name('vs_guild_admin_auth_group_access')
|
||||||
|
->alias('aga')
|
||||||
|
->join('fa_vs_guild_admin_auth_group ag', 'aga.group_id = ag.id', 'LEFT')
|
||||||
|
->field('aga.uid,aga.group_id,ag.id,ag.pid,ag.name,ag.rules')
|
||||||
|
->where("aga.uid='{$uid}' and ag.status='normal'")
|
||||||
|
->where('ag.guild_id', Session::get('guild_id'))
|
||||||
|
->select();
|
||||||
|
$groups[$uid] = $user_groups ?: [];
|
||||||
|
$ids = []; //保存用户所属用户组设置的所有权限规则id
|
||||||
|
foreach ($groups[$uid] as $g) {
|
||||||
|
$ids = array_merge($ids, explode(',', trim($g['rules'], ',')));
|
||||||
|
}
|
||||||
|
$ids = array_unique($ids);
|
||||||
|
return $ids;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isSuperAdmin()
|
||||||
|
{
|
||||||
|
return in_array('*', $this->getRuleIds()) ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取管理员所属于的分组ID
|
||||||
|
* @param int $uid
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getGroupIds($uid = null)
|
||||||
|
{
|
||||||
|
$groups = $this->getGroups($uid);
|
||||||
|
$groupIds = [];
|
||||||
|
foreach ($groups as $K => $v) {
|
||||||
|
$groupIds[] = (int)$v['group_id'];
|
||||||
|
}
|
||||||
|
return $groupIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 取出当前管理员所拥有权限的分组
|
||||||
|
* @param boolean $withself 是否包含当前所在的分组
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getChildrenGroupIds($withself = false)
|
||||||
|
{
|
||||||
|
//取出当前管理员所有的分组
|
||||||
|
$groups = $this->getGroups();
|
||||||
|
$groupIds = array_column($groups, 'id');
|
||||||
|
$originGroupIds = $groupIds;
|
||||||
|
foreach ($groups as $k => $v) {
|
||||||
|
if (in_array($v['pid'], $originGroupIds)) {
|
||||||
|
$groupIds = array_diff($groupIds, [$v['id']]);
|
||||||
|
unset($groups[$k]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 取出所有分组
|
||||||
|
$groupList = \app\guildAdmin\model\AuthGroup::where($this->isSuperAdmin() ? '1=1' : ['status' => 'normal'])->where('guild_id', Session::get('guild_id'))->select();
|
||||||
|
$objList = [];
|
||||||
|
foreach ($groups as $k => $v) {
|
||||||
|
if ($v['rules'] === '*') {
|
||||||
|
$objList = $groupList;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// 取出包含自己的所有子节点
|
||||||
|
$childrenList = Tree::instance()->init($groupList, 'pid')->getChildren($v['id'], true);
|
||||||
|
$obj = Tree::instance()->init($childrenList, 'pid')->getTreeArray($v['pid']);
|
||||||
|
$objList = array_merge($objList, Tree::instance()->getTreeList($obj));
|
||||||
|
}
|
||||||
|
$childrenGroupIds = [];
|
||||||
|
foreach ($objList as $k => $v) {
|
||||||
|
$childrenGroupIds[] = $v['id'];
|
||||||
|
}
|
||||||
|
if (!$withself) {
|
||||||
|
$childrenGroupIds = array_diff($childrenGroupIds, $groupIds);
|
||||||
|
}
|
||||||
|
return $childrenGroupIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 取出当前管理员所拥有权限的管理员
|
||||||
|
* @param boolean $withself 是否包含自身
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getChildrenAdminIds($withself = false)
|
||||||
|
{
|
||||||
|
$childrenAdminIds = [];
|
||||||
|
if (!$this->isSuperAdmin()) {
|
||||||
|
$groupIds = $this->getChildrenGroupIds(false);
|
||||||
|
$childrenAdminIds = \app\guildAdmin\model\AuthGroupAccess::where('group_id', 'in', $groupIds)
|
||||||
|
->column('uid');
|
||||||
|
} else {
|
||||||
|
//超级管理员拥有所有人的权限
|
||||||
|
$childrenAdminIds = Admin::where('guild_id', Session::get('guild_id'))->column('id');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($withself) {
|
||||||
|
if (!in_array($this->id, $childrenAdminIds)) {
|
||||||
|
$childrenAdminIds[] = $this->id;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$childrenAdminIds = array_diff($childrenAdminIds, [$this->id]);
|
||||||
|
}
|
||||||
|
return $childrenAdminIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得面包屑导航
|
||||||
|
* @param string $path
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getBreadCrumb($path = '')
|
||||||
|
{
|
||||||
|
if ($this->breadcrumb || !$path) {
|
||||||
|
return $this->breadcrumb;
|
||||||
|
}
|
||||||
|
$titleArr = [];
|
||||||
|
$menuArr = [];
|
||||||
|
$urlArr = explode('/', $path);
|
||||||
|
foreach ($urlArr as $index => $item) {
|
||||||
|
$pathArr[implode('/', array_slice($urlArr, 0, $index + 1))] = $index;
|
||||||
|
}
|
||||||
|
if (!$this->rules && $this->id) {
|
||||||
|
$this->getRuleList();
|
||||||
|
}
|
||||||
|
foreach ($this->rules as $rule) {
|
||||||
|
if (isset($pathArr[$rule['name']])) {
|
||||||
|
$rule['title'] = __($rule['title']);
|
||||||
|
$rule['url'] = url($rule['name']);
|
||||||
|
$titleArr[$pathArr[$rule['name']]] = $rule['title'];
|
||||||
|
$menuArr[$pathArr[$rule['name']]] = $rule;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ksort($menuArr);
|
||||||
|
$this->breadcrumb = $menuArr;
|
||||||
|
return $this->breadcrumb;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取左侧和顶部菜单栏
|
||||||
|
*
|
||||||
|
* @param array $params URL对应的badge数据
|
||||||
|
* @param string $fixedPage 默认页
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getSidebar($params = [], $fixedPage = 'dashboard')
|
||||||
|
{
|
||||||
|
// 边栏开始
|
||||||
|
Hook::listen("admin_sidebar_begin", $params);
|
||||||
|
$colorArr = ['red', 'green', 'yellow', 'blue', 'teal', 'orange', 'purple'];
|
||||||
|
$colorNums = count($colorArr);
|
||||||
|
$badgeList = [];
|
||||||
|
$module = request()->module();
|
||||||
|
// 生成菜单的badge
|
||||||
|
foreach ($params as $k => $v) {
|
||||||
|
$url = $k;
|
||||||
|
if (is_array($v)) {
|
||||||
|
$nums = $v[0] ?? 0;
|
||||||
|
$color = $v[1] ?? $colorArr[(is_numeric($nums) ? $nums : strlen($nums)) % $colorNums];
|
||||||
|
$class = $v[2] ?? 'label';
|
||||||
|
} else {
|
||||||
|
$nums = $v;
|
||||||
|
$color = $colorArr[(is_numeric($nums) ? $nums : strlen($nums)) % $colorNums];
|
||||||
|
$class = 'label';
|
||||||
|
}
|
||||||
|
//必须nums大于0才显示
|
||||||
|
if ($nums) {
|
||||||
|
$badgeList[$url] = '<small class="' . $class . ' pull-right bg-' . $color . '">' . $nums . '</small>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 读取管理员当前拥有的权限节点
|
||||||
|
$userRule = $this->getRuleList();
|
||||||
|
$selected = $referer = [];
|
||||||
|
$refererUrl = Session::get('referer');
|
||||||
|
// 必须将结果集转换为数组
|
||||||
|
$ruleList = collection(\app\guildAdmin\model\AuthRule::where('status', 'normal')
|
||||||
|
->where('ismenu', 1)
|
||||||
|
->order('weigh', 'desc')
|
||||||
|
->cache("__menu__")
|
||||||
|
->select())->toArray();
|
||||||
|
$indexRuleList = \app\guildAdmin\model\AuthRule::where('status', 'normal')
|
||||||
|
->where('ismenu', 0)
|
||||||
|
->where('name', 'like', '%/index')
|
||||||
|
->column('name,pid');
|
||||||
|
$pidArr = array_unique(array_filter(array_column($ruleList, 'pid')));
|
||||||
|
foreach ($ruleList as $k => &$v) {
|
||||||
|
if (!in_array(strtolower($v['name']), $userRule)) {
|
||||||
|
unset($ruleList[$k]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$indexRuleName = $v['name'] . '/index';
|
||||||
|
if (isset($indexRuleList[$indexRuleName]) && !in_array($indexRuleName, $userRule)) {
|
||||||
|
unset($ruleList[$k]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$v['icon'] = $v['icon'] . ' fa-fw';
|
||||||
|
$v['url'] = isset($v['url']) && $v['url'] ? $v['url'] : '/' . $module . '/' . $v['name'];
|
||||||
|
$v['badge'] = $badgeList[$v['name']] ?? '';
|
||||||
|
$v['title'] = __($v['title']);
|
||||||
|
$v['url'] = preg_match("/^((?:[a-z]+:)?\/\/|data:image\/)(.*)/i", $v['url']) ? $v['url'] : url($v['url']);
|
||||||
|
$v['menuclass'] = in_array($v['menutype'], ['dialog', 'ajax']) ? 'btn-' . $v['menutype'] : '';
|
||||||
|
$v['menutabs'] = !$v['menutype'] || in_array($v['menutype'], ['default', 'addtabs']) ? 'addtabs="' . $v['id'] . '"' : '';
|
||||||
|
$selected = $v['name'] == $fixedPage ? $v : $selected;
|
||||||
|
$referer = $v['url'] == $refererUrl ? $v : $referer;
|
||||||
|
}
|
||||||
|
$lastArr = array_unique(array_filter(array_column($ruleList, 'pid')));
|
||||||
|
$pidDiffArr = array_diff($pidArr, $lastArr);
|
||||||
|
foreach ($ruleList as $index => $item) {
|
||||||
|
if (in_array($item['id'], $pidDiffArr)) {
|
||||||
|
unset($ruleList[$index]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($selected == $referer) {
|
||||||
|
$referer = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$select_id = $referer ? $referer['id'] : ($selected ? $selected['id'] : 0);
|
||||||
|
$menu = $nav = '';
|
||||||
|
$showSubmenu = config('fastadmin.show_submenu');
|
||||||
|
if (Config::get('fastadmin.multiplenav')) {
|
||||||
|
$topList = [];
|
||||||
|
foreach ($ruleList as $index => $item) {
|
||||||
|
if (!$item['pid']) {
|
||||||
|
$topList[] = $item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$selectParentIds = [];
|
||||||
|
$tree = Tree::instance();
|
||||||
|
$tree->init($ruleList);
|
||||||
|
if ($select_id) {
|
||||||
|
$selectParentIds = $tree->getParentsIds($select_id, true);
|
||||||
|
}
|
||||||
|
foreach ($topList as $index => $item) {
|
||||||
|
$childList = Tree::instance()->getTreeMenu(
|
||||||
|
$item['id'],
|
||||||
|
'<li class="@class" pid="@pid"><a @extend href="@url@addtabs" addtabs="@id" class="@menuclass" url="@url" py="@py" pinyin="@pinyin"><i class="@icon"></i> <span>@title</span> <span class="pull-right-container">@caret @badge</span></a> @childlist</li>',
|
||||||
|
$select_id,
|
||||||
|
'',
|
||||||
|
'ul',
|
||||||
|
'class="treeview-menu' . ($showSubmenu ? ' menu-open' : '') . '"'
|
||||||
|
);
|
||||||
|
$current = in_array($item['id'], $selectParentIds);
|
||||||
|
$url = $childList ? 'javascript:;' : $item['url'];
|
||||||
|
$addtabs = $childList || !$url ? "" : (stripos($url, "?") !== false ? "&" : "?") . "ref=" . ($item['menutype'] ? $item['menutype'] : 'addtabs');
|
||||||
|
$childList = str_replace(
|
||||||
|
'" pid="' . $item['id'] . '"',
|
||||||
|
' ' . ($current ? '' : 'hidden') . '" pid="' . $item['id'] . '"',
|
||||||
|
$childList
|
||||||
|
);
|
||||||
|
$nav .= '<li class="' . ($current ? 'active' : '') . '"><a ' . $item['extend'] . ' href="' . $url . $addtabs . '" ' . $item['menutabs'] . ' class="' . $item['menuclass'] . '" url="' . $url . '" title="' . $item['title'] . '"><i class="' . $item['icon'] . '"></i> <span>' . $item['title'] . '</span> <span class="pull-right-container"> </span></a> </li>';
|
||||||
|
$menu .= $childList;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 构造菜单数据
|
||||||
|
Tree::instance()->init($ruleList);
|
||||||
|
$menu = Tree::instance()->getTreeMenu(
|
||||||
|
0,
|
||||||
|
'<li class="@class"><a @extend href="@url@addtabs" @menutabs class="@menuclass" url="@url" py="@py" pinyin="@pinyin"><i class="@icon"></i> <span>@title</span> <span class="pull-right-container">@caret @badge</span></a> @childlist</li>',
|
||||||
|
$select_id,
|
||||||
|
'',
|
||||||
|
'ul',
|
||||||
|
'class="treeview-menu' . ($showSubmenu ? ' menu-open' : '') . '"'
|
||||||
|
);
|
||||||
|
if ($selected) {
|
||||||
|
$nav .= '<li role="presentation" id="tab_' . $selected['id'] . '" class="' . ($referer ? '' : 'active') . '"><a href="#con_' . $selected['id'] . '" node-id="' . $selected['id'] . '" aria-controls="' . $selected['id'] . '" role="tab" data-toggle="tab"><i class="' . $selected['icon'] . ' fa-fw"></i> <span>' . $selected['title'] . '</span> </a></li>';
|
||||||
|
}
|
||||||
|
if ($referer) {
|
||||||
|
$nav .= '<li role="presentation" id="tab_' . $referer['id'] . '" class="active"><a href="#con_' . $referer['id'] . '" node-id="' . $referer['id'] . '" aria-controls="' . $referer['id'] . '" role="tab" data-toggle="tab"><i class="' . $referer['icon'] . ' fa-fw"></i> <span>' . $referer['title'] . '</span> </a> <i class="close-tab fa fa-remove"></i></li>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return [$menu, $nav, $selected, $referer];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置错误信息
|
||||||
|
*
|
||||||
|
* @param string $error 错误信息
|
||||||
|
* @return Auth
|
||||||
|
*/
|
||||||
|
public function setError($error)
|
||||||
|
{
|
||||||
|
$this->_error = $error;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取错误信息
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getError()
|
||||||
|
{
|
||||||
|
return $this->_error ? __($this->_error) : '';
|
||||||
|
}
|
||||||
|
}
|
||||||
37
application/guildAdmin/library/ExceptionHandle.php
Normal file
37
application/guildAdmin/library/ExceptionHandle.php
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\guildAdmin\library;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
|
use think\exception\Handle;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自定义API模块的错误显示
|
||||||
|
*/
|
||||||
|
class ExceptionHandle extends Handle
|
||||||
|
{
|
||||||
|
|
||||||
|
public function render(Exception $e)
|
||||||
|
{
|
||||||
|
// 在生产环境下返回code信息
|
||||||
|
if (!\think\Config::get('app_debug')) {
|
||||||
|
$statuscode = $code = 500;
|
||||||
|
$msg = 'An error occurred';
|
||||||
|
// 验证异常
|
||||||
|
if ($e instanceof \think\exception\ValidateException) {
|
||||||
|
$code = 0;
|
||||||
|
$statuscode = 200;
|
||||||
|
$msg = $e->getError();
|
||||||
|
}
|
||||||
|
// Http异常
|
||||||
|
if ($e instanceof \think\exception\HttpException) {
|
||||||
|
$statuscode = $code = $e->getStatusCode();
|
||||||
|
}
|
||||||
|
return json(['code' => $code, 'msg' => $msg, 'time' => time(), 'data' => null], $statuscode);
|
||||||
|
}
|
||||||
|
|
||||||
|
//其它此交由系统处理
|
||||||
|
return parent::render($e);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
63
application/guildAdmin/model/Admin.php
Normal file
63
application/guildAdmin/model/Admin.php
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
<?php
|
||||||
|
namespace app\guildAdmin\model;
|
||||||
|
|
||||||
|
use fast\Random;
|
||||||
|
use think\Model;
|
||||||
|
use think\Session;
|
||||||
|
use app\guildAdmin\library\Auth;
|
||||||
|
|
||||||
|
class Admin extends Model
|
||||||
|
{
|
||||||
|
|
||||||
|
// 开启自动写入时间戳字段
|
||||||
|
protected $autoWriteTimestamp = 'int';
|
||||||
|
// 定义时间戳字段名
|
||||||
|
protected $table = 'fa_vs_guild_admin';
|
||||||
|
protected $createTime = 'createtime';
|
||||||
|
protected $updateTime = 'updatetime';
|
||||||
|
|
||||||
|
protected $hidden = [
|
||||||
|
'password',
|
||||||
|
'salt'
|
||||||
|
];
|
||||||
|
|
||||||
|
public static function init()
|
||||||
|
{
|
||||||
|
self::beforeWrite(function ($row) {
|
||||||
|
$changed = $row->getChangedData();
|
||||||
|
//如果修改了用户或或密码则需要重新登录
|
||||||
|
if (isset($changed['username']) || isset($changed['password']) || isset($changed['salt'])) {
|
||||||
|
$row->token = '';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
//创建管理员(公会创建调用)
|
||||||
|
public function createAdmin($data){
|
||||||
|
$params['salt'] = Random::alnum();
|
||||||
|
$params['username'] = $data['username'];
|
||||||
|
$params['nickname'] = $data['nickname'];
|
||||||
|
$params['password'] = md5(md5($data['password']) . $params['salt']);
|
||||||
|
$params['guild_id'] = $data['guild_id'];
|
||||||
|
$result = $this->save($params);
|
||||||
|
if ($result === false) {
|
||||||
|
return V(0,"失败", []);
|
||||||
|
}
|
||||||
|
//创建角色组
|
||||||
|
$group_data = [
|
||||||
|
'guild_id' => $data['guild_id'],
|
||||||
|
'pid' => 1,
|
||||||
|
'name' => '超级管理员',
|
||||||
|
'rules' => '*',
|
||||||
|
'status' => 'normal'
|
||||||
|
];
|
||||||
|
$group = model('guildAdmin/AuthGroup')->create($group_data);
|
||||||
|
if (!$group) {
|
||||||
|
return V(0,"失败", []);
|
||||||
|
}
|
||||||
|
$dataset = [];
|
||||||
|
$dataset[] = ['uid' => $this->id, 'group_id' => $group['id']];
|
||||||
|
model('guildAdmin/AuthGroupAccess')->saveAll($dataset);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
118
application/guildAdmin/model/AdminLog.php
Normal file
118
application/guildAdmin/model/AdminLog.php
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\guildAdmin\model;
|
||||||
|
|
||||||
|
use app\admin\library\Auth;
|
||||||
|
use think\Model;
|
||||||
|
use think\Loader;
|
||||||
|
|
||||||
|
class AdminLog extends Model
|
||||||
|
{
|
||||||
|
|
||||||
|
// 开启自动写入时间戳字段
|
||||||
|
protected $autoWriteTimestamp = 'int';
|
||||||
|
protected $table = 'fa_vs_guild_admin_log';
|
||||||
|
// 定义时间戳字段名
|
||||||
|
protected $createTime = 'createtime';
|
||||||
|
protected $updateTime = '';
|
||||||
|
//自定义日志标题
|
||||||
|
protected static $title = '';
|
||||||
|
//自定义日志内容
|
||||||
|
protected static $content = '';
|
||||||
|
//忽略的链接正则列表
|
||||||
|
protected static $ignoreRegex = [
|
||||||
|
'/^(.*)\/(selectpage|index)$/i',
|
||||||
|
];
|
||||||
|
|
||||||
|
public static function setTitle($title)
|
||||||
|
{
|
||||||
|
self::$title = $title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function setContent($content)
|
||||||
|
{
|
||||||
|
self::$content = $content;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function setIgnoreRegex($regex = [])
|
||||||
|
{
|
||||||
|
$regex = is_array($regex) ? $regex : [$regex];
|
||||||
|
self::$ignoreRegex = array_merge(self::$ignoreRegex, $regex);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 记录日志
|
||||||
|
* @param string $title 日志标题
|
||||||
|
* @param string $content 日志内容
|
||||||
|
*/
|
||||||
|
public static function record($title = '', $content = '')
|
||||||
|
{
|
||||||
|
$auth = Auth::instance();
|
||||||
|
$admin_id = $auth->isLogin() ? $auth->id : 0;
|
||||||
|
$username = $auth->isLogin() ? $auth->username : __('Unknown');
|
||||||
|
|
||||||
|
// 设置过滤函数
|
||||||
|
request()->filter('trim,strip_tags,htmlspecialchars');
|
||||||
|
|
||||||
|
$controllername = Loader::parseName(request()->controller());
|
||||||
|
$actionname = strtolower(request()->action());
|
||||||
|
$path = str_replace('.', '/', $controllername) . '/' . $actionname;
|
||||||
|
if (self::$ignoreRegex) {
|
||||||
|
foreach (self::$ignoreRegex as $index => $item) {
|
||||||
|
if (preg_match($item, $path)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$content = $content ?: self::$content;
|
||||||
|
if (!$content) {
|
||||||
|
$content = request()->param('') ?: file_get_contents("php://input");
|
||||||
|
$content = self::getPureContent($content);
|
||||||
|
}
|
||||||
|
$title = $title ?: self::$title;
|
||||||
|
if (!$title) {
|
||||||
|
$title = [];
|
||||||
|
$breadcrumb = Auth::instance()->getBreadcrumb($path);
|
||||||
|
foreach ($breadcrumb as $k => $v) {
|
||||||
|
$title[] = $v['title'];
|
||||||
|
}
|
||||||
|
$title = implode(' / ', $title);
|
||||||
|
}
|
||||||
|
self::create([
|
||||||
|
'title' => $title,
|
||||||
|
'content' => !is_scalar($content) ? json_encode($content, JSON_UNESCAPED_UNICODE) : $content,
|
||||||
|
'url' => substr(xss_clean(strip_tags(request()->url())), 0, 1500),
|
||||||
|
'admin_id' => $admin_id,
|
||||||
|
'username' => $username,
|
||||||
|
'useragent' => substr(request()->server('HTTP_USER_AGENT'), 0, 255),
|
||||||
|
'ip' => xss_clean(strip_tags(request()->ip()))
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取已屏蔽关键信息的数据
|
||||||
|
* @param $content
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
protected static function getPureContent($content)
|
||||||
|
{
|
||||||
|
if (!is_array($content)) {
|
||||||
|
return $content;
|
||||||
|
}
|
||||||
|
foreach ($content as $index => &$item) {
|
||||||
|
if (preg_match("/(password|salt|token)/i", $index)) {
|
||||||
|
$item = "***";
|
||||||
|
} else {
|
||||||
|
if (is_array($item)) {
|
||||||
|
$item = self::getPureContent($item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $content;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function admin()
|
||||||
|
{
|
||||||
|
return $this->belongsTo('Admin', 'admin_id')->setEagerlyType(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
22
application/guildAdmin/model/AuthGroup.php
Normal file
22
application/guildAdmin/model/AuthGroup.php
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\guildAdmin\model;
|
||||||
|
|
||||||
|
use think\Model;
|
||||||
|
|
||||||
|
class AuthGroup extends Model
|
||||||
|
{
|
||||||
|
|
||||||
|
// 开启自动写入时间戳字段
|
||||||
|
protected $autoWriteTimestamp = 'int';
|
||||||
|
protected $table = 'fa_vs_guild_admin_auth_group';
|
||||||
|
// 定义时间戳字段名
|
||||||
|
protected $createTime = 'createtime';
|
||||||
|
protected $updateTime = 'updatetime';
|
||||||
|
|
||||||
|
public function getNameAttr($value, $data)
|
||||||
|
{
|
||||||
|
return __($value);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
11
application/guildAdmin/model/AuthGroupAccess.php
Normal file
11
application/guildAdmin/model/AuthGroupAccess.php
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\guildAdmin\model;
|
||||||
|
|
||||||
|
use think\Model;
|
||||||
|
|
||||||
|
class AuthGroupAccess extends Model
|
||||||
|
{
|
||||||
|
protected $table = 'fa_vs_guild_admin_auth_group_access';
|
||||||
|
//
|
||||||
|
}
|
||||||
63
application/guildAdmin/model/AuthRule.php
Normal file
63
application/guildAdmin/model/AuthRule.php
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\guildAdmin\model;
|
||||||
|
|
||||||
|
use think\Cache;
|
||||||
|
use think\Model;
|
||||||
|
|
||||||
|
class AuthRule extends Model
|
||||||
|
{
|
||||||
|
|
||||||
|
// 开启自动写入时间戳字段
|
||||||
|
protected $autoWriteTimestamp = 'int';
|
||||||
|
protected $table = 'fa_vs_guild_admin_auth';
|
||||||
|
// 定义时间戳字段名
|
||||||
|
protected $createTime = 'createtime';
|
||||||
|
protected $updateTime = 'updatetime';
|
||||||
|
// 数据自动完成字段
|
||||||
|
protected $insert = ['py', 'pinyin'];
|
||||||
|
protected $update = ['py', 'pinyin'];
|
||||||
|
// 拼音对象
|
||||||
|
protected static $pinyin = null;
|
||||||
|
|
||||||
|
protected static function init()
|
||||||
|
{
|
||||||
|
self::$pinyin = new \Overtrue\Pinyin\Pinyin('Overtrue\Pinyin\MemoryFileDictLoader');
|
||||||
|
|
||||||
|
self::beforeWrite(function ($row) {
|
||||||
|
if (isset($_POST['row']) && is_array($_POST['row']) && isset($_POST['row']['condition'])) {
|
||||||
|
$originRow = $_POST['row'];
|
||||||
|
$row['condition'] = $originRow['condition'] ?? '';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
self::afterWrite(function ($row) {
|
||||||
|
Cache::rm('__guild_menu__');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTitleAttr($value, $data)
|
||||||
|
{
|
||||||
|
return __($value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getMenutypeList()
|
||||||
|
{
|
||||||
|
return ['addtabs' => __('Addtabs'), 'dialog' => __('Dialog'), 'ajax' => __('Ajax'), 'blank' => __('Blank')];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setPyAttr($value, $data)
|
||||||
|
{
|
||||||
|
if (isset($data['title']) && $data['title']) {
|
||||||
|
return self::$pinyin->abbr(__($data['title']));
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setPinyinAttr($value, $data)
|
||||||
|
{
|
||||||
|
if (isset($data['title']) && $data['title']) {
|
||||||
|
return self::$pinyin->permalink(__($data['title']), '');
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user