作者 Karson

新增buttons按钮组click事件

新增系统配置开关控件
修复后台管理员头像在启用云储存时的错误
修复前台公用库切换为jsdelivr.net公用库
FastAdmin是一款基于ThinkPHP5+Bootstrap的极速后台开发框架。
===============
## **主要特性**
* 基于Auth的权限管理系统
* 基于`Auth`验证的权限管理系统
* 支持无限级父子级权限继承,父级的管理员可任意增删改子级管理员及权限设置
* 支持单管理员多角色
* 支持管理子级数据或个人数据
... ... @@ -13,17 +12,18 @@ FastAdmin是一款基于ThinkPHP5+Bootstrap的极速后台开发框架。
* 一键压缩打包JS和CSS文件,一键CDN静态资源部署
* 一键生成控制器菜单和规则
* 一键生成API接口文档
* 完善的前端功能组件
* 基于AdminLTE二次开发
* 基于Bootstrap开发,自适应手机、平板、PC
* 基于RequireJS进行JS模块管理,按需加载
* 基于Bower进行前端组件包管理
* 完善的前端功能组件开发
* 基于`AdminLTE`二次开发
* 基于`Bootstrap`开发,自适应手机、平板、PC
* 基于`RequireJS`进行JS模块管理,按需加载
* 基于`Less`进行样式开发
* 基于`Bower`进行前端组件包管理
* 强大的插件扩展功能,在线安装卸载升级插件
* 通用的会员模块和API模块
* 共用同一账号体系的Web端会员中心权限验证和API接口会员权限验证
* 二级域名部署支持,同时域名支持绑定到插件
* 多语言支持,服务端及客户端支持
* 强大的第三方模块支持(CMS、博客、文档生成)
* 强大的第三方模块支持([CMS](https://www.fastadmin.net/store/cms.html)[博客](https://www.fastadmin.net/store/blog.html)[文档生成](https://www.fastadmin.net/store/docs.html)[个人免签支付](https://www.fastadmin.net/store/pay.html))
* 整合第三方短信接口(阿里云、创蓝短信)
* 无缝整合第三方云存储(七牛、阿里云OSS、又拍云)功能
* 第三方富文本编辑器支持(Summernote、Tinymce、百度编辑器)
... ... @@ -53,7 +53,7 @@ https://demo.fastadmin.net
交流社区: https://forum.fastadmin.net
QQ群: [636393962](https://jq.qq.com/?_wv=1027&k=487PNBb)(交流群①) [708784003](https://jq.qq.com/?_wv=1027&k=5ObjtwM)(交流群②) [696992864](https://jq.qq.com/?_wv=1027&k=5R2AB00)(高级群,付费加入)
QQ群: [636393962](https://jq.qq.com/?_wv=1027&k=487PNBb)(交流群①) [708784003](https://jq.qq.com/?_wv=1027&k=5ObjtwM)(交流群②) [696992864](https://jq.qq.com/?_wv=1027&k=5R2AB00)(高级群,邀请加入)
Email: (karsonzhang#163.com, 把#换成@)
... ... @@ -80,7 +80,7 @@ Nice-validator: https://validator.niceue.com
SelectPage: https://github.com/TerryZ/SelectPage
## 版权信息
## **版权信息**
FastAdmin遵循Apache2开源协议发布,并提供免费使用。
... ...
... ... @@ -27,6 +27,7 @@ return [
'Files' => '文件(多)',
'Select' => '列表',
'Selects' => '列表(多选)',
'Switch' => '开关',
'Checkbox' => '复选',
'Radio' => '单选',
'Array' => '数组',
... ...
... ... @@ -89,13 +89,13 @@
<!-- 账号信息下拉框 -->
<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}">
<img src="{$admin.avatar|cdnurl}" 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="">
<img src="{$admin.avatar|cdnurl}" class="img-circle" alt="">
<p>
{$admin.nickname}
... ...
... ... @@ -3,7 +3,7 @@
<!-- 管理员信息 -->
<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>
<a href="general/profile" class="addtabsit"><img src="{$admin.avatar|cdnurl}" class="img-circle" /></a>
</div>
<div class="pull-left info">
<p>{$admin.nickname}</p>
... ...
... ... @@ -104,6 +104,12 @@
<span><button type="button" id="fachoose-{$item.name}" class="btn btn-primary fachoose" data-input-id="c-{$item.name}" data-multiple="{$item.type=='file'?'false':'true'}"><i class="fa fa-list"></i> {:__('Choose')}</button></span>
</div>
{/case}
{case switch}
<input id="c-{$item.name}" name="row[{$item.name}]" type="hidden" value="{:$item.value?1:0}">
<a href="javascript:;" data-toggle="switcher" class="btn-switcher" data-input-id="c-{$item.name}" data-yes="1" data-no="0" >
<i class="fa fa-toggle-on text-success {if !$item.value}fa-flip-horizontal text-gray{/if} fa-2x"></i>
</a>
{/case}
{case bool}
<label for="row[{$item.name}]-yes"><input id="row[{$item.name}]-yes" name="row[{$item.name}]" type="radio" value="1" {$item.value?'checked':''} data-tip="{$item.tip}" /> {:__('Yes')}</label>
<label for="row[{$item.name}]-no"><input id="row[{$item.name}]-no" name="row[{$item.name}]" type="radio" value="0" {$item.value?'':'checked'} data-tip="{$item.tip}" /> {:__('No')}</label>
... ...
<style>
.profile-avatar-container {
position:relative;
width:100px;margin:0 auto;
position: relative;
width: 100px;
margin: 0 auto;
}
.profile-avatar-container .profile-user-img{
width:100px;
height:100px;
.profile-avatar-container .profile-user-img {
width: 100px;
height: 100px;
}
.profile-avatar-container .profile-avatar-text {
display:none;
display: none;
}
.profile-avatar-container:hover .profile-avatar-text {
display:block;
position:absolute;
height:100px;
width:100px;
background:#444;
display: block;
position: absolute;
height: 100px;
width: 100px;
background: #444;
opacity: .6;
color: #fff;
top:0;
left:0;
top: 0;
left: 0;
line-height: 100px;
text-align: center;
}
.profile-avatar-container button{
position:absolute;
top:0;left:0;width:100px;height:100px;opacity: 0;
.profile-avatar-container button {
position: absolute;
top: 0;
left: 0;
width: 100px;
height: 100px;
opacity: 0;
}
</style>
<div class="row animated fadeInRight">
... ... @@ -37,33 +46,33 @@
<div class="panel-body">
<form id="update-form" role="form" data-toggle="validator" method="POST" action="{:url('general.profile/update')}">
<input type="hidden" id="c-avatar" name="row[avatar]" value="{$admin.avatar}" />
<input type="hidden" id="c-avatar" name="row[avatar]" value="{$admin.avatar}"/>
<div class="box-body box-profile">
<div class="profile-avatar-container">
<img class="profile-user-img img-responsive img-circle plupload" src="__CDN__{$admin.avatar}" alt="">
<img class="profile-user-img img-responsive img-circle plupload" src="{$admin.avatar|cdnurl}" alt="">
<div class="profile-avatar-text img-circle">{:__('Click to edit')}</div>
<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>
<p class="text-muted text-center">{$admin.email}</p>
<div class="form-group">
<label for="username" class="control-label">{:__('Username')}:</label>
<input type="text" class="form-control" name="row[username]" value="{$admin.username}" disabled />
<input type="text" class="form-control" id="username" name="row[username]" value="{$admin.username}" disabled/>
</div>
<div class="form-group">
<label for="email" class="control-label">{:__('Email')}:</label>
<input type="text" class="form-control" name="row[email]" value="{$admin.email}" data-rule="required;email" />
<input type="text" class="form-control" id="email" name="row[email]" value="{$admin.email}" data-rule="required;email"/>
</div>
<div class="form-group">
<label for="nickname" class="control-label">{:__('Nickname')}:</label>
<input type="text" class="form-control" name="row[nickname]" value="{$admin.nickname}" data-rule="required" />
<input type="text" class="form-control" id="nickname" name="row[nickname]" value="{$admin.nickname}" data-rule="required"/>
</div>
<div class="form-group">
<label for="password" class="control-label">{:__('Password')}:</label>
<input type="text" class="form-control" placeholder="{:__('Leave password blank if dont want to change')}" autocomplete="new-password" name="row[password]" value=""/>
<input type="text" class="form-control" id="password" placeholder="{:__('Leave password blank if dont want to change')}" autocomplete="new-password" name="row[password]" value=""/>
</div>
<div class="form-group">
<button type="submit" class="btn btn-success">{:__('Submit')}</button>
... ...
... ... @@ -41,6 +41,7 @@ class Config extends Model
'images' => __('Images'),
'file' => __('File'),
'files' => __('Files'),
'switch' => __('Switch'),
'checkbox' => __('Checkbox'),
'radio' => __('Radio'),
'array' => __('Array'),
... ... @@ -78,8 +79,7 @@ class Config extends Model
public static function getGroupList()
{
$groupList = config('site.configgroup');
foreach ($groupList as $k => &$v)
{
foreach ($groupList as $k => &$v) {
$v = __($v);
}
return $groupList;
... ... @@ -90,10 +90,8 @@ class Config extends Model
$fieldarr = $valuearr = [];
$field = isset($data['field']) ? $data['field'] : [];
$value = isset($data['value']) ? $data['value'] : [];
foreach ($field as $m => $n)
{
if ($n != '')
{
foreach ($field as $m => $n) {
if ($n != '') {
$fieldarr[] = $field[$m];
$valuearr[] = $value[$m];
}
... ... @@ -110,10 +108,8 @@ class Config extends Model
{
$content = explode($split, $text);
$arr = [];
foreach ($content as $k => $v)
{
if (stripos($v, "|") !== false)
{
foreach ($content as $k => $v) {
if (stripos($v, "|") !== false) {
$item = explode('|', $v);
$arr[$item[0]] = $item[1];
}
... ... @@ -129,11 +125,9 @@ class Config extends Model
public static function encode($array, $split = "\r\n")
{
$content = '';
if ($array && is_array($array))
{
if ($array && is_array($array)) {
$arr = [];
foreach ($array as $k => $v)
{
foreach ($array as $k => $v) {
$arr[] = "{$k}|{$v}";
}
$content = implode($split, $arr);
... ...
... ... @@ -12,17 +12,17 @@
<title>FastAdmin - {:__('The fastest framework based on ThinkPHP5 and Bootstrap')}</title>
<!-- Bootstrap Core CSS -->
<link href="//cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
<link href="//cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="__CDN__/assets/css/index.css" rel="stylesheet">
<!-- Plugin CSS -->
<link href="//cdn.bootcss.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
<link href="//cdn.bootcss.com/simple-line-icons/2.4.1/css/simple-line-icons.min.css" rel="stylesheet">
<link href="//cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css" rel="stylesheet">
<link href="//cdn.jsdelivr.net/npm/simple-line-icons@2.4.1/css/simple-line-icons.min.css" rel="stylesheet">
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]>
<script src="//cdn.bootcss.com/html5shiv/3.7.0/html5shiv.min.js"></script>
<script src="//cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/html5shiv@3.7.3/dist/html5shiv.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/respond.js@1.4.2/dest/respond.min.js"></script>
<![endif]-->
</head>
... ... @@ -163,13 +163,13 @@
</footer>
<!-- jQuery -->
<script src="//cdn.bootcss.com/jquery/2.1.4/jquery.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/jquery@2.1.4/dist/jquery.min.js"></script>
<!-- Bootstrap Core JavaScript -->
<script src="//cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js"></script>
<!-- Plugin JavaScript -->
<script src="//cdn.bootcss.com/jquery-easing/1.4.1/jquery.easing.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/jquery.easing@1.4.1/jquery.easing.min.js"></script>
<script>
$(function () {
... ...
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<meta name="author" content="">
<title>FastAdmin - {:__('The fastest framework based on ThinkPHP5 and Bootstrap')}</title>
<!-- Bootstrap Core CSS -->
<link href="//cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
<!-- Plugin CSS -->
<link href="//cdn.bootcss.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]>
<script src="//cdn.bootcss.com/html5shiv/3.7.0/html5shiv.min.js"></script>
<script src="//cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
<style>
body {
padding-top: 70px;
}
footer {
background-color: #222;
color:#9d9d9d;
padding:20px 0;
}
</style>
</head>
<body>
<!-- Navigation -->
<nav class="navbar navbar-inverse navbar-fixed-top" role="navigation">
<div class="container">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="https://www.fastadmin.net">FastAdmin</a>
</div>
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav pull-right">
<li><a href="https://www.fastadmin.net" target="_blank">{:__('Home')}</a></li>
<li><a href="https://www.fastadmin.net/store.html" target="_blank">{:__('Store')}</a></li>
<li><a href="https://www.fastadmin.net/service.html" target="_blank">{:__('Services')}</a></li>
<li><a href="https://www.fastadmin.net/download.html" target="_blank">{:__('Download')}</a></li>
<li><a href="https://www.fastadmin.net/demo.html" target="_blank">{:__('Demo')}</a></li>
<li><a href="https://www.fastadmin.net/donate.html" target="_blank">{:__('Donation')}</a></li>
<li><a href="https://forum.fastadmin.net" target="_blank">{:__('Forum')}</a></li>
<li><a href="https://doc.fastadmin.net" target="_blank">{:__('Docs')}</a></li>
</ul>
</div>
<!-- /.navbar-collapse -->
</div>
<!-- /.container -->
</nav>
<main class="content">
{__CONTENT__}
</main>
<footer>
<div class="container">
<!-- FastAdmin是开源程序,建议在您的网站底部保留一个FastAdmin的链接 -->
<p>&copy; 2017-2018 <a href="https://www.fastadmin.net" target="_blank">FastAdmin</a>. All Rights Reserved.</p>
<ul class="list-inline">
<li>
<a href="https://gitee.com/karson/fastadmin">{:__('Gitee')}</a>
</li>
<li>
<a href="https://github.com/karsonzhang/fastadmin">{:__('Github')}</a>
</li>
<li>
<a href="https://shang.qq.com/wpa/qunwpa?idkey=46c326e570d0f97cfae1f8257ae82322192ec8841c79b2136446df0b3b62028c">{:__('QQ group')}</a>
</li>
</ul>
</div>
</footer>
<!-- jQuery -->
<script src="//cdn.bootcss.com/jquery/2.1.4/jquery.min.js"></script>
<!-- Bootstrap Core JavaScript -->
<script src="//cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script>
$(function () {
});
</script>
</body>
</html>
... ... @@ -16,7 +16,7 @@
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="{:url('/')}" style="padding:6px 15px;"><img src="/assets/img/logo.png" style="height:40px;" alt=""></a>
<a class="navbar-brand" href="{:url('/')}" style="padding:6px 15px;"><img src="__CDN__/assets/img/logo.png" style="height:40px;" alt=""></a>
</div>
<div class="collapse navbar-collapse" id="header-navbar">
<ul class="nav navbar-nav navbar-right">
... ...
... ... @@ -209,6 +209,28 @@ define(['fast', 'template', 'moment'], function (Fast, Template, Moment) {
}
return false;
});
$(document).on('click', '.btn-click,.clickit', function (e) {
var that = this;
var options = $.extend({}, $(that).data() || {});
var row = {};
if (typeof options.tableId !== 'undefined') {
var index = parseInt(options.rowIndex);
var data = $("#" + options.tableId).bootstrapTable('getData');
row = typeof data[index] !== 'undefined' ? data[index] : {};
}
var button = Backend.api.gettablecolumnbutton(options);
var click = typeof button.click === 'function' ? button.click : $.noop;
if (typeof options.confirm !== 'undefined') {
Layer.confirm(options.confirm, function (index) {
click.apply(that, [options, row, button]);
Layer.close(index);
});
} else {
click.apply(that, [options, row, button]);
}
return false;
});
//修复含有fixed-footer类的body边距
if ($(".fixed-footer").size() > 0) {
$(document.body).css("padding-bottom", $(".fixed-footer").outerHeight());
... ...
... ... @@ -24,8 +24,8 @@ define(['jquery', 'bootstrap', 'backend', 'form', 'table'], function ($, undefin
[
{field: 'state', checkbox: true,},
{field: 'id', title: __('Id')},
{field: 'admin_id', title: __('Admin_id'), visible: false, addClass:"selectpage", extend:"data-source='auth/admin/index' data-field='nickname'"},
{field: 'user_id', title: __('User_id'), visible: false, addClass:"selectpage", extend:"data-source='user/user/index' data-field='nickname'"},
{field: 'admin_id', title: __('Admin_id'), visible: false, addClass: "selectpage", extend: "data-source='auth/admin/index' data-field='nickname'"},
{field: 'user_id', title: __('User_id'), visible: false, addClass: "selectpage", extend: "data-source='user/user/index' data-field='nickname'"},
{field: 'url', title: __('Preview'), formatter: Controller.api.formatter.thumb, operate: false},
{field: 'url', title: __('Url'), formatter: Controller.api.formatter.url},
{field: 'imagewidth', title: __('Imagewidth'), sortable: true},
... ... @@ -77,9 +77,9 @@ define(['jquery', 'bootstrap', 'backend', 'form', 'table'], function ($, undefin
{field: 'id', title: __('Id')},
{field: 'admin_id', title: __('Admin_id'), visible: false},
{field: 'user_id', title: __('User_id'), visible: false},
{field: 'url', title: __('Preview'), formatter: Controller.api.formatter.thumb},
{field: 'imagewidth', title: __('Imagewidth')},
{field: 'imageheight', title: __('Imageheight')},
{field: 'url', title: __('Preview'), formatter: Controller.api.formatter.thumb, operate: false},
{field: 'imagewidth', title: __('Imagewidth'), operate: false},
{field: 'imageheight', title: __('Imageheight'), operate: false},
{
field: 'mimetype', title: __('Mimetype'), operate: 'LIKE %...%',
process: function (value, arg) {
... ...
... ... @@ -5435,6 +5435,28 @@ define('backend',['fast', 'template', 'moment'], function (Fast, Template, Momen
}
return false;
});
$(document).on('click', '.btn-click,.clickit', function (e) {
var that = this;
var options = $.extend({}, $(that).data() || {});
var row = {};
if (typeof options.tableId !== 'undefined') {
var index = parseInt(options.rowIndex);
var data = $("#" + options.tableId).bootstrapTable('getData');
row = typeof data[index] !== 'undefined' ? data[index] : {};
}
var button = Backend.api.gettablecolumnbutton(options);
var click = typeof button.click === 'function' ? button.click : $.noop;
if (typeof options.confirm !== 'undefined') {
Layer.confirm(options.confirm, function (index) {
click.apply(that, [options, row, button]);
Layer.close(index);
});
} else {
click.apply(that, [options, row, button]);
}
return false;
});
//修复含有fixed-footer类的body边距
if ($(".fixed-footer").size() > 0) {
$(document.body).css("padding-bottom", $(".fixed-footer").outerHeight());
... ... @@ -9616,7 +9638,7 @@ define('table',['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstr
}
}
table.bootstrapTable('refresh');
}, function () {
}, function (data, ret) {
var error = $(element).data("error") || $.noop;
if (typeof error === 'function') {
if (false === error.call(element, data, ret)) {
... ... @@ -9901,7 +9923,7 @@ define('table',['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstr
type = typeof type === 'undefined' ? 'buttons' : type;
var options = table ? table.bootstrapTable('getOptions') : {};
var html = [];
var hidden, visible, url, classname, icon, text, title, refresh, confirm, extend;
var hidden, visible, url, classname, icon, text, title, refresh, confirm, extend, click;
var fieldIndex = column.fieldIndex;
$.each(buttons, function (i, j) {
... ...
... ... @@ -249,7 +249,7 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table
}
}
table.bootstrapTable('refresh');
}, function () {
}, function (data, ret) {
var error = $(element).data("error") || $.noop;
if (typeof error === 'function') {
if (false === error.call(element, data, ret)) {
... ... @@ -534,7 +534,7 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table
type = typeof type === 'undefined' ? 'buttons' : type;
var options = table ? table.bootstrapTable('getOptions') : {};
var html = [];
var hidden, visible, url, classname, icon, text, title, refresh, confirm, extend;
var hidden, visible, url, classname, icon, text, title, refresh, confirm, extend, click;
var fieldIndex = column.fieldIndex;
$.each(buttons, function (i, j) {
... ...