mirror of https://gitee.com/karson/fastadmin.git
377 lines
13 KiB
PHP
377 lines
13 KiB
PHP
<?php
|
|
|
|
namespace app\admin\controller;
|
|
|
|
use app\common\controller\Backend;
|
|
use fast\Random;
|
|
use fast\Tree;
|
|
use RecursiveDirectoryIterator;
|
|
use RecursiveIteratorIterator;
|
|
use think\Cache;
|
|
use think\Config;
|
|
use think\Db;
|
|
use think\Lang;
|
|
|
|
/**
|
|
* Ajax异步请求接口
|
|
* @internal
|
|
*/
|
|
class Ajax extends Backend
|
|
{
|
|
|
|
protected $noNeedLogin = ['lang'];
|
|
protected $noNeedRight = ['*'];
|
|
protected $layout = '';
|
|
|
|
/**
|
|
* 自动完成
|
|
*/
|
|
public function typeahead()
|
|
{
|
|
$search = $this->request->get("search");
|
|
$field = $this->request->get("field");
|
|
$field = str_replace(['row[', ']'], '', $field);
|
|
if (substr($field, -3) !== '_id' && substr($field, -4) !== '_ids')
|
|
{
|
|
$this->code = -1;
|
|
return;
|
|
}
|
|
$searchfield = 'name';
|
|
$field = substr($field, 0, -3);
|
|
switch ($field)
|
|
{
|
|
case 'category':
|
|
$field = 'category';
|
|
$searchfield = 'name';
|
|
break;
|
|
case 'user':
|
|
$searchfield = 'nickname';
|
|
break;
|
|
}
|
|
|
|
$searchlist = Db::name($field)
|
|
->whereOr($searchfield, 'like', "%{$search}%")
|
|
->whereOr('id', 'like', "%{$search}%")
|
|
->limit(10)
|
|
->field("id,{$searchfield} AS name")
|
|
->select();
|
|
|
|
foreach ($searchlist as $k => &$v)
|
|
{
|
|
$v['name'] = $v['name'] . "[id:{$v['id']}]";
|
|
}
|
|
unset($v);
|
|
$this->code = 1;
|
|
$this->data = ['searchlist' => $searchlist];
|
|
}
|
|
|
|
/**
|
|
* 加载语言包
|
|
*/
|
|
public function lang()
|
|
{
|
|
header('Content-Type: application/javascript');
|
|
$modulename = $this->request->module();
|
|
$callback = $this->request->get('callback');
|
|
$controllername = input("controllername");
|
|
Lang::load(APP_PATH . $modulename . '/lang/' . Lang::detect() . '/' . str_replace('.', '/', $controllername) . '.php');
|
|
//强制输出JSON Object
|
|
$result = 'define(' . json_encode(Lang::get(), JSON_FORCE_OBJECT | JSON_UNESCAPED_UNICODE) . ');';
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* 读取角色权限树
|
|
*/
|
|
public function roletree()
|
|
{
|
|
$model = model('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;
|
|
//读取父类角色所有节点列表
|
|
$parentrulelist = model('AuthRule')->all(in_array('*', explode(',', $parentgroupmodel->rules)) ? NULL : $parentgroupmodel->rules);
|
|
//读取当前角色下规则ID集合
|
|
$admin_rule_ids = $this->auth->getRuleIds();
|
|
$superadmin = $this->auth->isSuperAdmin();
|
|
$current_rule_ids = $id ? explode(',', $currentgroupmodel->rules) : [];
|
|
|
|
if (!$id || !in_array($pid, Tree::instance()->init($model->all(['status' => 'normal']))->getChildrenIds($id, TRUE)))
|
|
{
|
|
//构造jstree所需的数据
|
|
$nodelist = [];
|
|
foreach ($parentrulelist as $k => $v)
|
|
{
|
|
if (!$superadmin && !in_array($v['id'], $admin_rule_ids))
|
|
continue;
|
|
$state = array('selected' => !$v['ismenu'] && in_array($v['id'], $current_rule_ids));
|
|
$nodelist[] = array('id' => $v['id'], 'parent' => $v['pid'] ? $v['pid'] : '#', 'text' => $v['title'], 'type' => 'menu', 'state' => $state);
|
|
}
|
|
$this->code = 1;
|
|
$this->data = $nodelist;
|
|
}
|
|
else
|
|
{
|
|
$this->code = -1;
|
|
$this->data = __('Can not change the parent to child');
|
|
}
|
|
}
|
|
else
|
|
{
|
|
$this->code = -1;
|
|
$this->data = __('Group not found');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 上传文件
|
|
*/
|
|
public function upload()
|
|
{
|
|
$this->code = -1;
|
|
$file = $this->request->file('file');
|
|
|
|
//判断是否已经存在附件
|
|
$sha1 = $file->hash();
|
|
$uploaded = model("attachment")->where('sha1', $sha1)->find();
|
|
if ($uploaded)
|
|
{
|
|
$this->code = 1;
|
|
$this->data = [
|
|
'url' => $uploaded['url']
|
|
];
|
|
return;
|
|
}
|
|
|
|
$upload = Config::get('upload');
|
|
|
|
preg_match('/(\d+)(\w+)/', $upload['maxsize'], $matches);
|
|
$type = strtolower($matches[2]);
|
|
$typeDict = ['b' => 0, 'k' => 1, 'kb' => 1, 'm' => 2, 'mb' => 2, 'gb' => 3, 'g' => 3];
|
|
$size = (int) $upload['maxsize'] * pow(1024, isset($typeDict[$type]) ? $typeDict[$type] : 0);
|
|
$fileInfo = $file->getInfo();
|
|
$suffix = strtolower(pathinfo($fileInfo['name'], PATHINFO_EXTENSION));
|
|
$suffix = $suffix ? $suffix : 'file';
|
|
$replaceArr = [
|
|
'{year}' => date("Y"),
|
|
'{mon}' => date("m"),
|
|
'{day}' => date("d"),
|
|
'{hour}' => date("H"),
|
|
'{min}' => date("i"),
|
|
'{sec}' => date("s"),
|
|
'{random}' => Random::alnum(16),
|
|
'{random32}' => Random::alnum(32),
|
|
'{filename}' => $suffix ? substr($fileInfo['name'], 0, strripos($fileInfo['name'], '.')) : $fileInfo['name'],
|
|
'{suffix}' => $suffix,
|
|
'{.suffix}' => $suffix ? '.' . $suffix : '',
|
|
'{filemd5}' => md5_file($fileInfo['tmp_name']),
|
|
];
|
|
$savekey = $upload['savekey'];
|
|
$savekey = str_replace(array_keys($replaceArr), array_values($replaceArr), $savekey);
|
|
|
|
$uploadDir = substr($savekey, 0, strripos($savekey, '/') + 1);
|
|
$fileName = substr($savekey, strripos($savekey, '/') + 1);
|
|
//
|
|
$splInfo = $file->validate(['size' => $size])->move(ROOT_PATH . '/public' . $uploadDir, $fileName);
|
|
if ($splInfo)
|
|
{
|
|
$imagewidth = $imageheight = 0;
|
|
if (in_array($suffix, ['gif', 'jpg', 'jpeg', 'bmp', 'png', 'swf']))
|
|
{
|
|
$imgInfo = getimagesize($splInfo->getPathname());
|
|
$imagewidth = isset($imgInfo[0]) ? $imgInfo[0] : $imagewidth;
|
|
$imageheight = isset($imgInfo[1]) ? $imgInfo[1] : $imageheight;
|
|
}
|
|
$params = array(
|
|
'filesize' => $fileInfo['size'],
|
|
'imagewidth' => $imagewidth,
|
|
'imageheight' => $imageheight,
|
|
'imagetype' => $suffix,
|
|
'imageframes' => 0,
|
|
'mimetype' => $fileInfo['type'],
|
|
'url' => $uploadDir . $splInfo->getSaveName(),
|
|
'uploadtime' => time(),
|
|
'sha1' => $sha1,
|
|
);
|
|
model("attachment")->create(array_filter($params));
|
|
$this->code = 1;
|
|
$this->data = [
|
|
'url' => $uploadDir . $splInfo->getSaveName()
|
|
];
|
|
}
|
|
else
|
|
{
|
|
// 上传失败获取错误信息
|
|
$this->data = $file->getError();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 通用排序
|
|
*/
|
|
public function weigh()
|
|
{
|
|
//排序的数组
|
|
$ids = $this->request->post("ids");
|
|
//拖动的记录ID
|
|
$changeid = $this->request->post("changeid");
|
|
//操作字段
|
|
$field = $this->request->post("field");
|
|
//操作的数据表
|
|
$table = $this->request->post("table");
|
|
//排序的方式
|
|
$orderway = $this->request->post("orderway", 'strtolower');
|
|
$orderway = $orderway == 'asc' ? 'ASC' : 'DESC';
|
|
$sour = $weighdata = [];
|
|
$ids = explode(',', $ids);
|
|
$prikey = 'id';
|
|
$pid = $this->request->post("pid");
|
|
|
|
// 如果设定了pid的值,此时只匹配满足条件的ID,其它忽略
|
|
if ($pid !== '')
|
|
{
|
|
$hasids = [];
|
|
$list = Db::name($table)->where($prikey, 'in', $ids)->where('pid', 'in', $pid)->field('id,pid')->select();
|
|
foreach ($list as $k => $v)
|
|
{
|
|
$hasids[] = $v['id'];
|
|
}
|
|
$ids = array_values(array_intersect($ids, $hasids));
|
|
}
|
|
|
|
//直接修复排序
|
|
$one = Db::name($table)->field("{$field},COUNT(*) AS nums")->group($field)->having('nums > 1')->find();
|
|
if ($one)
|
|
{
|
|
$list = Db::name($table)->field("$prikey,$field")->order($field, $orderway)->select();
|
|
foreach ($list as $k => $v)
|
|
{
|
|
Db::name($table)->where($prikey, $v[$prikey])->update([$field => $k + 1]);
|
|
}
|
|
$this->code = 1;
|
|
}
|
|
else
|
|
{
|
|
$list = Db::name($table)->field("$prikey,$field")->where($prikey, 'in', $ids)->order($field, $orderway)->select();
|
|
foreach ($list as $k => $v)
|
|
{
|
|
$sour[] = $v[$prikey];
|
|
$weighdata[$v[$prikey]] = $v[$field];
|
|
}
|
|
$position = array_search($changeid, $ids);
|
|
$desc_id = $sour[$position]; //移动到目标的ID值,取出所处改变前位置的值
|
|
$sour_id = $changeid;
|
|
$desc_value = $weighdata[$desc_id];
|
|
$sour_value = $weighdata[$sour_id];
|
|
//echo "移动的ID:{$sour_id}\n";
|
|
//echo "替换的ID:{$desc_id}\n";
|
|
$weighids = array();
|
|
$temp = array_values(array_diff_assoc($ids, $sour));
|
|
foreach ($temp as $m => $n)
|
|
{
|
|
if ($n == $sour_id)
|
|
{
|
|
$offset = $desc_id;
|
|
}
|
|
else
|
|
{
|
|
if ($sour_id == $temp[0])
|
|
{
|
|
$offset = isset($temp[$m + 1]) ? $temp[$m + 1] : $sour_id;
|
|
}
|
|
else
|
|
{
|
|
$offset = isset($temp[$m - 1]) ? $temp[$m - 1] : $sour_id;
|
|
}
|
|
}
|
|
$weighids[$n] = $weighdata[$offset];
|
|
Db::name($table)->where($prikey, $n)->update([$field => $weighdata[$offset]]);
|
|
}
|
|
$this->code = 1;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 清空系统缓存
|
|
*/
|
|
public function wipecache()
|
|
{
|
|
$wipe_cache_type = ['TEMP_PATH', 'LOG_PATH', 'CACHE_PATH'];
|
|
foreach ($wipe_cache_type as $item)
|
|
{
|
|
$dir = constant($item);
|
|
if (!is_dir($dir))
|
|
continue;
|
|
$files = new RecursiveIteratorIterator(
|
|
new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS), RecursiveIteratorIterator::CHILD_FIRST
|
|
);
|
|
|
|
foreach ($files as $fileinfo)
|
|
{
|
|
$todo = ($fileinfo->isDir() ? 'rmdir' : 'unlink');
|
|
$todo($fileinfo->getRealPath());
|
|
}
|
|
|
|
//rmdir($dir);
|
|
}
|
|
Cache::clear();
|
|
$this->code = 1;
|
|
}
|
|
|
|
/**
|
|
* 读取分类数据
|
|
*/
|
|
public function category()
|
|
{
|
|
$type = $this->request->get('type');
|
|
$pid = $this->request->get('pid');
|
|
$where = ['status' => 'normal'];
|
|
if ($type)
|
|
{
|
|
$where['type'] = $type;
|
|
}
|
|
if ($pid)
|
|
{
|
|
$where['pid'] = $pid;
|
|
}
|
|
|
|
$categorylist = Db::name('category')->where($where)->field('id as value,name')->order('weigh desc,id desc')->select();
|
|
$this->code = 1;
|
|
$this->data = $categorylist;
|
|
return;
|
|
}
|
|
|
|
/**
|
|
* 读取省市区数据
|
|
*/
|
|
public function area()
|
|
{
|
|
$province = $this->request->get('province');
|
|
$city = $this->request->get('city');
|
|
$where = ['pid' => 0, 'level' => 1];
|
|
if ($province)
|
|
{
|
|
$where['pid'] = $province;
|
|
$where['level'] = 2;
|
|
}
|
|
if ($city)
|
|
{
|
|
$where['pid'] = $city;
|
|
$where['level'] = 3;
|
|
}
|
|
$provincelist = Db::name('area')->where($where)->field('id as value,name')->select();
|
|
$this->code = 1;
|
|
$this->data = $provincelist;
|
|
return;
|
|
}
|
|
|
|
}
|