作者 Karson

新增视图中根据权限控制元素显示

新增生产模式下新的异常提示页
新增Table.api.formatter权限控制
新增Table.api.formatter的buttons参数
将后台common.php中的通过方法移动到全局可调用
修复iOS在底部弹出窗时的错误
修复iOS下文本框自动变大的问题
修改CRUD基础index模板
移除Date::cron方法
修复后台登录一处JS报错
修复Fast.api.ajax发生错误时提示不正确的问题
... ... @@ -684,7 +684,7 @@ class Crud extends Command
}
//JS最后一列加上操作列
$javascriptList[] = str_repeat(" ", 24) . "{field: 'operate', title: __('Operate'), events: Table.api.events.operate, formatter: Table.api.formatter.operate}";
$javascriptList[] = str_repeat(" ", 24) . "{field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, formatter: Table.api.formatter.operate}";
$addList = implode("\n", array_filter($addList));
$editList = implode("\n", array_filter($editList));
$javascriptList = implode(",\n", array_filter($javascriptList));
... ...
... ... @@ -7,7 +7,7 @@
<div class="widget-body no-padding">
<div id="toolbar" class="toolbar">
{:build_toolbar()}
<div class="dropdown btn-group">
<div class="dropdown btn-group {:$auth->check('{%controllerUrl%}/multi')?'':'hide'}">
<a class="btn btn-primary btn-more dropdown-toggle btn-disabled disabled" data-toggle="dropdown"><i class="fa fa-cog"></i> {:__('More')}</a>
<ul class="dropdown-menu text-left" role="menu">
<li><a class="btn btn-link btn-multi btn-disabled disabled" href="javascript:;" data-params="status=normal"><i class="fa fa-eye"></i> {:__('Set to normal')}</a></li>
... ... @@ -15,7 +15,10 @@
</ul>
</div>
</div>
<table id="table" class="table table-striped table-bordered table-hover" width="100%">
<table id="table" class="table table-striped table-bordered table-hover"
data-operate-edit="{:$auth->check('{%controllerUrl%}/edit')}"
data-operate-del="{:$auth->check('{%controllerUrl%}/del')}"
width="100%">
</table>
</div>
</div>
... ...
... ... @@ -88,19 +88,27 @@ function build_category_select($name, $type, $selected = null, $attr = [], $head
*/
function build_toolbar($btns = NULL, $attr = [])
{
$btns = $btns ? $btns : ['refresh', 'add', 'edit', 'delete'];
$auth = \app\admin\library\Auth::instance();
$controller = strtolower(think\Request::instance()->controller());
$btns = $btns ? $btns : ['refresh', 'add', 'edit', 'del'];
$btns = is_array($btns) ? $btns : explode(',', $btns);
$index = array_search('delete', $btns);
if ($index !== FALSE)
{
$btns[$index] = 'del';
}
$btnAttr = [
'refresh' => ['javascript:;', 'btn btn-primary btn-refresh', 'fa fa-refresh', ''],
'add' => ['javascript:;', 'btn btn-success btn-add', 'fa fa-plus', __('Add')],
'edit' => ['javascript:;', 'btn btn-success btn-edit btn-disabled disabled', 'fa fa-pencil', __('Edit')],
'delete' => ['javascript:;', 'btn btn-danger btn-del btn-disabled disabled', 'fa fa-trash', __('Delete')],
'del' => ['javascript:;', 'btn btn-danger btn-del btn-disabled disabled', 'fa fa-trash', __('Delete')],
];
$btnAttr = array_merge($btnAttr, $attr);
$html = [];
foreach ($btns as $k => $v)
{
if (!isset($btnAttr[$v]))
//如果未定义或没有权限
if (!isset($btnAttr[$v]) || ($v !== 'refresh' && !$auth->check("{$controller}/{$v}")))
{
continue;
}
... ... @@ -135,87 +143,3 @@ function build_heading($title = NULL, $content = NULL)
return '';
return '<div class="panel-heading"><div class="panel-lead"><em>' . $title . '</em>' . $content . '</div></div>';
}
/**
* 判断文件或文件夹是否可写
* @param string
* @return bool
*/
function is_really_writable($file)
{
if (DIRECTORY_SEPARATOR === '/')
{
return is_writable($file);
}
if (is_dir($file))
{
$file = rtrim($file, '/') . '/' . md5(mt_rand());
if (($fp = @fopen($file, 'ab')) === FALSE)
{
return FALSE;
}
fclose($fp);
@chmod($file, 0777);
@unlink($file);
return TRUE;
}
elseif (!is_file($file) OR ( $fp = @fopen($file, 'ab')) === FALSE)
{
return FALSE;
}
fclose($fp);
return TRUE;
}
/**
* 删除文件夹
* @param string $dirname
* @return boolean
*/
function rmdirs($dirname)
{
if (!is_dir($dirname))
return false;
$files = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($dirname, RecursiveDirectoryIterator::SKIP_DOTS), RecursiveIteratorIterator::CHILD_FIRST
);
foreach ($files as $fileinfo)
{
$todo = ($fileinfo->isDir() ? 'rmdir' : 'unlink');
$todo($fileinfo->getRealPath());
}
@rmdir($dirname);
return true;
}
/**
* 复制文件夹
* @param string $source 源文件夹
* @param string $dest 目标文件夹
*/
function copydirs($source, $dest)
{
if (!is_dir($dest))
{
mkdir($dest, 0755);
}
foreach (
$iterator = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($source, RecursiveDirectoryIterator::SKIP_DOTS), RecursiveIteratorIterator::SELF_FIRST) as $item
)
{
if ($item->isDir())
{
$sontDir = $dest . DS . $iterator->getSubPathName();
if (!is_dir($sontDir))
{
mkdir($sontDir);
}
}
else
{
copy($item, $dest . DS . $iterator->getSubPathName());
}
}
}
... ...
... ... @@ -46,7 +46,7 @@ class Addon extends Backend
$name = $this->request->get("name");
if (!$name)
{
$this->error(__('Parameter %s can not be empty', $id ? 'id' : 'name'));
$this->error(__('Parameter %s can not be empty', $ids ? 'id' : 'name'));
}
if (!is_dir(ADDON_PATH . $name))
{
... ...
... ... @@ -28,7 +28,7 @@ class Category extends Backend
$tree = Tree::instance();
$tree->init($this->model->order('weigh desc,id desc')->select(), 'pid');
$this->categorylist = $tree->getTreeList($tree->getTreeArray(0), 'name');
$categorydata = [0 => ['type'=>'all', 'name'=>__('None')]];
$categorydata = [0 => ['type' => 'all', 'name' => __('None')]];
foreach ($this->categorylist as $k => $v)
{
$categorydata[$v['id']] = $v;
... ... @@ -45,11 +45,25 @@ class Category extends Backend
{
if ($this->request->isAjax())
{
$search = $this->request->request("search");
//构造父类select列表选项数据
$list = $this->categorylist;
$list = [];
if ($search)
{
foreach ($this->categorylist as $k => $v)
{
if (stripos($v['name'], $search) !== false || stripos($v['nickname'], $search) !== false)
{
$list[] = $v;
}
}
}
else
{
$list = $this->categorylist;
}
$total = count($list);
$result = array("total" => 1, "rows" => $list);
$result = array("total" => $total, "rows" => $list);
return json($result);
}
... ...
<meta charset="utf-8">
<title>{$title|default=''}</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<meta name="renderer" content="webkit">
<link rel="shortcut icon" href="__CDN__/assets/img/favicon.ico" />
... ...
... ... @@ -43,7 +43,7 @@
<div class="profile-avatar-container">
<img class="profile-user-img img-responsive img-circle plupload" src="__CDN__{$admin.avatar}" alt="">
<div class="profile-avatar-text img-circle">{:__('Click to edit')}</div>
<button id="plupload-avatar" class="plupload" data-input-id="c-avatar" data-after-upload="changeavatar"><i class="fa fa-upload"></i> {:__('Upload')}</button>
<button id="plupload-avatar" class="plupload" data-input-id="c-avatar"><i class="fa fa-upload"></i> {:__('Upload')}</button>
</div>
<h3 class="profile-username text-center">{$admin.username}</h3>
... ...
... ... @@ -94,3 +94,107 @@ if (!function_exists('cdnurl'))
}
}
if (!function_exists('is_really_writable'))
{
/**
* 判断文件或文件夹是否可写
* @param string $file 文件或目录
* @return bool
*/
function is_really_writable($file)
{
if (DIRECTORY_SEPARATOR === '/')
{
return is_writable($file);
}
if (is_dir($file))
{
$file = rtrim($file, '/') . '/' . md5(mt_rand());
if (($fp = @fopen($file, 'ab')) === FALSE)
{
return FALSE;
}
fclose($fp);
@chmod($file, 0777);
@unlink($file);
return TRUE;
}
elseif (!is_file($file) OR ( $fp = @fopen($file, 'ab')) === FALSE)
{
return FALSE;
}
fclose($fp);
return TRUE;
}
}
if (!function_exists('rmdirs'))
{
/**
* 删除文件夹
* @param string $dirname 目录
* @param bool $withself 是否删除自身
* @return boolean
*/
function rmdirs($dirname, $withself = true)
{
if (!is_dir($dirname))
return false;
$files = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($dirname, RecursiveDirectoryIterator::SKIP_DOTS), RecursiveIteratorIterator::CHILD_FIRST
);
foreach ($files as $fileinfo)
{
$todo = ($fileinfo->isDir() ? 'rmdir' : 'unlink');
$todo($fileinfo->getRealPath());
}
if ($withself)
{
@rmdir($dirname);
}
return true;
}
}
if (!function_exists('copydirs'))
{
/**
* 复制文件夹
* @param string $source 源文件夹
* @param string $dest 目标文件夹
*/
function copydirs($source, $dest)
{
if (!is_dir($dest))
{
mkdir($dest, 0755);
}
foreach (
$iterator = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($source, RecursiveDirectoryIterator::SKIP_DOTS), RecursiveIteratorIterator::SELF_FIRST) as $item
)
{
if ($item->isDir())
{
$sontDir = $dest . DS . $iterator->getSubPathName();
if (!is_dir($sontDir))
{
mkdir($sontDir);
}
}
else
{
copy($item, $dest . DS . $iterator->getSubPathName());
}
}
}
}
... ...
... ... @@ -26,11 +26,16 @@ class Common
{
Config::set('upload.cdnurl', $cdnurl);
}
// 如果是调试模式将version置为当前的时间戳可避免缓存
if (Config::get('app_debug'))
{
// 如果是调试模式将version置为当前的时间戳可避免缓存
Config::set('site.version', time());
}
else
{
// 如果是开发模式修改异常页的模板
Config::set('exception_tmpl', APP_PATH . 'common' . DS . 'view' . DS . 'tpl' . DS . 'think_exception.tpl');
}
}
}
... ...
... ... @@ -165,6 +165,8 @@ class Backend extends Controller
$this->assign('site', $site);
//渲染配置信息
$this->assign('config', $config);
//渲染权限对象
$this->assign('auth', $this->auth);
//渲染管理员对象
$this->assign('admin', Session::get('admin'));
}
... ...
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>发生错误</title>
<meta name="robots" content="noindex,nofollow" />
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<style>
* {-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;}
html,body,div,span,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,abbr,address,cite,code,del,dfn,em,img,ins,kbd,q,samp,small,strong,sub,sup,var,b,i,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,caption,article,aside,canvas,details,figcaption,figure,footer,header,hgroup,menu,nav,section,summary,time,mark,audio,video {margin:0;padding:0;border:0;outline:0;vertical-align:baseline;background:transparent;}
article,aside,details,figcaption,figure,footer,header,hgroup,nav,section {display:block;}
html {font-size:16px;line-height:24px;width:100%;height:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;overflow-y:scroll;overflow-x:hidden;}
img {vertical-align:middle;max-width:100%;height:auto;border:0;-ms-interpolation-mode:bicubic;}
body {min-height:100%;background:#edf1f4;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-family:"Helvetica Neue",Helvetica,"PingFang SC","Hiragino Sans GB","Microsoft YaHei",微软雅黑,Arial,sans-serif;}
.clearfix {clear:both;zoom:1;}
.clearfix:before,.clearfix:after {content:"\0020";display:block;height:0;visibility:hidden;}
.clearfix:after {clear:both;}
body.error-page-wrapper,.error-page-wrapper.preview {background-position:center center;background-repeat:no-repeat;background-size:cover;position:relative;}
.error-page-wrapper .content-container {border-radius:2px;text-align:center;box-shadow:1px 1px 1px rgba(99,99,99,0.1);padding:50px;background-color:#fff;width:100%;max-width:560px;position:absolute;left:50%;top:50%;margin-top:-220px;margin-left:-280px;}
.error-page-wrapper .content-container.in {left:0px;opacity:1;}
.error-page-wrapper .head-line {transition:color .2s linear;font-size:40px;line-height:60px;letter-spacing:-1px;margin-bottom:20px;color:#777;}
.error-page-wrapper .subheader {transition:color .2s linear;font-size:32px;line-height:46px;color:#494949;}
.error-page-wrapper .hr {height:1px;background-color:#eee;width:80%;max-width:350px;margin:25px auto;}
.error-page-wrapper .context {transition:color .2s linear;font-size:16px;line-height:27px;color:#aaa;}
.error-page-wrapper .context p {margin:0;}
.error-page-wrapper .context p:nth-child(n+2) {margin-top:16px;}
.error-page-wrapper .buttons-container {margin-top:35px;overflow:hidden;}
.error-page-wrapper .buttons-container a {transition:text-indent .2s ease-out,color .2s linear,background-color .2s linear;text-indent:0px;font-size:14px;text-transform:uppercase;text-decoration:none;color:#fff;background-color:#2ecc71;border-radius:99px;padding:8px 0 8px;text-align:center;display:inline-block;overflow:hidden;position:relative;width:45%;}
.error-page-wrapper .buttons-container a:hover {text-indent:15px;}
.error-page-wrapper .buttons-container a:nth-child(1) {float:left;}
.error-page-wrapper .buttons-container a:nth-child(2) {float:right;}
@media screen and (max-width:580px) {
.error-page-wrapper {padding:30px 5%;}
.error-page-wrapper .content-container {padding:37px;position:static;left:0;margin-top:0;margin-left:0;}
.error-page-wrapper .head-line {font-size:36px;}
.error-page-wrapper .subheader {font-size:27px;line-height:37px;}
.error-page-wrapper .hr {margin:30px auto;width:215px;}
}
@media screen and (max-width:450px) {
.error-page-wrapper {padding:30px;}
.error-page-wrapper .head-line {font-size:32px;}
.error-page-wrapper .hr {margin:25px auto;width:180px;}
.error-page-wrapper .context {font-size:15px;line-height:22px;}
.error-page-wrapper .context p:nth-child(n+2) {margin-top:10px;}
.error-page-wrapper .buttons-container {margin-top:29px;}
.error-page-wrapper .buttons-container a {float:none !important;width:65%;margin:0 auto;font-size:13px;padding:9px 0;}
.error-page-wrapper .buttons-container a:nth-child(2) {margin-top:12px;}
}
</style>
</head>
<body class="error-page-wrapper">
<div class="content-container">
<div class="head-line">
<img src="/assets/img/error.svg" alt="" width="120" />
</div>
<div class="subheader">
<?php echo htmlentities($message); ?>
</div>
<div class="hr"></div>
<div class="context">
<p>
你可以返回上一页重试,或直接向我们反馈错误报告
</p>
</div>
<div class="buttons-container">
<a href="<?php echo url('/');?>">返回主页</a>
<a href="<?php echo url('/');?>">反馈错误</a>
</div>
</div>
</body>
</html>
\ No newline at end of file
... ...
... ... @@ -146,7 +146,7 @@ return [
// 异常页面的模板文件
'exception_tmpl' => THINK_PATH . 'tpl' . DS . 'think_exception.tpl',
// 错误显示信息,非调试模式有效
'error_message' => '页面错误!请稍后再试~',
'error_message' => '你所浏览的页面暂时无法访问',
// 显示错误信息
'show_error_msg' => false,
// 异常处理handle类 留空使用 \think\exception\Handle
... ...
... ... @@ -21,7 +21,7 @@ class Index extends Frontend
public function news()
{
$newslist = \app\common\model\Page::where('category_id', 1)->order('weigh', 'desc')->select();
$newslist = [];
return jsonp(['newslist' => $newslist, 'new' => count($newslist), 'url' => 'http://www.fastadmin.net?ref=news']);
}
... ...
... ... @@ -157,78 +157,6 @@ class Date
}
/**
* 判断Unix时间是否满足Cron指定的执行条件
*
* @param string $cron Crontab格式
* @param string $time 时间,默认为当前时间
* @return boolean
*/
public static function cron($cron, $time = null)
{
$time = is_null($time) ? time() : $time;
$cron_parts = explode(' ', $cron);
if (count($cron_parts) != 5)
{
return false;
}
list($min, $hour, $day, $mon, $week) = explode(' ', $cron);
$to_check = array('min' => 'i', 'hour' => 'G', 'day' => 'j', 'mon' => 'n', 'week' => 'w');
$ranges = array(
'min' => '0-59',
'hour' => '0-23',
'day' => '1-31',
'mon' => '1-12',
'week' => '0-6',
);
foreach ($to_check as $part => $c)
{
$val = $$part;
$values = [];
if (strpos($val, '/') !== false)
{
//Get the range and step
list($range, $steps) = explode('/', $val);
//Now get the start and stop
if ($range == '*')
{
$range = $ranges[$part];
}
list($start, $stop) = explode('-', $range);
for ($i = $start; $i <= $stop; $i = $i + $steps)
{
$values[] = $i;
}
}
else
{
$k = explode(',', $val);
foreach ($k as $v)
{
if (strpos($v, '-') !== false)
{
list($start, $stop) = explode('-', $v);
for ($i = $start; $i <= $stop; $i++)
{
$values[] = $i;
}
}
else
{
$values[] = $v;
}
}
}
if (!in_array(date($c, $time), $values) and ( strval($val) != '*'))
{
return false;
}
}
return true;
}
/**
* 获取一个基于时间偏移的Unix时间戳
*
* @param string $type 时间类型,默认为day,可选minute,hour,day,week,month,quarter,year
... ...
... ... @@ -28,11 +28,11 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
{field: 'email', title: __('Email')},
{field: 'status', title: __("Status"), formatter: Table.api.formatter.status},
{field: 'logintime', title: __('Login time'), formatter: Table.api.formatter.datetime},
{field: 'operate', title: __('Operate'), events: Table.api.events.operate, formatter: function (value, row, index) {
{field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, formatter: function (value, row, index) {
if(row.id == 1){
return '';
}
return Table.api.formatter.operate.call(this, value, row, index, table);
return Table.api.formatter.operate.call(this, value, row, index);
}}
]
]
... ...
... ... @@ -24,11 +24,21 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
{field: 'id', title: 'ID', operate: false},
{field: 'username', title: __('Username'), formatter: Table.api.formatter.search},
{field: 'title', title: __('Title'), operate: 'LIKE %...%', placeholder: '模糊搜索,*表示任意字符', style: 'width:200px'},
{field: 'url', title: __('Url'), align: 'left', formatter: Controller.api.formatter.url},
{field: 'ip', title: __('IP'), events: Controller.api.events.ip, formatter: Controller.api.formatter.ip},
{field: 'browser', title: __('Browser'), operate: false, events: Controller.api.events.browser, formatter: Controller.api.formatter.browser},
{field: 'url', title: __('Url'), align: 'left', formatter: Table.api.formatter.url},
{field: 'ip', title: __('IP'), events: Table.api.events.ip, formatter: Table.api.formatter.search},
{field: 'browser', title: __('Browser'), operate: false, formatter: Controller.api.formatter.browser},
{field: 'createtime', title: __('Create time'), formatter: Table.api.formatter.datetime, operate: 'BETWEEN', type: 'datetime', addclass: 'datetimepicker', data: 'data-date-format="YYYY-MM-DD HH:mm:ss"'},
{field: 'operate', title: __('Operate'), events: Controller.api.events.operate, formatter: Controller.api.formatter.operate}
{field: 'operate', title: __('Operate'), table: table,
events: Table.api.events.operate,
buttons: [{
name: 'detail',
text: 'Detail',
icon: 'fa fa-list',
classname: 'btn btn-info btn-xs btn-detail btn-dialog',
url: 'auth/adminlog/detail'
}],
formatter: Table.api.formatter.operate
}
]
]
});
... ... @@ -41,35 +51,10 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
Form.api.bindevent($("form[role=form]"));
},
formatter: {
url: function (value, row, index) {
return '<div class="input-group input-group-sm" style="width:250px;"><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>';
},
ip: function (value, row, index) {
return '<a class="btn btn-xs btn-ip bg-success"><i class="fa fa-map-marker"></i> ' + value + '</a>';
},
browser: function (value, row, index) {
return '<a class="btn btn-xs btn-browser">' + row.useragent.split(" ")[0] + '</a>';
},
operate: function (value, row, index) {
return '<a class="btn btn-info btn-xs btn-detail">' + __('Detail') + '</a> '
+ Table.api.formatter.operate(value, row, index, $("#table"));
},
},
events: {
ip: {
'click .btn-ip': function (e, value, row, index) {
var options = $("#table").bootstrapTable('getOptions');
//这里我们手动将数据填充到表单然后提交
$("#commonSearchContent_" + options.idTable + " form [name='ip']").val(value);
$("#commonSearchContent_" + options.idTable + " form").trigger('submit');
}
},
operate: $.extend({
'click .btn-detail': function (e, value, row, index) {
Backend.api.open('auth/adminlog/detail/ids/' + row['id'], __('Detail'));
}
}, Table.api.events.operate)
}
}
};
return Controller;
... ...
... ... @@ -41,11 +41,11 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'jstree'], function (
{field: 'pid', title: __('Parent')},
{field: 'name', title: __('Name'), align: 'left'},
{field: 'status', title: __('Status'), formatter: Table.api.formatter.status},
{field: 'operate', title: __('Operate'), events: Table.api.events.operate, formatter: function (value, row, index) {
{field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, formatter: function (value, row, index) {
if (row.id == 1) {
return '';
}
return Table.api.formatter.operate.call(this, value, row, index, table);
return Table.api.formatter.operate.call(this, value, row, index);
}}
]
],
... ...
... ... @@ -32,7 +32,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
{field: 'status', title: __('Status'), formatter: Table.api.formatter.status},
{field: 'ismenu', title: __('Ismenu'), align: 'center', formatter: Controller.api.formatter.menu},
{field: 'id', title: '<a href="javascript:;" class="btn btn-success btn-xs btn-toggle"><i class="fa fa-chevron-up"></i></a>', operate: false, formatter: Controller.api.formatter.subnode},
{field: 'operate', title: __('Operate'), events: Table.api.events.operate, formatter: Table.api.formatter.operate}
{field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, formatter: Table.api.formatter.operate}
]
],
pagination: false,
... ...
... ... @@ -22,6 +22,8 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
escape: false,
pk: 'id',
sortName: 'weigh',
pagination: false,
commonSearch: false,
columns: [
[
{checkbox: true},
... ... @@ -33,7 +35,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
{field: 'image', title: __('Image'), operate: false, formatter: Table.api.formatter.image},
{field: 'weigh', title: __('Weigh'), operate: false},
{field: 'status', title: __('Status'), operate: false, formatter: Table.api.formatter.status},
{field: 'operate', title: __('Operate'), events: Table.api.events.operate, formatter: Table.api.formatter.operate}
{field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, formatter: Table.api.formatter.operate}
]
]
});
... ...
... ... @@ -33,7 +33,7 @@ define(['jquery', 'bootstrap', 'backend', 'form', 'table'], function ($, undefin
{field: 'filesize', title: __('Filesize')},
{field: 'mimetype', title: __('Mimetype')},
{field: 'createtime', title: __('Createtime'), formatter: Table.api.formatter.datetime},
{field: 'operate', title: __('Operate'), events: Table.api.events.operate, formatter: Table.api.formatter.operate}
{field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, formatter: Table.api.formatter.operate}
]
],
});
... ...
... ... @@ -29,7 +29,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
{field: 'intro', title: __('Intro')},
{field: 'group', title: __('Group')},
{field: 'type', title: __('Type')},
{field: 'operate', title: __('Operate'), events: Table.api.events.operate, formatter: Table.api.formatter.operate}
{field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, formatter: Table.api.formatter.operate}
]
]
});
... ...
... ... @@ -26,7 +26,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'upload'], function (
[
{field: 'id', title: 'ID'},
{field: 'title', title: __('Title')},
{field: 'url', title: __('Url'), align: 'left', formatter: Controller.api.formatter.url},
{field: 'url', title: __('Url'), align: 'left', formatter: Table.api.formatter.url},
{field: 'ip', title: __('ip')},
{field: 'createtime', title: __('Createtime'), formatter: Table.api.formatter.datetime},
]
... ... @@ -37,24 +37,21 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'upload'], function (
// 为表格绑定事件
Table.api.bindevent(table);//当内容渲染完成后
// 给上传按钮添加上传成功事件
$("#plupload-avatar").data("upload-success", function (data) {
var url = Backend.api.cdnurl(data.url);
$(".profile-user-img").prop("src", url);
Toastr.success("上传成功!");
});
// 给表单绑定事件
Form.api.bindevent($("#update-form"), function () {
$("input[name='row[password]']").val('');
var url = Backend.api.cdnurl($("#c-avatar").val());
top.window.$(".user-panel .image img,.user-menu > a > img,.user-header > img").prop("src", url);
return true;
});
Upload.api.custom.changeavatar = function (response) {
var url = Backend.api.cdnurl(response.url);
$(".profile-user-img").prop("src", url);
};
},
api: {
formatter: {
url: function (value, row, index) {
return '<div class="input-group input-group-sm" style="width:250px;"><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>';
},
},
}
};
return Controller;
});
\ No newline at end of file
... ...
... ... @@ -376,7 +376,7 @@ define(['jquery', 'bootstrap', 'backend', 'addtabs', 'adminlte', 'form'], functi
}
//让错误提示框居中
Backend.config.toastr.positionClass = "toast-top-center";
Fast.config.toastr.positionClass = "toast-top-center";
//本地验证未通过时提示
$("#login-form").data("validator-options", {
... ...
... ... @@ -74,9 +74,9 @@ define(['jquery', 'bootstrap', 'toastr', 'layer', 'lang'], function ($, undefine
Fast.events.onAjaxError(ret, error);
}
},
error: function (err) {
error: function (xhr) {
Layer.close(index);
var ret = {code: err.code, msg: err.message, data: null};
var ret = {code: xhr.status, msg: xhr.statusText, data: null};
Fast.events.onAjaxError(ret, error);
}
}, options);
... ... @@ -161,7 +161,7 @@ define(['jquery', 'bootstrap', 'toastr', 'layer', 'lang'], function ($, undefine
}, options ? options : {});
if (/iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream && top.$(".tab-pane.active").size() > 0) {
options.area = [top.$(".tab-pane.active").width() + "px", top.$(".tab-pane.active").height() + "px"];
options.offset = "lt";
options.offset = [ top.$(".tab-pane.active").scrollTop() + "px", "0px"];
}
Layer.open(options);
return false;
... ...
... ... @@ -1999,9 +1999,9 @@ define('fast',['jquery', 'bootstrap', 'toastr', 'layer', 'lang'], function ($, u
Fast.events.onAjaxError(ret, error);
}
},
error: function (err) {
error: function (xhr) {
Layer.close(index);
var ret = {code: err.code, msg: err.message, data: null};
var ret = {code: xhr.status, msg: xhr.statusText, data: null};
Fast.events.onAjaxError(ret, error);
}
}, options);
... ... @@ -2086,7 +2086,7 @@ define('fast',['jquery', 'bootstrap', 'toastr', 'layer', 'lang'], function ($, u
}, options ? options : {});
if (/iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream && top.$(".tab-pane.active").size() > 0) {
options.area = [top.$(".tab-pane.active").width() + "px", top.$(".tab-pane.active").height() + "px"];
options.offset = "lt";
options.offset = [ top.$(".tab-pane.active").scrollTop() + "px", "0px"];
}
Layer.open(options);
return false;
... ... @@ -7812,7 +7812,6 @@ define('table',['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstr
table.on('post-body.bs.table', function (e, settings, json, xhr) {
$(Table.config.refreshbtn, toolbar).find(".fa").removeClass("fa-spin");
$(Table.config.disabledbtn, toolbar).toggleClass('disabled', true);
if ($(Table.config.firsttd, table).find("input[type='checkbox'][data-index]").size() > 0) {
// 挺拽选择,需要重新绑定事件
require(['drag', 'drop'], function () {
... ... @@ -7841,18 +7840,15 @@ define('table',['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstr
});
}
});
// 处理选中筛选框后按钮的状态统一变更
table.on('check.bs.table uncheck.bs.table check-all.bs.table uncheck-all.bs.table fa.event.check', function () {
var ids = Table.api.selectedids(table);
$(Table.config.disabledbtn, toolbar).toggleClass('disabled', !ids.length);
});
// 刷新按钮事件
$(toolbar).on('click', Table.config.refreshbtn, function () {
table.bootstrapTable('refresh');
});
// 添加按钮事件
$(toolbar).on('click', Table.config.addbtn, function () {
var ids = Table.api.selectedids(table);
... ... @@ -7941,9 +7937,7 @@ define('table',['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstr
Layer.close(index);
}
);
});
var id = table.attr("id");
Table.list[id] = table;
return table;
... ... @@ -7992,6 +7986,11 @@ define('table',['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstr
}
}
},
auth: {
check: function (name) {
}
},
// 单元格数据格式化
formatter: {
icon: function (value, row, index) {
... ... @@ -8071,26 +8070,32 @@ define('table',['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstr
datetime: function (value, row, index) {
return value ? Moment(parseInt(value) * 1000).format("YYYY-MM-DD HH:mm:ss") : __('None');
},
operate: function (value, row, index, table) {
var showweigh = true;
var showedit = true;
var showdel = true;
if (typeof table != 'undefined') {
var options = table.bootstrapTable('getOptions');
if (options.extend.del_url == '')
showdel = false;
if (options.extend.edit_url == '')
showedit = false;
}
showweigh = typeof row[Table.config.dragsortfield] != 'undefined' ? true : false;
//行操作
operate: function (value, row, index) {
var table = this.table;
// 操作配置
var options = table ? table.bootstrapTable('getOptions') : {};
// 默认按钮组
var buttons = $.extend([], this.buttons || []);
buttons.push({name: 'dragsort', icon: 'fa fa-arrows', classname: 'btn btn-xs btn-primary btn-dragsort'});
buttons.push({name: 'edit', icon: 'fa fa-pencil', classname: 'btn btn-xs btn-success btn-editone'});
buttons.push({name: 'del', icon: 'fa fa-trash', classname: 'btn btn-xs btn-danger btn-delone'});
var html = [];
if (showweigh)
html.push('<a href="javascript:;" class="btn btn-primary btn-dragsort btn-xs"><i class="fa fa-arrows"></i></a>');
if (showedit)
html.push('<a href="javascript:;" class="btn btn-success btn-editone btn-xs"><i class="fa fa-pencil"></i></a>');
if (showdel)
html.push('<a href="javascript:;" class="btn btn-danger btn-delone btn-xs"><i class="fa fa-trash"></i></a>');
$.each(buttons, function (i, j) {
var attr = table.data("operate-" + j.name);
if ((typeof attr === 'undefined' || attr) || (j.name === 'dragsort' && typeof row[Table.config.dragsortfield] == 'undefined')) {
if (['add', 'edit', 'del', 'multi'].indexOf(j.name) > -1 && !options.extend[j.name + "_url"]) {
return true;
}
//自动加上ids
j.url = j.url ? j.url + (j.url.match(/(\?|&)+/) ? "&ids=" : "/ids/") + row[options.pk] : '';
url = j.url ? Fast.api.fixurl(j.url) : 'javascript:;';
classname = j.classname ? j.classname : 'btn-primary btn-' + name + 'one';
icon = j.icon ? j.icon : '';
text = j.text ? j.text : '';
title = j.title ? j.title : text;
html.push('<a href="' + url + '" class="' + classname + '" title="' + title + '"><i class="' + icon + '"></i>' + (text ? ' ' + text : '') + '</a>');
}
});
return html.join(' ');
}
},
... ...
... ... @@ -2011,9 +2011,9 @@ define('fast',['jquery', 'bootstrap', 'toastr', 'layer', 'lang'], function ($, u
Fast.events.onAjaxError(ret, error);
}
},
error: function (err) {
error: function (xhr) {
Layer.close(index);
var ret = {code: err.code, msg: err.message, data: null};
var ret = {code: xhr.status, msg: xhr.statusText, data: null};
Fast.events.onAjaxError(ret, error);
}
}, options);
... ... @@ -2098,7 +2098,7 @@ define('fast',['jquery', 'bootstrap', 'toastr', 'layer', 'lang'], function ($, u
}, options ? options : {});
if (/iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream && top.$(".tab-pane.active").size() > 0) {
options.area = [top.$(".tab-pane.active").width() + "px", top.$(".tab-pane.active").height() + "px"];
options.offset = "lt";
options.offset = [ top.$(".tab-pane.active").scrollTop() + "px", "0px"];
}
Layer.open(options);
return false;
... ...
... ... @@ -113,7 +113,6 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table
table.on('post-body.bs.table', function (e, settings, json, xhr) {
$(Table.config.refreshbtn, toolbar).find(".fa").removeClass("fa-spin");
$(Table.config.disabledbtn, toolbar).toggleClass('disabled', true);
if ($(Table.config.firsttd, table).find("input[type='checkbox'][data-index]").size() > 0) {
// 挺拽选择,需要重新绑定事件
require(['drag', 'drop'], function () {
... ... @@ -142,18 +141,15 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table
});
}
});
// 处理选中筛选框后按钮的状态统一变更
table.on('check.bs.table uncheck.bs.table check-all.bs.table uncheck-all.bs.table fa.event.check', function () {
var ids = Table.api.selectedids(table);
$(Table.config.disabledbtn, toolbar).toggleClass('disabled', !ids.length);
});
// 刷新按钮事件
$(toolbar).on('click', Table.config.refreshbtn, function () {
table.bootstrapTable('refresh');
});
// 添加按钮事件
$(toolbar).on('click', Table.config.addbtn, function () {
var ids = Table.api.selectedids(table);
... ... @@ -242,9 +238,7 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table
Layer.close(index);
}
);
});
var id = table.attr("id");
Table.list[id] = table;
return table;
... ... @@ -293,6 +287,11 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table
}
}
},
auth: {
check: function (name) {
}
},
// 单元格数据格式化
formatter: {
icon: function (value, row, index) {
... ... @@ -372,26 +371,32 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table
datetime: function (value, row, index) {
return value ? Moment(parseInt(value) * 1000).format("YYYY-MM-DD HH:mm:ss") : __('None');
},
operate: function (value, row, index, table) {
var showweigh = true;
var showedit = true;
var showdel = true;
if (typeof table != 'undefined') {
var options = table.bootstrapTable('getOptions');
if (options.extend.del_url == '')
showdel = false;
if (options.extend.edit_url == '')
showedit = false;
}
showweigh = typeof row[Table.config.dragsortfield] != 'undefined' ? true : false;
//行操作
operate: function (value, row, index) {
var table = this.table;
// 操作配置
var options = table ? table.bootstrapTable('getOptions') : {};
// 默认按钮组
var buttons = $.extend([], this.buttons || []);
buttons.push({name: 'dragsort', icon: 'fa fa-arrows', classname: 'btn btn-xs btn-primary btn-dragsort'});
buttons.push({name: 'edit', icon: 'fa fa-pencil', classname: 'btn btn-xs btn-success btn-editone'});
buttons.push({name: 'del', icon: 'fa fa-trash', classname: 'btn btn-xs btn-danger btn-delone'});
var html = [];
if (showweigh)
html.push('<a href="javascript:;" class="btn btn-primary btn-dragsort btn-xs"><i class="fa fa-arrows"></i></a>');
if (showedit)
html.push('<a href="javascript:;" class="btn btn-success btn-editone btn-xs"><i class="fa fa-pencil"></i></a>');
if (showdel)
html.push('<a href="javascript:;" class="btn btn-danger btn-delone btn-xs"><i class="fa fa-trash"></i></a>');
$.each(buttons, function (i, j) {
var attr = table.data("operate-" + j.name);
if ((typeof attr === 'undefined' || attr) || (j.name === 'dragsort' && typeof row[Table.config.dragsortfield] == 'undefined')) {
if (['add', 'edit', 'del', 'multi'].indexOf(j.name) > -1 && !options.extend[j.name + "_url"]) {
return true;
}
//自动加上ids
j.url = j.url ? j.url + (j.url.match(/(\?|&)+/) ? "&ids=" : "/ids/") + row[options.pk] : '';
url = j.url ? Fast.api.fixurl(j.url) : 'javascript:;';
classname = j.classname ? j.classname : 'btn-primary btn-' + name + 'one';
icon = j.icon ? j.icon : '';
text = j.text ? j.text : '';
title = j.title ? j.title : text;
html.push('<a href="' + url + '" class="' + classname + '" title="' + title + '"><i class="' + icon + '"></i>' + (text ? ' ' + text : '') + '</a>');
}
});
return html.join(' ');
}
},
... ...