mirror of https://gitee.com/karson/fastadmin.git
Merge branch '1.6.x-dev' into 1.7.x-dev
# Conflicts: # application/admin/controller/Index.php # application/common/controller/Backend.php # application/common/library/SelectPage.php # application/config.php # public/assets/js/require-frontend.min.js1.7.x-dev
commit
aaa16feb8a
|
|
@ -19,8 +19,8 @@ class Api extends Command
|
|||
->setName('api')
|
||||
->addOption('url', 'u', Option::VALUE_OPTIONAL, 'default api url', '')
|
||||
->addOption('cdnurl', 'd', Option::VALUE_OPTIONAL, 'default cdn url', '')
|
||||
->addOption('module', 'm', Option::VALUE_OPTIONAL, 'module name(admin/index/api)', 'api')
|
||||
->addOption('output', 'o', Option::VALUE_OPTIONAL, 'output index file name', 'api.html')
|
||||
->addOption('module', 'm', Option::VALUE_OPTIONAL, 'module name(index/api)', 'api')
|
||||
->addOption('output', 'o', Option::VALUE_OPTIONAL, 'output index file name', '')
|
||||
->addOption('template', 'e', Option::VALUE_OPTIONAL, '', 'index.html')
|
||||
->addOption('force', 'f', Option::VALUE_OPTIONAL, 'force override general file', false)
|
||||
->addOption('title', 't', Option::VALUE_OPTIONAL, 'document title', $site['name'] ?? '')
|
||||
|
|
@ -43,22 +43,30 @@ class Api extends Command
|
|||
if (!preg_match("/^([a-z0-9]+)\.html\$/i", $template)) {
|
||||
throw new Exception('template file not correct');
|
||||
}
|
||||
$language = $language ? $language : 'zh-cn';
|
||||
$language = $language ?: 'zh-cn';
|
||||
$langFile = $apiDir . 'lang' . DS . $language . '.php';
|
||||
if (!is_file($langFile)) {
|
||||
throw new Exception('language file not found');
|
||||
}
|
||||
$lang = include_once $langFile;
|
||||
|
||||
// 目标目录
|
||||
$output_dir = ROOT_PATH . 'public' . DS;
|
||||
$output_file = $output_dir . $input->getOption('output');
|
||||
if (is_file($output_file) && !$force) {
|
||||
$outputDir = ROOT_PATH . 'runtime' . DS . 'docs' . DS;
|
||||
if (!is_dir($outputDir)) {
|
||||
mkdir($outputDir, 0755, true);
|
||||
}
|
||||
$outputFilename = $input->getOption('output') ?: 'doc_' . date('Ymd_') . strtolower(\fast\Random::alnum(6)) . '.html';
|
||||
if ($outputFilename === 'api.html') {
|
||||
throw new Exception('api.html cannot be used as the output file name');
|
||||
}
|
||||
$outputFile = $outputDir . $outputFilename;
|
||||
if (is_file($outputFile) && !$force) {
|
||||
throw new Exception("api index file already exists!\nIf you need to rebuild again, use the parameter --force=true ");
|
||||
}
|
||||
// 模板文件
|
||||
$template_dir = $apiDir . 'template' . DS;
|
||||
$template_file = $template_dir . $template;
|
||||
if (!is_file($template_file)) {
|
||||
$templateDir = $apiDir . 'template' . DS;
|
||||
$templateFile = $templateDir . $template;
|
||||
if (!is_file($templateFile)) {
|
||||
throw new Exception('template file not found');
|
||||
}
|
||||
// 额外的类
|
||||
|
|
@ -70,7 +78,6 @@ class Api extends Command
|
|||
// 插件
|
||||
$addon = $input->getOption('addon');
|
||||
|
||||
$moduleDir = $addonDir = '';
|
||||
if ($addon) {
|
||||
$addonInfo = get_addon_info($addon);
|
||||
if (!$addonInfo) {
|
||||
|
|
@ -83,9 +90,12 @@ class Api extends Command
|
|||
if (!is_dir($moduleDir)) {
|
||||
throw new Exception('module not found');
|
||||
}
|
||||
if (in_array($module, ['admin', 'common'])) {
|
||||
throw new Exception('module not allowed');
|
||||
}
|
||||
|
||||
if (version_compare(PHP_VERSION, '7.0.0', '<')) {
|
||||
throw new Exception("Requires PHP version 7.0 or newer");
|
||||
if (version_compare(PHP_VERSION, '7.4.0', '<')) {
|
||||
throw new Exception("Requires PHP version 7.4 or newer");
|
||||
}
|
||||
|
||||
//控制器名
|
||||
|
|
@ -118,7 +128,7 @@ class Api extends Command
|
|||
|
||||
$classes = array_unique(array_filter($classes));
|
||||
|
||||
$cdnurl = $cdnurl ? : Config::get('site.cdnurl');
|
||||
$cdnurl = $cdnurl ?: Config::get('site.cdnurl');
|
||||
|
||||
$config = [
|
||||
'sitename' => config('site.name'),
|
||||
|
|
@ -132,12 +142,13 @@ class Api extends Command
|
|||
|
||||
Config::set('view_replace_str.__CDN__', $cdnurl);
|
||||
$builder = new Builder($classes);
|
||||
$content = $builder->render($template_file, ['config' => $config, 'lang' => $lang]);
|
||||
$content = $builder->render($templateFile, ['config' => $config, 'lang' => $lang]);
|
||||
|
||||
if (!file_put_contents($output_file, $content)) {
|
||||
throw new Exception('Cannot save the content to ' . $output_file);
|
||||
if (!file_put_contents($outputFile, $content)) {
|
||||
throw new Exception('Cannot save the content to ' . $outputFile);
|
||||
}
|
||||
$output->info("Build Successed!");
|
||||
$output->info("Docs Location:" . $outputFile);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -32,17 +32,13 @@ class Index extends Backend
|
|||
*/
|
||||
public function index()
|
||||
{
|
||||
$cookieArr = ['adminskin' => "/^skin\-([a-z\-]+)\$/i", 'simplenav' => "/^(0|1)\$/", 'multiplenav' => "/^(0|1)\$/", 'multipletab' => "/^(0|1)\$/", 'show_submenu' => "/^(0|1)\$/"];
|
||||
$cookieArr = ['adminskin' => "/^skin\-([a-z\-]+)\$/i", 'multiplenav' => "/^(0|1)\$/", 'multipletab' => "/^(0|1)\$/", 'show_submenu' => "/^(0|1)\$/"];
|
||||
foreach ($cookieArr as $key => $regex) {
|
||||
$cookieValue = $this->request->cookie($key);
|
||||
if (!is_null($cookieValue) && preg_match($regex, $cookieValue)) {
|
||||
config('fastadmin.' . $key, $cookieValue);
|
||||
}
|
||||
}
|
||||
//如同时启用简洁和多级菜单,简洁菜单将失效
|
||||
if (config('fastadmin.simplenav') && config('fastadmin.multiplenav')) {
|
||||
config('fastadmin.simplenav', false);
|
||||
}
|
||||
//左侧菜单
|
||||
list($menulist, $navlist, $fixedmenu, $referermenu) = $this->auth->getSidebar([
|
||||
'dashboard' => 'hot',
|
||||
|
|
@ -70,22 +66,20 @@ class Index extends Backend
|
|||
public function login()
|
||||
{
|
||||
$url = $this->request->get('url', '', 'url_clean');
|
||||
$url = $url && !preg_match('/\/index\/(login|logout)$/', $url) ? $url : 'index/index';
|
||||
$url = $url ?: 'index/index';
|
||||
if ($this->auth->isLogin()) {
|
||||
$this->success(__("You've logged in, do not login again"), $url);
|
||||
}
|
||||
//保持会话有效时长,单位:小时
|
||||
$keeyloginhours = 24;
|
||||
if ($this->request->isPost()) {
|
||||
AdminLog::setTitle(__('Login'));
|
||||
|
||||
$username = $this->request->post('username');
|
||||
$password = $this->request->post('password', '', null);
|
||||
$keeplogin = $this->request->post('keeplogin');
|
||||
$token = $this->request->post('__token__');
|
||||
$rule = [
|
||||
'username' => 'require|length:3,30',
|
||||
'password' => 'require|length:6,30',
|
||||
'password' => 'require|length:3,30',
|
||||
'__token__' => 'require|token',
|
||||
];
|
||||
$data = [
|
||||
|
|
@ -133,22 +127,20 @@ class Index extends Backend
|
|||
*/
|
||||
public function logout()
|
||||
{
|
||||
|
||||
if ($this->request->isPost()) {
|
||||
$user_id = $this->auth->id;
|
||||
$username = $this->auth->username;
|
||||
AdminLog::event('before_insert', function ($row) use ($user_id, $username) {
|
||||
$row->admin_id = $user_id;
|
||||
$row->username = $username;
|
||||
});
|
||||
AdminLog::setTitle(__('Logout'));
|
||||
// 加强校验referer是否来自服务器,允许referer为空
|
||||
$referer = $this->request->server('HTTP_REFERER');
|
||||
if ($referer && strtolower(parse_url($referer, PHP_URL_HOST)) != strtolower($this->request->host())) {
|
||||
$this->error(__('Invalid request'));
|
||||
}
|
||||
|
||||
$this->token();
|
||||
$this->auth->logout();
|
||||
Hook::listen("admin_logout_after", $this->request);
|
||||
$this->success(__('Logout successful'), 'index/login');
|
||||
}
|
||||
$html = "<form id='logout_submit' name='logout_submit' action='' method='post'>" . token() . "<input type='submit' value='ok' style='display:none;'></form>";
|
||||
$html .= "<script>document.forms['logout_submit'].submit();</script>";
|
||||
|
||||
return $html;
|
||||
return $this->view->fetch();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,6 +38,8 @@ return [
|
|||
'Please try again after 1 day' => '请于1天后再尝试登录',
|
||||
'Login successful' => '登录成功!',
|
||||
'Logout successful' => '退出成功!',
|
||||
'Are you sure you want to sign out?' => '确定要退出后台管理吗?',
|
||||
'Confirm sign out' => '确定退出',
|
||||
'Verification code is incorrect' => '验证码不正确',
|
||||
'Wipe cache completed' => '清除缓存成功',
|
||||
'Wipe cache failed' => '清除缓存失败',
|
||||
|
|
|
|||
|
|
@ -0,0 +1,48 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
{include file="common/meta" /}
|
||||
|
||||
<style type="text/css">
|
||||
body {
|
||||
color: #999;
|
||||
background-color: #f1f4fd;
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #444;
|
||||
}
|
||||
|
||||
.logout-main {
|
||||
text-align: center;
|
||||
max-width: 430px;
|
||||
margin: 0 auto;
|
||||
margin-top: 150px;
|
||||
background-color: #fff;
|
||||
padding: 40px 30px;
|
||||
border-radius: 3px;
|
||||
box-shadow: 0 0 30px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="logout-main text-center">
|
||||
<div class="image">
|
||||
<img src="__CDN__/assets/img/info.svg" alt="" width="100" />
|
||||
</div>
|
||||
<h3 class="my-4" style="font-size:16px;">{:__('Are you sure you want to sign out?')}</h3>
|
||||
<form name="form" id="logout-form" class="form-vertical" method="POST" action="#">
|
||||
{:token()}
|
||||
<div class="form-group">
|
||||
<button type="submit" class="btn btn-primary btn-lg btn-block">{:__('Confirm sign out')}</button>
|
||||
<button type="button" class="btn btn-default btn-lg btn-block mt-3" onclick="history.back()">{:__('Cancel')}</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{include file="common/script" /}
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -39,37 +39,20 @@ class Common extends Api
|
|||
* 加载初始化
|
||||
*
|
||||
* @ApiParams (name="version", type="string", required=true, description="版本号")
|
||||
* @ApiParams (name="lng", type="string", required=true, description="经度")
|
||||
* @ApiParams (name="lat", type="string", required=true, description="纬度")
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
if ($version = $this->request->request('version')) {
|
||||
$lng = $this->request->request('lng');
|
||||
$lat = $this->request->request('lat');
|
||||
|
||||
//配置信息
|
||||
$upload = Config::get('upload');
|
||||
//如果非服务端中转模式需要修改为中转
|
||||
if ($upload['storage'] != 'local' && isset($upload['uploadmode']) && $upload['uploadmode'] != 'server') {
|
||||
//临时修改上传模式为服务端中转
|
||||
set_addon_config($upload['storage'], ["uploadmode" => "server"], false);
|
||||
|
||||
$upload = \app\common\model\Config::upload();
|
||||
// 上传信息配置后
|
||||
Hook::listen("upload_config_init", $upload);
|
||||
|
||||
$upload = Config::set('upload', array_merge(Config::get('upload'), $upload));
|
||||
}
|
||||
|
||||
$upload['cdnurl'] = $upload['cdnurl'] ? $upload['cdnurl'] : cdnurl('', true);
|
||||
$upload['uploadurl'] = preg_match("/^((?:[a-z]+:)?\/\/)(.*)/i", $upload['uploadurl']) ? $upload['uploadurl'] : url($upload['storage'] == 'local' ? '/api/common/upload' : $upload['uploadurl'], '', false, true);
|
||||
$uploaddata = [];
|
||||
$uploaddata['cdnurl'] = $upload['cdnurl'] ?: cdnurl('', true);
|
||||
$uploaddata['uploadurl'] = url('/api/common/upload', '', false, true);
|
||||
|
||||
$content = [
|
||||
'citydata' => Area::getCityFromLngLat($lng, $lat),
|
||||
'versiondata' => Version::check($version),
|
||||
'uploaddata' => $upload,
|
||||
'coverdata' => Config::get("cover"),
|
||||
'uploaddata' => $uploaddata,
|
||||
];
|
||||
$this->success('', $content);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -192,8 +192,15 @@ class User extends Api
|
|||
}
|
||||
$user->nickname = $nickname;
|
||||
}
|
||||
if ($avatar) {
|
||||
//判断是否匹配config('upload.cdnurl')开头以及当前$SERVER['HTTP_HOST']开头。
|
||||
if (preg_match('/^' . preg_quote(config('upload.cdnurl') . '/', '/') . '/i', $avatar)
|
||||
|| preg_match('/^' . preg_quote(substr(config('upload.savekey'), 0, strpos(config('upload.savekey'), '{')), '/') . '/i', $avatar)
|
||||
|| preg_match('/^' . preg_quote($_SERVER['HTTP_HOST'] . '/', '/') . '/i', $avatar)) {
|
||||
$user->avatar = $avatar;
|
||||
}
|
||||
}
|
||||
$user->bio = $bio;
|
||||
$user->avatar = $avatar;
|
||||
$user->save();
|
||||
$this->success();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -102,11 +102,6 @@ class Backend extends Controller
|
|||
*/
|
||||
protected $excludeFields = "";
|
||||
|
||||
/**
|
||||
* 排序字段
|
||||
*/
|
||||
protected $dragsortFields = 'weigh';
|
||||
|
||||
/**
|
||||
* 导入文件首行类型
|
||||
* 支持comment/name
|
||||
|
|
@ -152,18 +147,14 @@ class Backend extends Controller
|
|||
$url = $url ? $url : $this->request->url();
|
||||
if (in_array($this->request->pathinfo(), ['/', 'index/index'])) {
|
||||
$this->redirect('index/login', [], 302, ['referer' => $url]);
|
||||
exit;
|
||||
}
|
||||
$this->error(__('Please login first'), url('index/login', ['url' => $url]));
|
||||
}
|
||||
// 判断是否需要验证权限
|
||||
if (!$this->auth->match($this->noNeedRight)) {
|
||||
// 判断控制器和方法是否有对应权限
|
||||
$subpath = str_replace('.', '/', $this->request->path());
|
||||
// 判断当前路径和子路径是否都无权限
|
||||
$hasPathPermission = $this->auth->check($path);
|
||||
$hasSubpathPermission = ($path === $subpath) ? $hasPathPermission : $this->auth->check($subpath);
|
||||
|
||||
if (!$hasPathPermission && !$hasSubpathPermission) {
|
||||
if (!$this->auth->check($path)) {
|
||||
Hook::listen('admin_nopermission', $this);
|
||||
$this->error(__('You have no permission'), '');
|
||||
}
|
||||
|
|
@ -477,15 +468,15 @@ class Backend extends Controller
|
|||
$selectPage = new SelectPage($this->model, $this->selectpageFields);
|
||||
|
||||
// 数据限制
|
||||
$adminIds = $this->getDataLimitAdminIds();
|
||||
if (is_array($adminIds)) {
|
||||
$selectPage->setDataLimit($this->dataLimit, $this->dataLimitField, $adminIds);
|
||||
$dataLimitIds = $this->getDataLimitAdminIds();
|
||||
if (is_array($dataLimitIds)) {
|
||||
$selectPage->setDataLimit($this->dataLimit, $this->dataLimitField, $dataLimitIds);
|
||||
}
|
||||
|
||||
try {
|
||||
$result = $selectPage->execute($this->request->request());
|
||||
} catch (\think\Exception $e) {
|
||||
$this->error($e->getMessage());
|
||||
$this->error(__($e->getMessage()));
|
||||
}
|
||||
|
||||
return json($result);
|
||||
|
|
|
|||
|
|
@ -76,22 +76,39 @@ class SelectPage
|
|||
$this->orderFields = $this->allowedFields;
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据限制的ID集合
|
||||
* @var array
|
||||
*/
|
||||
protected $dataLimitIds = [];
|
||||
|
||||
/**
|
||||
* 设置数据限制
|
||||
* @param bool|string $dataLimit auth/personal/false
|
||||
* @param string $field 限制字段
|
||||
* @param array $adminIds 允许的管理员ID列表
|
||||
* @param bool|string $dataLimit auth/personal/false
|
||||
* @param string $dataLimitField 限制字段
|
||||
* @param array $dataLimitIds 允许的ID列表
|
||||
* @return $this
|
||||
*/
|
||||
public function setDataLimit($dataLimit, $field = 'admin_id', array $adminIds = [])
|
||||
public function setDataLimit($dataLimit, $dataLimitField = 'admin_id', array $dataLimitIds = [])
|
||||
{
|
||||
$this->dataLimit = $dataLimit;
|
||||
$this->dataLimitField = $field;
|
||||
$this->dataLimitField = $dataLimitField;
|
||||
$this->dataLimitIds = $dataLimitIds;
|
||||
|
||||
if (is_array($adminIds) && !empty($adminIds)) {
|
||||
$this->model->where($this->dataLimitField, 'in', $adminIds);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 应用数据限制条件(每次构建新查询链前调用)
|
||||
* ThinkPHP 的 count()/select() 执行后会清空 model options,
|
||||
* 所以需要在每次查询前重新注入 dataLimit 条件。
|
||||
* @return $this
|
||||
*/
|
||||
protected function applyDataLimit()
|
||||
{
|
||||
if ($this->dataLimit) {
|
||||
$this->model->where($this->dataLimitField, 'in', $this->dataLimitIds);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
|
@ -122,14 +139,8 @@ class SelectPage
|
|||
}
|
||||
|
||||
// 验证字段
|
||||
$showFields = $this->normalizeField($showField);
|
||||
$keyFields = $keyField ? $this->normalizeField($keyField) : [];
|
||||
foreach ($showFields as $f) {
|
||||
$this->validateField($f);
|
||||
}
|
||||
foreach ($keyFields as $f) {
|
||||
$this->validateField($f);
|
||||
}
|
||||
$this->validateField($showField);
|
||||
$this->validateField($keyField);
|
||||
|
||||
// 验证搜索字段
|
||||
foreach ($searchField as $f) {
|
||||
|
|
@ -154,7 +165,9 @@ class SelectPage
|
|||
);
|
||||
|
||||
// 执行总数统计
|
||||
$total = $this->model->where($where)->count();
|
||||
$total = $this->applyDataLimit()
|
||||
->model->where($where)
|
||||
->count();
|
||||
|
||||
if ($total <= 0) {
|
||||
return ['list' => [], 'total' => 0];
|
||||
|
|
@ -167,8 +180,9 @@ class SelectPage
|
|||
$this->model->order($order);
|
||||
}
|
||||
|
||||
// 执行查询
|
||||
$dataList = $this->model->where($where)
|
||||
// 执行查询(count()会清空options,需重新应用dataLimit)
|
||||
$dataList = $this->applyDataLimit()
|
||||
->model->where($where)
|
||||
->page($page, $pageSize)
|
||||
->select();
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
*{box-sizing:border-box;margin:0;padding:0;font-family:Lantinghei SC,Open Sans,Arial,Hiragino Sans GB,Microsoft YaHei,"微软雅黑",STHeiti,WenQuanYi Micro Hei,SimSun,sans-serif;-webkit-font-smoothing:antialiased}
|
||||
body{padding:70px 50px;background:#f4f6f8;font-weight:400;font-size:1pc;-webkit-text-size-adjust:none;color:#333}
|
||||
a{outline:0;color:#3498db;text-decoration:none;cursor:pointer}
|
||||
.system-message{margin:20px auto;padding:50px 0px;background:#fff;box-shadow:0 0 30px hsla(0,0%,39%,.06);text-align:center;width:100%;border-radius:2px;}
|
||||
.system-message{margin:20px auto;padding:80px 0px;background:#fff;box-shadow:0 0 30px hsla(0,0%,39%,.06);text-align:center;width:100%;border-radius:10px;}
|
||||
.system-message h1{margin:0;margin-bottom:9pt;color:#444;font-weight:400;font-size:30px}
|
||||
.system-message .jump,.system-message .image{margin:20px 0;padding:0;padding:10px 0;font-weight:400}
|
||||
.system-message .jump{font-size:14px}
|
||||
|
|
@ -32,7 +32,7 @@
|
|||
<div class="image">
|
||||
<img src="__CDN__/assets/img/{$codeText}.svg" alt="" width="120" />
|
||||
</div>
|
||||
<h1>{$msg}</h1>
|
||||
<h1>{$msg|htmlentities}</h1>
|
||||
{if $url}
|
||||
<p class="jump">
|
||||
{:__('This page will be re-directed in %s seconds', '<span id="wait">' . $wait . '</span>')}
|
||||
|
|
|
|||
|
|
@ -255,16 +255,22 @@ class User extends Frontend
|
|||
*/
|
||||
public function logout()
|
||||
{
|
||||
|
||||
if ($this->request->isPost()) {
|
||||
// 加强校验referer是否来自服务器
|
||||
$referer = $this->request->server('HTTP_REFERER');
|
||||
if (!$referer || strtolower(parse_url($referer, PHP_URL_HOST)) != strtolower($this->request->host())) {
|
||||
$this->error(__('Invalid request'));
|
||||
}
|
||||
|
||||
$this->token();
|
||||
//退出本站
|
||||
$this->auth->logout();
|
||||
$this->success(__('Logout successful'), url('user/index'));
|
||||
}
|
||||
$html = "<form id='logout_submit' name='logout_submit' action='' method='post'>" . token() . "<input type='submit' value='ok' style='display:none;'></form>";
|
||||
$html .= "<script>document.forms['logout_submit'].submit();</script>";
|
||||
|
||||
return $html;
|
||||
$this->view->assign('title', __('Logout'));
|
||||
return $this->view->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -76,6 +76,8 @@ return [
|
|||
'Operation failed' => '操作失败',
|
||||
'Invalid parameters' => '参数不正确',
|
||||
'Change password failure' => '修改密码失败',
|
||||
'Are you sure you want to sign out?' => '确定要退出登录吗?',
|
||||
'Confirm sign out' => '确定退出',
|
||||
'All' => '全部',
|
||||
'Url' => '物理路径',
|
||||
'Imagewidth' => '宽度',
|
||||
|
|
|
|||
|
|
@ -0,0 +1,17 @@
|
|||
<div id="content-container" class="container">
|
||||
<div class="user-section login-section">
|
||||
<div class="login-main text-center">
|
||||
<div class="image">
|
||||
<img src="__CDN__/assets/img/info.svg" alt="" width="100" />
|
||||
</div>
|
||||
<h3 class="my-4" style="font-size:16px;">{:__('Are you sure you want to sign out?')}</h3>
|
||||
<form name="form" id="logout-form" class="form-vertical" method="POST" action="#">
|
||||
{:token()}
|
||||
<div class="form-group">
|
||||
<button type="submit" class="btn btn-primary btn-lg btn-block">{:__('Confirm sign out')}</button>
|
||||
<button type="button" class="btn btn-default btn-lg btn-block mt-3" onclick="history.back()">{:__('Cancel')}</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -387,6 +387,24 @@ define(['jquery', 'bootstrap', 'backend', 'addtabs', 'adminlte', 'form'], functi
|
|||
}
|
||||
});
|
||||
|
||||
$(document).on("click", "a[href*='index/logout']", function () {
|
||||
var that = this;
|
||||
$.ajax({
|
||||
type: 'GET', dataType: 'html', url: $(that).attr("href"),
|
||||
success: function (data, status, xhr) {
|
||||
Fast.api.ajax({url: $(that).attr("href"), loading: false, data: {__token__: xhr.getResponseHeader('__token__')}}, function (data, ret) {
|
||||
Layer.msg(ret.msg, {icon: 1, time: 1500}, function () {
|
||||
location.reload();
|
||||
});
|
||||
return false;
|
||||
});
|
||||
}, error: function (xhr, type) {
|
||||
Layer.msg(__('Network error'), {icon: 2});
|
||||
}
|
||||
});
|
||||
return false;
|
||||
});
|
||||
|
||||
$(window).resize();
|
||||
|
||||
},
|
||||
|
|
|
|||
|
|
@ -91,6 +91,24 @@ define(['fast', 'template', 'moment'], function (Fast, Template, Moment) {
|
|||
$(document).on("click", ".sidebar-toggle", function () {
|
||||
$("body").toggleClass("sidebar-open");
|
||||
});
|
||||
|
||||
$(document).on("click", "a[href*='user/logout']", function () {
|
||||
var that = this;
|
||||
$.ajax({
|
||||
type: 'GET', dataType: 'html', url: $(that).attr("href"),
|
||||
success: function (data, status, xhr) {
|
||||
Fast.api.ajax({url: $(that).attr("href"), loading:false, data: {__token__: xhr.getResponseHeader('__token__')}}, function (data, ret) {
|
||||
Layer.msg(ret.msg, {icon: 1, time: 1500}, function () {
|
||||
location.reload();
|
||||
});
|
||||
return false;
|
||||
});
|
||||
}, error: function (xhr, type) {
|
||||
Layer.msg(__('Network error'), {icon: 2});
|
||||
}
|
||||
});
|
||||
return false;
|
||||
});
|
||||
}
|
||||
};
|
||||
Frontend.api = $.extend(Fast.api, Frontend.api);
|
||||
|
|
|
|||
Loading…
Reference in New Issue