Browse Source

Merge remote-tracking branch 'upstream/develop' into develop

gtlee 8 months ago
parent
commit
d12f549396

+ 6 - 6
application/admin/command/Api/template/index.html

@@ -8,15 +8,15 @@
         <title>{$config.title}</title>
 
         <!-- Bootstrap Core CSS -->
-        <link href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
+        <link href="https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
 
         <!-- Plugin CSS -->
-        <link href="https://cdn.staticfile.org/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
+        <link href="https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/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="https://cdn.staticfile.org/html5shiv/3.7.3/html5shiv.min.js"></script>
-        <script src="https://cdn.staticfile.org/respond.js/1.4.2/respond.min.js"></script>
+        <script src="https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/html5shiv/3.7.3/html5shiv.min.js"></script>
+        <script src="https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/respond.js/1.4.2/respond.min.js"></script>
         <![endif]-->
 
         <style type="text/css">
@@ -401,10 +401,10 @@
         </div> <!-- /container -->
 
         <!-- jQuery -->
-        <script src="https://cdn.staticfile.org/jquery/2.1.4/jquery.min.js"></script>
+        <script src="https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/jquery/3.6.0/jquery.min.js"></script>
 
         <!-- Bootstrap Core JavaScript -->
-        <script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
+        <script src="https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
 
         <script type="text/javascript">
             function syntaxHighlight(json) {

+ 10 - 7
application/admin/command/Crud.php

@@ -435,16 +435,19 @@ class Crud extends Command
         $modelName = $table = stripos($table, $prefix) === 0 ? substr($table, strlen($prefix)) : $table;
         $modelTableType = 'table';
         $modelTableTypeName = $modelTableName = $modelName;
-        $modelTableInfo = $dbconnect->query("SHOW TABLE STATUS LIKE '{$modelTableName}'", [], true);
-        if (!$modelTableInfo) {
-            $modelTableType = 'name';
-            $modelTableName = $prefix . $modelName;
+        $modelTableInfo = null;
+        if (!$input->getOption('delete')) {
             $modelTableInfo = $dbconnect->query("SHOW TABLE STATUS LIKE '{$modelTableName}'", [], true);
             if (!$modelTableInfo) {
-                throw new Exception("table not found");
+                $modelTableType = 'name';
+                $modelTableName = $prefix . $modelName;
+                $modelTableInfo = $dbconnect->query("SHOW TABLE STATUS LIKE '{$modelTableName}'", [], true);
+                if (!$modelTableInfo) {
+                    throw new Exception("table not found");
+                }
             }
+            $modelTableInfo = $modelTableInfo[0];
         }
-        $modelTableInfo = $modelTableInfo[0];
 
         $relations = [];
         //检查关联表
@@ -1081,7 +1084,7 @@ class Crud extends Command
             }
 
             //表注释
-            $tableComment = $modelTableInfo['Comment'];
+            $tableComment = $modelTableInfo ? $modelTableInfo['Comment'] : '';
             $tableComment = mb_substr($tableComment, -1) == '表' ? mb_substr($tableComment, 0, -1) . '管理' : $tableComment;
 
             $modelInit = '';

+ 1 - 1
application/admin/command/Install.php

@@ -93,7 +93,7 @@ class Install extends Command
      */
     public function index()
     {
-        $this->view = View::instance(Config::get('template'), Config::get('view_replace_str'));
+        $this->view = View::instance(array_merge(Config::get('template'), ['tpl_cache' => false]));
         $this->request = Request::instance();
 
         define('INSTALL_PATH', APP_PATH . 'admin' . DS . 'command' . DS . 'Install' . DS);

+ 1 - 1
application/admin/command/Install/install.html

@@ -254,7 +254,7 @@
         </form>
 
         <!-- jQuery -->
-        <script src="https://cdn.staticfile.org/jquery/2.1.4/jquery.min.js"></script>
+        <script src="__ROOT__/assets/libs/jquery/dist/jquery.min.js"></script>
 
         <script>
             $(function () {

+ 1 - 1
application/admin/command/Install/zh-cn.php

@@ -20,7 +20,7 @@ return [
     'Dashboard'                                                                                             => '进入后台',
     'Go back'                                                                                               => '返回上一页',
     'Install Successed'                                                                                     => '安装成功!',
-    'Security tips'                                                                                         => '温馨提示:请将以下后台登录入口添加到你的收藏夹,为了你的安全,不要泄漏或发送给他人!如有泄漏请及时修改!',
+    'Security tips'                                                                                         => '温馨提示:请将以下后台登录入口添加到你的收藏夹,为了你的站点安全,不要泄漏或发送给他人!如有泄漏请及时修改!',
     'Please input correct database'                                                                         => '请输入正确的数据库名',
     'Please input correct username'                                                                         => '用户名只能由3-30位数字、字母、下划线组合',
     'Please input correct password'                                                                         => '密码长度必须在6-30位之间,不能包含空格',

+ 1 - 1
application/admin/lang/zh-cn/general/profile.php

@@ -2,7 +2,7 @@
 
 return [
     'Url'                                         => '链接',
-    'Userame'                                     => '用户名',
+    'Username'                                    => '用户名',
     'Createtime'                                  => '操作时间',
     'Click to edit'                               => '点击编辑',
     'Admin log'                                   => '操作日志',

+ 1 - 1
application/admin/library/Auth.php

@@ -472,7 +472,7 @@ class Auth extends \fast\Auth
             ->column('name,pid');
         $pidArr = array_unique(array_filter(array_column($ruleList, 'pid')));
         foreach ($ruleList as $k => &$v) {
-            if (!in_array($v['name'], $userRule)) {
+            if (!in_array(strtolower($v['name']), $userRule)) {
                 unset($ruleList[$k]);
                 continue;
             }

+ 2 - 2
application/admin/view/index/index.html

@@ -28,12 +28,12 @@
             <div class="content-wrapper tab-content tab-addtabs">
                 {if $fixedmenu}
                 <div role="tabpanel" class="tab-pane {:$referermenu?'':'active'}" id="con_{$fixedmenu.id}">
-                    <iframe src="{$fixedmenu.url}?addtabs=1" width="100%" height="100%" frameborder="no" border="0" marginwidth="0" marginheight="0" scrolling-x="no" scrolling-y="auto" allowtransparency="yes"></iframe>
+                    <iframe src="{$fixedmenu.url}{:stripos($fixedmenu.url, '?') !== false ? '&' : '?'}addtabs=1" width="100%" height="100%" frameborder="no" border="0" marginwidth="0" marginheight="0" scrolling-x="no" scrolling-y="auto" allowtransparency="yes"></iframe>
                 </div>
                 {/if}
                 {if $referermenu}
                 <div role="tabpanel" class="tab-pane active" id="con_{$referermenu.id}">
-                    <iframe src="{$referermenu.url}?addtabs=1" width="100%" height="100%" frameborder="no" border="0" marginwidth="0" marginheight="0" scrolling-x="no" scrolling-y="auto" allowtransparency="yes"></iframe>
+                    <iframe src="{$referermenu.url}{:stripos($referermenu.url, '?') !== false ? '&' : '?'}addtabs=1" width="100%" height="100%" frameborder="no" border="0" marginwidth="0" marginheight="0" scrolling-x="no" scrolling-y="auto" allowtransparency="yes"></iframe>
                 </div>
                 {/if}
             </div>

+ 23 - 0
application/api/controller/Ems.php

@@ -34,8 +34,20 @@ class Ems extends Api
         $event = $this->request->post("event");
         $event = $event ? $event : 'register';
 
+        if (!$email || !filter_var($email, FILTER_VALIDATE_EMAIL)) {
+            $this->error(__('邮箱格式错误'));
+        }
+        if (!preg_match("/^[a-z0-9_\-]{3,30}\$/i", $event)) {
+            $this->error(__('事件名称错误'));
+        }
+
         //发送前验证码
         if (config('fastadmin.user_api_captcha')) {
+
+            if (!preg_match("/^[a-z0-9]{4,6}\$/i", $captcha)) {
+                $this->error(__('验证码格式错误'));
+            }
+
             if (!\think\Validate::is($captcha, 'captcha')) {
                 $this->error("验证码不正确");
             }
@@ -87,6 +99,17 @@ class Ems extends Api
         $event = $event ? $event : 'register';
         $captcha = $this->request->post("captcha");
 
+        if (!$email || !filter_var($email, FILTER_VALIDATE_EMAIL)) {
+            $this->error(__('邮箱格式错误'));
+        }
+        if (!preg_match("/^[a-z0-9_\-]{3,30}\$/i", $event)) {
+            $this->error(__('事件名称错误'));
+        }
+
+        if (!preg_match("/^[a-z0-9]{4,6}\$/i", $captcha)) {
+            $this->error(__('验证码格式错误'));
+        }
+
         if ($event) {
             $userinfo = User::getByEmail($email);
             if ($event == 'register' && $userinfo) {

+ 21 - 0
public/assets/js/backend/addon.js

@@ -241,6 +241,27 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template', 'cookie']
                             Layer.close(index);
                         });
                         return false;
+                    } else if (ret && ret.code === -3) {
+                        //插件目录发现影响全局的文件
+                        Layer.open({
+                            content: Template("conflicttpl", ret.data),
+                            shade: 0.8,
+                            area: area,
+                            title: __('Warning'),
+                            btn: [__('Continue install'), __('Cancel')],
+                            end: function () {
+
+                            },
+                            yes: function (index) {
+                                up.removeFile(file);
+                                file.force = true;
+                                up.uploadFile(file);
+                                Layer.close(index);
+                            }
+                        });
+
+                    } else {
+                        Layer.alert(ret.msg, {title: __('Warning'), icon: 0});
                     }
                 });
 

+ 1 - 1
public/assets/js/backend/general/attachment.js

@@ -167,7 +167,7 @@ define(['jquery', 'bootstrap', 'backend', 'form', 'table'], function ($, undefin
                         {
                             field: 'operate', title: __('Operate'), width: 85, events: {
                                 'click .btn-chooseone': function (e, value, row, index) {
-                                    Fast.api.close({url: row.url, multiple: multiple});
+                                    Fast.api.close($.extend({multiple: multiple}, row));
                                 },
                             }, formatter: function () {
                                 return '<a href="javascript:;" class="btn btn-danger btn-chooseone btn-xs"><i class="fa fa-check"></i> ' + __('Choose') + '</a>';

+ 1 - 1
public/assets/js/require-backend.js

@@ -138,7 +138,7 @@ require(['jquery', 'bootstrap'], function ($, undefined) {
     window.Config = Config;
     // 配置语言包的路径
     var paths = {};
-    paths['lang'] = Config.moduleurl + '/ajax/lang?callback=define&controllername=' + Config.controllername + '&lang=' + Config.language + '&v=' + Config.site.version;
+    paths['lang'] = Config.moduleurl + '/ajax/lang?callback=define&controllername=' + Config.controllername + '&lang=' + Config.language;
     // 避免目录冲突
     paths['backend/'] = 'backend/';
     // 如果是英文,则移除默认的定义

+ 9 - 2
public/assets/js/require-form.js

@@ -265,7 +265,7 @@ define(['jquery', 'bootstrap', 'upload', 'validator', 'validator-lang'], functio
                         var url = $(this).data("url") ? $(this).data("url") : (typeof Backend !== 'undefined' ? "general/attachment/select" : "user/attachment");
                         parent.Fast.api.open(url + "?element_id=" + $(this).attr("id") + "&multiple=" + multiple + "&mimetype=" + mimetype + "&admin_id=" + admin_id + "&user_id=" + user_id, __('Choose'), {
                             callback: function (data) {
-                                var button = $("#" + $(that).attr("id"));
+                                var button = $(that);
                                 var maxcount = $(button).data("maxcount");
                                 var input_id = $(button).data("input-id") ? $(button).data("input-id") : "";
                                 maxcount = typeof maxcount !== "undefined" ? maxcount : 0;
@@ -295,6 +295,9 @@ define(['jquery', 'bootstrap', 'upload', 'validator', 'validator-lang'], functio
                                     var url = Config.upload.fullmode ? Fast.api.cdnurl(data.url) : data.url;
                                     $("#" + input_id).val(url).trigger("change").trigger("validate");
                                 }
+
+                                // 触发选择文件自定义事件
+                                button.trigger("fa.event.selectedfile", data);
                             }
                         });
                         return false;
@@ -510,7 +513,11 @@ define(['jquery', 'bootstrap', 'upload', 'validator', 'validator-lang'], functio
             autocomplete: function (form) {
                 if ($("[data-role='autocomplete']", form).length > 0) {
                     require(['autocomplete'], function () {
-                        $("[data-role='autocomplete']").autocomplete();
+                        $("[data-role='autocomplete']").autocomplete({
+                            onSelect: function () {
+                                $(this).trigger('change').trigger('validate');
+                            }
+                        });
                     });
                 }
             },

+ 1 - 1
public/assets/js/require-frontend.js

@@ -138,7 +138,7 @@ require(['jquery', 'bootstrap'], function ($, undefined) {
     window.Config = Config;
     // 配置语言包的路径
     var paths = {};
-    paths['lang'] = Config.moduleurl + '/ajax/lang?callback=define&controllername=' + Config.controllername + '&lang=' + Config.language + '&v=' + Config.site.version;
+    paths['lang'] = Config.moduleurl + '/ajax/lang?callback=define&controllername=' + Config.controllername + '&lang=' + Config.language;
     // 避免目录冲突
     paths['frontend/'] = 'frontend/';
     // 如果是英文,则移除默认的定义

+ 26 - 19
public/assets/js/require-table.js

@@ -469,8 +469,10 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table
                 toolbar.on('click', Table.config.delbtn, function () {
                     var that = this;
                     var ids = Table.api.selectedids(table);
+                    var confirm = $(this).data("confirm");
+                    var message = typeof confirm === 'function' ? confirm.call(this, ids) : (typeof confirm !== 'undefined' ? __(confirm, ids.length) : '');
                     Layer.confirm(
-                        __('Are you sure you want to delete the %s selected item?', ids.length),
+                        message || __('Are you sure you want to delete the %s selected item?', ids.length),
                         {icon: 3, title: __('Warning'), offset: 0, shadeClose: true, btn: [__('OK'), __('Cancel')]},
                         function (index) {
                             Table.api.multi("del", ids, table, that);
@@ -692,7 +694,7 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table
                             top = left = undefined;
                         }
                         Layer.confirm(
-                            __('Are you sure you want to delete this item?'),
+                            $(that).data("confirm") || __('Are you sure you want to delete this item?'),
                             {icon: 3, title: __('Warning'), offset: [top, left], shadeClose: true, btn: [__('OK'), __('Cancel')]},
                             function (index) {
                                 var table = $(that).closest('table');
@@ -753,7 +755,7 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table
                     return html.join(' ');
                 },
                 file: function (value, row, index) {
-                    Table.api.formatter.files.call(this, value, row, index);
+                    return Table.api.formatter.files.call(this, value, row, index);
                 },
                 files: function (value, row, index) {
                     value = value == null || value.length === 0 ? '' : value.toString();
@@ -915,23 +917,28 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table
                     var table = this.table;
                     // 操作配置
                     var options = table ? table.bootstrapTable('getOptions') : {};
-                    // 默认按钮组
-                    var buttons = $.extend([], this.buttons || []);
-                    // 所有按钮名称
-                    var names = [];
-                    buttons.forEach(function (item) {
-                        names.push(item.name);
+                    var buttons = [];
+                    var existBtn = [];
+                    var defaultBtn = ['dragsort', 'edit', 'del'];
+                    var tempButton = $.extend({}, Table.button, {});
+                    (this.buttons || []).forEach(function (item, index) {
+                        if (defaultBtn.indexOf(item.name) > -1) {
+                            $.extend(tempButton[item.name], item, Table.button[item.name], item.name === 'edit' ? {url: options.extend.edit_url} : {});
+                            if (item.keep) {
+                                if (options.extend[item.name + "_url"] !== '') {
+                                    buttons.push(tempButton[item.name]);
+                                }
+                                existBtn.push(item.name);
+                            }
+                        } else {
+                            buttons.push(item);
+                        }
+                    });
+                    defaultBtn.forEach(function (value, index) {
+                        if (existBtn.indexOf(value) === -1) {
+                            buttons.push(tempButton[value]);
+                        }
                     });
-                    if (options.extend.dragsort_url !== '' && names.indexOf('dragsort') === -1) {
-                        buttons.push(Table.button.dragsort);
-                    }
-                    if (options.extend.edit_url !== '' && names.indexOf('edit') === -1) {
-                        Table.button.edit.url = options.extend.edit_url;
-                        buttons.push(Table.button.edit);
-                    }
-                    if (options.extend.del_url !== '' && names.indexOf('del') === -1) {
-                        buttons.push(Table.button.del);
-                    }
                     return Table.api.buttonlink(this, buttons, value, row, index, 'operate');
                 }
                 ,