Merge remote-tracking branch 'karson/master'

pull/71/head
PPPSCN 2018-05-14 15:04:50 +08:00
commit 320c8e10ce
24 changed files with 1861 additions and 2077 deletions

11
.env.sample 100644
View File

@ -0,0 +1,11 @@
[app]
debug = false
trace = false
[database]
hostname = 127.0.0.1
database = fastadmin
username = root
password = root
hostport = 3306
prefix = fa_

2
application/admin/command/Api.php 100755 → 100644
View File

@ -70,7 +70,7 @@ class Api extends Command
}
if (version_compare(PHP_VERSION, '7.0.0', '<')) {
if (extension_loaded('opcache')) {
if (extension_loaded('Zend OPcache')) {
$configuration = opcache_get_configuration();
$directives = $configuration['directives'];
$configName = request()->isCli() ? 'opcache.enable_cli' : 'opcache.enable';

View File

@ -30,21 +30,20 @@ class Index extends Backend
public function index()
{
//左侧菜单
$menulist = $this->auth->getSidebar([
list($menulist, $navlist) = $this->auth->getSidebar([
'dashboard' => 'hot',
'addon' => ['new', 'red', 'badge'],
'auth/rule' => __('Menu'),
'general' => ['new', 'purple'],
], $this->view->site['fixedpage']);
], $this->view->site['fixedpage']);
$action = $this->request->request('action');
if ($this->request->isPost())
{
if ($action == 'refreshmenu')
{
$this->success('', null, ['menulist' => $menulist]);
if ($this->request->isPost()) {
if ($action == 'refreshmenu') {
$this->success('', null, ['menulist' => $menulist, 'navlist' => $navlist]);
}
}
$this->view->assign('menulist', $menulist);
$this->view->assign('navlist', $navlist);
$this->view->assign('title', __('Home'));
return $this->view->fetch();
}
@ -55,12 +54,10 @@ class Index extends Backend
public function login()
{
$url = $this->request->get('url', 'index/index');
if ($this->auth->isLogin())
{
if ($this->auth->isLogin()) {
$this->success(__("You've logged in, do not login again"), $url);
}
if ($this->request->isPost())
{
if ($this->request->isPost()) {
$username = $this->request->post('username');
$password = $this->request->post('password');
$keeplogin = $this->request->post('keeplogin');
@ -75,26 +72,21 @@ class Index extends Backend
'password' => $password,
'__token__' => $token,
];
if (Config::get('fastadmin.login_captcha'))
{
if (Config::get('fastadmin.login_captcha')) {
$rule['captcha'] = 'require|captcha';
$data['captcha'] = $this->request->post('captcha');
}
$validate = new Validate($rule, [], ['username' => __('Username'), 'password' => __('Password'), 'captcha' => __('Captcha')]);
$result = $validate->check($data);
if (!$result)
{
if (!$result) {
$this->error($validate->getError(), $url, ['token' => $this->request->token()]);
}
AdminLog::setTitle(__('Login'));
$result = $this->auth->login($username, $password, $keeplogin ? 86400 : 0);
if ($result === true)
{
if ($result === true) {
Hook::listen("admin_login_after", $this->request);
$this->success(__('Login successful'), $url, ['url' => $url, 'id' => $this->auth->id, 'username' => $username, 'avatar' => $this->auth->avatar]);
}
else
{
} else {
$msg = $this->auth->getError();
$msg = $msg ? $msg : __('Username or password is incorrect');
$this->error($msg, $url, ['token' => $this->request->token()]);
@ -102,12 +94,11 @@ class Index extends Backend
}
// 根据客户端的cookie,判断是否可以自动登录
if ($this->auth->autologin())
{
if ($this->auth->autologin()) {
$this->redirect($url);
}
$background = Config::get('fastadmin.login_background');
$background = stripos($background, 'http')===0 ? $background : config('site.cdnurl') . $background;
$background = stripos($background, 'http') === 0 ? $background : config('site.cdnurl') . $background;
$this->view->assign('background', $background);
$this->view->assign('title', __('Login'));
Hook::listen("admin_login_init", $this->request);

View File

@ -18,6 +18,7 @@ class Rule extends Backend
*/
protected $model = null;
protected $rulelist = [];
protected $multiFields = 'ismenu,status';
public function _initialize()
{

View File

@ -112,6 +112,7 @@ return [
'Go back' => '返回首页',
'Jump now' => '立即跳转',
'Click to search %s' => '点击搜索 %s',
'Click to toggle' => '点击切换',
'Operation completed' => '操作成功!',
'Operation failed' => '操作失败!',
'Unknown data format' => '未知的数据格式!',

View File

@ -31,26 +31,23 @@ class Auth extends \fast\Auth
/**
* 管理员登录
*
* @param string $username 用户名
* @param string $password 密码
* @param int $keeptime 有效时长
* @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)
{
if (!$admin) {
$this->setError('Username is incorrect');
return false;
}
if (Config::get('fastadmin.login_failure_retry') && $admin->loginfailure >= 10 && time() - $admin->updatetime < 86400)
{
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 != md5(md5($password) . $admin->salt))
{
if ($admin->password != md5(md5($password) . $admin->salt)) {
$admin->loginfailure++;
$admin->save();
$this->setError('Password is incorrect');
@ -71,8 +68,7 @@ class Auth extends \fast\Auth
public function logout()
{
$admin = Admin::get(intval($this->id));
if (!$admin)
{
if (!$admin) {
return true;
}
$admin->token = '';
@ -89,30 +85,24 @@ class Auth extends \fast\Auth
public function autologin()
{
$keeplogin = Cookie::get('keeplogin');
if (!$keeplogin)
{
if (!$keeplogin) {
return false;
}
list($id, $keeptime, $expiretime, $key) = explode('|', $keeplogin);
if ($id && $keeptime && $expiretime && $key && $expiretime > time())
{
if ($id && $keeptime && $expiretime && $key && $expiretime > time()) {
$admin = Admin::get($id);
if (!$admin || !$admin->token)
{
if (!$admin || !$admin->token) {
return false;
}
//token有变更
if ($key != md5(md5($id) . md5($keeptime) . md5($expiretime) . $admin->token))
{
if ($key != md5(md5($id) . md5($keeptime) . md5($expiretime) . $admin->token)) {
return false;
}
Session::set("admin", $admin->toArray());
//刷新自动登录的时效
$this->keeplogin($keeptime);
return true;
}
else
{
} else {
return false;
}
}
@ -120,13 +110,12 @@ class Auth extends \fast\Auth
/**
* 刷新保持登录的Cookie
*
* @param int $keeptime
* @param int $keeptime
* @return boolean
*/
protected function keeplogin($keeptime = 0)
{
if ($keeptime)
{
if ($keeptime) {
$expiretime = time() + $keeptime;
$key = md5(md5($this->id) . md5($keeptime) . md5($expiretime) . $this->token);
$data = [$this->id, $keeptime, $expiretime, $key];
@ -150,15 +139,13 @@ class Auth extends \fast\Auth
{
$request = Request::instance();
$arr = is_array($arr) ? $arr : explode(',', $arr);
if (!$arr)
{
if (!$arr) {
return FALSE;
}
$arr = array_map('strtolower', $arr);
// 是否存在
if (in_array(strtolower($request->action()), $arr) || in_array('*', $arr))
{
if (in_array(strtolower($request->action()), $arr) || in_array('*', $arr)) {
return TRUE;
}
@ -173,21 +160,17 @@ class Auth extends \fast\Auth
*/
public function isLogin()
{
if ($this->logined)
{
if ($this->logined) {
return true;
}
$admin = Session::get('admin');
if (!$admin)
{
if (!$admin) {
return false;
}
//判断是否同一时间同一账号只能在一个地方登录
if (Config::get('fastadmin.login_unique'))
{
if (Config::get('fastadmin.login_unique')) {
$my = Admin::get($admin['id']);
if (!$my || $my['token'] != $admin['token'])
{
if (!$my || $my['token'] != $admin['token']) {
return false;
}
}
@ -252,9 +235,8 @@ class Auth extends \fast\Auth
{
$groups = $this->getGroups($uid);
$groupIds = [];
foreach ($groups as $K => $v)
{
$groupIds[] = (int) $v['group_id'];
foreach ($groups as $K => $v) {
$groupIds[] = (int)$v['group_id'];
}
return $groupIds;
}
@ -269,17 +251,14 @@ class Auth extends \fast\Auth
//取出当前管理员所有的分组
$groups = $this->getGroups();
$groupIds = [];
foreach ($groups as $k => $v)
{
foreach ($groups as $k => $v) {
$groupIds[] = $v['id'];
}
// 取出所有分组
$groupList = \app\admin\model\AuthGroup::where(['status' => 'normal'])->select();
$objList = [];
foreach ($groups as $K => $v)
{
if ($v['rules'] === '*')
{
foreach ($groups as $K => $v) {
if ($v['rules'] === '*') {
$objList = $groupList;
break;
}
@ -289,12 +268,10 @@ class Auth extends \fast\Auth
$objList = array_merge($objList, Tree::instance()->getTreeList($obj));
}
$childrenGroupIds = [];
foreach ($objList as $k => $v)
{
foreach ($objList as $k => $v) {
$childrenGroupIds[] = $v['id'];
}
if (!$withself)
{
if (!$withself) {
$childrenGroupIds = array_diff($childrenGroupIds, $groupIds);
}
return $childrenGroupIds;
@ -308,33 +285,25 @@ class Auth extends \fast\Auth
public function getChildrenAdminIds($withself = false)
{
$childrenAdminIds = [];
if (!$this->isSuperAdmin())
{
if (!$this->isSuperAdmin()) {
$groupIds = $this->getChildrenGroupIds(false);
$authGroupList = \app\admin\model\AuthGroupAccess::
field('uid,group_id')
->where('group_id', 'in', $groupIds)
->select();
field('uid,group_id')
->where('group_id', 'in', $groupIds)
->select();
foreach ($authGroupList as $k => $v)
{
foreach ($authGroupList as $k => $v) {
$childrenAdminIds[] = $v['uid'];
}
}
else
{
} else {
//超级管理员拥有所有人的权限
$childrenAdminIds = Admin::column('id');
}
if ($withself)
{
if (!in_array($this->id, $childrenAdminIds))
{
if ($withself) {
if (!in_array($this->id, $childrenAdminIds)) {
$childrenAdminIds[] = $this->id;
}
}
else
{
} else {
$childrenAdminIds = array_diff($childrenAdminIds, [$this->id]);
}
return $childrenAdminIds;
@ -350,15 +319,12 @@ class Auth extends \fast\Auth
if ($this->breadcrumb || !$path)
return $this->breadcrumb;
$path_rule_id = 0;
foreach ($this->rules as $rule)
{
foreach ($this->rules as $rule) {
$path_rule_id = $rule['name'] == $path ? $rule['id'] : $path_rule_id;
}
if ($path_rule_id)
{
if ($path_rule_id) {
$this->breadcrumb = Tree::instance()->init($this->rules)->getParents($path_rule_id, true);
foreach ($this->breadcrumb as $k => &$v)
{
foreach ($this->breadcrumb as $k => &$v) {
$v['url'] = url($v['name']);
$v['title'] = __($v['title']);
}
@ -367,10 +333,11 @@ class Auth extends \fast\Auth
}
/**
* 获取左侧菜单栏
* 获取左侧和顶部菜单栏
*
* @param array $params URL对应的badge数据
* @return string
* @param string $fixedPage 默认页
* @return array
*/
public function getSidebar($params = [], $fixedPage = 'dashboard')
{
@ -379,26 +346,21 @@ class Auth extends \fast\Auth
$badgeList = [];
$module = request()->module();
// 生成菜单的badge
foreach ($params as $k => $v)
{
foreach ($params as $k => $v) {
$url = $k;
if (is_array($v))
{
if (is_array($v)) {
$nums = isset($v[0]) ? $v[0] : 0;
$color = isset($v[1]) ? $v[1] : $colorArr[(is_numeric($nums) ? $nums : strlen($nums)) % $colorNums];
$class = isset($v[2]) ? $v[2] : 'label';
}
else
{
} else {
$nums = $v;
$color = $colorArr[(is_numeric($nums) ? $nums : strlen($nums)) % $colorNums];
$class = 'label';
}
//必须nums大于0才显示
if ($nums)
{
if ($nums) {
$badgeList[$url] = '<small class="' . $class . ' pull-right bg-' . $color . '">' . $nums . '</small>';
}
}
@ -409,10 +371,8 @@ class Auth extends \fast\Auth
$pinyin = new \Overtrue\Pinyin\Pinyin('Overtrue\Pinyin\MemoryFileDictLoader');
// 必须将结果集转换为数组
$ruleList = collection(\app\admin\model\AuthRule::where('status', 'normal')->where('ismenu', 1)->order('weigh', 'desc')->cache("__menu__")->select())->toArray();
foreach ($ruleList as $k => &$v)
{
if (!in_array($v['name'], $userRule))
{
foreach ($ruleList as $k => &$v) {
if (!in_array($v['name'], $userRule)) {
unset($ruleList[$k]);
continue;
}
@ -423,16 +383,45 @@ class Auth extends \fast\Auth
$v['pinyin'] = $pinyin->permalink($v['title'], '');
$v['title'] = __($v['title']);
}
// 构造菜单数据
Tree::instance()->init($ruleList);
$menu = Tree::instance()->getTreeMenu(0, '<li class="@class"><a href="@url@addtabs" addtabs="@id" 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"');
return $menu;
$menu = $nav = '';
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 href="@url@addtabs" addtabs="@id" 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"');
$current = in_array($item['id'], $selectParentIds);
$url = $childList ? 'javascript:;' : url($item['url']);
$addtabs = $childList || !$url ? "" : (stripos($url, "?") !== false ? "&" : "?") . "ref=addtabs";
$childList = str_replace('" pid="' . $item['id'] . '"', ' treeview ' . ($current ? '' : 'hidden') . '" pid="' . $item['id'] . '"', $childList);
$nav .= '<li class="' . ($current ? 'active' : '') . '"><a href="' . $url . $addtabs . '" addtabs="' . $item['id'] . '" url="' . $url . '"><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 href="@url@addtabs" addtabs="@id" 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"');
}
return [$menu, $nav];
}
/**
* 设置错误信息
*
* @param $error 错误信息
* @return Auth
*/
public function setError($error)
{

View File

@ -1,131 +1,147 @@
<!-- Logo -->
<a href="javascript:;" class="logo hidden-xs">
<a href="javascript:;" class="logo">
<!-- 迷你模式下Logo的大小为50X50 -->
<span class="logo-mini">{$site.name|mb_substr=0,4,'utf-8'|mb_strtoupper='utf-8'}</span>
<!-- 普通模式下Logo -->
<span class="logo-lg"><b>{$site.name|mb_substr=0,4,'utf-8'}</b>{$site.name|mb_substr=4,null,'utf-8'}</span>
</a>
<!-- 顶部通栏样式 -->
<nav class="navbar navbar-static-top">
<!-- 边栏切换按钮-->
<a href="#" class="sidebar-toggle" data-toggle="offcanvas" role="button">
<span class="sr-only">{:__('Toggle navigation')}</span>
</a>
<div id="nav" class="pull-left">
<!--第一级菜单-->
<div id="firstnav">
<!-- 边栏切换按钮-->
<a href="#" class="sidebar-toggle" data-toggle="offcanvas" role="button">
<span class="sr-only">{:__('Toggle navigation')}</span>
</a>
<!--如果不想在顶部显示角标,则给ul加上disable-top-badge类即可-->
<ul class="nav nav-tabs nav-addtabs disable-top-badge hidden-xs" role="tablist">
{$navlist}
</ul>
<div class="navbar-custom-menu">
<ul class="nav navbar-nav">
<li>
<a href="__PUBLIC__" target="_blank"><i class="fa fa-home" style="font-size:14px;"></i></a>
</li>
<li class="dropdown notifications-menu hidden-xs">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
<i class="fa fa-bell-o"></i>
<span class="label label-warning"></span>
</a>
<ul class="dropdown-menu">
<li class="header">{:__('Latest news')}</li>
<li>
<!-- FastAdmin最新更新信息,你可以替换成你自己站点的信息,请注意修改public/assets/js/backend/index.js文件 -->
<ul class="menu">
</ul>
</li>
<li class="footer"><a href="#" target="_blank">{:__('View more')}</a></li>
</ul>
</li>
<!-- 账号信息下拉框 -->
<li class="hidden-xs">
<a href="javascript:;" data-toggle="checkupdate" title="{:__('Check for updates')}">
<i class="fa fa-refresh"></i>
</a>
</li>
<!-- 清除缓存 -->
<li>
<a href="javascript:;" data-toggle="dropdown" title="{:__('Wipe cache')}">
<i class="fa fa-trash"></i>
</a>
<ul class="dropdown-menu wipecache">
<li><a href="javascript:;" data-type="all"><i class="fa fa-trash"></i> {:__('Wipe all cache')}</a></li>
<li class="divider"></li>
<li><a href="javascript:;" data-type="content"><i class="fa fa-file-text"></i> {:__('Wipe content cache')}</a></li>
<li><a href="javascript:;" data-type="template"><i class="fa fa-file-image-o"></i> {:__('Wipe template cache')}</a></li>
<li><a href="javascript:;" data-type="addons"><i class="fa fa-rocket"></i> {:__('Wipe addons cache')}</a></li>
</ul>
</li>
<!-- 多语言列表 -->
{if $Think.config.lang_switch_on}
<li class="hidden-xs">
<a href="javascript:;" class="dropdown-toggle" data-toggle="dropdown"><i class="fa fa-language"></i></a>
<ul class="dropdown-menu">
<li class="{$config['language']=='zh-cn'?'active':''}">
<a href="?ref=addtabs&lang=zh-cn">简体中文</a>
</li>
<li class="{$config['language']=='en'?'active':''}">
<a href="?ref=addtabs&lang=en">English</a>
</li>
</ul>
</li>
{/if}
<!-- 全屏按钮 -->
<li class="hidden-xs">
<a href="#" data-toggle="fullscreen"><i class="fa fa-arrows-alt"></i></a>
</li>
<!-- 账号信息下拉框 -->
<li class="dropdown user user-menu">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
<img src="__CDN__{$admin.avatar}" class="user-image" alt="{$admin.nickname}">
<span class="hidden-xs">{$admin.nickname}</span>
</a>
<ul class="dropdown-menu">
<!-- User image -->
<li class="user-header">
<img src="__CDN__{$admin.avatar}" class="img-circle" alt="">
<p>
{$admin.nickname}
<small>{$admin.logintime|date="Y-m-d H:i:s",###}</small>
</p>
</li>
<!-- Menu Body -->
<li class="user-body">
<div class="row">
<div class="col-xs-4 text-center">
<a href="https://www.fastadmin.net" target="_blank">{:__('FastAdmin')}</a>
</div>
<div class="col-xs-4 text-center">
<a href="https://forum.fastadmin.net" target="_blank">{:__('Forum')}</a>
</div>
<div class="col-xs-4 text-center">
<a href="https://doc.fastadmin.net" target="_blank">{:__('Docs')}</a>
</div>
</div>
</li>
<!-- Menu Footer-->
<li class="user-footer">
<div class="pull-left">
<a href="general/profile" class="btn btn-primary addtabsit"><i class="fa fa-user"></i>
{:__('Profile')}</a>
</div>
<div class="pull-right">
<a href="{:url('index/logout')}" class="btn btn-danger"><i class="fa fa-sign-out"></i>
{:__('Logout')}</a>
</div>
</li>
</ul>
</li>
<!-- 控制栏切换按钮 -->
<li class="hidden-xs">
<a href="javascript:;" data-toggle="control-sidebar"><i class="fa fa-gears"></i></a>
</li>
</ul>
</div>
</div>
{if $config.fastadmin.multiplenav}
<!--第二级菜单,只有在multiplenav开启时才显示-->
<div id="secondnav">
<ul class="nav nav-tabs nav-addtabs disable-top-badge" role="tablist">
</ul>
</div>
<div class="navbar-custom-menu">
<ul class="nav navbar-nav">
<li>
<a href="__PUBLIC__" target="_blank"><i class="fa fa-home" style="font-size:14px;"></i></a>
</li>
<li class="dropdown notifications-menu hidden-xs">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
<i class="fa fa-bell-o"></i>
<span class="label label-warning"></span>
</a>
<ul class="dropdown-menu">
<li class="header">{:__('Latest news')}</li>
<li>
<!-- FastAdmin最新更新信息,你可以替换成你自己站点的信息,请注意修改public/assets/js/backend/index.js文件 -->
<ul class="menu">
</ul>
</li>
<li class="footer"><a href="#" target="_blank">{:__('View more')}</a></li>
</ul>
</li>
<li class="hidden-xs">
<a href="javascript:;" data-toggle="checkupdate" title="{:__('Check for updates')}">
<i class="fa fa-refresh"></i>
</a>
</li>
<li>
<a href="javascript:;" data-toggle="dropdown" title="{:__('Wipe cache')}">
<i class="fa fa-trash"></i>
</a>
<ul class="dropdown-menu wipecache">
<li><a href="javascript:;" data-type="all"><i class="fa fa-trash"></i> {:__('Wipe all cache')}</a></li>
<li class="divider"></li>
<li><a href="javascript:;" data-type="content"><i class="fa fa-file-text"></i> {:__('Wipe content cache')}</a></li>
<li><a href="javascript:;" data-type="template"><i class="fa fa-file-image-o"></i> {:__('Wipe template cache')}</a></li>
<li><a href="javascript:;" data-type="addons"><i class="fa fa-rocket"></i> {:__('Wipe addons cache')}</a></li>
</ul>
</li>
{if $Think.config.lang_switch_on}
<li class="hidden-xs">
<a href="javascript:;" class="dropdown-toggle" data-toggle="dropdown"><i class="fa fa-language"></i></a>
<ul class="dropdown-menu">
<li class="{$config['language']=='zh-cn'?'active':''}">
<a href="?ref=addtabs&lang=zh-cn">简体中文</a>
</li>
<li class="{$config['language']=='en'?'active':''}">
<a href="?ref=addtabs&lang=en">English</a>
</li>
</ul>
</li>
{/if}
<li class="hidden-xs">
<a href="#" data-toggle="fullscreen"><i class="fa fa-arrows-alt"></i></a>
</li>
<!-- 账号信息下拉框 -->
<li class="dropdown user user-menu">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
<img src="__CDN__{$admin.avatar}" class="user-image" alt="{$admin.nickname}">
<span class="hidden-xs">{$admin.nickname}</span>
</a>
<ul class="dropdown-menu">
<!-- User image -->
<li class="user-header">
<img src="__CDN__{$admin.avatar}" class="img-circle" alt="">
<p>
{$admin.nickname}
<small>{$admin.logintime|date="Y-m-d H:i:s",###}</small>
</p>
</li>
<!-- Menu Body -->
<li class="user-body">
<div class="row">
<div class="col-xs-4 text-center">
<a href="https://www.fastadmin.net" target="_blank">{:__('FastAdmin')}</a>
</div>
<div class="col-xs-4 text-center">
<a href="https://forum.fastadmin.net" target="_blank">{:__('Forum')}</a>
</div>
<div class="col-xs-4 text-center">
<a href="https://doc.fastadmin.net" target="_blank">{:__('Docs')}</a>
</div>
</div>
</li>
<!-- Menu Footer-->
<li class="user-footer">
<div class="pull-left">
<a href="general/profile" class="btn btn-primary addtabsit"><i class="fa fa-user"></i>
{:__('Profile')}</a>
</div>
<div class="pull-right">
<a href="{:url('index/logout')}" class="btn btn-danger"><i class="fa fa-sign-out"></i>
{:__('Logout')}</a>
</div>
</li>
</ul>
</li>
<!-- 控制栏切换按钮 -->
<li class="hidden-xs">
<a href="javascript:;" data-toggle="control-sidebar"><i class="fa fa-gears"></i></a>
</li>
</ul>
</div>
{/if}
</nav>

View File

@ -1,6 +1,6 @@
<!-- sidebar: style can be found in sidebar.less -->
<!-- 左侧菜单栏 -->
<section class="sidebar">
<!-- Sidebar user panel -->
<!-- 管理员信息 -->
<div class="user-panel hidden-xs">
<div class="pull-left image">
<a href="general/profile" class="addtabsit"><img src="__CDN__{$admin.avatar}" class="img-circle" /></a>
@ -11,7 +11,7 @@
</div>
</div>
<!-- search form -->
<!-- 菜单搜索 -->
<form action="" method="get" class="sidebar-form" onsubmit="return false;">
<div class="input-group">
<input type="text" name="q" class="form-control" placeholder="{:__('Search menu')}">
@ -23,16 +23,22 @@
</div>
</div>
</form>
<!-- /.search form -->
<!-- sidebar menu: : style can be found in sidebar.less -->
<!--如果想始终显示子菜单,则给ul加上show-submenu类即可-->
<ul class="sidebar-menu">
<!-- 移动端一级菜单 -->
<div class="mobilenav visible-xs">
</div>
<!--如果想始终显示子菜单,则给ul加上show-submenu类即可,当multiplenav开启的情况下默认为展开-->
<ul class="sidebar-menu {if $config.fastadmin.multiplenav}show-submenu{/if}">
<!-- 菜单可以在 后台管理->权限管理->菜单规则 中进行增删改排序 -->
{$menulist}
<!--以下4行可以删除或改成自己的链接,但建议你在你的网站上添加一个FastAdmin的链接-->
<li class="header" data-rel="external">{:__('Links')}</li>
<li data-rel="external"><a href="https://doc.fastadmin.net" target="_blank"><i class="fa fa-list text-red"></i> <span>{:__('Docs')}</span></a></li>
<li data-rel="external"><a href="https://forum.fastadmin.net" target="_blank"><i class="fa fa-comment text-yellow"></i> <span>{:__('Forum')}</span></a></li>
<li data-rel="external"><a href="https://jq.qq.com/?_wv=1027&k=487PNBb" target="_blank"><i class="fa fa-qq text-aqua"></i> <span>{:__('QQ qun')}</span></a></li>
</ul>
</section>
<!-- /.sidebar -->
</section>

View File

@ -1,38 +1,40 @@
<!DOCTYPE html>
<html lang="{$config.language}">
<head>
<!-- 加载部部样式及META信息 -->
{include file="common/meta" /}
</head>
<body class="hold-transition skin-blue sidebar-mini fixed /*sidebar-collapse*/" id="tabs">
<body class="hold-transition skin-green sidebar-mini fixed {if $config.fastadmin.multiplenav}multiplenav{/if}" id="tabs">
<div class="wrapper">
<!-- 头部区域 -->
<header id="header" class="main-header">
{include file='common/header' /}
</header>
<!-- Left side column. contains the logo and sidebar -->
<!-- 左侧菜单栏 -->
<aside class="main-sidebar">
{include file='common/menu' /}
</aside>
<!-- Content Wrapper. Contains page content -->
<!-- 主体内容区域 -->
<div class="content-wrapper tab-content tab-addtabs">
</div>
<!-- /.content-wrapper -->
<!-- 底部链接,默认隐藏 -->
<footer class="main-footer hide">
<div class="pull-right hidden-xs">
</div>
<strong>Copyright &copy; 2017-2018 <a href="https://www.fastadmin.net">Fastadmin</a>.</strong> All rights
reserved.
<strong>Copyright &copy; 2017-2018 <a href="https://www.fastadmin.net">Fastadmin</a>.</strong> All rights reserved.
</footer>
<!-- Add the sidebar's background. This div must be placed
immediately after the control sidebar -->
<!-- 右侧控制栏 -->
<div class="control-sidebar-bg"></div>
{include file="common/control" /}
</div>
<!-- ./wrapper -->
<!-- end main content -->
<!-- 加载JS脚本 -->
{include file="common/script" /}
</body>
</html>

View File

@ -16,7 +16,7 @@
<small>{:__('Control panel')}</small>
</h1>
</section>
{if !IS_DIALOG}
{if !IS_DIALOG && !$config.fastadmin.multiplenav}
<!-- RIBBON -->
<div id="ribbon">
<ol class="breadcrumb pull-left">

View File

@ -267,10 +267,12 @@ return [
'login_unique' => false,
//登录页默认背景图
'login_background' => "/assets/img/loginbg.jpg",
//是否启用多级菜单导航
'multiplenav' => false,
//自动检测更新
'checkupdate' => false,
//版本号
'version' => '1.0.0.20180506_beta',
'version' => '1.0.0.20180513_beta',
//API接口地址
'api_url' => 'https://api.fastadmin.net',
],

View File

@ -9,10 +9,12 @@
@import url("../libs/eonasdan-bootstrap-datetimepicker/build/css/bootstrap-datetimepicker.min.css");
@import url("../libs/bootstrap-daterangepicker/daterangepicker.css");
@import url("../libs/nice-validator/dist/jquery.validator.css");
@import url("../libs/bootstrap-select/dist/css/bootstrap-select.min.css");
@import url("../libs/fastadmin-selectpage/selectpage.css");
@import url("../libs/bootstrap-slider/slider.css");
body {
background: #f1f4f6;
font-size: 13px;
}
body.is-dialog {
background: #fff;
@ -32,19 +34,6 @@ body.is-dialog {
.main-header .navbar {
position: relative;
}
.main-header .navbar .sidebar-toggle {
position: absolute;
width: 45px;
text-align: center;
}
.main-header .navbar #nav {
position: absolute;
left: 45px;
}
.main-header .navbar .navbar-custom-menu {
position: absolute;
right: 0;
}
.bootstrap-dialog .modal-dialog {
/*width: 70%;*/
max-width: 885px;
@ -61,7 +50,6 @@ html.ios-fix body {
}
#header {
background: #fff;
box-shadow: 0 2px 2px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(0, 0, 0, 0.05);
}
.content-wrapper {
position: relative;
@ -112,9 +100,6 @@ html.ios-fix body {
margin-bottom: 15px;
background-color: #f5f5f5;
}
.searchit {
border-bottom: 1px dashed #3c8dbc;
}
/* 固定的底部按钮 */
.fixed-footer {
position: fixed;
@ -291,6 +276,7 @@ form.form-horizontal .control-label {
}
/*顶栏addtabs*/
.nav-addtabs {
height: 100%;
border: none;
}
.nav-addtabs.disable-top-badge > li > a > .pull-right-container {
@ -300,8 +286,8 @@ form.form-horizontal .control-label {
margin: 0;
}
.nav-addtabs > li > a {
height: 49px;
line-height: 49px;
height: 50px;
line-height: 50px;
padding: 0 15px;
border-radius: 0;
border: none;
@ -319,8 +305,8 @@ form.form-horizontal .control-label {
margin-right: 3px;
}
.nav-addtabs > li.active > a {
height: 49px;
line-height: 49px;
height: 50px;
line-height: 50px;
padding: 0 15px;
border-radius: 0;
border: none;
@ -333,21 +319,28 @@ form.form-horizontal .control-label {
.nav-addtabs > li.active > a:focus {
border: none;
color: #2c3e50;
border-right: 1px solid rgba(0, 0, 0, 0.05);
background: #f1f4f6;
border-right: 1px solid rgba(0, 0, 0, 0.05);
}
.nav-addtabs > li .close-tab {
font-size: 10px;
position: absolute;
right: 5px;
right: 0px;
top: 50%;
margin-top: -7px;
margin-top: -8px;
z-index: 100;
cursor: hand;
cursor: pointer;
color: #fff;
color: #eee;
display: none;
}
.nav-addtabs > li .close-tab:before {
content: "\e626";
font-family: iconfont;
font-style: normal;
font-weight: normal;
text-decoration: inherit;
font-size: 18px;
}
.nav-addtabs .open > a:hover,
.nav-addtabs .open > a:focus {
border-right: 1px solid rgba(0, 0, 0, 0.05);
@ -358,6 +351,119 @@ form.form-horizontal .control-label {
.nav-addtabs li:hover > .close-tab {
display: block;
}
.multiplenav .content-wrapper,
.multiplenav .right-side {
padding-top: 94px;
}
.multiplenav #firstnav .nav-addtabs {
padding-right: 450px;
}
#firstnav {
height: 50px;
border-bottom: 1px solid transparent;
box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
position: relative;
}
#firstnav .sidebar-toggle {
position: absolute;
width: 45px;
text-align: center;
height: 50px;
line-height: 50px;
padding: 0;
}
#firstnav .nav-addtabs {
position: absolute;
left: 45px;
z-index: 98;
}
#firstnav .navbar-custom-menu {
position: absolute;
top: 0;
right: 0;
z-index: 99;
background: transparent;
}
/*次栏菜单栏*/
#secondnav {
height: 44px;
position: absolute;
top: 50px;
left: 0;
background: #fff;
width: 100%;
box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
padding: 5px 10px;
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
}
#secondnav .nav-addtabs {
height: 100%;
border: none;
}
#secondnav .nav-addtabs.disable-top-badge > li > a > .pull-right-container {
display: none;
}
#secondnav .nav-addtabs > li {
border: 1px solid #eee;
border-radius: 3px;
padding: 0 15px;
height: 30px;
line-height: 30px;
margin: 2px 5px 2px 0;
background: #fff;
}
#secondnav .nav-addtabs > li > a {
display: block;
color: #495060 !important;
height: 100%;
padding: 0;
line-height: 28px;
font-size: 12px;
vertical-align: middle;
opacity: 1;
overflow: hidden;
background: none;
border: none;
}
#secondnav .nav-addtabs > li > a i {
margin-right: 3px;
}
#secondnav .nav-addtabs > li.active {
border-color: #bdbebd;
background-color: #f7f7f7;
}
#secondnav .nav-addtabs > li .close-tab {
font-size: 10px;
position: absolute;
right: 0px;
top: 50%;
margin-top: -8px;
z-index: 100;
cursor: pointer;
color: #eee;
}
#secondnav .nav-addtabs > li .close-tab:before {
content: "\e626";
font-family: iconfont;
font-style: normal;
font-weight: normal;
text-decoration: inherit;
font-size: 18px;
}
#secondnav .nav-addtabs > li:hover,
#secondnav .nav-addtabs > li:focus {
border-color: #bdbebd;
}
#secondnav .nav-addtabs ul li {
position: relative;
}
#secondnav .nav-addtabs li:hover > .close-tab {
display: block;
border-color: #222e32;
color: #222e32;
}
.main-sidebar .sidebar-form {
overflow: visible;
}
@ -404,7 +510,7 @@ form.form-horizontal .control-label {
top: 41px;
}
.sidebar-mini.sidebar-collapse .sidebar-menu > li:hover > a > .pull-right-container {
top: 7px!important;
top: 7px !important;
height: 17px;
}
}
@ -495,7 +601,7 @@ form.form-horizontal .control-label {
}
/*去除bootstrap-table的边框*/
.fixed-table-container {
border: none!important;
border: none !important;
}
/*修复nice-validator新版下的一处BUG*/
.nice-validator input,
@ -543,11 +649,14 @@ form.form-horizontal .control-label {
}
.dropdown-menu.text-left a,
.dropdown-menu.text-left li {
text-align: left!important;
text-align: left !important;
}
.bootstrap-table .fixed-table-toolbar .dropdown-menu {
overflow: auto;
}
.bootstrap-table .fa-toggle-on.fa-2x {
font-size: 1.86em;
}
.toolbar {
margin-top: 10px;
margin-bottom: 10px;
@ -620,25 +729,25 @@ form.form-horizontal .control-label {
}
/*重写toast的几个背景色*/
.toast-primary {
background-color: #48c9b0!important;
background-color: #48c9b0 !important;
}
.toast-success {
background-color: #18bc9c!important;
background-color: #18bc9c !important;
}
.toast-error {
background-color: #e74c3c!important;
background-color: #e74c3c !important;
}
.toast-info {
background-color: #5dade2!important;
background-color: #5dade2 !important;
}
.toast-warning {
background-color: #f1c40f!important;
background-color: #f1c40f !important;
}
.toast-inverse {
background-color: #34495e!important;
background-color: #34495e !important;
}
.toast-default {
background-color: #bdc3c7!important;
background-color: #bdc3c7 !important;
}
#toast-container > div,
#toast-container > div:hover {
@ -650,8 +759,8 @@ form.form-horizontal .control-label {
/*自定义底部灰色操作区*/
}
.layui-layer-fast .layui-layer-title {
background: #2c3e50!important;
color: #fff!important;
background: #2c3e50 !important;
color: #fff !important;
border-bottom: none;
}
.layui-layer-fast .layui-layer-title ~ .layui-layer-setwin {
@ -664,7 +773,7 @@ form.form-horizontal .control-label {
display: inline-block;
}
.layui-layer-fast.layui-layer-border {
border: none!important;
border: none !important;
box-shadow: 1px 1px 50px rgba(0, 0, 0, 0.3) !important;
}
.layui-layer-fast.layui-layer-iframe {
@ -676,15 +785,15 @@ form.form-horizontal .control-label {
box-sizing: content-box;
}
.layui-layer-fast .layui-layer-btn {
text-align: center!important;
padding: 10px!important;
text-align: center !important;
padding: 10px !important;
background: #ecf0f1;
overflow: hidden;
}
.layui-layer-fast .layui-layer-btn a {
background-color: #95a5a6;
border-color: #95a5a6;
color: #fff!important;
color: #fff !important;
height: 31px;
margin-top: 0;
border: 1px solid transparent;
@ -697,10 +806,10 @@ form.form-horizontal .control-label {
padding: 8px 20px;
background-color: #ecf0f1;
height: auto;
text-align: inherit!important;
text-align: inherit !important;
}
.layui-layer-fast .layui-layer-setwin > a {
background: none!important;
background: none !important;
}
.layui-layer-fast .layui-layer-setwin > a cite {
display: none;
@ -718,11 +827,11 @@ form.form-horizontal .control-label {
z-index: 1;
}
.layui-layer-fast .layui-layer-setwin > a:hover {
text-decoration: none!important;
background: none!important;
text-decoration: none !important;
background: none !important;
}
.layui-layer-fast .layui-layer-setwin > a:focus {
text-decoration: none!important;
text-decoration: none !important;
}
.layui-layer-fast .layui-layer-setwin .layui-layer-min {
display: none;
@ -781,8 +890,12 @@ form.form-horizontal .control-label {
}
/*手机版样式*/
@media (max-width: 480px) {
.nav-addtabs {
display: none;
#firstnav .navbar-custom-menu ul li a {
padding-left: 10px;
padding-right: 10px;
}
#firstnav .navbar-nav > .user-menu .user-image {
margin-top: -3px;
}
.fixed-table-toolbar .columns-right.btn-group {
display: none;
@ -791,9 +904,64 @@ form.form-horizontal .control-label {
.fixed .right-side {
padding-top: 50px;
}
.multiplenav .fixed .content-wrapper,
.multiplenav .fixed .right-side {
padding-top: 94px;
}
.multiplenav .content-wrapper,
.multiplenav .right-side {
padding-top: 94px;
}
.main-sidebar,
.left-side {
padding-top: 144px;
}
}
/*平板样式*/
@media (max-width: 768px) {
body .wrapper .main-header .logo {
background: none;
color: #fff;
border-bottom: 0 solid transparent;
position: absolute;
top: 0;
z-index: 1200;
width: 130px;
left: 50%;
margin-left: -65px;
}
body .sidebar .mobilenav a.btn-app {
color: #444;
width: 100px;
height: 70px;
font-size: 13px;
}
body .sidebar .mobilenav a.btn-app i.fa {
font-size: 24px;
}
body .sidebar .mobilenav a.btn-app span {
margin-top: 5px;
display: block;
}
body .sidebar .mobilenav a.btn-app.active {
color: #222d32;
}
body .wrapper .main-header .navbar .dropdown-menu li > a {
color: #333;
}
body .wrapper .main-header .navbar .dropdown-menu li > a:hover {
background: #eee;
}
body .wrapper .main-header .navbar .dropdown-menu li.active > a {
color: #fff;
}
body .wrapper .main-header .navbar .dropdown-menu li.active > a:hover {
background: #222d32;
}
.main-sidebar,
.left-side {
padding-top: 94px;
}
.n-bootstrap .n-right {
margin-top: 0;
top: -20px;
@ -819,7 +987,7 @@ form.form-horizontal .control-label {
margin: 2px 0 0;
}
.wipecache li a {
color: #444444!important;
color: #444444 !important;
}
.col-md-1-5 {

File diff suppressed because one or more lines are too long

View File

@ -304,7 +304,7 @@ function _init() {
$(".sidebar").slimscroll({
height: ($(window).height() - $(".main-header").height()) + "px",
color: "rgba(0,0,0,0.2)",
size: "3px"
size: "8px"
});
}
}

View File

@ -34,7 +34,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
field: 'ismenu',
title: __('Ismenu'),
align: 'center',
formatter: Controller.api.formatter.menu
formatter: Table.api.formatter.toggle
},
{
field: 'id',
@ -117,10 +117,6 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
name: function (value, row, index) {
return !row.ismenu || row.status == 'hidden' ? "<span class='text-muted'>" + value + "</span>" : value;
},
menu: function (value, row, index) {
return "<a href='javascript:;' data-toggle='tooltip' title='" + __('Toggle menu visible') + "' class='btn btn-" + (value ? "info" : "default") + " btn-xs btn-change' data-id='"
+ row.id + "' data-params='ismenu=" + (value ? 0 : 1) + "'>" + (value ? __('Yes') : __('No')) + "</a>";
},
icon: function (value, row, index) {
return '<span class="' + (!row.ismenu || row.status == 'hidden' ? 'text-muted' : '') + '"><i class="' + value + '"></i></span>';
},

View File

@ -215,6 +215,11 @@ define(['jquery', 'bootstrap', 'backend', 'addtabs', 'adminlte', 'form'], functi
}
});
var multiplenav = Config.fastadmin.multiplenav;
var firstnav = $("#firstnav .nav-addtabs");
var nav = multiplenav ? $("#secondnav .nav-addtabs") : firstnav;
//刷新菜单事件
$(document).on('refresh', '.sidebar-menu', function () {
Fast.api.ajax({
@ -223,28 +228,103 @@ define(['jquery', 'bootstrap', 'backend', 'addtabs', 'adminlte', 'form'], functi
}, function (data) {
$(".sidebar-menu li:not([data-rel='external'])").remove();
$(".sidebar-menu").prepend(data.menulist);
$("#nav ul li[role='presentation'].active a").trigger('click');
if (multiplenav) {
firstnav.html(data.navlist);
}
$("li[role='presentation'].active a", nav).trigger('click');
return false;
}, function () {
return false;
});
});
if (multiplenav) {
//一级菜单自适应
$(window).resize(function () {
var siblingsWidth = 0;
firstnav.siblings().each(function () {
siblingsWidth += $(this).outerWidth();
});
firstnav.width(firstnav.parent().width() - siblingsWidth);
firstnav.refreshAddtabs();
});
//点击顶部第一级菜单栏
firstnav.on("click", "li a", function () {
$("li", firstnav).removeClass("active");
$(this).closest("li").addClass("active");
$(".sidebar-menu > li.treeview").addClass("hidden");
if ($(this).attr("url") == "javascript:;") {
var sonlist = $(".sidebar-menu > li[pid='" + $(this).attr("addtabs") + "']");
sonlist.removeClass("hidden");
var last_id = $(this).attr("last-id");
if (last_id) {
$(".sidebar-menu > li[pid='" + $(this).attr("addtabs") + "'] a[addtabs='" + last_id + "']").trigger('click');
} else {
$(".sidebar-menu > li[pid='" + $(this).attr("addtabs") + "']:first > a").trigger('click');
}
} else {
}
});
//点击左侧菜单栏
$(document).on('click', '.sidebar-menu li a[addtabs]', function (e) {
var parents = $(this).parentsUntil("ul.sidebar-menu", "li");
var top = parents[parents.length - 1];
var pid = $(top).attr("pid");
if (pid) {
var obj = $("li a[addtabs=" + pid + "]", firstnav);
var last_id = obj.attr("last-id");
if (!last_id || last_id != pid) {
obj.attr("last-id", $(this).attr("addtabs"));
if (!obj.closest("li").hasClass("active")) {
obj.trigger("click");
}
}
}
});
var mobilenav = $(".mobilenav");
$("#firstnav .nav-addtabs li a").each(function(){
mobilenav.append($(this).clone().addClass("btn btn-app"));
});
//点击移动端一级菜单
mobilenav.on("click", "a", function () {
$("a", mobilenav).removeClass("active");
$(this).addClass("active");
$(".sidebar-menu > li.treeview").addClass("hidden");
if ($(this).attr("url") == "javascript:;") {
var sonlist = $(".sidebar-menu > li[pid='" + $(this).attr("addtabs") + "']");
sonlist.removeClass("hidden");
}
});
}
//这一行需要放在点击左侧链接事件之前
var addtabs = Config.referer ? localStorage.getItem("addtabs") : null;
//绑定tabs事件,如果需要点击强制刷新iframe,则请将iframeForceRefresh置为true
$('#nav').addtabs({iframeHeight: "100%", iframeForceRefresh: false});
nav.addtabs({iframeHeight: "100%", iframeForceRefresh: false, nav: nav});
if ($("ul.sidebar-menu li.active a").size() > 0) {
$("ul.sidebar-menu li.active a").trigger("click");
} else {
$("ul.sidebar-menu li a[url!='javascript:;']:first").trigger("click");
if (Config.fastadmin.multiplenav) {
$("li:first > a", firstnav).trigger("click");
} else {
$("ul.sidebar-menu li a[url!='javascript:;']:first").trigger("click");
}
}
//如果是刷新操作则直接返回刷新前的页面
if (Config.referer) {
if (Config.referer === $(addtabs).attr("url")) {
var active = $("ul.sidebar-menu li a[addtabs=" + $(addtabs).attr("addtabs") + "]");
if (multiplenav && active.size() == 0) {
active = $("ul li a[addtabs='" + $(addtabs).attr("addtabs") + "']");
}
if (active.size() > 0) {
active.trigger("click");
} else {
@ -319,7 +399,7 @@ define(['jquery', 'bootstrap', 'backend', 'addtabs', 'adminlte', 'form'], functi
if ($(this).data("menu") == 'show-submenu') {
$("ul.sidebar-menu").toggleClass("show-submenu");
} else {
$(".nav-addtabs").toggleClass("disable-top-badge");
nav.toggleClass("disable-top-badge");
}
});
@ -365,7 +445,7 @@ define(['jquery', 'bootstrap', 'backend', 'addtabs', 'adminlte', 'form'], functi
if ($('ul.sidebar-menu').hasClass('show-submenu')) {
$("[data-menu='show-submenu']").attr('checked', 'checked');
}
if ($('ul.nav-addtabs').hasClass('disable-top-badge')) {
if (nav.hasClass('disable-top-badge')) {
$("[data-menu='disable-top-badge']").attr('checked', 'checked');
}

View File

@ -30,7 +30,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
{field: 'title', title: __('Title'), align: 'left'},
{field: 'name', title: __('Name'), align: 'left'},
{field: 'remark', title: __('Remark')},
{field: 'ismenu', title: __('Ismenu'), formatter: Controller.api.formatter.toggle},
{field: 'ismenu', title: __('Ismenu'), formatter: Table.api.formatter.toggle},
{field: 'createtime', title: __('Createtime'), formatter: Table.api.formatter.datetime, operate: 'RANGE', addclass: 'datetimerange', sortable: true, visible: false},
{field: 'updatetime', title: __('Updatetime'), formatter: Table.api.formatter.datetime, operate: 'RANGE', addclass: 'datetimerange', sortable: true, visible: false},
{field: 'weigh', title: __('Weigh')},
@ -60,12 +60,6 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
});
$("input[name='row[ismenu]']:checked").trigger("click");
Form.api.bindevent($("form[role=form]"));
},
formatter: {
toggle: function (value, row, index) {
//添加上btn-change可以自定义请求的URL进行数据处理
return '<i class="fa ' + (value == 0 ? 'fa-toggle-off' : 'fa-toggle-on') + ' fa-2x"></i>';
},
}
}
};

View File

@ -194,7 +194,7 @@
}
} else {
value = $("[name='" + name + "']:checked", that.$commonsearch).val();
value = (vObjCol && typeof vObjCol.process === 'function') ? vObjCol.process(obj.val()) : obj.val();
value = (vObjCol && typeof vObjCol.process === 'function') ? vObjCol.process(value) : value;
}
} else {
value = (vObjCol && typeof vObjCol.process === 'function') ? vObjCol.process(obj.val()) : obj.val();
@ -321,7 +321,16 @@
that.$container.on("click", "." + that.options.searchClass, function () {
var obj = $("form [name='" + $(this).data("field") + "']", that.$commonsearch);
if (obj.size() > 0) {
obj.val($(this).data("value"));
var value = $(this).data("value");
if (obj.is("select")) {
console.log($("option[value='" + value + "']", obj));
$("option[value='" + value + "']", obj).prop("selected", true);
} else if (obj.size() > 1) {
$("form [name='" + $(this).data("field") + "'][value='" + value + "']", that.$commonsearch).prop("checked", true);
} else {
obj.val(value);
}
obj.trigger("change");
$("form", that.$commonsearch).trigger("submit");
}
});

View File

@ -1,10 +1,10 @@
require.config({
urlArgs: "v=" + requirejs.s.contexts._.config.config.site.version,
packages: [{
name: 'moment',
location: '../libs/moment',
main: 'moment'
}
name: 'moment',
location: '../libs/moment',
main: 'moment'
}
],
//在打包压缩时将会把include中的模块合并到主文件中
include: ['css', 'layer', 'toastr', 'fast', 'backend', 'backend-init', 'table', 'form', 'dragsort', 'drag', 'drop', 'addtabs', 'selectpage'],
@ -103,10 +103,10 @@ require.config({
'moment/locale/zh-cn',
// 'css!../libs/eonasdan-bootstrap-datetimepicker/build/css/bootstrap-datetimepicker.min.css',
],
'bootstrap-select': ['css!../libs/bootstrap-select/dist/css/bootstrap-select.min.css', ],
// 'bootstrap-select': ['css!../libs/bootstrap-select/dist/css/bootstrap-select.min.css',],
'bootstrap-select-lang': ['bootstrap-select'],
// 'toastr': ['css!../libs/toastr/toastr.min.css'],
'jstree': ['css!../libs/jstree/dist/themes/default/style.css', ],
'jstree': ['css!../libs/jstree/dist/themes/default/style.css',],
'plupload': {
deps: ['../libs/plupload/js/moxie.min'],
exports: "plupload"

File diff suppressed because it is too large Load Diff

View File

@ -49,7 +49,7 @@ require.config({
'template': '../libs/art-template/dist/template-native',
'selectpage': '../libs/fastadmin-selectpage/selectpage',
'citypicker': '../libs/city-picker/dist/js/city-picker.min',
'citypicker-data': '../libs/city-picker/dist/js/city-picker.data',
'citypicker-data': '../libs/city-picker/dist/js/city-picker.data'
},
// shim依赖配置
shim: {
@ -102,7 +102,7 @@ require.config({
'moment/locale/zh-cn',
// 'css!../libs/eonasdan-bootstrap-datetimepicker/build/css/bootstrap-datetimepicker.min.css',
],
'bootstrap-select': ['css!../libs/bootstrap-select/dist/css/bootstrap-select.min.css', ],
// 'bootstrap-select': ['css!../libs/bootstrap-select/dist/css/bootstrap-select.min.css', ],
'bootstrap-select-lang': ['bootstrap-select'],
// 'toastr': ['css!../libs/toastr/toastr.min.css'],
'jstree': ['css!../libs/jstree/dist/themes/default/style.css', ],

View File

@ -63,7 +63,7 @@ require.config({
'template': '../libs/art-template/dist/template-native',
'selectpage': '../libs/fastadmin-selectpage/selectpage',
'citypicker': '../libs/city-picker/dist/js/city-picker.min',
'citypicker-data': '../libs/city-picker/dist/js/city-picker.data',
'citypicker-data': '../libs/city-picker/dist/js/city-picker.data'
},
// shim依赖配置
shim: {
@ -116,7 +116,7 @@ require.config({
'moment/locale/zh-cn',
// 'css!../libs/eonasdan-bootstrap-datetimepicker/build/css/bootstrap-datetimepicker.min.css',
],
'bootstrap-select': ['css!../libs/bootstrap-select/dist/css/bootstrap-select.min.css', ],
// 'bootstrap-select': ['css!../libs/bootstrap-select/dist/css/bootstrap-select.min.css', ],
'bootstrap-select-lang': ['bootstrap-select'],
// 'toastr': ['css!../libs/toastr/toastr.min.css'],
'jstree': ['css!../libs/jstree/dist/themes/default/style.css', ],

View File

@ -387,7 +387,7 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table
image: function (value, row, index) {
value = value ? value : '/assets/img/blank.gif';
var classname = typeof this.classname !== 'undefined' ? this.classname : 'img-sm img-center';
return '<img class="' + classname + '" src="' + Fast.api.cdnurl(value) + '" />';
return '<a href="' + Fast.api.cdnurl(value) + '" target="_blank"><img class="' + classname + '" src="' + Fast.api.cdnurl(value) + '" /></a>';
},
images: function (value, row, index) {
value = value === null ? '' : value.toString();
@ -396,7 +396,7 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table
var html = [];
$.each(arr, function (i, value) {
value = value ? value : '/assets/img/blank.gif';
html.push('<img class="' + classname + '" src="' + Fast.api.cdnurl(value) + '" />');
html.push('<a href="' + Fast.api.cdnurl(value) + '" target="_blank"><img class="' + classname + '" src="' + Fast.api.cdnurl(value) + '" /></a>');
});
return html.join(' ');
},
@ -409,11 +409,21 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table
}
value = value === null ? '' : value.toString();
var color = value && typeof colorArr[value] !== 'undefined' ? colorArr[value] : 'primary';
value = value.charAt(0).toUpperCase() + value.slice(1);
var newValue = value.charAt(0).toUpperCase() + value.slice(1);
//渲染状态
var html = '<span class="text-' + color + '"><i class="fa fa-circle"></i> ' + __(value) + '</span>';
var html = '<span class="text-' + color + '"><i class="fa fa-circle"></i> ' + __(newValue) + '</span>';
if (this.operate != false) {
html = '<a href="javascript:;" class="searchit" data-toggle="tooltip" title="' + __('Click to search %s', __(newValue)) + '" data-field="' + this.field + '" data-value="' + value + '">' + html + '</a>';
}
return html;
},
toggle: function (value, row, index) {
var color = typeof this.color !== 'undefined' ? this.color : 'success';
var yes = typeof this.yes !== 'undefined' ? this.yes : 1;
var no = typeof this.no !== 'undefined' ? this.no : 0;
return "<a href='javascript:;' data-toggle='tooltip' title='" + __('Click to toggle') + "' class='btn-change' data-id='"
+ row.id + "' data-params='" + this.field + "=" + (value ? no : yes) + "'><i class='fa fa-toggle-on " + (value == yes ? 'text-' + color : 'fa-flip-horizontal text-gray') + " fa-2x'></i></a>";
},
url: function (value, row, index) {
return '<div class="input-group input-group-sm" style="width:250px;margin:0 auto;"><input type="text" class="form-control input-sm" value="' + value + '"><span class="input-group-btn input-group-sm"><a href="' + value + '" target="_blank" class="btn btn-default btn-sm"><i class="fa fa-link"></i></a></span></div>';
},
@ -457,7 +467,12 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table
return Table.api.formatter.flag.call(this, value, row, index);
},
datetime: function (value, row, index) {
return value ? Moment(parseInt(value) * 1000).format("YYYY-MM-DD HH:mm:ss") : __('None');
var datetimeFormat = typeof this.datetimeFormat === 'undefined' ? 'YYYY-MM-DD HH:mm:ss' : this.datetimeFormat;
if (isNaN(value)) {
return value ? Moment(value).format(datetimeFormat) : __('None');
} else {
return value ? Moment(parseInt(value) * 1000).format(datetimeFormat) : __('None');
}
},
operate: function (value, row, index) {
var table = this.table;

File diff suppressed because it is too large Load Diff