mirror of https://gitee.com/karson/fastadmin.git
parent
9d5ccb91b4
commit
acb42e8eb8
|
|
@ -6,7 +6,8 @@ class AdminLog
|
|||
{
|
||||
public function run(&$params)
|
||||
{
|
||||
if (request()->isPost()) {
|
||||
//只记录POST请求的日志
|
||||
if (request()->isPost() && config('fastadmin.auto_record_log')) {
|
||||
\app\admin\model\AdminLog::record();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ class Addon extends Command
|
|||
'name' => $name,
|
||||
'addon' => $name,
|
||||
'addonClassName' => ucfirst($name),
|
||||
'addonInstallMenu' => $createMenu ? "\$menu = " . var_export_short($createMenu, "\t") . ";\n\tMenu::create(\$menu);" : '',
|
||||
'addonInstallMenu' => $createMenu ? "\$menu = " . var_export_short($createMenu) . ";\n\tMenu::create(\$menu);" : '',
|
||||
'addonUninstallMenu' => $menuList ? 'Menu::delete("' . $name . '");' : '',
|
||||
'addonEnableMenu' => $menuList ? 'Menu::enable("' . $name . '");' : '',
|
||||
'addonDisableMenu' => $menuList ? 'Menu::disable("' . $name . '");' : '',
|
||||
|
|
|
|||
|
|
@ -245,7 +245,7 @@ class Install extends Command
|
|||
$config[$value['name']] = $value['value'];
|
||||
}
|
||||
$config['name'] = $siteName;
|
||||
file_put_contents($configFile, '<?php' . "\n\nreturn " . var_export($config, true) . ";");
|
||||
file_put_contents($configFile, '<?php' . "\n\nreturn " . var_export_short($config) . ";\n");
|
||||
}
|
||||
|
||||
$installLockFile = INSTALL_PATH . "install.lock";
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
<style>
|
||||
body {
|
||||
background: #fff;
|
||||
background: #f1f6fd;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
line-height: 1.5;
|
||||
|
|
@ -71,8 +71,8 @@
|
|||
}
|
||||
|
||||
.form-field input {
|
||||
background: #EDF2F7;
|
||||
margin: 0 0 1px;
|
||||
background: #fff;
|
||||
margin: 0 0 2px;
|
||||
border: 2px solid transparent;
|
||||
transition: background 0.2s, border-color 0.2s, color 0.2s;
|
||||
width: 100%;
|
||||
|
|
|
|||
|
|
@ -116,6 +116,8 @@ class Addon extends Backend
|
|||
if (!preg_match("/^[a-zA-Z0-9]+$/", $name)) {
|
||||
$this->error(__('Addon name incorrect'));
|
||||
}
|
||||
|
||||
$info = [];
|
||||
try {
|
||||
$uid = $this->request->post("uid");
|
||||
$token = $this->request->post("token");
|
||||
|
|
@ -127,16 +129,13 @@ class Addon extends Backend
|
|||
'version' => $version,
|
||||
'faversion' => $faversion
|
||||
];
|
||||
Service::install($name, $force, $extend);
|
||||
$info = get_addon_info($name);
|
||||
$info['config'] = get_addon_config($name) ? 1 : 0;
|
||||
$info['state'] = 1;
|
||||
$this->success(__('Install successful'), null, ['addon' => $info]);
|
||||
$info = Service::install($name, $force, $extend);
|
||||
} catch (AddonException $e) {
|
||||
$this->result($e->getData(), $e->getCode(), __($e->getMessage()));
|
||||
} catch (Exception $e) {
|
||||
$this->error(__($e->getMessage()), $e->getCode());
|
||||
}
|
||||
$this->success(__('Install successful'), '', ['addon' => $info]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -171,12 +170,12 @@ class Addon extends Backend
|
|||
Db::execute("DROP TABLE IF EXISTS `{$table}`");
|
||||
}
|
||||
}
|
||||
$this->success(__('Uninstall successful'));
|
||||
} catch (AddonException $e) {
|
||||
$this->result($e->getData(), $e->getCode(), __($e->getMessage()));
|
||||
} catch (Exception $e) {
|
||||
$this->error(__($e->getMessage()));
|
||||
}
|
||||
$this->success(__('Uninstall successful'));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -198,12 +197,12 @@ class Addon extends Backend
|
|||
//调用启用、禁用的方法
|
||||
Service::$action($name, $force);
|
||||
Cache::rm('__menu__');
|
||||
$this->success(__('Operate successful'));
|
||||
} catch (AddonException $e) {
|
||||
$this->result($e->getData(), $e->getCode(), __($e->getMessage()));
|
||||
} catch (Exception $e) {
|
||||
$this->error(__($e->getMessage()));
|
||||
}
|
||||
$this->success(__('Operate successful'));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -213,75 +212,27 @@ class Addon extends Backend
|
|||
{
|
||||
Config::set('default_return_type', 'json');
|
||||
|
||||
$info = [];
|
||||
$file = $this->request->file('file');
|
||||
$addonTmpDir = RUNTIME_PATH . 'addons' . DS;
|
||||
if (!is_dir($addonTmpDir)) {
|
||||
@mkdir($addonTmpDir, 0755, true);
|
||||
}
|
||||
$info = $file->rule('uniqid')->validate(['size' => 10240000, 'ext' => 'zip'])->move($addonTmpDir);
|
||||
if ($info) {
|
||||
$tmpName = substr($info->getFilename(), 0, stripos($info->getFilename(), '.'));
|
||||
$tmpAddonDir = ADDON_PATH . $tmpName . DS;
|
||||
$tmpFile = $addonTmpDir . $info->getSaveName();
|
||||
try {
|
||||
Service::unzip($tmpName);
|
||||
unset($info);
|
||||
@unlink($tmpFile);
|
||||
$infoFile = $tmpAddonDir . 'info.ini';
|
||||
if (!is_file($infoFile)) {
|
||||
throw new Exception(__('Addon info file was not found'));
|
||||
}
|
||||
|
||||
$config = Config::parse($infoFile, '', $tmpName);
|
||||
$name = isset($config['name']) ? $config['name'] : '';
|
||||
if (!$name) {
|
||||
throw new Exception(__('Addon info file data incorrect'));
|
||||
}
|
||||
if (!preg_match("/^[a-zA-Z0-9]+$/", $name)) {
|
||||
throw new Exception(__('Addon name incorrect'));
|
||||
}
|
||||
|
||||
$newAddonDir = ADDON_PATH . $name . DS;
|
||||
if (is_dir($newAddonDir)) {
|
||||
throw new Exception(__('Addon already exists'));
|
||||
}
|
||||
|
||||
//重命名插件文件夹
|
||||
rename($tmpAddonDir, $newAddonDir);
|
||||
try {
|
||||
//默认禁用该插件
|
||||
$info = get_addon_info($name);
|
||||
if ($info['state']) {
|
||||
$info['state'] = 0;
|
||||
set_addon_info($name, $info);
|
||||
}
|
||||
|
||||
//执行插件的安装方法
|
||||
$class = get_addon_class($name);
|
||||
if (class_exists($class)) {
|
||||
$addon = new $class();
|
||||
$addon->install();
|
||||
}
|
||||
|
||||
//导入SQL
|
||||
Service::importsql($name);
|
||||
|
||||
$info['config'] = get_addon_config($name) ? 1 : 0;
|
||||
$this->success(__('Offline installed tips'), null, ['addon' => $info]);
|
||||
} catch (Exception $e) {
|
||||
@rmdirs($newAddonDir);
|
||||
throw new Exception(__($e->getMessage()));
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
unset($info);
|
||||
@unlink($tmpFile);
|
||||
@rmdirs($tmpAddonDir);
|
||||
$this->error(__($e->getMessage()));
|
||||
try {
|
||||
$uid = $this->request->post("uid");
|
||||
$token = $this->request->post("token");
|
||||
$faversion = $this->request->post("faversion");
|
||||
if (!$uid || !$token) {
|
||||
throw new Exception(__('Please login and try to install'));
|
||||
}
|
||||
} else {
|
||||
// 上传失败获取错误信息
|
||||
$this->error(__($file->getError()));
|
||||
$extend = [
|
||||
'uid' => $uid,
|
||||
'token' => $token,
|
||||
'faversion' => $faversion
|
||||
];
|
||||
$info = Service::local($file, $extend);
|
||||
} catch (AddonException $e) {
|
||||
$this->result($e->getData(), $e->getCode(), __($e->getMessage()));
|
||||
} catch (Exception $e) {
|
||||
$this->error(__($e->getMessage()));
|
||||
}
|
||||
$this->success(__('Offline installed tips'), '', ['addon' => $info]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -300,6 +251,8 @@ class Addon extends Backend
|
|||
if (!is_dir($addonTmpDir)) {
|
||||
@mkdir($addonTmpDir, 0755, true);
|
||||
}
|
||||
|
||||
$info = [];
|
||||
try {
|
||||
$uid = $this->request->post("uid");
|
||||
$token = $this->request->post("token");
|
||||
|
|
@ -312,14 +265,14 @@ class Addon extends Backend
|
|||
'faversion' => $faversion
|
||||
];
|
||||
//调用更新的方法
|
||||
Service::upgrade($name, $extend);
|
||||
$info = Service::upgrade($name, $extend);
|
||||
Cache::rm('__menu__');
|
||||
$this->success(__('Operate successful'));
|
||||
} catch (AddonException $e) {
|
||||
$this->result($e->getData(), $e->getCode(), __($e->getMessage()));
|
||||
} catch (Exception $e) {
|
||||
$this->error(__($e->getMessage()));
|
||||
}
|
||||
$this->success(__('Operate successful'), '', ['addon' => $info]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -352,7 +305,7 @@ class Addon extends Backend
|
|||
$addons = get_addon_list();
|
||||
$list = [];
|
||||
foreach ($addons as $k => $v) {
|
||||
if ($search && stripos($v['name'], $search) === false && stripos($v['intro'], $search) === false) {
|
||||
if ($search && stripos($v['name'], $search) === false && stripos($v['title'], $search) === false && stripos($v['intro'], $search) === false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -393,6 +346,9 @@ class Addon extends Backend
|
|||
public function get_table_list()
|
||||
{
|
||||
$name = $this->request->post("name");
|
||||
if (!preg_match("/^[a-zA-Z0-9]+$/", $name)) {
|
||||
$this->error(__('Addon name incorrect'));
|
||||
}
|
||||
$tables = get_addon_tables($name);
|
||||
$prefix = Config::get('database.prefix');
|
||||
foreach ($tables as $index => $table) {
|
||||
|
|
|
|||
|
|
@ -190,7 +190,7 @@ class Config extends Backend
|
|||
}
|
||||
file_put_contents(
|
||||
APP_PATH . 'extra' . DS . 'site.php',
|
||||
'<?php' . "\n\nreturn " . var_export($config, true) . ";"
|
||||
'<?php' . "\n\nreturn " . var_export_short($config) . ";\n"
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -21,19 +21,21 @@ return [
|
|||
'Pay tips' => '扫码支付后如果仍然无法立即下载,请不要重复支付,请稍后再重试安装!',
|
||||
'Pay click tips' => '请点击这里在新窗口中进行支付!',
|
||||
'Pay new window tips' => '请在新弹出的窗口中进行支付,支付完成后再重新点击安装按钮进行安装!',
|
||||
'Upgrade tips' => '确认升级<b>[%s]</b>?<p class="text-danger">升级后可能出现部分冗余数据记录,请根据需要移除即可!!!</p>如有重要数据请备份后再操作!',
|
||||
'Offline installed tips' => '插件安装成功!清除浏览器缓存和框架缓存后生效!',
|
||||
'Online installed tips' => '插件安装成功!清除浏览器缓存和框架缓存后生效!',
|
||||
'Upgrade tips' => '确认升级<b>《%s》</b>?<p class="text-danger">1、请务必做好代码和数据库备份!备份!备份!<br>2、升级后如出现冗余数据,请根据需要移除即可!<br>3、不建议在生产环境升级,请在本地完成升级测试</p>如有重要数据请备份后再操作!',
|
||||
'Offline installed tips' => '安装成功!清除浏览器缓存和框架缓存后生效!',
|
||||
'Online installed tips' => '安装成功!清除浏览器缓存和框架缓存后生效!',
|
||||
'Not login tips' => '你当前未登录FastAdmin,登录后将同步已购买的记录,下载时无需二次付费!',
|
||||
'Please login and try to install' => '请登录后再进行离线安装!',
|
||||
'Not installed tips' => '请安装后再访问插件前台页面!',
|
||||
'Not enabled tips' => '插件已经禁用,请启用后再访问插件前台页面!',
|
||||
'New version tips' => '发现新版本:%s 点击查看更新日志',
|
||||
'Store now available tips' => '插件市场暂不可用,是否切换到本地插件?',
|
||||
'Switch to the local' => '切换到本地插件',
|
||||
'try to reload' => '重新尝试加载',
|
||||
'Please disable addon first' => '请先禁用插件再进行升级',
|
||||
'Please disable the add before trying to upgrade' => '请先禁用插件再进行升级',
|
||||
'Please disable the add before trying to uninstall' => '请先禁用插件再进行卸载',
|
||||
'Login now' => '立即登录',
|
||||
'Continue install' => '不登录,继续安装',
|
||||
'Continue install' => '继续安装',
|
||||
'View addon home page' => '查看插件介绍和帮助',
|
||||
'View addon index page' => '查看插件前台首页',
|
||||
'View addon screenshots' => '点击查看插件截图',
|
||||
|
|
@ -85,10 +87,17 @@ return [
|
|||
'Addon name incorrect' => '插件名称不正确',
|
||||
'Addon info file was not found' => '插件配置文件未找到',
|
||||
'Addon info file data incorrect' => '插件配置信息不正确',
|
||||
'Addon already exists' => '上传的插件已经存在',
|
||||
'Addon already exists' => '插件已经存在',
|
||||
'Addon package download failed' => '插件下载失败',
|
||||
'Conflicting file found' => '发现冲突文件',
|
||||
'Invalid addon package' => '未验证的插件',
|
||||
'No permission to write temporary files' => '没有权限写入临时文件',
|
||||
'The addon file does not exist' => '插件主启动程序不存在',
|
||||
'The configuration file content is incorrect' => '配置文件不完整',
|
||||
'Unable to open the zip file' => '无法打开ZIP文件',
|
||||
'Unable to extract the file' => '无法解压ZIP文件',
|
||||
'Are you sure you want to unstall %s?' => '确认卸载插件《%s》?',
|
||||
'Unable to open file \'%s\' for writing' => '文件(%s)没有写入权限',
|
||||
'Are you sure you want to unstall %s?' => '确认卸载<b>《%s》</b>?',
|
||||
'Delete all the addon file and cannot be recovered!' => '卸载将会删除所有插件文件且不可找回!!!',
|
||||
'Delete all the addon database and cannot be recovered!' => '删除所有插件相关数据表且不可找回!!!',
|
||||
'Please backup important data manually before uninstall!' => '如有重要数据请备份后再操作!!!',
|
||||
|
|
|
|||
|
|
@ -18,6 +18,10 @@ class AdminLog extends Model
|
|||
protected static $title = '';
|
||||
//自定义日志内容
|
||||
protected static $content = '';
|
||||
//忽略的链接正则列表
|
||||
protected static $ignoreRegex = [
|
||||
'/^(.*)\/(selectpage|index)$/i',
|
||||
];
|
||||
|
||||
public static function setTitle($title)
|
||||
{
|
||||
|
|
@ -29,26 +33,41 @@ class AdminLog extends Model
|
|||
self::$content = $content;
|
||||
}
|
||||
|
||||
public static function record($title = '')
|
||||
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');
|
||||
$content = self::$content;
|
||||
if (!$content) {
|
||||
$content = request()->param('', null, 'trim,strip_tags,htmlspecialchars');
|
||||
foreach ($content as $k => $v) {
|
||||
if (is_string($v) && strlen($v) > 200 || stripos($k, 'password') !== false) {
|
||||
unset($content[$k]);
|
||||
|
||||
$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;
|
||||
}
|
||||
}
|
||||
}
|
||||
$title = self::$title;
|
||||
$content = $content ? $content : self::$content;
|
||||
if (!$content) {
|
||||
$content = request()->param('', null, 'trim,strip_tags,htmlspecialchars');
|
||||
$content = self::getPureContent($content);
|
||||
}
|
||||
$title = $title ? $title : self::$title;
|
||||
if (!$title) {
|
||||
$title = [];
|
||||
$controllername = Loader::parseName(request()->controller());
|
||||
$actionname = strtolower(request()->action());
|
||||
$path = str_replace('.', '/', $controllername) . '/' . $actionname;
|
||||
$breadcrumb = Auth::instance()->getBreadcrumb($path);
|
||||
foreach ($breadcrumb as $k => $v) {
|
||||
$title[] = $v['title'];
|
||||
|
|
@ -57,7 +76,7 @@ class AdminLog extends Model
|
|||
}
|
||||
self::create([
|
||||
'title' => $title,
|
||||
'content' => !is_scalar($content) ? json_encode($content) : $content,
|
||||
'content' => !is_scalar($content) ? json_encode($content, JSON_UNESCAPED_UNICODE) : $content,
|
||||
'url' => substr(request()->url(), 0, 1500),
|
||||
'admin_id' => $admin_id,
|
||||
'username' => $username,
|
||||
|
|
@ -66,6 +85,28 @@ class AdminLog extends Model
|
|||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取已屏蔽关键信息的数据
|
||||
* @param $content
|
||||
* @return false|string
|
||||
*/
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -78,18 +78,18 @@
|
|||
<div class="tab-pane fade active in" id="one">
|
||||
<div class="widget-body no-padding">
|
||||
<div id="toolbar" class="toolbar">
|
||||
{:build_toolbar('refresh')}
|
||||
<button type="button" id="faupload-addon" class="btn btn-danger faupload" data-url="addon/local" data-chunking="false" data-mimetype="zip" data-multiple="false"><i class="fa fa-upload"></i>
|
||||
<a href="javascript:;" class="btn btn-primary btn-refresh" title="{:__('Refresh')}" data-force-refresh="false"><i class="fa fa-refresh"></i> </a>
|
||||
{if $Think.config.fastadmin.api_url}
|
||||
<button type="button" id="faupload-addon" class="btn btn-danger faupload btn-mini-xs" data-url="addon/local" data-chunking="false" data-mimetype="zip,fastaddon" data-multiple="false"><i class="fa fa-upload"></i>
|
||||
{:__('Offline install')}
|
||||
</button>
|
||||
{if $Think.config.fastadmin.api_url}
|
||||
<div class="btn-group">
|
||||
<a href="#" class="btn btn-info btn-switch active" data-type="all"><i class="fa fa-list"></i> {:__('All')}</a>
|
||||
<a href="#" class="btn btn-info btn-switch" data-type="free"><i class="fa fa-gift"></i> {:__('Free')}</a>
|
||||
<a href="#" class="btn btn-info btn-switch" data-type="price"><i class="fa fa-rmb"></i> {:__('Paying')}</a>
|
||||
<a href="#" class="btn btn-info btn-switch" data-type="local" data-url="addon/downloaded"><i class="fa fa-laptop"></i> {:__('Local addon')}</a>
|
||||
<a href="#" class="btn btn-info btn-switch active btn-mini-xs" data-type="all"><i class="fa fa-list"></i> {:__('All')}</a>
|
||||
<a href="#" class="btn btn-info btn-switch btn-mini-xs" data-type="free"><i class="fa fa-gift"></i> {:__('Free')}</a>
|
||||
<a href="#" class="btn btn-info btn-switch btn-mini-xs" data-type="price"><i class="fa fa-rmb"></i> {:__('Paying')}</a>
|
||||
<a href="#" class="btn btn-info btn-switch btn-mini-xs" data-type="local" data-url="addon/downloaded"><i class="fa fa-laptop"></i> {:__('Local addon')}</a>
|
||||
</div>
|
||||
<a class="btn btn-primary btn-userinfo" href="javascript:;"><i class="fa fa-user"></i> {:__('Userinfo')}</a>
|
||||
<a class="btn btn-primary btn-userinfo btn-mini-xs" href="javascript:;"><i class="fa fa-user"></i> {:__('Userinfo')}</a>
|
||||
{/if}
|
||||
</div>
|
||||
<table id="table" class="table table-striped table-bordered table-hover" width="100%">
|
||||
|
|
@ -208,7 +208,7 @@
|
|||
</script>
|
||||
<script id="uninstalltpl" type="text/html">
|
||||
<div class="">
|
||||
<div class=""><%=__("Are you sure you want to unstall %s?", addon['title'])%>
|
||||
<div class=""><%=#__("Are you sure you want to unstall %s?", addon['title'])%>
|
||||
<p class="text-danger">{:__('Delete all the addon file and cannot be recovered!')} </p>
|
||||
{if config('app_debug')}
|
||||
<p class="text-danger"><input type="checkbox" name="droptables" id="droptables" data-name="<%=addon['name']%>"/> {:__('Delete all the addon database and cannot be recovered!')} </p>
|
||||
|
|
|
|||
|
|
@ -1,17 +1,22 @@
|
|||
<table class="table table-striped">
|
||||
<style>
|
||||
.table-adminlog tr td {
|
||||
word-break: break-all;
|
||||
}
|
||||
</style>
|
||||
<table class="table table-striped table-adminlog">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{:__('Title')}</th>
|
||||
<th>{:__('Content')}</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th width="100">{:__('Title')}</th>
|
||||
<th>{:__('Content')}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{volist name="row" id="vo" }
|
||||
<tr>
|
||||
<td>{:__($key)}</td>
|
||||
<td>{if $key=='createtime'}{$vo|datetime}{else/}{$vo|htmlentities}{/if}</td>
|
||||
</tr>
|
||||
{/volist}
|
||||
{volist name="row" id="vo" }
|
||||
<tr>
|
||||
<td>{:__($key)}</td>
|
||||
<td>{if $key=='createtime'}{$vo|datetime}{else/}{$vo|htmlentities}{/if}</td>
|
||||
</tr>
|
||||
{/volist}
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="hide layer-footer">
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
<div class="tab-pane fade active in" id="one">
|
||||
<div class="widget-body no-padding">
|
||||
<div id="toolbar" class="toolbar">
|
||||
<a href="javascript:;" class="btn btn-primary btn-refresh" title="{:__('Refresh')}" ><i class="fa fa-refresh"></i> </a>
|
||||
<a href="javascript:;" class="btn btn-primary btn-refresh" title="{:__('Refresh')}" data-force-refresh="false"><i class="fa fa-refresh"></i> </a>
|
||||
<a href="javascript:;" class="btn btn-success btn-add {:$auth->check('auth/rule/add')?'':'hide'}" title="{:__('Add')}" ><i class="fa fa-plus"></i> {:__('Add')}</a>
|
||||
<a href="javascript:;" class="btn btn-success btn-edit btn-disabled disabled {:$auth->check('auth/rule/edit')?'':'hide'}" title="{:__('Edit')}" ><i class="fa fa-pencil"></i> {:__('Edit')}</a>
|
||||
<a href="javascript:;" class="btn btn-danger btn-del btn-disabled disabled {:$auth->check('auth/rule/del')?'':'hide'}" title="{:__('Delete')}" ><i class="fa fa-trash"></i> {:__('Delete')}</a>
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
// 公共助手函数
|
||||
|
||||
use Symfony\Component\VarExporter\VarExporter;
|
||||
|
||||
if (!function_exists('__')) {
|
||||
|
||||
/**
|
||||
|
|
@ -264,29 +266,12 @@ if (!function_exists('var_export_short')) {
|
|||
|
||||
/**
|
||||
* 返回打印数组结构
|
||||
* @param string $var 数组
|
||||
* @param string $indent 缩进字符
|
||||
* @param string $var 数组
|
||||
* @return string
|
||||
*/
|
||||
function var_export_short($var, $indent = "")
|
||||
function var_export_short($var)
|
||||
{
|
||||
switch (gettype($var)) {
|
||||
case "string":
|
||||
return '"' . addcslashes($var, "\\\$\"\r\n\t\v\f") . '"';
|
||||
case "array":
|
||||
$indexed = array_keys($var) === range(0, count($var) - 1);
|
||||
$r = [];
|
||||
foreach ($var as $key => $value) {
|
||||
$r[] = "$indent "
|
||||
. ($indexed ? "" : var_export_short($key) . " => ")
|
||||
. var_export_short($value, "$indent ");
|
||||
}
|
||||
return "[\n" . implode(",\n", $r) . "\n" . $indent . "]";
|
||||
case "boolean":
|
||||
return $var ? "TRUE" : "FALSE";
|
||||
default:
|
||||
return var_export($var, true);
|
||||
}
|
||||
return VarExporter::export($var);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -277,7 +277,7 @@ class Backend extends Controller
|
|||
$bind = [];
|
||||
$name = '';
|
||||
$aliasName = '';
|
||||
if (!empty($this->model)) {
|
||||
if (!empty($this->model) && $this->relationSearch) {
|
||||
$name = $this->model->getTable();
|
||||
$alias[$name] = Loader::parseName(basename(str_replace('\\', '/', get_class($this->model))));
|
||||
$aliasName = $alias[$name] . '.';
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@ namespace app\common\library;
|
|||
|
||||
use app\admin\model\AuthRule;
|
||||
use fast\Tree;
|
||||
use think\addons\Service;
|
||||
use think\Db;
|
||||
use think\Exception;
|
||||
use think\exception\PDOException;
|
||||
|
||||
|
|
@ -15,32 +17,16 @@ class Menu
|
|||
* @param array $menu
|
||||
* @param mixed $parent 父类的name或pid
|
||||
*/
|
||||
public static function create($menu, $parent = 0)
|
||||
public static function create($menu = [], $parent = 0)
|
||||
{
|
||||
if (!is_numeric($parent)) {
|
||||
$parentRule = AuthRule::getByName($parent);
|
||||
$pid = $parentRule ? $parentRule['id'] : 0;
|
||||
} else {
|
||||
$pid = $parent;
|
||||
}
|
||||
$allow = array_flip(['file', 'name', 'title', 'icon', 'condition', 'remark', 'ismenu', 'weigh']);
|
||||
foreach ($menu as $k => $v) {
|
||||
$hasChild = isset($v['sublist']) && $v['sublist'] ? true : false;
|
||||
$old = [];
|
||||
self::menuUpdate($menu, $old, $parent);
|
||||
|
||||
$data = array_intersect_key($v, $allow);
|
||||
|
||||
$data['ismenu'] = isset($data['ismenu']) ? $data['ismenu'] : ($hasChild ? 1 : 0);
|
||||
$data['icon'] = isset($data['icon']) ? $data['icon'] : ($hasChild ? 'fa fa-list' : 'fa fa-circle-o');
|
||||
$data['pid'] = $pid;
|
||||
$data['status'] = 'normal';
|
||||
try {
|
||||
$menu = AuthRule::create($data);
|
||||
if ($hasChild) {
|
||||
self::create($v['sublist'], $menu->id);
|
||||
}
|
||||
} catch (PDOException $e) {
|
||||
throw new Exception($e->getMessage());
|
||||
}
|
||||
//菜单刷新处理
|
||||
$info = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2)[1];
|
||||
preg_match('/addons\\\\([a-z0-9]+)\\\\/i', $info['class'], $matches);
|
||||
if ($matches && isset($matches[1])) {
|
||||
Menu::refresh($matches[1], $menu);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -97,13 +83,70 @@ class Menu
|
|||
*/
|
||||
public static function upgrade($name, $menu)
|
||||
{
|
||||
$old = AuthRule::where('name', 'like', "{$name}%")->select();
|
||||
$ids = self::getAuthRuleIdsByName($name);
|
||||
$old = AuthRule::where('id', 'in', $ids)->select();
|
||||
$old = collection($old)->toArray();
|
||||
$old = array_column($old, null, 'name');
|
||||
self::menuUpdate($menu, $old);
|
||||
|
||||
Db::startTrans();
|
||||
try {
|
||||
self::menuUpdate($menu, $old);
|
||||
$ids = [];
|
||||
foreach ($old as $index => $item) {
|
||||
if (!isset($item['keep'])) {
|
||||
$ids[] = $item['id'];
|
||||
}
|
||||
}
|
||||
if ($ids) {
|
||||
//旧版本的菜单需要做删除处理
|
||||
$config = Service::config($name);
|
||||
$menus = isset($config['menus']) ? $config['menus'] : [];
|
||||
$where = ['id' => ['in', $ids]];
|
||||
if ($menus) {
|
||||
//必须是旧版本中的菜单,可排除用户自主创建的菜单
|
||||
$where['name'] = ['in', $menus];
|
||||
}
|
||||
AuthRule::where($where)->delete();
|
||||
}
|
||||
|
||||
Db::commit();
|
||||
} catch (PDOException $e) {
|
||||
Db::rollback();
|
||||
return false;
|
||||
}
|
||||
|
||||
Menu::refresh($name, $menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新插件菜单配置缓存
|
||||
* @param string $name
|
||||
* @param array $menu
|
||||
*/
|
||||
public static function refresh($name, $menu = [])
|
||||
{
|
||||
if (!$menu) {
|
||||
// $menu为空时表示首次安装,首次安装需刷新插件菜单标识缓存
|
||||
$menuIds = Menu::getAuthRuleIdsByName($name);
|
||||
$menus = Db::name("auth_rule")->where('id', 'in', $menuIds)->column('name');
|
||||
} else {
|
||||
// 刷新新的菜单缓存
|
||||
$getMenus = function ($menu) use (&$getMenus) {
|
||||
$result = [];
|
||||
foreach ($menu as $index => $item) {
|
||||
$result[] = $item['name'];
|
||||
$result = array_merge($result, isset($item['sublist']) && is_array($item['sublist']) ? $getMenus($item['sublist']) : []);
|
||||
}
|
||||
return $result;
|
||||
};
|
||||
$menus = $getMenus($menu);
|
||||
}
|
||||
|
||||
//刷新新的插件核心菜单缓存
|
||||
Service::config($name, ['menus' => $menus]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出指定名称的菜单规则
|
||||
* @param string $name
|
||||
|
|
@ -131,7 +174,7 @@ class Menu
|
|||
* @param int $parent
|
||||
* @throws Exception
|
||||
*/
|
||||
private static function menuUpdate($newMenu, $oldMenu, $parent = 0)
|
||||
private static function menuUpdate($newMenu, &$oldMenu, $parent = 0)
|
||||
{
|
||||
if (!is_numeric($parent)) {
|
||||
$parentRule = AuthRule::getByName($parent);
|
||||
|
|
@ -147,17 +190,16 @@ class Menu
|
|||
$data['icon'] = isset($data['icon']) ? $data['icon'] : ($hasChild ? 'fa fa-list' : 'fa fa-circle-o');
|
||||
$data['pid'] = $pid;
|
||||
$data['status'] = 'normal';
|
||||
try {
|
||||
if (!isset($oldMenu[$data['name']])) {
|
||||
$menu = AuthRule::create($data);
|
||||
} else {
|
||||
$menu = $oldMenu[$data['name']];
|
||||
}
|
||||
if ($hasChild) {
|
||||
self::menuUpdate($v['sublist'], $oldMenu, $menu['id']);
|
||||
}
|
||||
} catch (PDOException $e) {
|
||||
throw new Exception($e->getMessage());
|
||||
if (!isset($oldMenu[$data['name']])) {
|
||||
$menu = AuthRule::create($data);
|
||||
} else {
|
||||
$menu = $oldMenu[$data['name']];
|
||||
//更新旧菜单
|
||||
AuthRule::update($data, ['id' => $menu['id']]);
|
||||
$oldMenu[$data['name']]['keep'] = true;
|
||||
}
|
||||
if ($hasChild) {
|
||||
self::menuUpdate($v['sublist'], $oldMenu, $menu['id']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -311,6 +311,9 @@ class Upload
|
|||
$sourceFile = $this->file->getRealPath() ?: $this->file->getPathname();
|
||||
$info = $this->file->getInfo();
|
||||
$this->file = null;
|
||||
if (!is_dir($destDir)) {
|
||||
@mkdir($destDir, 0755, true);
|
||||
}
|
||||
rename($sourceFile, $destFile);
|
||||
$file = new File($destFile);
|
||||
$file->setSaveName($fileName)->setUploadInfo($info);
|
||||
|
|
|
|||
|
|
@ -279,6 +279,14 @@ return [
|
|||
'adminskin' => '',
|
||||
//后台是否启用面包屑
|
||||
'breadcrumb' => false,
|
||||
//是否允许未知来源的插件压缩包
|
||||
'unknownsources' => true,
|
||||
//插件启用禁用时是否备份对应的全局文件
|
||||
'backup_global_files' => true,
|
||||
//是否开启后台自动日志记录
|
||||
'auto_record_log' => true,
|
||||
//插件纯净模式,插件启用后是否删除插件目录的application、public和assets文件夹
|
||||
'addon_pure_mode' => true,
|
||||
//允许跨域的域名,多个以,分隔
|
||||
'cors_request_domain' => 'localhost,127.0.0.1',
|
||||
//版本号
|
||||
|
|
|
|||
|
|
@ -1,14 +1,8 @@
|
|||
<?php
|
||||
|
||||
return array (
|
||||
'autoload' => false,
|
||||
'hooks' =>
|
||||
array (
|
||||
),
|
||||
'route' =>
|
||||
array (
|
||||
),
|
||||
'priority' =>
|
||||
array (
|
||||
),
|
||||
);
|
||||
return [
|
||||
'autoload' => false,
|
||||
'hooks' => [],
|
||||
'route' => [],
|
||||
'priority' => [],
|
||||
];
|
||||
|
|
|
|||
|
|
@ -1,38 +1,35 @@
|
|||
<?php
|
||||
|
||||
return array (
|
||||
'name' => '我的网站',
|
||||
'beian' => '',
|
||||
'cdnurl' => '',
|
||||
'version' => '1.0.1',
|
||||
'timezone' => 'Asia/Shanghai',
|
||||
'forbiddenip' => '',
|
||||
'languages' =>
|
||||
array (
|
||||
'backend' => 'zh-cn',
|
||||
'frontend' => 'zh-cn',
|
||||
),
|
||||
'fixedpage' => 'dashboard',
|
||||
'categorytype' =>
|
||||
array (
|
||||
'default' => 'Default',
|
||||
'page' => 'Page',
|
||||
'article' => 'Article',
|
||||
'test' => 'Test',
|
||||
),
|
||||
'configgroup' =>
|
||||
array (
|
||||
'basic' => 'Basic',
|
||||
'email' => 'Email',
|
||||
'dictionary' => 'Dictionary',
|
||||
'user' => 'User',
|
||||
'example' => 'Example',
|
||||
),
|
||||
'mail_type' => '1',
|
||||
'mail_smtp_host' => 'smtp.qq.com',
|
||||
'mail_smtp_port' => '465',
|
||||
'mail_smtp_user' => '10000',
|
||||
'mail_smtp_pass' => 'password',
|
||||
'mail_verify_type' => '2',
|
||||
'mail_from' => '10000@qq.com',
|
||||
);
|
||||
return [
|
||||
'name' => '我的网站',
|
||||
'beian' => '',
|
||||
'cdnurl' => '',
|
||||
'version' => '1.0.1',
|
||||
'timezone' => 'Asia/Shanghai',
|
||||
'forbiddenip' => '',
|
||||
'languages' => [
|
||||
'backend' => 'zh-cn',
|
||||
'frontend' => 'zh-cn',
|
||||
],
|
||||
'fixedpage' => 'dashboard',
|
||||
'categorytype' => [
|
||||
'default' => 'Default',
|
||||
'page' => 'Page',
|
||||
'article' => 'Article',
|
||||
'test' => 'Test',
|
||||
],
|
||||
'configgroup' => [
|
||||
'basic' => 'Basic',
|
||||
'email' => 'Email',
|
||||
'dictionary' => 'Dictionary',
|
||||
'user' => 'User',
|
||||
'example' => 'Example',
|
||||
],
|
||||
'mail_type' => '1',
|
||||
'mail_smtp_host' => 'smtp.qq.com',
|
||||
'mail_smtp_port' => '465',
|
||||
'mail_smtp_user' => '10000',
|
||||
'mail_smtp_pass' => 'password',
|
||||
'mail_verify_type' => '2',
|
||||
'mail_from' => '10000@qq.com',
|
||||
];
|
||||
|
|
|
|||
|
|
@ -19,10 +19,12 @@
|
|||
"topthink/framework": "~5.0.24",
|
||||
"topthink/think-captcha": "^1.0",
|
||||
"phpmailer/phpmailer": "~6.1.6",
|
||||
"karsonzhang/fastadmin-addons": "~1.2.0",
|
||||
"karsonzhang/fastadmin-addons": "~1.2.4",
|
||||
"overtrue/pinyin": "~3.0",
|
||||
"phpoffice/phpspreadsheet": "^1.2",
|
||||
"overtrue/wechat": "4.2.11",
|
||||
"nelexa/zip": "^3.3",
|
||||
"symfony/var-exporter ": "^4.4.13",
|
||||
"ext-json": "*",
|
||||
"ext-curl": "*"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1008,7 +1008,7 @@ table.table-nowrap thead > tr > th {
|
|||
.fixed-table-toolbar .toolbar a.btn-import,
|
||||
.fixed-table-toolbar .toolbar a.btn-more,
|
||||
.fixed-table-toolbar .toolbar a.btn-recyclebin,
|
||||
.fixed-table-toolbar .toolbar a.btn-mini-xs {
|
||||
.fixed-table-toolbar .toolbar .btn-mini-xs {
|
||||
font-size: 0;
|
||||
}
|
||||
.fixed-table-toolbar .toolbar a.btn-refresh .fa,
|
||||
|
|
@ -1018,7 +1018,7 @@ table.table-nowrap thead > tr > th {
|
|||
.fixed-table-toolbar .toolbar a.btn-import .fa,
|
||||
.fixed-table-toolbar .toolbar a.btn-more .fa,
|
||||
.fixed-table-toolbar .toolbar a.btn-recyclebin .fa,
|
||||
.fixed-table-toolbar .toolbar a.btn-mini-xs .fa {
|
||||
.fixed-table-toolbar .toolbar .btn-mini-xs .fa {
|
||||
font-size: initial;
|
||||
}
|
||||
.fixed-table-toolbar .search {
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -1,38 +1,3 @@
|
|||
define([], function () {
|
||||
require.config({
|
||||
paths: {
|
||||
'jquery-colorpicker': '../addons/cms/js/jquery.colorpicker.min',
|
||||
'jquery-autocomplete': '../addons/cms/js/jquery.autocomplete',
|
||||
'jquery-tagsinput': '../addons/cms/js/jquery.tagsinput',
|
||||
'clipboard': '../addons/cms/js/clipboard.min',
|
||||
},
|
||||
shim: {
|
||||
'jquery-colorpicker': {
|
||||
deps: ['jquery'],
|
||||
exports: '$.fn.extend'
|
||||
},
|
||||
'jquery-autocomplete': {
|
||||
deps: ['jquery'],
|
||||
exports: '$.fn.extend'
|
||||
},
|
||||
'jquery-tagsinput': {
|
||||
deps: ['jquery', 'jquery-autocomplete', 'css!../addons/cms/css/jquery.tagsinput.min.css'],
|
||||
exports: '$.fn.extend'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
require.config({
|
||||
paths: {
|
||||
'async': '../addons/example/js/async',
|
||||
'BMap': ['//api.map.baidu.com/api?v=2.0&ak=mXijumfojHnAaN2VxpBGoqHM'],
|
||||
},
|
||||
shim: {
|
||||
'BMap': {
|
||||
deps: ['jquery'],
|
||||
exports: 'BMap'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
|
@ -31,6 +31,8 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
|
|||
btn: [__('Switch to the local'), __('Try to reload')]
|
||||
}, function (index) {
|
||||
layer.close(index);
|
||||
$(".panel .nav-tabs").hide();
|
||||
$(".toolbar > *:not(:first)").hide();
|
||||
$(".btn-switch[data-type='local']").trigger("click");
|
||||
}, function (index) {
|
||||
layer.close(index);
|
||||
|
|
@ -62,6 +64,15 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
|
|||
Template.helper("Moment", Moment);
|
||||
Template.helper("addons", Config['addons']);
|
||||
|
||||
$("#faupload-addon").data("params", function () {
|
||||
var userinfo = Controller.api.userinfo.get();
|
||||
return {
|
||||
uid: userinfo ? userinfo.id : '',
|
||||
token: userinfo ? userinfo.token : '',
|
||||
version: Config.faversion
|
||||
};
|
||||
});
|
||||
|
||||
// 初始化表格
|
||||
table.bootstrapTable({
|
||||
url: $.fn.bootstrapTable.defaults.extend.index_url,
|
||||
|
|
@ -168,6 +179,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
|
|||
Config['addons'][data.addon.name] = data.addon;
|
||||
Toastr.success(ret.msg);
|
||||
operate(data.addon.name, 'enable', false);
|
||||
return false;
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -220,12 +232,13 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
|
|||
// 会员信息
|
||||
$(document).on("click", ".btn-userinfo", function () {
|
||||
var that = this;
|
||||
var area = [$(window).width() > 800 ? '500px' : '95%', $(window).height() > 600 ? '400px' : '95%'];
|
||||
var userinfo = Controller.api.userinfo.get();
|
||||
if (!userinfo) {
|
||||
Layer.open({
|
||||
content: Template("logintpl", {}),
|
||||
zIndex: 99,
|
||||
area: [$(window).width() > 800 ? '500px' : '95%', $(window).height() > 600 ? '400px' : '95%'],
|
||||
area: area,
|
||||
title: __('Login FastAdmin'),
|
||||
resize: false,
|
||||
btn: [__('Login'), __('Register')],
|
||||
|
|
@ -315,8 +328,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
|
|||
title: __('Warning'),
|
||||
icon: 1
|
||||
});
|
||||
$('.btn-refresh').trigger('click');
|
||||
Fast.api.refreshmenu();
|
||||
Controller.api.refresh(table, name);
|
||||
}, function (data, ret) {
|
||||
//如果是需要购买的插件则弹出二维码提示
|
||||
if (ret && ret.code === -1) {
|
||||
|
|
@ -377,8 +389,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
|
|||
}, function (data, ret) {
|
||||
delete Config['addons'][name];
|
||||
Layer.closeAll();
|
||||
$('.btn-refresh').trigger('click');
|
||||
Fast.api.refreshmenu();
|
||||
Controller.api.refresh(table, name);
|
||||
}, function (data, ret) {
|
||||
if (ret && ret.code === -3) {
|
||||
//插件目录发现影响全局的文件
|
||||
|
|
@ -411,8 +422,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
|
|||
var addon = Config['addons'][name];
|
||||
addon.state = action === 'enable' ? 1 : 0;
|
||||
Layer.closeAll();
|
||||
$('.btn-refresh').trigger('click');
|
||||
Fast.api.refreshmenu();
|
||||
Controller.api.refresh(table, name);
|
||||
}, function (data, ret) {
|
||||
if (ret && ret.code === -3) {
|
||||
//插件目录发现影响全局的文件
|
||||
|
|
@ -445,10 +455,9 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
|
|||
url: 'addon/upgrade',
|
||||
data: {name: name, uid: uid, token: token, version: version, faversion: Config.faversion}
|
||||
}, function (data, ret) {
|
||||
Config['addons'][name].version = version;
|
||||
Config['addons'][name] = data.addon;
|
||||
Layer.closeAll();
|
||||
$('.btn-refresh').trigger('click');
|
||||
Fast.api.refreshmenu();
|
||||
Controller.api.refresh(table, name);
|
||||
}, function (data, ret) {
|
||||
Layer.alert(ret.msg);
|
||||
return false;
|
||||
|
|
@ -483,7 +492,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
|
|||
$(document).on("click", ".btn-uninstall", function () {
|
||||
var name = $(this).closest(".operate").data('name');
|
||||
if (Config['addons'][name].state == 1) {
|
||||
Layer.alert(__('Please disable addon first'), {icon: 7});
|
||||
Layer.alert(__('Please disable the add before trying to uninstall'), {icon: 7});
|
||||
return false;
|
||||
}
|
||||
Template.helper("__", __);
|
||||
|
|
@ -509,7 +518,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
|
|||
$(document).on("click", ".btn-upgrade", function () {
|
||||
var name = $(this).closest(".operate").data('name');
|
||||
if (Config['addons'][name].state == 1) {
|
||||
Layer.alert(__('Please disable addon first'), {icon: 7});
|
||||
Layer.alert(__('Please disable the add before trying to upgrade'), {icon: 7});
|
||||
return false;
|
||||
}
|
||||
var version = $(this).data("version");
|
||||
|
|
@ -602,6 +611,20 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
|
|||
localStorage.removeItem("fastadmin_userinfo");
|
||||
}
|
||||
}
|
||||
},
|
||||
refresh: function (table, name) {
|
||||
//刷新左侧边栏
|
||||
Fast.api.refreshmenu();
|
||||
|
||||
//刷新行数据
|
||||
if ($(".operate[data-name='" + name + "']").length > 0) {
|
||||
var index = $(".operate[data-name='" + name + "']").closest("tr[data-index]").data("index");
|
||||
var row = Table.api.getrowbyindex(table, index);
|
||||
row.addon = typeof Config['addons'][name] !== 'undefined' ? Config['addons'][name] : undefined;
|
||||
table.bootstrapTable("updateRow", {index: index, row: row});
|
||||
} else if ($(".btn-switch.active").data("type") == "local") {
|
||||
$(".btn-refresh").trigger("click");
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -116,7 +116,8 @@ define(['jquery', 'bootstrap', 'backend', 'addtabs', 'adminlte', 'form'], functi
|
|||
$(document).on('refresh', '.sidebar-menu', function () {
|
||||
Fast.api.ajax({
|
||||
url: 'index/index',
|
||||
data: {action: 'refreshmenu'}
|
||||
data: {action: 'refreshmenu'},
|
||||
loading: false
|
||||
}, function (data) {
|
||||
$(".sidebar-menu li:not([data-rel='external'])").remove();
|
||||
$(".sidebar-menu").prepend(data.menulist);
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -1243,7 +1243,7 @@ table.table-nowrap {
|
|||
}
|
||||
|
||||
.toolbar {
|
||||
a.btn-refresh, a.btn-del, a.btn-add, a.btn-edit, a.btn-import, a.btn-more, a.btn-recyclebin, a.btn-mini-xs {
|
||||
a.btn-refresh, a.btn-del, a.btn-add, a.btn-edit, a.btn-import, a.btn-more, a.btn-recyclebin, .btn-mini-xs {
|
||||
font-size: 0;
|
||||
|
||||
.fa {
|
||||
|
|
|
|||
Loading…
Reference in New Issue