Selaa lähdekoodia

update

update
jqh 5 vuotta sitten
vanhempi
commit
96294963fa

+ 1026 - 0
resources/assets/dcat/extra/upload.js

@@ -0,0 +1,1026 @@
+(function (w, $) {
+    function Uploader(opts) {
+        opts = $.extend({
+            wrapper: '.web-uploader', // 图片显示容器选择器
+            addFileButton: '.add-file-button', // 继续添加按钮选择器
+            isImage: false,
+            preview: [], // 数据预览
+            deleteUrl: '',
+            deleteData: {},
+            thumbHeight: 160,
+            disabled: false, // 禁止任何上传编辑
+            autoUpdateColumn: false,
+            disableRemove: false, // 禁止删除图片,允许替换
+            dimensions: {
+                // width: 100, // 图片宽限制
+                // height: 100, // 图片高限制
+                // min_width: 100, //
+                // min_height: 100,
+                // max_width: 100,
+                // max_height: 100,
+                // ratio: 3/2, // 宽高比
+            },
+            lang: {
+                exceed_size: '文件大小超出',
+                interrupt: '上传暂停',
+                upload_failed: '上传失败,请重试',
+                selected_files: '选中:num个文件,共:size。',
+                selected_has_failed: '已成功上传:success个文件,:fail个文件上传失败,<a class="retry"  href="javascript:"";">重新上传</a>失败文件或<a class="ignore" href="javascript:"";">忽略</a>',
+                selected_success: '共:num个(:size),已上传:success个。',
+                dot: ',',
+                failed_num: '失败:fail个。',
+                pause_upload: '暂停上传',
+                go_on_upload: '继续上传',
+                start_upload: '开始上传',
+                upload_success_message: '已成功上传:success个文件',
+                go_on_add: '继续添加',
+                Q_TYPE_DENIED: '对不起,不允许上传此类型文件',
+                Q_EXCEED_NUM_LIMIT: '对不起,已超出文件上传数量限制,最多只能上传:num个文件',
+                F_EXCEED_SIZE: '对不起,当前选择的文件过大',
+                Q_EXCEED_SIZE_LIMIT: '对不起,已超出文件大小限制',
+                F_DUPLICATE: '文件重复',
+
+            },
+            upload: { // web-uploader配置
+                formData: {
+                    _id: null, // 唯一id
+                },
+                thumb: {
+                    width: 160,
+                    height: 160,
+                    quality: 70,
+                    allowMagnify: true,
+                    crop: true,
+                    preserveHeaders: false,
+                    // 为空的话则保留原有图片格式。
+                    // 否则强制转换成指定的类型。
+                    // IE 8下面 base64 大小不能超过 32K 否则预览失败,而非 jpeg 编码的图片很可
+                    // 能会超过 32k, 所以这里设置成预览的时候都是 image/jpeg
+                    type: 'image/jpeg'
+                },
+            }
+        }, opts);
+
+        var $selector = $(opts.selector),
+            updateColumn = opts.upload.formData.upload_column || ('webup' + Math.floor(Math.random()*10000)),
+            elementName = opts.elementName;
+
+        if (typeof opts.upload.formData._id == "undefined" || !opts.upload.formData._id) {
+            opts.upload.formData._id = updateColumn + Math.floor(Math.random()*10000);
+        }
+
+        let Dcat = w.Dcat,
+
+            $wrap,
+
+            // 展示图片
+            showImg = opts.isImage,
+
+            // 图片容器
+            $queue,
+
+            // 状态栏,包括进度和控制按钮
+            $statusBar,
+
+            // 文件总体选择信息。
+            $info,
+
+            // 上传按钮
+            $upload,
+
+            // 没选择文件之前的内容。
+            $placeHolder,
+
+            $progress,
+
+            // 已上传文件数量
+            originalFilesNum = Dcat.helpers.len(opts.preview),
+
+            // 上传表单
+            $input = $selector.find('input[name="' + elementName + '"]'),
+
+            // 获取文件视图选择器
+            getFileViewSelector = function (fileId) {
+                return elementName.replace(/[\[\]]*/g, '_')+'-'+fileId;
+            },
+
+            getFileView = function (fileId) {
+                return $('#' + getFileViewSelector(fileId));
+            },
+
+            // 继续添加按钮选择器
+            addFileButtonSelector = opts.addFileButton,
+
+            // 临时存储上传失败的文件,key为file id
+            faildFiles = {},
+
+            // 临时存储添加到form表单的文件
+            formFiles = {},
+
+            // 添加的文件数量
+            fileCount = 0,
+
+            // 添加的文件总大小
+            fileSize = 0,
+
+            // 可能有pedding, ready, uploading, confirm, done.
+            state = 'pedding',
+
+            // 所有文件的进度信息,key为file id
+            percentages = {},
+            // 判断浏览器是否支持图片的base64
+            isSupportBase64 = (function () {
+                var data = new Image();
+                var support = true;
+                data.onload = data.onerror = function () {
+                    if (this.width != 1 || this.height != 1) {
+                        support = false;
+                    }
+                };
+                data.src = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==";
+                return support;
+            })(),
+
+            // 检测是否已经安装flash,检测flash的版本
+            flashVersion = (function () {
+                var version;
+
+                try {
+                    version = navigator.plugins['Shockwave Flash'];
+                    version = version.description;
+                } catch (ex) {
+                    try {
+                        version = new ActiveXObject('ShockwaveFlash.ShockwaveFlash')
+                            .GetVariable('$version');
+                    } catch (ex2) {
+                        version = '0.0';
+                    }
+                }
+                version = version.match(/\d+/g);
+                return parseFloat(version[0] + '.' + version[1], 10);
+            })(),
+
+            // 判断是否是图片
+            isImage = function (file) {
+                return file.type.match(/^image/);
+            },
+
+            // 翻译
+            lang = Dcat.Translator(opts.lang),
+            __ = lang.trans.bind(lang),
+
+            // WebUploader实例
+            uploader;
+
+        // 当有文件添加进来时执行,负责view的创建
+        function addFile(file) {
+            var size = WebUploader.formatSize(file.size), $li, $btns;
+
+            if (showImg) {
+                $li = $('<li id="' + getFileViewSelector(file.id) + '" title="' + file.name + '" style="margin:7px">' +
+                    '<p class="file-type">' + (file.ext.toUpperCase() || 'FILE') + '</p>' +
+                    '<p class="imgWrap "></p>' +
+                    '<p class="title" style="">' + file.name + '</p>' +
+                    '<p class="title" style=\'margin-bottom:12px;\'>(<b>' + size + '</b>)</p>' +
+                    '</li>');
+
+                $btns = $('<div class="file-panel">' +
+                    '<a class=\'btn btn-xs btn-default\' data-file-act="cancel"><i class="fa fa-close red-dark" style=\'font-size:13px\'></i></a>' +
+                    '<a class=\'btn btn-xs btn-default\' data-file-act="delete" style="display: none"><i class="ti-trash red-dark" style=\'font-size:13px\'></i></a>' +
+                    '<a class=\'btn btn-xs btn-default\' data-file-act="preview" ><i class="glyphicon glyphicon-zoom-in"></i></a>' +
+                    '</div>').appendTo($li);
+            } else {
+                $li = $('<li id="' + getFileViewSelector(file.id) + '" title="' + file.name + '">' +
+                    '<p class="title" style="display:block"><i class=\'ti-check green _success\' style=\'font-weight:bold;font-size:17px;display:none\'></i>' +
+                    file.name + ' (' + size + ')</p>' +
+                    '</li>');
+
+                $btns = $('<span data-file-act="cancel" class="_act" style="font-size:13px"><i class=\'ti-close red-dark\'></i></span>' +
+                    '<span data-file-act="delete" class="_act" style="display:none"><i class=\'ti-trash red-dark\'></i></span>'
+                ).appendTo($li);
+            }
+
+            var $wrap = $li.find('p.imgWrap'),
+                $info = $('<p class="error"></p>'),
+
+                showError = function (code, file) {
+                    var text = '';
+                    switch (code) {
+                        case 'exceed_size':
+                            text = __('exceed_size');
+                            break;
+
+                        case 'interrupt':
+                            text = __('interrupt');
+                            break;
+
+                        default:
+                            text = __('upload_failed');
+                            break;
+                    }
+
+                    faildFiles[file.id] = file;
+
+                    $info.text(text).appendTo($li);
+                };
+
+            $li.appendTo($queue);
+
+            if (file.getStatus() === 'invalid') {
+                showError(file.statusText, file);
+            } else {
+                if (showImg) {
+                    var image = uploader.makeThumb(file, function (error, src) {
+                        var img;
+
+                        $wrap.empty();
+                        if (error) {
+                            $li.find('.title').show();
+                            $li.find('.file-type').show();
+                            return;
+                        }
+
+                        if (isSupportBase64) {
+                            img = $('<img src="' + src + '">');
+                            $wrap.append(img);
+                        } else {
+                            $li.find('.file-type').show();
+                        }
+                    });
+
+                    try {
+                        image.once('load', function () {
+                            file._info = file._info || image.info();
+                            file._meta = file._meta || image.meta();
+                            var width = file._info.width,
+                                height = file._info.height;
+
+                            if (!validateDimensions(file)) {
+                                Dcat.error('The image dimensions is invalid.');
+                                uploader.removeFile(file);
+                                return false;
+                            }
+
+                            image.resize(width, height);
+                        });
+                    } catch (e) {
+                        // 不是图片
+                        return setTimeout(function () {
+                            uploader.removeFile(file);
+                        }, 10);
+                    }
+                }
+
+                percentages[file.id] = [file.size, 0];
+                file.rotation = 0;
+            }
+
+            file.on('statuschange', function (cur, prev) {
+                if (prev === 'progress') {
+                    // $prgress.hide().width(0);
+                } else if (prev === 'queued') {
+                    $btns.find('[data-file-act="cancel"]').hide();
+                    $btns.find('[data-file-act="delete"]').show();
+                }
+
+                // 成功
+                if (cur === 'error' || cur === 'invalid') {
+                    showError(file.statusText, file);
+                    percentages[file.id][1] = 1;
+                } else if (cur === 'interrupt') {
+                    showError('interrupt', file);
+                } else if (cur === 'queued') {
+                    percentages[file.id][1] = 0;
+                } else if (cur === 'progress') {
+                    $info.remove();
+                    // $prgress.css('display', 'block');
+                } else if (cur === 'complete') {
+                    if (showImg) {
+                        $li.append('<span class="success"><em></em><i class="ti-check"></i></span>');
+                    } else {
+                        $li.find('._success').show();
+                    }
+                }
+
+                $li.removeClass('state-' + prev).addClass('state-' + cur);
+            });
+
+            var $act = showImg ? $btns.find('a') : $btns;
+
+            $act.on('click', function () {
+                var index = $(this).data('file-act');
+
+                switch (index) {
+                    case 'cancel':
+                        uploader.removeFile(file);
+                        return;
+                    case 'deleteurl':
+                    case 'delete':
+                        if (opts.disableRemove) {
+                            return uploader.removeFile(file);
+                        }
+
+                        var post = opts.deleteData;
+
+                        post.key = file.serverId;
+                        if (!post.key) {
+                            return uploader.removeFile(file);
+                        }
+                        post._column = updateColumn;
+
+                        Dcat.loading();
+                        $.post(opts.deleteUrl, post, function (result) {
+                            Dcat.loading(false);
+                            if (result.status) {
+                                deleteInput(file.serverId);
+                                uploader.removeFile(file);
+                                return;
+                            }
+
+                            Dcat.error(result.message || 'Remove file failed.');
+                        });
+
+                        break;
+                    case 'preview':
+                        Dcat.helpers.previewImage($wrap.find('img').attr('src'), null, file.name);
+                        break;
+                }
+
+            });
+        }
+
+        // 图片宽高验证
+        function validateDimensions(file) {
+            // The image dimensions is invalid.
+            if (!showImg || !isImage(file) || !Dcat.helpers.len(opts.dimensions)) return true;
+            var dimensions = opts.dimensions,
+                width = file._info.width,
+                height = file._info.height,
+                isset = Dcat.helpers.isset;
+            if (
+                (isset(dimensions, 'width') && dimensions['width'] != width) ||
+                (isset(dimensions, 'min_width') && dimensions['min_width'] > width)||
+                (isset(dimensions, 'max_width') && dimensions['max_width'] < width) ||
+                (isset(dimensions, 'height') && dimensions['height'] != height) ||
+                (isset(dimensions, 'min_height') && dimensions['min_height'] > height) ||
+                (isset(dimensions, 'max_height') && dimensions['max_height'] < height) ||
+                (isset(dimensions, 'ratio') && dimensions['ratio'] != (width / height))
+            ) {
+                return false;
+            }
+
+            return true;
+        }
+
+        // 负责view的销毁
+        function removeUploadFile(file) {
+            var $li = getFileView(file.id);
+
+            delete percentages[file.id];
+            updateTotalProgress();
+            $li.off().find('.file-panel').off().end().remove();
+        }
+
+        function updateTotalProgress() {
+            var loaded = 0,
+                total = 0,
+                $bar = $progress.find('.progress-bar'),
+                percent;
+
+            $.each(percentages, function (k, v) {
+                total += v[0];
+                loaded += v[0] * v[1];
+            });
+
+            percent = total ? loaded / total : 0;
+            percent = Math.round(percent * 100) + '%';
+
+            $bar.text(percent);
+            $bar.css('width', percent);
+            updateStatusText();
+        }
+
+        function updateStatusText() {
+            var text = '', stats;
+
+            if (!uploader) {
+                return;
+            }
+
+            if (state === 'ready') {
+                stats = uploader.getStats();
+                if (fileCount) {
+                    text = __('selected_files', {num: fileCount, size: WebUploader.formatSize(fileSize)});
+                } else {
+                    showSuccess();
+                }
+            } else if (state === 'confirm') {
+                stats = uploader.getStats();
+                if (stats.uploadFailNum) {
+                    text = __('selected_has_failed', {success: stats.successNum, fail: stats.uploadFailNum});
+                }
+            } else {
+                showSuccess();
+            }
+
+            function showSuccess() {
+                stats = uploader.getStats();
+                if (stats.successNum) {
+                    text = __('selected_success', {num: fileCount, size: WebUploader.formatSize(fileSize), success: stats.successNum});
+                }
+
+                if (stats.uploadFailNum) {
+                    text += (text ? __('dot') : '') + __('failed_num', {fail: stats.uploadFailNum});
+                }
+            }
+
+            $info.html(text);
+        }
+
+        // 上传文件后修改字段值
+        function updateFileColumn() {
+            var values = getInput(),
+                num = uploader.getStats().successNum,
+                form = $.extend({}, opts.formData);
+
+            if (!num || !values || !opts.autoUpdateColumn) {
+                return;
+            }
+
+            form[updateColumn] = values.join(',');
+            delete form['upload_column'];
+
+            $.post(opts.server, form);
+        }
+
+        function setState(val, args) {
+            var stats;
+            args = args || {};
+
+            if (val === state) {
+                return;
+            }
+
+            if ($upload) {
+                $upload.removeClass('state-' + state);
+                $upload.addClass('state-' + val);
+            }
+            state = val;
+
+            switch (state) {
+                case 'pedding':
+                    if (opts.disabled) return;
+                    $placeHolder.removeClass('element-invisible');
+                    $queue.hide();
+                    $statusBar.addClass('element-invisible');
+                    if (showImg) {
+                        $wrap.removeAttr('style');
+                        $wrap.find('.queueList').removeAttr('style');
+                    }
+
+                    refreshButton();
+                    break;
+
+                case 'ready':
+                    $placeHolder.addClass('element-invisible');
+                    $selector.find(addFileButtonSelector).removeClass('element-invisible');
+                    $queue.show();
+                    if (!opts.disabled) {
+                        $statusBar.removeClass('element-invisible');
+                    }
+                    refreshButton();
+                    if (showImg) {
+                        $wrap.find('.queueList').css({'border': '1px solid #d3dde5', 'padding':'5px'});
+                        // $wrap.find('.queueList').removeAttr('style');
+                    }
+                    break;
+
+                case 'uploading':
+                    $selector.find(addFileButtonSelector).addClass('element-invisible');
+                    $progress.show();
+                    $upload.text(__('pause_upload'));
+                    break;
+
+                case 'paused':
+                    $progress.show();
+                    $upload.text(__('go_on_upload'));
+                    break;
+
+                case 'confirm':
+                    if (uploader) {
+                        $progress.hide();
+                        $selector.find(addFileButtonSelector).removeClass('element-invisible');
+                        $upload.text(__('start_upload'));
+
+                        stats = uploader.getStats();
+                        if (stats.successNum && !stats.uploadFailNum) {
+                            setState('finish');
+                            return;
+                        }
+                    }
+                    break;
+                case 'finish':
+                    if (uploader) {
+                        stats = uploader.getStats();
+                        if (stats.successNum) {
+                            Dcat.success(__('upload_success_message', {success: stats.successNum}));
+                        } else {
+                            // 没有成功的图片,重设
+                            state = 'done';
+                            location.reload();
+                        }
+                    }
+                    break;
+                case 'decrOriginalFileNum':
+                    if (originalFilesNum > 0) originalFilesNum --;
+                    break;
+
+                case 'incrOriginalFileNum':
+                    originalFilesNum ++;
+                    break;
+
+                case 'decrFileNumLimit': // 减少上传文件数量限制
+                    if (!uploader) {
+                        return;
+                    }
+                    var ofl = uploader.option('fileNumLimit'),
+                        num = args.num || 1;
+
+                    if (ofl == '-1') ofl = 0;
+
+                    num = ofl >= num ? ofl - num : 0;
+
+                    if (num == 0) num = '-1';
+
+                    uploader.option('fileNumLimit', num);
+
+                    break;
+                case 'incrFileNumLimit': // 增加上传文件数量限制
+                    if (!uploader) {
+                        return;
+                    }
+                    var ofl = uploader.option('fileNumLimit'),
+                        num = args.num || 1;
+
+                    if (ofl == '-1') ofl = 0;
+
+                    num = ofl + num;
+
+                    uploader.option('fileNumLimit', num);
+                    break;
+                case 'init': // 初始化
+                    $upload.addClass('state-' + state);
+                    updateTotalProgress();
+
+                    if (originalFilesNum || opts.disabled) {
+                        $placeHolder.addClass('element-invisible');
+                        if (!opts.disabled) {
+                            $statusBar.show();
+                        } else {
+                            $wrap.addClass('disabled');
+                        }
+                        setState('ready');
+                    } else if (showImg) {
+                        $wrap.removeAttr('style');
+                        $wrap.find('.queueList').css('margin', '0');
+                    }
+                    refreshButton();
+                    break;
+
+            }
+
+            updateStatusText();
+        }
+
+        // 移除form表单的文件
+        function removeFormFile(fileId) {
+            if (!fileId) return;
+
+            var file = formFiles[fileId];
+
+            deleteInput(fileId);
+            delete formFiles[fileId];
+            if (uploader && !file.fake) {
+                uploader.removeFile(file);
+            }
+
+            setState('decrOriginalFileNum');
+            setState('incrFileNumLimit');
+
+            if (!Dcat.helpers.len(formFiles) && !Dcat.helpers.len(percentages)) {
+                setState('pedding');
+            }
+        }
+
+        // 获取表单值
+        function getInput() {
+            var val = $input.val();
+
+            return val ? val.split(',') : [];
+        }
+
+        // 新增表单值
+        function addInput(id) {
+            var val = getInput();
+            val.push(id);
+            setInput(val);
+        }
+
+        // 设置表单值
+        function setInput(arr) {
+            arr = arr.filter(function(v, k, self) {
+                return self.indexOf(v) === k;
+            }).filter(function (v) {
+                return v ? true : false;
+            });
+
+            $input.val(arr.join(','));
+        }
+
+        // 删除表单值
+        function deleteInput(id) {
+            if (!id) {
+                return $input.val('');
+            }
+            setInput(getInput().filter(function (v) {
+                return v != id;
+            }));
+        }
+
+        // 重新计算按钮定位
+        function refreshButton() {
+            uploader.refresh();
+        }
+
+        // 添加上传成功文件到表单区域
+        function appendUploadedFileForm(file) {
+            var html = "";
+            html += "<li title='" + file.serverPath + "'>";
+
+            if (showImg) {
+                html += "<p class='imgWrap'>";
+                html += "	<img src='" + file.serverUrl + "'>";
+                html += "</p>";
+            } else if (!opts.disabled) {
+                html += '<p class="_act" data-file-act=\'delete\' data-id="' + file.serverId + '"><i class=\'ti-trash red-dark\'></i></p>';
+            }
+
+            html += "<p class='title' style=''><i class='ti-check green _success' style='font-weight:bold;font-size:17px;display:none'></i>";
+            html += file.serverPath;
+            html += "</p>";
+
+            if (showImg) {
+                html += "<p class='title' style='margin-bottom:12px;'>&nbsp;</p>";
+                html += "<div class='file-panel' >";
+
+                if (!opts.disabled) {
+                    html += "<a class='btn btn-xs btn-default' data-file-act='deleteurl' data-id='" + file.serverId + "'><i class='ti-trash red-dark' style='font-size:13px'></i></a>";
+                }
+                html += "<a class='btn btn-xs btn-default' data-file-act='preview' data-url='" + file.serverUrl + "' ><i class='glyphicon glyphicon-zoom-in'></i></a>";
+
+                html += "</div>";
+            }
+
+            html += "</li>";
+            html = $(html);
+
+            if (!showImg) {
+                html.find('.file-type').show();
+                html.find('.title').show();
+                $wrap.css('background', 'transparent');
+            }
+
+            var deleteFile = function () {
+                var fileId = $(this).data('id'), post = opts.deleteData;
+
+                if (opts.disableRemove) {
+                    html.remove();
+
+                    return removeFormFile(fileId);
+                }
+
+                post.key = fileId;
+                post._column = updateColumn;
+
+                Dcat.loading();
+                $.post(opts.deleteUrl, post, function (result) {
+                    Dcat.loading(false);
+                    if (result.status) {
+                        // 移除
+                        html.remove();
+
+                        removeFormFile(fileId);
+                        return;
+                    }
+
+                    Dcat.error(result.message || 'Remove file failed.')
+                });
+            };
+
+            // 删除按钮点击事件
+            html.find('[data-file-act="deleteurl"]').click(deleteFile);
+            html.find('[data-file-act="delete"]').click(deleteFile);
+
+
+            // 放大图片
+            html.find('[data-file-act="preview"]').click(function () {
+                var url = $(this).data('url');
+
+                Dcat.helpers.previewImage(url);
+            });
+
+            setState('incrOriginalFileNum');
+            setState('decrFileNumLimit');
+            formFiles[file.serverId] = file;
+
+            addInput(file.serverId);
+
+            $queue.append(html);
+
+            if (showImg) {
+                setTimeout(function () { html.css('margin', '7px');}, 80);
+            }
+        }
+
+        // 初始化web-uploader
+        function build() {
+            $wrap = $selector.find(opts.wrapper);
+
+            // 图片容器
+            $queue = $('<ul class="filelist"></ul>').appendTo($wrap.find('.queueList'));
+
+            // 状态栏,包括进度和控制按钮
+            $statusBar = $wrap.find('.statusBar');
+
+            // 文件总体选择信息。
+            $info = $statusBar.find('.info');
+
+            // 上传按钮
+            $upload = $wrap.find('.uploadBtn');
+
+            // 没选择文件之前的内容。
+            $placeHolder = $wrap.find('.placeholder');
+
+            $progress = $statusBar.find('.upload-progress').hide();
+
+            // IE;
+            supportIe();
+
+            // 实例化
+            uploader = WebUploader.create(opts.upload);
+
+            // 拖拽时不接受 js, txt 文件。
+            uploader.on('dndAccept', function (items) {
+                var denied = false,
+                    len = items.length,
+                    i = 0,
+                    // 修改js类型
+                    unAllowed = 'text/plain;application/javascript ';
+
+                for (; i < len; i++) {
+                    // 如果在列表里面
+                    if (~unAllowed.indexOf(items[i].type)) {
+                        denied = true;
+                        break;
+                    }
+                }
+
+                return !denied;
+            });
+
+            if (opts.upload.fileNumLimit > 1 && !opts.disabled) {
+                // 添加“添加文件”的按钮,
+                uploader.addButton({
+                    id: addFileButtonSelector,
+                    label: '<i class="glyphicon glyphicon-folder-open"></i> &nbsp;' + __('go_on_add')
+                });
+            }
+
+            uploader.onUploadProgress = function (file, percentage) {
+                percentages[file.id][1] = percentage;
+                updateTotalProgress();
+            };
+
+            uploader.onBeforeFileQueued = function (file) {
+
+            };
+
+            uploader.onFileQueued = function (file) {
+                fileCount++;
+                fileSize += file.size;
+
+                if (fileCount === 1) {
+                    $placeHolder.addClass('element-invisible');
+                    $statusBar.show();
+                }
+
+                addFile(file);
+                setState('ready');
+                updateTotalProgress();
+            };
+
+            // 删除文件事件监听
+            uploader.onFileDequeued = function (file) {
+                fileCount--;
+                fileSize -= file.size;
+
+                if (!fileCount && !Dcat.helpers.len(formFiles)) {
+                    setState('pedding');
+                }
+
+                removeUploadFile(file);
+            };
+
+            uploader.on('all', function (type, obj, reason) {
+                switch (type) {
+                    case 'uploadFinished':
+                        setState('confirm');
+                        updateFileColumn();
+                        break;
+
+                    case 'startUpload':
+                        setState('uploading');
+                        break;
+
+                    case 'stopUpload':
+                        setState('paused');
+                        break;
+                    case  'uploadAccept':
+                        // 上传失败,返回false
+                        if (reason && reason.error) {
+                            Dcat.error(reason.error.message);
+
+                            faildFiles[obj.file.id] = obj.file;
+
+                            return false;
+                        }
+
+                        if (reason.merge) {
+                            // 分片上传
+                            return;
+                        }
+
+                        // 上传成功,保存新文件名和路径到file对象
+                        obj.file.serverId   = reason.id;
+                        obj.file.serverName = reason.name;
+                        obj.file.serverPath = reason.path;
+                        obj.file.serverUrl  = reason.url || null;
+
+                        addInput(reason.id);
+
+                        if (!showImg) {
+                            var $li = getFileView(obj.file.id);
+                            $li.find('._act').hide();
+                            $li.find('[data-file-act="delete"]').show();
+                        }
+
+                        break;
+                }
+
+            });
+
+            uploader.onError = function (code) {
+                switch (code) {
+                    case 'Q_TYPE_DENIED':
+                        Dcat.error(__('Q_TYPE_DENIED'));
+                        break;
+                    case 'Q_EXCEED_NUM_LIMIT':
+                        Dcat.error(__('Q_EXCEED_NUM_LIMIT', {num: opts.upload.fileNumLimit}));
+                        break;
+                    case 'F_EXCEED_SIZE':
+                        Dcat.error(__('F_EXCEED_SIZE'));
+                        break;
+                    case 'Q_EXCEED_SIZE_LIMIT':
+                        Dcat.error(__('Q_EXCEED_SIZE_LIMIT'));
+                        break;
+                    case 'F_DUPLICATE':
+                        Dcat.warning(__('F_DUPLICATE'));
+                        break;
+                    default:
+                        Dcat.error('Error: ' + code);
+                }
+
+            };
+
+            $upload.on('click', function () {
+                if ($(this).hasClass('disabled')) {
+                    return false;
+                }
+
+                if (state === 'ready') {
+                    uploader.upload();
+                } else if (state === 'paused') {
+                    uploader.upload();
+                } else if (state === 'uploading') {
+                    uploader.stop();
+                }
+            });
+
+            $info.on('click', '.retry', function () {
+                uploader.retry();
+            });
+
+            $info.on('click', '.ignore', function () {
+                for (var i in faildFiles) {
+                    uploader.removeFile(i, true);
+                    delete faildFiles[i];
+                }
+
+            });
+
+            setState('init');
+        }
+
+        // 预览
+        function preview() {
+            for (var i in opts.preview) {
+                var path = opts.preview[i].path, ext;
+
+                if (path.indexOf('.')) {
+                    ext = path.split('.').pop();
+                }
+
+                appendUploadedFileForm({
+                    serverId: opts.preview[i].id,
+                    serverUrl: opts.preview[i].url,
+                    serverPath: path,
+                    ext: ext,
+                    fake: 1,
+                })
+            }
+        }
+
+        this.uploader = uploader;
+        this.options = opts;
+        this.build = build;
+        this.preview = preview;
+        this.setState = setState;
+        this.refreshButton = refreshButton;
+        this.getFileView = getFileView;
+        this.getFileViewSelector = getFileViewSelector;
+        this.addFileView = addFile;
+        this.removeUploadFileView = removeUploadFile;
+        this.isImage = isImage;
+        this.getColumn = function () {
+            return updateColumn;
+        };
+
+        function supportIe() {
+            if (!WebUploader.Uploader.support('flash') && WebUploader.browser.ie) {
+
+                // flash 安装了但是版本过低。
+                if (flashVersion) {
+                    (function (container) {
+                        window['expressinstallcallback'] = function (state) {
+                            switch (state) {
+                                case 'Download.Cancelled':
+                                    break;
+
+                                case 'Download.Failed':
+                                    Dcat.error('Install failed!');
+                                    break;
+
+                                default:
+                                    Dcat.success('Install Success!');
+                                    break;
+                            }
+                            delete window['expressinstallcallback'];
+                        };
+
+                        var swf = './expressInstall.swf';
+                        // insert flash object
+                        var html = '<object type="application/' +
+                            'x-shockwave-flash" data="' + swf + '" ';
+
+                        if (WebUploader.browser.ie) {
+                            html += 'classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" ';
+                        }
+
+                        html += 'width="100%" height="100%" style="outline:0">' +
+                            '<param name="movie" value="' + swf + '" />' +
+                            '<param name="wmode" value="transparent" />' +
+                            '<param name="allowscriptaccess" value="always" />' +
+                            '</object>';
+
+                        container.html(html);
+
+                    })($wrap);
+
+                    // 压根就没有安转。
+                } else {
+                    $wrap.html('<a href="http://www.adobe.com/go/getflashplayer" target="_blank" border="0"><img alt="get flash player" src="http://www.adobe.com/macromedia/style_guide/images/160x41_Get_Flash_Player.jpg" /></a>');
+                }
+
+                return;
+            } else if (!WebUploader.Uploader.support()) {
+                Dcat.error('Web Uploader 不支持您的浏览器!');
+                return;
+            }
+        }
+
+        return this;
+    }
+
+    Dcat.Uploader = Uploader;
+
+})(window, jQuery);

+ 17 - 1
resources/assets/dcat/js/Dcat.js

@@ -1,4 +1,7 @@
 
+import Helpers from './extensions/Helpers'
+import Translator from './extensions/Translator'
+
 let $ = jQuery,
     pjaxResponded = false,
     bootingCallbacks = [],
@@ -8,6 +11,12 @@ let $ = jQuery,
 
 export default class Dcat {
     constructor(config) {
+        this.token = null;
+        this.lang = null;
+
+        // 工具函数
+        new Helpers(this);
+
         this.withConfig(config);
     }
 
@@ -175,8 +184,15 @@ export default class Dcat {
     }
 
     withLang(lang) {
-        lang && (this.lang = lang);
+        if (lang && typeof lang === 'object') {
+            this.lang = this.Translator(lang);
+        }
 
         return this
     }
+
+    // 语言包
+    Translator(lang) {
+        return new Translator(this, lang);
+    }
 }

+ 3 - 6
resources/assets/dcat/js/dcat-app.js

@@ -11,7 +11,6 @@
 import Dcat from './Dcat'
 
 import NProgress from './nprogress/NProgress.min'
-import Helpers from './extensions/Helpers'
 import Ajax from './extensions/Ajax'
 import Toastr from './extensions/Toastr'
 import SweetAlert2 from './extensions/SweetAlert2'
@@ -20,10 +19,10 @@ import Grid from './extensions/Grid'
 import Form from './extensions/Form'
 import DialogForm from './extensions/DialogForm'
 import Loading from './extensions/Loading'
-import PreviewImage from './extensions/PreviewImage'
 import AssetsLoader from './extensions/AssetsLoader'
 import Slider from './extensions/Slider'
 import Color from './extensions/Color'
+import Validator from './extensions/Validator'
 
 import Menu from './bootstrappers/Menu'
 import Footer from './bootstrappers/Footer'
@@ -35,8 +34,6 @@ let win = window,
 
 // 扩展Dcat对象
 function extend (Dcat) {
-    // 工具函数
-    new Helpers(Dcat);
     // ajax处理相关扩展函数
     new Ajax(Dcat);
     // Toastr简化使用函数
@@ -47,12 +44,12 @@ function extend (Dcat) {
     new Grid(Dcat);
     // loading效果
     new Loading(Dcat);
-    // 图片预览功能
-    new PreviewImage(Dcat);
     // 静态资源加载器
     new AssetsLoader(Dcat);
     // 颜色管理
     new Color(Dcat);
+    // 表单验证器
+    new Validator(Dcat);
 
     // 加载进度条
     Dcat.NP = NProgress;

+ 54 - 0
resources/assets/dcat/js/extensions/Helpers.js

@@ -5,6 +5,8 @@ export default class Helpers {
     constructor(Dcat) {
         Dcat.helpers = this;
 
+        this.dcat = Dcat;
+
         // 延迟触发,消除重复触发
         this.debounce = debounce;
     }
@@ -190,4 +192,56 @@ export default class Helpers {
     random(len) {
         return Math.random().toString(12).substr(2, len || 16)
     }
+
+    // 预览图片
+    previewImage(src, width, title) {
+        let Dcat = this.dcat,
+            img = new Image(),
+            win = this.isset(window.top) ? top : window,
+            clientWidth = Math.ceil(win.screen.width * 0.6),
+            clientHeight = Math.ceil(win.screen.height * 0.8);
+
+        img.style.display = 'none';
+        img.style.height = 'auto';
+        img.style.width = width || '100%';
+        img.src = src;
+
+        document.body.appendChild(img);
+
+        Dcat.loading();
+        img.onload = function () {
+            Dcat.loading(false);
+            let srcw = this.width,
+                srch = this.height,
+                width = srcw > clientWidth ? clientWidth : srcw,
+                height = Math.ceil(width * (srch/srcw));
+
+            height = height > clientHeight ? clientHeight : height;
+
+            title = title || src.split('/').pop();
+
+            if (title.length > 50) {
+                title = title.substr(0, 50) + '...';
+            }
+
+            win.layer.open({
+                type: 1,
+                shade: 0.2,
+                title: false,
+                maxmin: false,
+                shadeClose: true,
+                closeBtn: 2,
+                content: $(img),
+                area: [width+'px', (height) + 'px'],
+                skin: 'layui-layer-nobg',
+                end: function () {
+                    document.body.removeChild(img);
+                }
+            });
+        };
+        img.onerror = function () {
+            Dcat.loading(false);
+            Dcat.warning('预览失败');
+        };
+    }
 }

+ 0 - 59
resources/assets/dcat/js/extensions/PreviewImage.js

@@ -1,59 +0,0 @@
-
-export default class PreviewImage {
-    constructor(Dcat) {
-        this.dcat = Dcat;
-
-        Dcat.previewImage = this.preview
-    }
-
-    preview(src, width, title) {
-        let Dcat = this.dcat,
-            img = new Image(),
-            win = Dcat.helpers.isset(window.top) ? top : window,
-            clientWidth = Math.ceil(win.screen.width * 0.6),
-            clientHeight = Math.ceil(win.screen.height * 0.8);
-
-        img.style.display = 'none';
-        img.style.height = 'auto';
-        img.style.width = width || '100%';
-        img.src = src;
-
-        document.body.appendChild(img);
-
-        Dcat.loading();
-        img.onload = function () {
-            Dcat.loading(false);
-            let srcw = this.width,
-                srch = this.height,
-                width = srcw > clientWidth ? clientWidth : srcw,
-                height = Math.ceil(width * (srch/srcw));
-
-            height = height > clientHeight ? clientHeight : height;
-
-            title = title || src.split('/').pop();
-
-            if (title.length > 50) {
-                title = title.substr(0, 50) + '...';
-            }
-
-            win.layer.open({
-                type: 1,
-                shade: 0.2,
-                title: false,
-                maxmin: false,
-                shadeClose: true,
-                closeBtn: 2,
-                content: $(img),
-                area: [width+'px', (height) + 'px'],
-                skin: 'layui-layer-nobg',
-                end: function () {
-                    document.body.removeChild(img);
-                }
-            });
-        };
-        img.onerror = function () {
-            Dcat.loading(false);
-            Dcat.warning('预览失败');
-        };
-    }
-}

+ 48 - 0
resources/assets/dcat/js/extensions/Translator.js

@@ -0,0 +1,48 @@
+
+export default class Translator{
+    constructor(Dcat, lang) {
+        this.dcat = Dcat;
+        this.lang = lang;
+
+        for (let i in lang) {
+            if (! Dcat.helpers.isset(this, i)) {
+                this[i] = lang[i];
+            }
+        }
+    }
+
+    /**
+     * 翻译
+     *
+     * @example
+     *      this.trans('name')
+     *      this.trans('selected_options', {':num': 18}) // :num options selected
+     *
+     * @param {string} label
+     * @param {object} replace
+     * @returns {*}
+     */
+    trans(label, replace) {
+        let _this = this,
+            helpers = _this.dcat.helpers;
+
+        if (typeof _this.lang !== 'object') {
+            return label;
+        }
+
+        var text = helpers.get(_this.lang, label), i;
+        if (! helpers.isset(text)) {
+            return label;
+        }
+
+        if (! replace) {
+            return text;
+        }
+
+        for (i in replace) {
+            text = helpers.replace(text, ':'+i, replace[i]);
+        }
+
+        return text;
+    }
+}

+ 14 - 0
resources/assets/dcat/js/extensions/Validator.js

@@ -0,0 +1,14 @@
+
+export default class Validator {
+    constructor(Dcat) {
+        Dcat.validator = this;
+    }
+
+    // 注册自定义验证器
+    extend(rule, callback, message) {
+        let DEFAULTS = $.fn.validator.Constructor.DEFAULTS;
+
+        DEFAULTS.custom[rule] = callback;
+        DEFAULTS.errors[rule] = message || null;
+    }
+}

+ 4 - 0
resources/assets/dcat/sass/components/_form.scss

@@ -1,3 +1,7 @@
+.form-control {
+  //padding: 0.55rem 0.7rem;
+}
+
 .form-control-sm {
   //height: calc(1em + 1rem + 2px);
   padding: 0.5rem 1.5rem;

+ 2 - 0
resources/assets/dcat/sass/dcat-app.scss

@@ -100,9 +100,11 @@ code {
   padding: 3px 5px;
   background: #f7f7f9;
   color: darken($primary, 8%);
+  font-family: Montserrat,Nunito,sans-serif;
 }
 pre {
   padding: 7px;
   white-space: pre-wrap;
   margin-bottom: 0;
+  font-family: Montserrat,Nunito,sans-serif;
 }

+ 36 - 36
resources/dist/css/plugins/loaders/animations/ball-grid-beat.css

@@ -27,66 +27,66 @@
 }
 
 .ball-grid-beat > div:nth-child(1) {
-  -webkit-animation-delay: 0.55s;
-          animation-delay: 0.55s;
-  -webkit-animation-duration: 1.47s;
-          animation-duration: 1.47s;
+  -webkit-animation-delay: 0.65s;
+          animation-delay: 0.65s;
+  -webkit-animation-duration: 0.67s;
+          animation-duration: 0.67s;
 }
 
 .ball-grid-beat > div:nth-child(2) {
-  -webkit-animation-delay: 0.39s;
-          animation-delay: 0.39s;
-  -webkit-animation-duration: 1.05s;
-          animation-duration: 1.05s;
+  -webkit-animation-delay: -0.14s;
+          animation-delay: -0.14s;
+  -webkit-animation-duration: 0.7s;
+          animation-duration: 0.7s;
 }
 
 .ball-grid-beat > div:nth-child(3) {
-  -webkit-animation-delay: 0.69s;
-          animation-delay: 0.69s;
-  -webkit-animation-duration: 0.99s;
-          animation-duration: 0.99s;
+  -webkit-animation-delay: 0.74s;
+          animation-delay: 0.74s;
+  -webkit-animation-duration: 0.97s;
+          animation-duration: 0.97s;
 }
 
 .ball-grid-beat > div:nth-child(4) {
-  -webkit-animation-delay: 0.74s;
-          animation-delay: 0.74s;
-  -webkit-animation-duration: 1.38s;
-          animation-duration: 1.38s;
+  -webkit-animation-delay: 0.25s;
+          animation-delay: 0.25s;
+  -webkit-animation-duration: 1.32s;
+          animation-duration: 1.32s;
 }
 
 .ball-grid-beat > div:nth-child(5) {
-  -webkit-animation-delay: 0.08s;
-          animation-delay: 0.08s;
-  -webkit-animation-duration: 1.3s;
-          animation-duration: 1.3s;
+  -webkit-animation-delay: 0.6s;
+          animation-delay: 0.6s;
+  -webkit-animation-duration: 0.96s;
+          animation-duration: 0.96s;
 }
 
 .ball-grid-beat > div:nth-child(6) {
-  -webkit-animation-delay: 0.77s;
-          animation-delay: 0.77s;
-  -webkit-animation-duration: 1.48s;
-          animation-duration: 1.48s;
+  -webkit-animation-delay: 0.41s;
+          animation-delay: 0.41s;
+  -webkit-animation-duration: 0.85s;
+          animation-duration: 0.85s;
 }
 
 .ball-grid-beat > div:nth-child(7) {
-  -webkit-animation-delay: 0.18s;
-          animation-delay: 0.18s;
-  -webkit-animation-duration: 0.66s;
-          animation-duration: 0.66s;
+  -webkit-animation-delay: 0.12s;
+          animation-delay: 0.12s;
+  -webkit-animation-duration: 1.44s;
+          animation-duration: 1.44s;
 }
 
 .ball-grid-beat > div:nth-child(8) {
-  -webkit-animation-delay: 0.76s;
-          animation-delay: 0.76s;
-  -webkit-animation-duration: 1.38s;
-          animation-duration: 1.38s;
+  -webkit-animation-delay: -0.17s;
+          animation-delay: -0.17s;
+  -webkit-animation-duration: 1.22s;
+          animation-duration: 1.22s;
 }
 
 .ball-grid-beat > div:nth-child(9) {
-  -webkit-animation-delay: -0.12s;
-          animation-delay: -0.12s;
-  -webkit-animation-duration: 1.47s;
-          animation-duration: 1.47s;
+  -webkit-animation-delay: -0.02s;
+          animation-delay: -0.02s;
+  -webkit-animation-duration: 0.83s;
+          animation-duration: 0.83s;
 }
 
 .ball-grid-beat > div {

+ 34 - 34
resources/dist/css/plugins/loaders/animations/ball-grid-pulse.css

@@ -39,66 +39,66 @@
 }
 
 .ball-grid-pulse > div:nth-child(1) {
-  -webkit-animation-delay: 0.12s;
-          animation-delay: 0.12s;
-  -webkit-animation-duration: 1.4s;
-          animation-duration: 1.4s;
+  -webkit-animation-delay: 0.73s;
+          animation-delay: 0.73s;
+  -webkit-animation-duration: 1.1s;
+          animation-duration: 1.1s;
 }
 
 .ball-grid-pulse > div:nth-child(2) {
-  -webkit-animation-delay: 0.37s;
-          animation-delay: 0.37s;
-  -webkit-animation-duration: 0.73s;
-          animation-duration: 0.73s;
+  -webkit-animation-delay: 0.49s;
+          animation-delay: 0.49s;
+  -webkit-animation-duration: 1.05s;
+          animation-duration: 1.05s;
 }
 
 .ball-grid-pulse > div:nth-child(3) {
-  -webkit-animation-delay: 0.76s;
-          animation-delay: 0.76s;
-  -webkit-animation-duration: 1.02s;
-          animation-duration: 1.02s;
+  -webkit-animation-delay: -0.15s;
+          animation-delay: -0.15s;
+  -webkit-animation-duration: 0.84s;
+          animation-duration: 0.84s;
 }
 
 .ball-grid-pulse > div:nth-child(4) {
   -webkit-animation-delay: 0.69s;
           animation-delay: 0.69s;
-  -webkit-animation-duration: 0.68s;
-          animation-duration: 0.68s;
+  -webkit-animation-duration: 1.08s;
+          animation-duration: 1.08s;
 }
 
 .ball-grid-pulse > div:nth-child(5) {
-  -webkit-animation-delay: 0.09s;
-          animation-delay: 0.09s;
-  -webkit-animation-duration: 0.67s;
-          animation-duration: 0.67s;
+  -webkit-animation-delay: 0.21s;
+          animation-delay: 0.21s;
+  -webkit-animation-duration: 0.71s;
+          animation-duration: 0.71s;
 }
 
 .ball-grid-pulse > div:nth-child(6) {
-  -webkit-animation-delay: 0.08s;
-          animation-delay: 0.08s;
-  -webkit-animation-duration: 1.44s;
-          animation-duration: 1.44s;
+  -webkit-animation-delay: 0.53s;
+          animation-delay: 0.53s;
+  -webkit-animation-duration: 1.35s;
+          animation-duration: 1.35s;
 }
 
 .ball-grid-pulse > div:nth-child(7) {
-  -webkit-animation-delay: 0.25s;
-          animation-delay: 0.25s;
-  -webkit-animation-duration: 0.71s;
-          animation-duration: 0.71s;
+  -webkit-animation-delay: -0.09s;
+          animation-delay: -0.09s;
+  -webkit-animation-duration: 1.5s;
+          animation-duration: 1.5s;
 }
 
 .ball-grid-pulse > div:nth-child(8) {
-  -webkit-animation-delay: -0.13s;
-          animation-delay: -0.13s;
-  -webkit-animation-duration: 0.69s;
-          animation-duration: 0.69s;
+  -webkit-animation-delay: 0.7s;
+          animation-delay: 0.7s;
+  -webkit-animation-duration: 0.63s;
+          animation-duration: 0.63s;
 }
 
 .ball-grid-pulse > div:nth-child(9) {
-  -webkit-animation-delay: 0.78s;
-          animation-delay: 0.78s;
-  -webkit-animation-duration: 0.78s;
-          animation-duration: 0.78s;
+  -webkit-animation-delay: 0.41s;
+          animation-delay: 0.41s;
+  -webkit-animation-duration: 1.25s;
+          animation-duration: 1.25s;
 }
 
 .ball-grid-pulse > div {

+ 16 - 16
resources/dist/css/plugins/loaders/animations/line-scale-random.css

@@ -31,31 +31,31 @@
 }
 
 .line-scale-party > div:nth-child(1) {
-  -webkit-animation-delay: 0.06s;
-          animation-delay: 0.06s;
-  -webkit-animation-duration: 1.13s;
-          animation-duration: 1.13s;
+  -webkit-animation-delay: 0.39s;
+          animation-delay: 0.39s;
+  -webkit-animation-duration: 1.17s;
+          animation-duration: 1.17s;
 }
 
 .line-scale-party > div:nth-child(2) {
-  -webkit-animation-delay: 0.79s;
-          animation-delay: 0.79s;
-  -webkit-animation-duration: 0.75s;
-          animation-duration: 0.75s;
+  -webkit-animation-delay: 0.5s;
+          animation-delay: 0.5s;
+  -webkit-animation-duration: 0.88s;
+          animation-duration: 0.88s;
 }
 
 .line-scale-party > div:nth-child(3) {
-  -webkit-animation-delay: 0.65s;
-          animation-delay: 0.65s;
-  -webkit-animation-duration: 1.09s;
-          animation-duration: 1.09s;
+  -webkit-animation-delay: 0.31s;
+          animation-delay: 0.31s;
+  -webkit-animation-duration: 1.15s;
+          animation-duration: 1.15s;
 }
 
 .line-scale-party > div:nth-child(4) {
-  -webkit-animation-delay: -0.1s;
-          animation-delay: -0.1s;
-  -webkit-animation-duration: 1.1s;
-          animation-duration: 1.1s;
+  -webkit-animation-delay: 0.2s;
+          animation-delay: 0.2s;
+  -webkit-animation-duration: 0.74s;
+          animation-duration: 0.74s;
 }
 
 .line-scale-party > div {

+ 88 - 88
resources/dist/css/plugins/loaders/loaders.css

@@ -1454,66 +1454,66 @@
 }
 
 .ball-grid-beat > div:nth-child(1) {
-  -webkit-animation-delay: 0.01s;
-          animation-delay: 0.01s;
-  -webkit-animation-duration: 1.33s;
-          animation-duration: 1.33s;
+  -webkit-animation-delay: 0.52s;
+          animation-delay: 0.52s;
+  -webkit-animation-duration: 0.95s;
+          animation-duration: 0.95s;
 }
 
 .ball-grid-beat > div:nth-child(2) {
-  -webkit-animation-delay: 0.09s;
-          animation-delay: 0.09s;
-  -webkit-animation-duration: 1.31s;
-          animation-duration: 1.31s;
+  -webkit-animation-delay: 0.39s;
+          animation-delay: 0.39s;
+  -webkit-animation-duration: 1.41s;
+          animation-duration: 1.41s;
 }
 
 .ball-grid-beat > div:nth-child(3) {
-  -webkit-animation-delay: 0.69s;
-          animation-delay: 0.69s;
-  -webkit-animation-duration: 0.8s;
-          animation-duration: 0.8s;
+  -webkit-animation-delay: 0.04s;
+          animation-delay: 0.04s;
+  -webkit-animation-duration: 1.08s;
+          animation-duration: 1.08s;
 }
 
 .ball-grid-beat > div:nth-child(4) {
-  -webkit-animation-delay: 0.15s;
-          animation-delay: 0.15s;
-  -webkit-animation-duration: 1.12s;
-          animation-duration: 1.12s;
+  -webkit-animation-delay: 0.61s;
+          animation-delay: 0.61s;
+  -webkit-animation-duration: 1.41s;
+          animation-duration: 1.41s;
 }
 
 .ball-grid-beat > div:nth-child(5) {
-  -webkit-animation-delay: -0.13s;
-          animation-delay: -0.13s;
-  -webkit-animation-duration: 1.39s;
-          animation-duration: 1.39s;
+  -webkit-animation-delay: 0.48s;
+          animation-delay: 0.48s;
+  -webkit-animation-duration: 0.72s;
+          animation-duration: 0.72s;
 }
 
 .ball-grid-beat > div:nth-child(6) {
-  -webkit-animation-delay: -0.14s;
-          animation-delay: -0.14s;
-  -webkit-animation-duration: 1.25s;
-          animation-duration: 1.25s;
+  -webkit-animation-delay: 0.59s;
+          animation-delay: 0.59s;
+  -webkit-animation-duration: 1.24s;
+          animation-duration: 1.24s;
 }
 
 .ball-grid-beat > div:nth-child(7) {
-  -webkit-animation-delay: -0.16s;
-          animation-delay: -0.16s;
-  -webkit-animation-duration: 1.17s;
-          animation-duration: 1.17s;
+  -webkit-animation-delay: 0.27s;
+          animation-delay: 0.27s;
+  -webkit-animation-duration: 0.87s;
+          animation-duration: 0.87s;
 }
 
 .ball-grid-beat > div:nth-child(8) {
-  -webkit-animation-delay: -0.05s;
-          animation-delay: -0.05s;
-  -webkit-animation-duration: 1.41s;
-          animation-duration: 1.41s;
+  -webkit-animation-delay: 0.46s;
+          animation-delay: 0.46s;
+  -webkit-animation-duration: 0.66s;
+          animation-duration: 0.66s;
 }
 
 .ball-grid-beat > div:nth-child(9) {
-  -webkit-animation-delay: -0.17s;
-          animation-delay: -0.17s;
-  -webkit-animation-duration: 1.46s;
-          animation-duration: 1.46s;
+  -webkit-animation-delay: 0.43s;
+          animation-delay: 0.43s;
+  -webkit-animation-duration: 0.78s;
+          animation-duration: 0.78s;
 }
 
 .ball-grid-beat > div {
@@ -1575,66 +1575,66 @@
 }
 
 .ball-grid-pulse > div:nth-child(1) {
-  -webkit-animation-delay: 0.45s;
-          animation-delay: 0.45s;
-  -webkit-animation-duration: 0.78s;
-          animation-duration: 0.78s;
+  -webkit-animation-delay: 0.32s;
+          animation-delay: 0.32s;
+  -webkit-animation-duration: 0.93s;
+          animation-duration: 0.93s;
 }
 
 .ball-grid-pulse > div:nth-child(2) {
-  -webkit-animation-delay: -0.16s;
-          animation-delay: -0.16s;
-  -webkit-animation-duration: 1.01s;
-          animation-duration: 1.01s;
+  -webkit-animation-delay: 0.42s;
+          animation-delay: 0.42s;
+  -webkit-animation-duration: 0.74s;
+          animation-duration: 0.74s;
 }
 
 .ball-grid-pulse > div:nth-child(3) {
-  -webkit-animation-delay: 0.21s;
-          animation-delay: 0.21s;
-  -webkit-animation-duration: 0.78s;
-          animation-duration: 0.78s;
+  -webkit-animation-delay: 0.06s;
+          animation-delay: 0.06s;
+  -webkit-animation-duration: 1.08s;
+          animation-duration: 1.08s;
 }
 
 .ball-grid-pulse > div:nth-child(4) {
-  -webkit-animation-delay: 0.71s;
-          animation-delay: 0.71s;
-  -webkit-animation-duration: 1.29s;
-          animation-duration: 1.29s;
+  -webkit-animation-delay: 0.38s;
+          animation-delay: 0.38s;
+  -webkit-animation-duration: 1.11s;
+          animation-duration: 1.11s;
 }
 
 .ball-grid-pulse > div:nth-child(5) {
-  -webkit-animation-delay: 0.77s;
-          animation-delay: 0.77s;
-  -webkit-animation-duration: 1.32s;
-          animation-duration: 1.32s;
+  -webkit-animation-delay: 0.52s;
+          animation-delay: 0.52s;
+  -webkit-animation-duration: 1.5s;
+          animation-duration: 1.5s;
 }
 
 .ball-grid-pulse > div:nth-child(6) {
-  -webkit-animation-delay: 0.02s;
-          animation-delay: 0.02s;
-  -webkit-animation-duration: 0.86s;
-          animation-duration: 0.86s;
+  -webkit-animation-delay: 0.07s;
+          animation-delay: 0.07s;
+  -webkit-animation-duration: 1.16s;
+          animation-duration: 1.16s;
 }
 
 .ball-grid-pulse > div:nth-child(7) {
-  -webkit-animation-delay: 0.69s;
-          animation-delay: 0.69s;
-  -webkit-animation-duration: 0.8s;
-          animation-duration: 0.8s;
+  -webkit-animation-delay: 0.18s;
+          animation-delay: 0.18s;
+  -webkit-animation-duration: 1.41s;
+          animation-duration: 1.41s;
 }
 
 .ball-grid-pulse > div:nth-child(8) {
-  -webkit-animation-delay: 0.09s;
-          animation-delay: 0.09s;
-  -webkit-animation-duration: 0.8s;
-          animation-duration: 0.8s;
+  -webkit-animation-delay: 0.71s;
+          animation-delay: 0.71s;
+  -webkit-animation-duration: 0.93s;
+          animation-duration: 0.93s;
 }
 
 .ball-grid-pulse > div:nth-child(9) {
-  -webkit-animation-delay: 0.41s;
-          animation-delay: 0.41s;
-  -webkit-animation-duration: 1.37s;
-          animation-duration: 1.37s;
+  -webkit-animation-delay: -0.05s;
+          animation-delay: -0.05s;
+  -webkit-animation-duration: 1.45s;
+          animation-duration: 1.45s;
 }
 
 .ball-grid-pulse > div {
@@ -2181,31 +2181,31 @@
 }
 
 .line-scale-party > div:nth-child(1) {
-  -webkit-animation-delay: -0.13s;
-          animation-delay: -0.13s;
-  -webkit-animation-duration: 1.07s;
-          animation-duration: 1.07s;
+  -webkit-animation-delay: 0.34s;
+          animation-delay: 0.34s;
+  -webkit-animation-duration: 1.29s;
+          animation-duration: 1.29s;
 }
 
 .line-scale-party > div:nth-child(2) {
-  -webkit-animation-delay: 0.44s;
-          animation-delay: 0.44s;
-  -webkit-animation-duration: 0.64s;
-          animation-duration: 0.64s;
+  -webkit-animation-delay: 0.65s;
+          animation-delay: 0.65s;
+  -webkit-animation-duration: 0.95s;
+          animation-duration: 0.95s;
 }
 
 .line-scale-party > div:nth-child(3) {
-  -webkit-animation-delay: -0.05s;
-          animation-delay: -0.05s;
-  -webkit-animation-duration: 0.6s;
-          animation-duration: 0.6s;
+  -webkit-animation-delay: 0.71s;
+          animation-delay: 0.71s;
+  -webkit-animation-duration: 0.78s;
+          animation-duration: 0.78s;
 }
 
 .line-scale-party > div:nth-child(4) {
-  -webkit-animation-delay: 0.65s;
-          animation-delay: 0.65s;
-  -webkit-animation-duration: 0.56s;
-          animation-duration: 0.56s;
+  -webkit-animation-delay: -0.01s;
+          animation-delay: -0.01s;
+  -webkit-animation-duration: 0.36s;
+          animation-duration: 0.36s;
 }
 
 .line-scale-party > div {

+ 2 - 0
resources/dist/dcat/css/dcat-app.css

@@ -2454,11 +2454,13 @@ code {
   padding: 3px 5px;
   background: #f7f7f9;
   color: #4152b9;
+  font-family: Montserrat, Nunito, sans-serif;
 }
 
 pre {
   padding: 7px;
   white-space: pre-wrap;
   margin-bottom: 0;
+  font-family: Montserrat, Nunito, sans-serif;
 }
 

+ 1 - 1
resources/dist/dcat/extra/grid-extend.js

@@ -419,7 +419,7 @@
 /*! no static exports found */
 /***/ (function(module, exports, __webpack_require__) {
 
-module.exports = __webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\dcat\extra\grid-extend.js */"./resources/assets/dcat/extra/grid-extend.js");
+module.exports = __webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\dcat\extra\grid-extend.js */"./resources/assets/dcat/extra/grid-extend.js");
 
 
 /***/ })

+ 1 - 1
resources/dist/dcat/extra/resource-selector.js

@@ -471,7 +471,7 @@ function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "functi
 /*! no static exports found */
 /***/ (function(module, exports, __webpack_require__) {
 
-module.exports = __webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\dcat\extra\resource-selector.js */"./resources/assets/dcat/extra/resource-selector.js");
+module.exports = __webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\dcat\extra\resource-selector.js */"./resources/assets/dcat/extra/resource-selector.js");
 
 
 /***/ })

+ 1096 - 0
resources/dist/dcat/extra/upload.js

@@ -0,0 +1,1096 @@
+/******/ (function(modules) { // webpackBootstrap
+/******/ 	// The module cache
+/******/ 	var installedModules = {};
+/******/
+/******/ 	// The require function
+/******/ 	function __webpack_require__(moduleId) {
+/******/
+/******/ 		// Check if module is in cache
+/******/ 		if(installedModules[moduleId]) {
+/******/ 			return installedModules[moduleId].exports;
+/******/ 		}
+/******/ 		// Create a new module (and put it into the cache)
+/******/ 		var module = installedModules[moduleId] = {
+/******/ 			i: moduleId,
+/******/ 			l: false,
+/******/ 			exports: {}
+/******/ 		};
+/******/
+/******/ 		// Execute the module function
+/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
+/******/
+/******/ 		// Flag the module as loaded
+/******/ 		module.l = true;
+/******/
+/******/ 		// Return the exports of the module
+/******/ 		return module.exports;
+/******/ 	}
+/******/
+/******/
+/******/ 	// expose the modules object (__webpack_modules__)
+/******/ 	__webpack_require__.m = modules;
+/******/
+/******/ 	// expose the module cache
+/******/ 	__webpack_require__.c = installedModules;
+/******/
+/******/ 	// define getter function for harmony exports
+/******/ 	__webpack_require__.d = function(exports, name, getter) {
+/******/ 		if(!__webpack_require__.o(exports, name)) {
+/******/ 			Object.defineProperty(exports, name, { enumerable: true, get: getter });
+/******/ 		}
+/******/ 	};
+/******/
+/******/ 	// define __esModule on exports
+/******/ 	__webpack_require__.r = function(exports) {
+/******/ 		if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
+/******/ 			Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
+/******/ 		}
+/******/ 		Object.defineProperty(exports, '__esModule', { value: true });
+/******/ 	};
+/******/
+/******/ 	// create a fake namespace object
+/******/ 	// mode & 1: value is a module id, require it
+/******/ 	// mode & 2: merge all properties of value into the ns
+/******/ 	// mode & 4: return value when already ns object
+/******/ 	// mode & 8|1: behave like require
+/******/ 	__webpack_require__.t = function(value, mode) {
+/******/ 		if(mode & 1) value = __webpack_require__(value);
+/******/ 		if(mode & 8) return value;
+/******/ 		if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
+/******/ 		var ns = Object.create(null);
+/******/ 		__webpack_require__.r(ns);
+/******/ 		Object.defineProperty(ns, 'default', { enumerable: true, value: value });
+/******/ 		if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
+/******/ 		return ns;
+/******/ 	};
+/******/
+/******/ 	// getDefaultExport function for compatibility with non-harmony modules
+/******/ 	__webpack_require__.n = function(module) {
+/******/ 		var getter = module && module.__esModule ?
+/******/ 			function getDefault() { return module['default']; } :
+/******/ 			function getModuleExports() { return module; };
+/******/ 		__webpack_require__.d(getter, 'a', getter);
+/******/ 		return getter;
+/******/ 	};
+/******/
+/******/ 	// Object.prototype.hasOwnProperty.call
+/******/ 	__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
+/******/
+/******/ 	// __webpack_public_path__
+/******/ 	__webpack_require__.p = "/";
+/******/
+/******/
+/******/ 	// Load entry module and return exports
+/******/ 	return __webpack_require__(__webpack_require__.s = 3);
+/******/ })
+/************************************************************************/
+/******/ ({
+
+/***/ "./resources/assets/dcat/extra/upload.js":
+/*!***********************************************!*\
+  !*** ./resources/assets/dcat/extra/upload.js ***!
+  \***********************************************/
+/*! no static exports found */
+/***/ (function(module, exports) {
+
+(function (w, $) {
+  function Uploader(opts) {
+    opts = $.extend({
+      wrapper: '.web-uploader',
+      // 图片显示容器选择器
+      addFileButton: '.add-file-button',
+      // 继续添加按钮选择器
+      isImage: false,
+      preview: [],
+      // 数据预览
+      deleteUrl: '',
+      deleteData: {},
+      thumbHeight: 160,
+      disabled: false,
+      // 禁止任何上传编辑
+      autoUpdateColumn: false,
+      disableRemove: false,
+      // 禁止删除图片,允许替换
+      dimensions: {// width: 100, // 图片宽限制
+        // height: 100, // 图片高限制
+        // min_width: 100, //
+        // min_height: 100,
+        // max_width: 100,
+        // max_height: 100,
+        // ratio: 3/2, // 宽高比
+      },
+      lang: {
+        exceed_size: '文件大小超出',
+        interrupt: '上传暂停',
+        upload_failed: '上传失败,请重试',
+        selected_files: '选中:num个文件,共:size。',
+        selected_has_failed: '已成功上传:success个文件,:fail个文件上传失败,<a class="retry"  href="javascript:"";">重新上传</a>失败文件或<a class="ignore" href="javascript:"";">忽略</a>',
+        selected_success: '共:num个(:size),已上传:success个。',
+        dot: ',',
+        failed_num: '失败:fail个。',
+        pause_upload: '暂停上传',
+        go_on_upload: '继续上传',
+        start_upload: '开始上传',
+        upload_success_message: '已成功上传:success个文件',
+        go_on_add: '继续添加',
+        Q_TYPE_DENIED: '对不起,不允许上传此类型文件',
+        Q_EXCEED_NUM_LIMIT: '对不起,已超出文件上传数量限制,最多只能上传:num个文件',
+        F_EXCEED_SIZE: '对不起,当前选择的文件过大',
+        Q_EXCEED_SIZE_LIMIT: '对不起,已超出文件大小限制',
+        F_DUPLICATE: '文件重复'
+      },
+      upload: {
+        // web-uploader配置
+        formData: {
+          _id: null // 唯一id
+
+        },
+        thumb: {
+          width: 160,
+          height: 160,
+          quality: 70,
+          allowMagnify: true,
+          crop: true,
+          preserveHeaders: false,
+          // 为空的话则保留原有图片格式。
+          // 否则强制转换成指定的类型。
+          // IE 8下面 base64 大小不能超过 32K 否则预览失败,而非 jpeg 编码的图片很可
+          // 能会超过 32k, 所以这里设置成预览的时候都是 image/jpeg
+          type: 'image/jpeg'
+        }
+      }
+    }, opts);
+    var $selector = $(opts.selector),
+        updateColumn = opts.upload.formData.upload_column || 'webup' + Math.floor(Math.random() * 10000),
+        elementName = opts.elementName;
+
+    if (typeof opts.upload.formData._id == "undefined" || !opts.upload.formData._id) {
+      opts.upload.formData._id = updateColumn + Math.floor(Math.random() * 10000);
+    }
+
+    var Dcat = w.Dcat,
+        $wrap,
+        // 展示图片
+    showImg = opts.isImage,
+        // 图片容器
+    $queue,
+        // 状态栏,包括进度和控制按钮
+    $statusBar,
+        // 文件总体选择信息。
+    $info,
+        // 上传按钮
+    $upload,
+        // 没选择文件之前的内容。
+    $placeHolder,
+        $progress,
+        // 已上传文件数量
+    originalFilesNum = Dcat.helpers.len(opts.preview),
+        // 上传表单
+    $input = $selector.find('input[name="' + elementName + '"]'),
+        // 获取文件视图选择器
+    getFileViewSelector = function getFileViewSelector(fileId) {
+      return elementName.replace(/[\[\]]*/g, '_') + '-' + fileId;
+    },
+        getFileView = function getFileView(fileId) {
+      return $('#' + getFileViewSelector(fileId));
+    },
+        // 继续添加按钮选择器
+    addFileButtonSelector = opts.addFileButton,
+        // 临时存储上传失败的文件,key为file id
+    faildFiles = {},
+        // 临时存储添加到form表单的文件
+    formFiles = {},
+        // 添加的文件数量
+    fileCount = 0,
+        // 添加的文件总大小
+    fileSize = 0,
+        // 可能有pedding, ready, uploading, confirm, done.
+    state = 'pedding',
+        // 所有文件的进度信息,key为file id
+    percentages = {},
+        // 判断浏览器是否支持图片的base64
+    isSupportBase64 = function () {
+      var data = new Image();
+      var support = true;
+
+      data.onload = data.onerror = function () {
+        if (this.width != 1 || this.height != 1) {
+          support = false;
+        }
+      };
+
+      data.src = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==";
+      return support;
+    }(),
+        // 检测是否已经安装flash,检测flash的版本
+    flashVersion = function () {
+      var version;
+
+      try {
+        version = navigator.plugins['Shockwave Flash'];
+        version = version.description;
+      } catch (ex) {
+        try {
+          version = new ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable('$version');
+        } catch (ex2) {
+          version = '0.0';
+        }
+      }
+
+      version = version.match(/\d+/g);
+      return parseFloat(version[0] + '.' + version[1], 10);
+    }(),
+        // 判断是否是图片
+    isImage = function isImage(file) {
+      return file.type.match(/^image/);
+    },
+        // 翻译
+    lang = Dcat.Translator(opts.lang),
+        __ = lang.trans.bind(lang),
+        // WebUploader实例
+    uploader; // 当有文件添加进来时执行,负责view的创建
+
+
+    function addFile(file) {
+      var size = WebUploader.formatSize(file.size),
+          $li,
+          $btns;
+
+      if (showImg) {
+        $li = $('<li id="' + getFileViewSelector(file.id) + '" title="' + file.name + '" style="margin:7px">' + '<p class="file-type">' + (file.ext.toUpperCase() || 'FILE') + '</p>' + '<p class="imgWrap "></p>' + '<p class="title" style="">' + file.name + '</p>' + '<p class="title" style=\'margin-bottom:12px;\'>(<b>' + size + '</b>)</p>' + '</li>');
+        $btns = $('<div class="file-panel">' + '<a class=\'btn btn-xs btn-default\' data-file-act="cancel"><i class="fa fa-close red-dark" style=\'font-size:13px\'></i></a>' + '<a class=\'btn btn-xs btn-default\' data-file-act="delete" style="display: none"><i class="ti-trash red-dark" style=\'font-size:13px\'></i></a>' + '<a class=\'btn btn-xs btn-default\' data-file-act="preview" ><i class="glyphicon glyphicon-zoom-in"></i></a>' + '</div>').appendTo($li);
+      } else {
+        $li = $('<li id="' + getFileViewSelector(file.id) + '" title="' + file.name + '">' + '<p class="title" style="display:block"><i class=\'ti-check green _success\' style=\'font-weight:bold;font-size:17px;display:none\'></i>' + file.name + ' (' + size + ')</p>' + '</li>');
+        $btns = $('<span data-file-act="cancel" class="_act" style="font-size:13px"><i class=\'ti-close red-dark\'></i></span>' + '<span data-file-act="delete" class="_act" style="display:none"><i class=\'ti-trash red-dark\'></i></span>').appendTo($li);
+      }
+
+      var $wrap = $li.find('p.imgWrap'),
+          $info = $('<p class="error"></p>'),
+          showError = function showError(code, file) {
+        var text = '';
+
+        switch (code) {
+          case 'exceed_size':
+            text = __('exceed_size');
+            break;
+
+          case 'interrupt':
+            text = __('interrupt');
+            break;
+
+          default:
+            text = __('upload_failed');
+            break;
+        }
+
+        faildFiles[file.id] = file;
+        $info.text(text).appendTo($li);
+      };
+
+      $li.appendTo($queue);
+
+      if (file.getStatus() === 'invalid') {
+        showError(file.statusText, file);
+      } else {
+        if (showImg) {
+          var image = uploader.makeThumb(file, function (error, src) {
+            var img;
+            $wrap.empty();
+
+            if (error) {
+              $li.find('.title').show();
+              $li.find('.file-type').show();
+              return;
+            }
+
+            if (isSupportBase64) {
+              img = $('<img src="' + src + '">');
+              $wrap.append(img);
+            } else {
+              $li.find('.file-type').show();
+            }
+          });
+
+          try {
+            image.once('load', function () {
+              file._info = file._info || image.info();
+              file._meta = file._meta || image.meta();
+              var width = file._info.width,
+                  height = file._info.height;
+
+              if (!validateDimensions(file)) {
+                Dcat.error('The image dimensions is invalid.');
+                uploader.removeFile(file);
+                return false;
+              }
+
+              image.resize(width, height);
+            });
+          } catch (e) {
+            // 不是图片
+            return setTimeout(function () {
+              uploader.removeFile(file);
+            }, 10);
+          }
+        }
+
+        percentages[file.id] = [file.size, 0];
+        file.rotation = 0;
+      }
+
+      file.on('statuschange', function (cur, prev) {
+        if (prev === 'progress') {// $prgress.hide().width(0);
+        } else if (prev === 'queued') {
+          $btns.find('[data-file-act="cancel"]').hide();
+          $btns.find('[data-file-act="delete"]').show();
+        } // 成功
+
+
+        if (cur === 'error' || cur === 'invalid') {
+          showError(file.statusText, file);
+          percentages[file.id][1] = 1;
+        } else if (cur === 'interrupt') {
+          showError('interrupt', file);
+        } else if (cur === 'queued') {
+          percentages[file.id][1] = 0;
+        } else if (cur === 'progress') {
+          $info.remove(); // $prgress.css('display', 'block');
+        } else if (cur === 'complete') {
+          if (showImg) {
+            $li.append('<span class="success"><em></em><i class="ti-check"></i></span>');
+          } else {
+            $li.find('._success').show();
+          }
+        }
+
+        $li.removeClass('state-' + prev).addClass('state-' + cur);
+      });
+      var $act = showImg ? $btns.find('a') : $btns;
+      $act.on('click', function () {
+        var index = $(this).data('file-act');
+
+        switch (index) {
+          case 'cancel':
+            uploader.removeFile(file);
+            return;
+
+          case 'deleteurl':
+          case 'delete':
+            if (opts.disableRemove) {
+              return uploader.removeFile(file);
+            }
+
+            var post = opts.deleteData;
+            post.key = file.serverId;
+
+            if (!post.key) {
+              return uploader.removeFile(file);
+            }
+
+            post._column = updateColumn;
+            Dcat.loading();
+            $.post(opts.deleteUrl, post, function (result) {
+              Dcat.loading(false);
+
+              if (result.status) {
+                deleteInput(file.serverId);
+                uploader.removeFile(file);
+                return;
+              }
+
+              Dcat.error(result.message || 'Remove file failed.');
+            });
+            break;
+
+          case 'preview':
+            Dcat.helpers.previewImage($wrap.find('img').attr('src'), null, file.name);
+            break;
+        }
+      });
+    } // 图片宽高验证
+
+
+    function validateDimensions(file) {
+      // The image dimensions is invalid.
+      if (!showImg || !isImage(file) || !Dcat.helpers.len(opts.dimensions)) return true;
+      var dimensions = opts.dimensions,
+          width = file._info.width,
+          height = file._info.height,
+          isset = Dcat.helpers.isset;
+
+      if (isset(dimensions, 'width') && dimensions['width'] != width || isset(dimensions, 'min_width') && dimensions['min_width'] > width || isset(dimensions, 'max_width') && dimensions['max_width'] < width || isset(dimensions, 'height') && dimensions['height'] != height || isset(dimensions, 'min_height') && dimensions['min_height'] > height || isset(dimensions, 'max_height') && dimensions['max_height'] < height || isset(dimensions, 'ratio') && dimensions['ratio'] != width / height) {
+        return false;
+      }
+
+      return true;
+    } // 负责view的销毁
+
+
+    function removeUploadFile(file) {
+      var $li = getFileView(file.id);
+      delete percentages[file.id];
+      updateTotalProgress();
+      $li.off().find('.file-panel').off().end().remove();
+    }
+
+    function updateTotalProgress() {
+      var loaded = 0,
+          total = 0,
+          $bar = $progress.find('.progress-bar'),
+          percent;
+      $.each(percentages, function (k, v) {
+        total += v[0];
+        loaded += v[0] * v[1];
+      });
+      percent = total ? loaded / total : 0;
+      percent = Math.round(percent * 100) + '%';
+      $bar.text(percent);
+      $bar.css('width', percent);
+      updateStatusText();
+    }
+
+    function updateStatusText() {
+      var text = '',
+          stats;
+
+      if (!uploader) {
+        return;
+      }
+
+      if (state === 'ready') {
+        stats = uploader.getStats();
+
+        if (fileCount) {
+          text = __('selected_files', {
+            num: fileCount,
+            size: WebUploader.formatSize(fileSize)
+          });
+        } else {
+          showSuccess();
+        }
+      } else if (state === 'confirm') {
+        stats = uploader.getStats();
+
+        if (stats.uploadFailNum) {
+          text = __('selected_has_failed', {
+            success: stats.successNum,
+            fail: stats.uploadFailNum
+          });
+        }
+      } else {
+        showSuccess();
+      }
+
+      function showSuccess() {
+        stats = uploader.getStats();
+
+        if (stats.successNum) {
+          text = __('selected_success', {
+            num: fileCount,
+            size: WebUploader.formatSize(fileSize),
+            success: stats.successNum
+          });
+        }
+
+        if (stats.uploadFailNum) {
+          text += (text ? __('dot') : '') + __('failed_num', {
+            fail: stats.uploadFailNum
+          });
+        }
+      }
+
+      $info.html(text);
+    } // 上传文件后修改字段值
+
+
+    function updateFileColumn() {
+      var values = getInput(),
+          num = uploader.getStats().successNum,
+          form = $.extend({}, opts.formData);
+
+      if (!num || !values || !opts.autoUpdateColumn) {
+        return;
+      }
+
+      form[updateColumn] = values.join(',');
+      delete form['upload_column'];
+      $.post(opts.server, form);
+    }
+
+    function setState(val, args) {
+      var stats;
+      args = args || {};
+
+      if (val === state) {
+        return;
+      }
+
+      if ($upload) {
+        $upload.removeClass('state-' + state);
+        $upload.addClass('state-' + val);
+      }
+
+      state = val;
+
+      switch (state) {
+        case 'pedding':
+          if (opts.disabled) return;
+          $placeHolder.removeClass('element-invisible');
+          $queue.hide();
+          $statusBar.addClass('element-invisible');
+
+          if (showImg) {
+            $wrap.removeAttr('style');
+            $wrap.find('.queueList').removeAttr('style');
+          }
+
+          refreshButton();
+          break;
+
+        case 'ready':
+          $placeHolder.addClass('element-invisible');
+          $selector.find(addFileButtonSelector).removeClass('element-invisible');
+          $queue.show();
+
+          if (!opts.disabled) {
+            $statusBar.removeClass('element-invisible');
+          }
+
+          refreshButton();
+
+          if (showImg) {
+            $wrap.find('.queueList').css({
+              'border': '1px solid #d3dde5',
+              'padding': '5px'
+            }); // $wrap.find('.queueList').removeAttr('style');
+          }
+
+          break;
+
+        case 'uploading':
+          $selector.find(addFileButtonSelector).addClass('element-invisible');
+          $progress.show();
+          $upload.text(__('pause_upload'));
+          break;
+
+        case 'paused':
+          $progress.show();
+          $upload.text(__('go_on_upload'));
+          break;
+
+        case 'confirm':
+          if (uploader) {
+            $progress.hide();
+            $selector.find(addFileButtonSelector).removeClass('element-invisible');
+            $upload.text(__('start_upload'));
+            stats = uploader.getStats();
+
+            if (stats.successNum && !stats.uploadFailNum) {
+              setState('finish');
+              return;
+            }
+          }
+
+          break;
+
+        case 'finish':
+          if (uploader) {
+            stats = uploader.getStats();
+
+            if (stats.successNum) {
+              Dcat.success(__('upload_success_message', {
+                success: stats.successNum
+              }));
+            } else {
+              // 没有成功的图片,重设
+              state = 'done';
+              location.reload();
+            }
+          }
+
+          break;
+
+        case 'decrOriginalFileNum':
+          if (originalFilesNum > 0) originalFilesNum--;
+          break;
+
+        case 'incrOriginalFileNum':
+          originalFilesNum++;
+          break;
+
+        case 'decrFileNumLimit':
+          // 减少上传文件数量限制
+          if (!uploader) {
+            return;
+          }
+
+          var ofl = uploader.option('fileNumLimit'),
+              num = args.num || 1;
+          if (ofl == '-1') ofl = 0;
+          num = ofl >= num ? ofl - num : 0;
+          if (num == 0) num = '-1';
+          uploader.option('fileNumLimit', num);
+          break;
+
+        case 'incrFileNumLimit':
+          // 增加上传文件数量限制
+          if (!uploader) {
+            return;
+          }
+
+          var ofl = uploader.option('fileNumLimit'),
+              num = args.num || 1;
+          if (ofl == '-1') ofl = 0;
+          num = ofl + num;
+          uploader.option('fileNumLimit', num);
+          break;
+
+        case 'init':
+          // 初始化
+          $upload.addClass('state-' + state);
+          updateTotalProgress();
+
+          if (originalFilesNum || opts.disabled) {
+            $placeHolder.addClass('element-invisible');
+
+            if (!opts.disabled) {
+              $statusBar.show();
+            } else {
+              $wrap.addClass('disabled');
+            }
+
+            setState('ready');
+          } else if (showImg) {
+            $wrap.removeAttr('style');
+            $wrap.find('.queueList').css('margin', '0');
+          }
+
+          refreshButton();
+          break;
+      }
+
+      updateStatusText();
+    } // 移除form表单的文件
+
+
+    function removeFormFile(fileId) {
+      if (!fileId) return;
+      var file = formFiles[fileId];
+      deleteInput(fileId);
+      delete formFiles[fileId];
+
+      if (uploader && !file.fake) {
+        uploader.removeFile(file);
+      }
+
+      setState('decrOriginalFileNum');
+      setState('incrFileNumLimit');
+
+      if (!Dcat.helpers.len(formFiles) && !Dcat.helpers.len(percentages)) {
+        setState('pedding');
+      }
+    } // 获取表单值
+
+
+    function getInput() {
+      var val = $input.val();
+      return val ? val.split(',') : [];
+    } // 新增表单值
+
+
+    function addInput(id) {
+      var val = getInput();
+      val.push(id);
+      setInput(val);
+    } // 设置表单值
+
+
+    function setInput(arr) {
+      arr = arr.filter(function (v, k, self) {
+        return self.indexOf(v) === k;
+      }).filter(function (v) {
+        return v ? true : false;
+      });
+      $input.val(arr.join(','));
+    } // 删除表单值
+
+
+    function deleteInput(id) {
+      if (!id) {
+        return $input.val('');
+      }
+
+      setInput(getInput().filter(function (v) {
+        return v != id;
+      }));
+    } // 重新计算按钮定位
+
+
+    function refreshButton() {
+      uploader.refresh();
+    } // 添加上传成功文件到表单区域
+
+
+    function appendUploadedFileForm(file) {
+      var html = "";
+      html += "<li title='" + file.serverPath + "'>";
+
+      if (showImg) {
+        html += "<p class='imgWrap'>";
+        html += "	<img src='" + file.serverUrl + "'>";
+        html += "</p>";
+      } else if (!opts.disabled) {
+        html += '<p class="_act" data-file-act=\'delete\' data-id="' + file.serverId + '"><i class=\'ti-trash red-dark\'></i></p>';
+      }
+
+      html += "<p class='title' style=''><i class='ti-check green _success' style='font-weight:bold;font-size:17px;display:none'></i>";
+      html += file.serverPath;
+      html += "</p>";
+
+      if (showImg) {
+        html += "<p class='title' style='margin-bottom:12px;'>&nbsp;</p>";
+        html += "<div class='file-panel' >";
+
+        if (!opts.disabled) {
+          html += "<a class='btn btn-xs btn-default' data-file-act='deleteurl' data-id='" + file.serverId + "'><i class='ti-trash red-dark' style='font-size:13px'></i></a>";
+        }
+
+        html += "<a class='btn btn-xs btn-default' data-file-act='preview' data-url='" + file.serverUrl + "' ><i class='glyphicon glyphicon-zoom-in'></i></a>";
+        html += "</div>";
+      }
+
+      html += "</li>";
+      html = $(html);
+
+      if (!showImg) {
+        html.find('.file-type').show();
+        html.find('.title').show();
+        $wrap.css('background', 'transparent');
+      }
+
+      var deleteFile = function deleteFile() {
+        var fileId = $(this).data('id'),
+            post = opts.deleteData;
+
+        if (opts.disableRemove) {
+          html.remove();
+          return removeFormFile(fileId);
+        }
+
+        post.key = fileId;
+        post._column = updateColumn;
+        Dcat.loading();
+        $.post(opts.deleteUrl, post, function (result) {
+          Dcat.loading(false);
+
+          if (result.status) {
+            // 移除
+            html.remove();
+            removeFormFile(fileId);
+            return;
+          }
+
+          Dcat.error(result.message || 'Remove file failed.');
+        });
+      }; // 删除按钮点击事件
+
+
+      html.find('[data-file-act="deleteurl"]').click(deleteFile);
+      html.find('[data-file-act="delete"]').click(deleteFile); // 放大图片
+
+      html.find('[data-file-act="preview"]').click(function () {
+        var url = $(this).data('url');
+        Dcat.helpers.previewImage(url);
+      });
+      setState('incrOriginalFileNum');
+      setState('decrFileNumLimit');
+      formFiles[file.serverId] = file;
+      addInput(file.serverId);
+      $queue.append(html);
+
+      if (showImg) {
+        setTimeout(function () {
+          html.css('margin', '7px');
+        }, 80);
+      }
+    } // 初始化web-uploader
+
+
+    function build() {
+      $wrap = $selector.find(opts.wrapper); // 图片容器
+
+      $queue = $('<ul class="filelist"></ul>').appendTo($wrap.find('.queueList')); // 状态栏,包括进度和控制按钮
+
+      $statusBar = $wrap.find('.statusBar'); // 文件总体选择信息。
+
+      $info = $statusBar.find('.info'); // 上传按钮
+
+      $upload = $wrap.find('.uploadBtn'); // 没选择文件之前的内容。
+
+      $placeHolder = $wrap.find('.placeholder');
+      $progress = $statusBar.find('.upload-progress').hide(); // IE;
+
+      supportIe(); // 实例化
+
+      uploader = WebUploader.create(opts.upload); // 拖拽时不接受 js, txt 文件。
+
+      uploader.on('dndAccept', function (items) {
+        var denied = false,
+            len = items.length,
+            i = 0,
+            // 修改js类型
+        unAllowed = 'text/plain;application/javascript ';
+
+        for (; i < len; i++) {
+          // 如果在列表里面
+          if (~unAllowed.indexOf(items[i].type)) {
+            denied = true;
+            break;
+          }
+        }
+
+        return !denied;
+      });
+
+      if (opts.upload.fileNumLimit > 1 && !opts.disabled) {
+        // 添加“添加文件”的按钮,
+        uploader.addButton({
+          id: addFileButtonSelector,
+          label: '<i class="glyphicon glyphicon-folder-open"></i> &nbsp;' + __('go_on_add')
+        });
+      }
+
+      uploader.onUploadProgress = function (file, percentage) {
+        percentages[file.id][1] = percentage;
+        updateTotalProgress();
+      };
+
+      uploader.onBeforeFileQueued = function (file) {};
+
+      uploader.onFileQueued = function (file) {
+        fileCount++;
+        fileSize += file.size;
+
+        if (fileCount === 1) {
+          $placeHolder.addClass('element-invisible');
+          $statusBar.show();
+        }
+
+        addFile(file);
+        setState('ready');
+        updateTotalProgress();
+      }; // 删除文件事件监听
+
+
+      uploader.onFileDequeued = function (file) {
+        fileCount--;
+        fileSize -= file.size;
+
+        if (!fileCount && !Dcat.helpers.len(formFiles)) {
+          setState('pedding');
+        }
+
+        removeUploadFile(file);
+      };
+
+      uploader.on('all', function (type, obj, reason) {
+        switch (type) {
+          case 'uploadFinished':
+            setState('confirm');
+            updateFileColumn();
+            break;
+
+          case 'startUpload':
+            setState('uploading');
+            break;
+
+          case 'stopUpload':
+            setState('paused');
+            break;
+
+          case 'uploadAccept':
+            // 上传失败,返回false
+            if (reason && reason.error) {
+              Dcat.error(reason.error.message);
+              faildFiles[obj.file.id] = obj.file;
+              return false;
+            }
+
+            if (reason.merge) {
+              // 分片上传
+              return;
+            } // 上传成功,保存新文件名和路径到file对象
+
+
+            obj.file.serverId = reason.id;
+            obj.file.serverName = reason.name;
+            obj.file.serverPath = reason.path;
+            obj.file.serverUrl = reason.url || null;
+            addInput(reason.id);
+
+            if (!showImg) {
+              var $li = getFileView(obj.file.id);
+              $li.find('._act').hide();
+              $li.find('[data-file-act="delete"]').show();
+            }
+
+            break;
+        }
+      });
+
+      uploader.onError = function (code) {
+        switch (code) {
+          case 'Q_TYPE_DENIED':
+            Dcat.error(__('Q_TYPE_DENIED'));
+            break;
+
+          case 'Q_EXCEED_NUM_LIMIT':
+            Dcat.error(__('Q_EXCEED_NUM_LIMIT', {
+              num: opts.upload.fileNumLimit
+            }));
+            break;
+
+          case 'F_EXCEED_SIZE':
+            Dcat.error(__('F_EXCEED_SIZE'));
+            break;
+
+          case 'Q_EXCEED_SIZE_LIMIT':
+            Dcat.error(__('Q_EXCEED_SIZE_LIMIT'));
+            break;
+
+          case 'F_DUPLICATE':
+            Dcat.warning(__('F_DUPLICATE'));
+            break;
+
+          default:
+            Dcat.error('Error: ' + code);
+        }
+      };
+
+      $upload.on('click', function () {
+        if ($(this).hasClass('disabled')) {
+          return false;
+        }
+
+        if (state === 'ready') {
+          uploader.upload();
+        } else if (state === 'paused') {
+          uploader.upload();
+        } else if (state === 'uploading') {
+          uploader.stop();
+        }
+      });
+      $info.on('click', '.retry', function () {
+        uploader.retry();
+      });
+      $info.on('click', '.ignore', function () {
+        for (var i in faildFiles) {
+          uploader.removeFile(i, true);
+          delete faildFiles[i];
+        }
+      });
+      setState('init');
+    } // 预览
+
+
+    function preview() {
+      for (var i in opts.preview) {
+        var path = opts.preview[i].path,
+            ext;
+
+        if (path.indexOf('.')) {
+          ext = path.split('.').pop();
+        }
+
+        appendUploadedFileForm({
+          serverId: opts.preview[i].id,
+          serverUrl: opts.preview[i].url,
+          serverPath: path,
+          ext: ext,
+          fake: 1
+        });
+      }
+    }
+
+    this.uploader = uploader;
+    this.options = opts;
+    this.build = build;
+    this.preview = preview;
+    this.setState = setState;
+    this.refreshButton = refreshButton;
+    this.getFileView = getFileView;
+    this.getFileViewSelector = getFileViewSelector;
+    this.addFileView = addFile;
+    this.removeUploadFileView = removeUploadFile;
+    this.isImage = isImage;
+
+    this.getColumn = function () {
+      return updateColumn;
+    };
+
+    function supportIe() {
+      if (!WebUploader.Uploader.support('flash') && WebUploader.browser.ie) {
+        // flash 安装了但是版本过低。
+        if (flashVersion) {
+          (function (container) {
+            window['expressinstallcallback'] = function (state) {
+              switch (state) {
+                case 'Download.Cancelled':
+                  break;
+
+                case 'Download.Failed':
+                  Dcat.error('Install failed!');
+                  break;
+
+                default:
+                  Dcat.success('Install Success!');
+                  break;
+              }
+
+              delete window['expressinstallcallback'];
+            };
+
+            var swf = './expressInstall.swf'; // insert flash object
+
+            var html = '<object type="application/' + 'x-shockwave-flash" data="' + swf + '" ';
+
+            if (WebUploader.browser.ie) {
+              html += 'classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" ';
+            }
+
+            html += 'width="100%" height="100%" style="outline:0">' + '<param name="movie" value="' + swf + '" />' + '<param name="wmode" value="transparent" />' + '<param name="allowscriptaccess" value="always" />' + '</object>';
+            container.html(html);
+          })($wrap); // 压根就没有安转。
+
+        } else {
+          $wrap.html('<a href="http://www.adobe.com/go/getflashplayer" target="_blank" border="0"><img alt="get flash player" src="http://www.adobe.com/macromedia/style_guide/images/160x41_Get_Flash_Player.jpg" /></a>');
+        }
+
+        return;
+      } else if (!WebUploader.Uploader.support()) {
+        Dcat.error('Web Uploader 不支持您的浏览器!');
+        return;
+      }
+    }
+
+    return this;
+  }
+
+  Dcat.Uploader = Uploader;
+})(window, jQuery);
+
+/***/ }),
+
+/***/ 3:
+/*!*****************************************************!*\
+  !*** multi ./resources/assets/dcat/extra/upload.js ***!
+  \*****************************************************/
+/*! no static exports found */
+/***/ (function(module, exports, __webpack_require__) {
+
+module.exports = __webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\dcat\extra\upload.js */"./resources/assets/dcat/extra/upload.js");
+
+
+/***/ })
+
+/******/ });

+ 407 - 303
resources/dist/dcat/js/dcat-app.js

@@ -107,12 +107,18 @@
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return Dcat; });
+/* harmony import */ var _extensions_Helpers__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./extensions/Helpers */ "./resources/assets/dcat/js/extensions/Helpers.js");
+/* harmony import */ var _extensions_Translator__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./extensions/Translator */ "./resources/assets/dcat/js/extensions/Translator.js");
+function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
+
 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
 
 function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
 
 function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
 
+
+
 var $ = jQuery,
     _pjaxResponded = false,
     bootingCallbacks = [],
@@ -124,14 +130,18 @@ var Dcat = /*#__PURE__*/function () {
   function Dcat(config) {
     _classCallCheck(this, Dcat);
 
+    this.token = null;
+    this.lang = null; // 工具函数
+
+    new _extensions_Helpers__WEBPACK_IMPORTED_MODULE_0__["default"](this);
     this.withConfig(config);
   }
-  /**
-   * 初始化事件监听方法
-   *
-   * @param callback
-   * @param once
-   * @returns {Dcat}
+  /**
+   * 初始化事件监听方法
+   *
+   * @param callback
+   * @param once
+   * @returns {Dcat}
    */
 
 
@@ -142,11 +152,11 @@ var Dcat = /*#__PURE__*/function () {
       bootingCallbacks.push([callback, once]);
       return this;
     }
-    /**
-     * 初始化事件监听方法,每个请求都会触发
-     *
-     * @param callback
-     * @returns {Dcat}
+    /**
+     * 初始化事件监听方法,每个请求都会触发
+     *
+     * @param callback
+     * @returns {Dcat}
      */
 
   }, {
@@ -154,8 +164,8 @@ var Dcat = /*#__PURE__*/function () {
     value: function bootingEveryRequest(callback) {
       return this.booting(callback, false);
     }
-    /**
-     * 初始化
+    /**
+     * 初始化
      */
 
   }, {
@@ -177,13 +187,13 @@ var Dcat = /*#__PURE__*/function () {
 
       _this.onPjaxLoaded(_this.boot.bind(this));
     }
-    /**
-     * 监听所有js脚本加载完毕事件,需要用此方法代替 $.ready 方法
-     * 此方法允许在iframe中监听父窗口的事件
-     *
-     * @param callback
-     * @param _window
-     * @returns {*|jQuery|*|jQuery.fn.init|jQuery|HTMLElement}
+    /**
+     * 监听所有js脚本加载完毕事件,需要用此方法代替 $.ready 方法
+     * 此方法允许在iframe中监听父窗口的事件
+     *
+     * @param callback
+     * @param _window
+     * @returns {*|jQuery|*|jQuery.fn.init|jQuery|HTMLElement}
      */
 
   }, {
@@ -207,8 +217,8 @@ var Dcat = /*#__PURE__*/function () {
 
       _window.Dcat.ready(proxy);
     }
-    /**
-     * 主动触发 ready 事件
+    /**
+     * 主动触发 ready 事件
      */
 
   }, {
@@ -222,10 +232,10 @@ var Dcat = /*#__PURE__*/function () {
         $(document).trigger('pjax:loaded');
       });
     }
-    /**
-     * 如果是 pjax 响应的页面,需要调用此方法
-     *
-     * @returns {Dcat}
+    /**
+     * 如果是 pjax 响应的页面,需要调用此方法
+     *
+     * @returns {Dcat}
      */
 
   }, {
@@ -234,10 +244,10 @@ var Dcat = /*#__PURE__*/function () {
       _pjaxResponded = true;
       return this;
     }
-    /**
-     * 使用pjax重载页面
-     *
-     * @param url
+    /**
+     * 使用pjax重载页面
+     *
+     * @param url
      */
 
   }, {
@@ -250,13 +260,13 @@ var Dcat = /*#__PURE__*/function () {
       url && (opt.url = url);
       $.pjax.reload(opt);
     }
-    /**
-     * 监听pjax加载js脚本完毕事件方法,此事件在 pjax:complete 事件之后触发
-     *
-     * @param callback
-     * @param once 默认true
-     *
-     * @returns {*|jQuery}
+    /**
+     * 监听pjax加载js脚本完毕事件方法,此事件在 pjax:complete 事件之后触发
+     *
+     * @param callback
+     * @param once 默认true
+     *
+     * @returns {*|jQuery}
      */
 
   }, {
@@ -270,12 +280,12 @@ var Dcat = /*#__PURE__*/function () {
 
       return $(document).on('pjax:loaded', callback);
     }
-    /**
-     * 监听pjax加载完毕完毕事件方法
-     *
-     * @param callback
-     * @param once 默认true
-     * @returns {*|jQuery}
+    /**
+     * 监听pjax加载完毕完毕事件方法
+     *
+     * @param callback
+     * @param once 默认true
+     * @returns {*|jQuery}
      */
 
   }, {
@@ -308,8 +318,17 @@ var Dcat = /*#__PURE__*/function () {
   }, {
     key: "withLang",
     value: function withLang(lang) {
-      lang && (this.lang = lang);
+      if (lang && _typeof(lang) === 'object') {
+        this.lang = this.Translator(lang);
+      }
+
       return this;
+    } // 语言包
+
+  }, {
+    key: "Translator",
+    value: function Translator(lang) {
+      return new _extensions_Translator__WEBPACK_IMPORTED_MODULE_1__["default"](this, lang);
     }
   }]);
 
@@ -623,30 +642,29 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony import */ var _Dcat__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Dcat */ "./resources/assets/dcat/js/Dcat.js");
 /* harmony import */ var _nprogress_NProgress_min__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./nprogress/NProgress.min */ "./resources/assets/dcat/js/nprogress/NProgress.min.js");
 /* harmony import */ var _nprogress_NProgress_min__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_nprogress_NProgress_min__WEBPACK_IMPORTED_MODULE_1__);
-/* harmony import */ var _extensions_Helpers__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./extensions/Helpers */ "./resources/assets/dcat/js/extensions/Helpers.js");
-/* harmony import */ var _extensions_Ajax__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./extensions/Ajax */ "./resources/assets/dcat/js/extensions/Ajax.js");
-/* harmony import */ var _extensions_Toastr__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./extensions/Toastr */ "./resources/assets/dcat/js/extensions/Toastr.js");
-/* harmony import */ var _extensions_SweetAlert2__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./extensions/SweetAlert2 */ "./resources/assets/dcat/js/extensions/SweetAlert2.js");
-/* harmony import */ var _extensions_RowSelector__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./extensions/RowSelector */ "./resources/assets/dcat/js/extensions/RowSelector.js");
-/* harmony import */ var _extensions_Grid__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./extensions/Grid */ "./resources/assets/dcat/js/extensions/Grid.js");
-/* harmony import */ var _extensions_Form__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./extensions/Form */ "./resources/assets/dcat/js/extensions/Form.js");
-/* harmony import */ var _extensions_DialogForm__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./extensions/DialogForm */ "./resources/assets/dcat/js/extensions/DialogForm.js");
-/* harmony import */ var _extensions_Loading__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./extensions/Loading */ "./resources/assets/dcat/js/extensions/Loading.js");
-/* harmony import */ var _extensions_PreviewImage__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./extensions/PreviewImage */ "./resources/assets/dcat/js/extensions/PreviewImage.js");
-/* harmony import */ var _extensions_AssetsLoader__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./extensions/AssetsLoader */ "./resources/assets/dcat/js/extensions/AssetsLoader.js");
-/* harmony import */ var _extensions_Slider__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./extensions/Slider */ "./resources/assets/dcat/js/extensions/Slider.js");
-/* harmony import */ var _extensions_Color__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./extensions/Color */ "./resources/assets/dcat/js/extensions/Color.js");
-/* harmony import */ var _bootstrappers_Menu__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./bootstrappers/Menu */ "./resources/assets/dcat/js/bootstrappers/Menu.js");
-/* harmony import */ var _bootstrappers_Footer__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./bootstrappers/Footer */ "./resources/assets/dcat/js/bootstrappers/Footer.js");
-/* harmony import */ var _bootstrappers_Pjax__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ./bootstrappers/Pjax */ "./resources/assets/dcat/js/bootstrappers/Pjax.js");
-/* harmony import */ var _bootstrappers_DataActions__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ./bootstrappers/DataActions */ "./resources/assets/dcat/js/bootstrappers/DataActions.js");
-/*=========================================================================================
-  File Name: app.js
-  Description: Dcat Admin JS脚本.
-  ----------------------------------------------------------------------------------------
-  Item Name: Dcat Admin
-  Author: Jqh
-  Author URL: https://github.com/jqhph
+/* harmony import */ var _extensions_Ajax__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./extensions/Ajax */ "./resources/assets/dcat/js/extensions/Ajax.js");
+/* harmony import */ var _extensions_Toastr__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./extensions/Toastr */ "./resources/assets/dcat/js/extensions/Toastr.js");
+/* harmony import */ var _extensions_SweetAlert2__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./extensions/SweetAlert2 */ "./resources/assets/dcat/js/extensions/SweetAlert2.js");
+/* harmony import */ var _extensions_RowSelector__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./extensions/RowSelector */ "./resources/assets/dcat/js/extensions/RowSelector.js");
+/* harmony import */ var _extensions_Grid__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./extensions/Grid */ "./resources/assets/dcat/js/extensions/Grid.js");
+/* harmony import */ var _extensions_Form__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./extensions/Form */ "./resources/assets/dcat/js/extensions/Form.js");
+/* harmony import */ var _extensions_DialogForm__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./extensions/DialogForm */ "./resources/assets/dcat/js/extensions/DialogForm.js");
+/* harmony import */ var _extensions_Loading__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./extensions/Loading */ "./resources/assets/dcat/js/extensions/Loading.js");
+/* harmony import */ var _extensions_AssetsLoader__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./extensions/AssetsLoader */ "./resources/assets/dcat/js/extensions/AssetsLoader.js");
+/* harmony import */ var _extensions_Slider__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./extensions/Slider */ "./resources/assets/dcat/js/extensions/Slider.js");
+/* harmony import */ var _extensions_Color__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./extensions/Color */ "./resources/assets/dcat/js/extensions/Color.js");
+/* harmony import */ var _extensions_Validator__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./extensions/Validator */ "./resources/assets/dcat/js/extensions/Validator.js");
+/* harmony import */ var _bootstrappers_Menu__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./bootstrappers/Menu */ "./resources/assets/dcat/js/bootstrappers/Menu.js");
+/* harmony import */ var _bootstrappers_Footer__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./bootstrappers/Footer */ "./resources/assets/dcat/js/bootstrappers/Footer.js");
+/* harmony import */ var _bootstrappers_Pjax__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./bootstrappers/Pjax */ "./resources/assets/dcat/js/bootstrappers/Pjax.js");
+/* harmony import */ var _bootstrappers_DataActions__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ./bootstrappers/DataActions */ "./resources/assets/dcat/js/bootstrappers/DataActions.js");
+/*=========================================================================================
+  File Name: app.js
+  Description: Dcat Admin JS脚本.
+  ----------------------------------------------------------------------------------------
+  Item Name: Dcat Admin
+  Author: Jqh
+  Author URL: https://github.com/jqhph
 ==========================================================================================*/
 
 
@@ -666,49 +684,46 @@ __webpack_require__.r(__webpack_exports__);
 
 
 
-
 var win = window,
     $ = jQuery; // 扩展Dcat对象
 
 function extend(Dcat) {
-  // 工具函数
-  new _extensions_Helpers__WEBPACK_IMPORTED_MODULE_2__["default"](Dcat); // ajax处理相关扩展函数
-
-  new _extensions_Ajax__WEBPACK_IMPORTED_MODULE_3__["default"](Dcat); // Toastr简化使用函数
+  // ajax处理相关扩展函数
+  new _extensions_Ajax__WEBPACK_IMPORTED_MODULE_2__["default"](Dcat); // Toastr简化使用函数
 
-  new _extensions_Toastr__WEBPACK_IMPORTED_MODULE_4__["default"](Dcat); // SweetAlert2简化使用函数
+  new _extensions_Toastr__WEBPACK_IMPORTED_MODULE_3__["default"](Dcat); // SweetAlert2简化使用函数
 
-  new _extensions_SweetAlert2__WEBPACK_IMPORTED_MODULE_5__["default"](Dcat); // Grid相关功能函数
+  new _extensions_SweetAlert2__WEBPACK_IMPORTED_MODULE_4__["default"](Dcat); // Grid相关功能函数
 
-  new _extensions_Grid__WEBPACK_IMPORTED_MODULE_7__["default"](Dcat); // loading效果
+  new _extensions_Grid__WEBPACK_IMPORTED_MODULE_6__["default"](Dcat); // loading效果
 
-  new _extensions_Loading__WEBPACK_IMPORTED_MODULE_10__["default"](Dcat); // 图片预览功能
+  new _extensions_Loading__WEBPACK_IMPORTED_MODULE_9__["default"](Dcat); // 静态资源加载器
 
-  new _extensions_PreviewImage__WEBPACK_IMPORTED_MODULE_11__["default"](Dcat); // 静态资源加载器
+  new _extensions_AssetsLoader__WEBPACK_IMPORTED_MODULE_10__["default"](Dcat); // 颜色管理
 
-  new _extensions_AssetsLoader__WEBPACK_IMPORTED_MODULE_12__["default"](Dcat); // 颜色管理
+  new _extensions_Color__WEBPACK_IMPORTED_MODULE_12__["default"](Dcat); // 表单验证器
 
-  new _extensions_Color__WEBPACK_IMPORTED_MODULE_14__["default"](Dcat); // 加载进度条
+  new _extensions_Validator__WEBPACK_IMPORTED_MODULE_13__["default"](Dcat); // 加载进度条
 
   Dcat.NP = _nprogress_NProgress_min__WEBPACK_IMPORTED_MODULE_1___default.a; // 行选择器
 
   Dcat.RowSelector = function (options) {
-    return new _extensions_RowSelector__WEBPACK_IMPORTED_MODULE_6__["default"](options);
+    return new _extensions_RowSelector__WEBPACK_IMPORTED_MODULE_5__["default"](options);
   }; // ajax表单提交
 
 
   Dcat.Form = function (options) {
-    return new _extensions_Form__WEBPACK_IMPORTED_MODULE_8__["default"](options);
+    return new _extensions_Form__WEBPACK_IMPORTED_MODULE_7__["default"](options);
   }; // 弹窗表单
 
 
   Dcat.DialogForm = function (options) {
-    return new _extensions_DialogForm__WEBPACK_IMPORTED_MODULE_9__["default"](Dcat, options);
+    return new _extensions_DialogForm__WEBPACK_IMPORTED_MODULE_8__["default"](Dcat, options);
   }; // 滑动面板
 
 
   Dcat.Slider = function (options) {
-    return new _extensions_Slider__WEBPACK_IMPORTED_MODULE_13__["default"](Dcat, options);
+    return new _extensions_Slider__WEBPACK_IMPORTED_MODULE_11__["default"](Dcat, options);
   };
 } // 初始化
 
@@ -734,16 +749,16 @@ function listen(Dcat) {
     }); //////////////////////////////////////////////////////////
     // 菜单点击选中效果
 
-    new _bootstrappers_Menu__WEBPACK_IMPORTED_MODULE_15__["default"](Dcat); // 返回顶部按钮
+    new _bootstrappers_Menu__WEBPACK_IMPORTED_MODULE_14__["default"](Dcat); // 返回顶部按钮
 
-    new _bootstrappers_Footer__WEBPACK_IMPORTED_MODULE_16__["default"](Dcat);
+    new _bootstrappers_Footer__WEBPACK_IMPORTED_MODULE_15__["default"](Dcat);
   }); // 每个请求都初始化
 
   Dcat.bootingEveryRequest(function () {
     // pjax初始化功能
-    new _bootstrappers_Pjax__WEBPACK_IMPORTED_MODULE_17__["default"](Dcat); // data-action 动作绑定(包括删除、批量删除等操作)
+    new _bootstrappers_Pjax__WEBPACK_IMPORTED_MODULE_16__["default"](Dcat); // data-action 动作绑定(包括删除、批量删除等操作)
 
-    new _bootstrappers_DataActions__WEBPACK_IMPORTED_MODULE_18__["default"](Dcat);
+    new _bootstrappers_DataActions__WEBPACK_IMPORTED_MODULE_17__["default"](Dcat);
   });
 } // 开始初始化
 
@@ -754,8 +769,8 @@ function boot(Dcat) {
   $(Dcat.boot.bind(Dcat));
   return Dcat;
 }
-/**
- * @returns {Dcat}
+/**
+ * @returns {Dcat}
  */
 
 
@@ -1916,15 +1931,16 @@ var Helpers = /*#__PURE__*/function () {
   function Helpers(Dcat) {
     _classCallCheck(this, Helpers);
 
-    Dcat.helpers = this; // 延迟触发,消除重复触发
+    Dcat.helpers = this;
+    this.dcat = Dcat; // 延迟触发,消除重复触发
 
     this.debounce = _Debounce__WEBPACK_IMPORTED_MODULE_0__["default"];
   }
-  /**
-   * 获取json对象或数组的长度
-   *
-   * @param obj
-   * @returns {number}
+  /**
+   * 获取json对象或数组的长度
+   *
+   * @param obj
+   * @returns {number}
    */
 
 
@@ -1944,12 +1960,12 @@ var Helpers = /*#__PURE__*/function () {
 
       return len;
     }
-    /**
-     * 判断变量或key是否存在
-     *
-     * @param _var
-     * @param key
-     * @returns {boolean}
+    /**
+     * 判断变量或key是否存在
+     *
+     * @param _var
+     * @param key
+     * @returns {boolean}
      */
 
   }, {
@@ -1971,13 +1987,13 @@ var Helpers = /*#__PURE__*/function () {
   }, {
     key: "get",
 
-    /**
-     * 根据key获取对象的值,支持获取多维数据
-     *
-     * @param arr
-     * @param key
-     * @param def
-     * @returns {null|*}
+    /**
+     * 根据key获取对象的值,支持获取多维数据
+     *
+     * @param arr
+     * @param key
+     * @param def
+     * @returns {null|*}
      */
     value: function get(arr, key, def) {
       def = null;
@@ -1998,12 +2014,12 @@ var Helpers = /*#__PURE__*/function () {
 
       return arr;
     }
-    /**
-     * 判断key是否存在
-     *
-     * @param arr
-     * @param key
-     * @returns {def|boolean}
+    /**
+     * 判断key是否存在
+     *
+     * @param arr
+     * @param key
+     * @returns {def|boolean}
      */
 
   }, {
@@ -2022,13 +2038,13 @@ var Helpers = /*#__PURE__*/function () {
 
       return true;
     }
-    /**
-     * 判断元素是否在对象中存在
-     *
-     * @param arr
-     * @param val
-     * @param strict
-     * @returns {boolean}
+    /**
+     * 判断元素是否在对象中存在
+     *
+     * @param arr
+     * @param val
+     * @param strict
+     * @returns {boolean}
      */
 
   }, {
@@ -2110,16 +2126,66 @@ var Helpers = /*#__PURE__*/function () {
 
       return str.replace(new RegExp(_replace, "g"), subject);
     }
-    /**
-     * 生成随机字符串
-     *
-     * @returns {string}
+    /**
+     * 生成随机字符串
+     *
+     * @returns {string}
      */
 
   }, {
     key: "random",
     value: function random(len) {
       return Math.random().toString(12).substr(2, len || 16);
+    } // 预览图片
+
+  }, {
+    key: "previewImage",
+    value: function previewImage(src, width, title) {
+      var Dcat = this.dcat,
+          img = new Image(),
+          win = this.isset(window.top) ? top : window,
+          clientWidth = Math.ceil(win.screen.width * 0.6),
+          clientHeight = Math.ceil(win.screen.height * 0.8);
+      img.style.display = 'none';
+      img.style.height = 'auto';
+      img.style.width = width || '100%';
+      img.src = src;
+      document.body.appendChild(img);
+      Dcat.loading();
+
+      img.onload = function () {
+        Dcat.loading(false);
+        var srcw = this.width,
+            srch = this.height,
+            width = srcw > clientWidth ? clientWidth : srcw,
+            height = Math.ceil(width * (srch / srcw));
+        height = height > clientHeight ? clientHeight : height;
+        title = title || src.split('/').pop();
+
+        if (title.length > 50) {
+          title = title.substr(0, 50) + '...';
+        }
+
+        win.layer.open({
+          type: 1,
+          shade: 0.2,
+          title: false,
+          maxmin: false,
+          shadeClose: true,
+          closeBtn: 2,
+          content: $(img),
+          area: [width + 'px', height + 'px'],
+          skin: 'layui-layer-nobg',
+          end: function end() {
+            document.body.removeChild(img);
+          }
+        });
+      };
+
+      img.onerror = function () {
+        Dcat.loading(false);
+        Dcat.warning('预览失败');
+      };
     }
   }]);
 
@@ -2242,88 +2308,6 @@ function extend(Dcat) {
 
 /* harmony default export */ __webpack_exports__["default"] = (extend);
 
-/***/ }),
-
-/***/ "./resources/assets/dcat/js/extensions/PreviewImage.js":
-/*!*************************************************************!*\
-  !*** ./resources/assets/dcat/js/extensions/PreviewImage.js ***!
-  \*************************************************************/
-/*! exports provided: default */
-/***/ (function(module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return PreviewImage; });
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
-
-function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
-
-var PreviewImage = /*#__PURE__*/function () {
-  function PreviewImage(Dcat) {
-    _classCallCheck(this, PreviewImage);
-
-    this.dcat = Dcat;
-    Dcat.previewImage = this.preview;
-  }
-
-  _createClass(PreviewImage, [{
-    key: "preview",
-    value: function preview(src, width, title) {
-      var Dcat = this.dcat,
-          img = new Image(),
-          win = Dcat.helpers.isset(window.top) ? top : window,
-          clientWidth = Math.ceil(win.screen.width * 0.6),
-          clientHeight = Math.ceil(win.screen.height * 0.8);
-      img.style.display = 'none';
-      img.style.height = 'auto';
-      img.style.width = width || '100%';
-      img.src = src;
-      document.body.appendChild(img);
-      Dcat.loading();
-
-      img.onload = function () {
-        Dcat.loading(false);
-        var srcw = this.width,
-            srch = this.height,
-            width = srcw > clientWidth ? clientWidth : srcw,
-            height = Math.ceil(width * (srch / srcw));
-        height = height > clientHeight ? clientHeight : height;
-        title = title || src.split('/').pop();
-
-        if (title.length > 50) {
-          title = title.substr(0, 50) + '...';
-        }
-
-        win.layer.open({
-          type: 1,
-          shade: 0.2,
-          title: false,
-          maxmin: false,
-          shadeClose: true,
-          closeBtn: 2,
-          content: $(img),
-          area: [width + 'px', height + 'px'],
-          skin: 'layui-layer-nobg',
-          end: function end() {
-            document.body.removeChild(img);
-          }
-        });
-      };
-
-      img.onerror = function () {
-        Dcat.loading(false);
-        Dcat.warning('预览失败');
-      };
-    }
-  }]);
-
-  return PreviewImage;
-}();
-
-
-
 /***/ }),
 
 /***/ "./resources/assets/dcat/js/extensions/RowSelector.js":
@@ -2694,6 +2678,126 @@ var Toastr = /*#__PURE__*/function () {
 
 
 
+/***/ }),
+
+/***/ "./resources/assets/dcat/js/extensions/Translator.js":
+/*!***********************************************************!*\
+  !*** ./resources/assets/dcat/js/extensions/Translator.js ***!
+  \***********************************************************/
+/*! exports provided: default */
+/***/ (function(module, __webpack_exports__, __webpack_require__) {
+
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return Translator; });
+function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
+
+function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
+
+var Translator = /*#__PURE__*/function () {
+  function Translator(Dcat, lang) {
+    _classCallCheck(this, Translator);
+
+    this.dcat = Dcat;
+    this.lang = lang;
+
+    for (var i in lang) {
+      if (!Dcat.helpers.isset(this, i)) {
+        this[i] = lang[i];
+      }
+    }
+  }
+  /**
+   * 翻译
+   *
+   * @example
+   *      this.trans('name')
+   *      this.trans('selected_options', {':num': 18}) // :num options selected
+   *
+   * @param {string} label
+   * @param {object} replace
+   * @returns {*}
+   */
+
+
+  _createClass(Translator, [{
+    key: "trans",
+    value: function trans(label, replace) {
+      var _this = this,
+          helpers = _this.dcat.helpers;
+
+      if (_typeof(_this.lang) !== 'object') {
+        return label;
+      }
+
+      var text = helpers.get(_this.lang, label),
+          i;
+
+      if (!helpers.isset(text)) {
+        return label;
+      }
+
+      if (!replace) {
+        return text;
+      }
+
+      for (i in replace) {
+        text = helpers.replace(text, ':' + i, replace[i]);
+      }
+
+      return text;
+    }
+  }]);
+
+  return Translator;
+}();
+
+
+
+/***/ }),
+
+/***/ "./resources/assets/dcat/js/extensions/Validator.js":
+/*!**********************************************************!*\
+  !*** ./resources/assets/dcat/js/extensions/Validator.js ***!
+  \**********************************************************/
+/*! exports provided: default */
+/***/ (function(module, __webpack_exports__, __webpack_require__) {
+
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return Validator; });
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
+
+function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
+
+var Validator = /*#__PURE__*/function () {
+  function Validator(Dcat) {
+    _classCallCheck(this, Validator);
+
+    Dcat.validator = this;
+  } // 注册自定义验证器
+
+
+  _createClass(Validator, [{
+    key: "extend",
+    value: function extend(rule, callback, message) {
+      var DEFAULTS = $.fn.validator.Constructor.DEFAULTS;
+      DEFAULTS.custom[rule] = callback;
+      DEFAULTS.errors[rule] = message || null;
+    }
+  }]);
+
+  return Validator;
+}();
+
+
+
 /***/ }),
 
 /***/ "./resources/assets/dcat/js/jquery-form/jquery.form.min.js":
@@ -2703,10 +2807,10 @@ var Toastr = /*#__PURE__*/function () {
 /*! no static exports found */
 /***/ (function(module, exports) {
 
-/*!
- * jQuery Form Plugin
- * version: 4.2.2
- * Project repository: https://github.com/jquery-form/form
+/*!
+ * jQuery Form Plugin
+ * version: 4.2.2
+ * Project repository: https://github.com/jquery-form/form
  */
 var module = {};
 eval(function (p, a, c, k, _e, r) {
@@ -3806,97 +3910,97 @@ eval(function (p, a, c, k, _e, r) {
 /*! no static exports found */
 /***/ (function(module, exports, __webpack_require__) {
 
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\dcat\js\dcat-app.js */"./resources/assets/dcat/js/dcat-app.js");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\plugins\animate\animate.scss */"./resources/assets/sass/plugins/animate/animate.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\plugins\calendars\fullcalendar.scss */"./resources/assets/sass/plugins/calendars/fullcalendar.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\plugins\extensions\context-menu.scss */"./resources/assets/sass/plugins/extensions/context-menu.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\plugins\extensions\drag-and-drop.scss */"./resources/assets/sass/plugins/extensions/drag-and-drop.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\plugins\extensions\media-plyr.scss */"./resources/assets/sass/plugins/extensions/media-plyr.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\plugins\extensions\noui-slider.scss */"./resources/assets/sass/plugins/extensions/noui-slider.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\plugins\extensions\swiper.scss */"./resources/assets/sass/plugins/extensions/swiper.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\plugins\extensions\toastr.scss */"./resources/assets/sass/plugins/extensions/toastr.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\plugins\file-uploaders\dropzone.scss */"./resources/assets/sass/plugins/file-uploaders/dropzone.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\plugins\forms\extended\typeahed.scss */"./resources/assets/sass/plugins/forms/extended/typeahed.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\plugins\forms\form-inputs-groups.scss */"./resources/assets/sass/plugins/forms/form-inputs-groups.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\plugins\forms\validation\form-validation.scss */"./resources/assets/sass/plugins/forms/validation/form-validation.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\plugins\forms\wizard.scss */"./resources/assets/sass/plugins/forms/wizard.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\plugins\loaders\animations\ball-beat.scss */"./resources/assets/sass/plugins/loaders/animations/ball-beat.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\plugins\loaders\animations\ball-clip-rotate-multiple.scss */"./resources/assets/sass/plugins/loaders/animations/ball-clip-rotate-multiple.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\plugins\loaders\animations\ball-clip-rotate-pulse.scss */"./resources/assets/sass/plugins/loaders/animations/ball-clip-rotate-pulse.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\plugins\loaders\animations\ball-clip-rotate.scss */"./resources/assets/sass/plugins/loaders/animations/ball-clip-rotate.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\plugins\loaders\animations\ball-grid-beat.scss */"./resources/assets/sass/plugins/loaders/animations/ball-grid-beat.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\plugins\loaders\animations\ball-grid-pulse.scss */"./resources/assets/sass/plugins/loaders/animations/ball-grid-pulse.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\plugins\loaders\animations\ball-pulse-rise.scss */"./resources/assets/sass/plugins/loaders/animations/ball-pulse-rise.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\plugins\loaders\animations\ball-pulse-round.scss */"./resources/assets/sass/plugins/loaders/animations/ball-pulse-round.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\plugins\loaders\animations\ball-pulse-sync.scss */"./resources/assets/sass/plugins/loaders/animations/ball-pulse-sync.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\plugins\loaders\animations\ball-pulse.scss */"./resources/assets/sass/plugins/loaders/animations/ball-pulse.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\plugins\loaders\animations\ball-rotate.scss */"./resources/assets/sass/plugins/loaders/animations/ball-rotate.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\plugins\loaders\animations\ball-scale-multiple.scss */"./resources/assets/sass/plugins/loaders/animations/ball-scale-multiple.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\plugins\loaders\animations\ball-scale-random.scss */"./resources/assets/sass/plugins/loaders/animations/ball-scale-random.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\plugins\loaders\animations\ball-scale-ripple-multiple.scss */"./resources/assets/sass/plugins/loaders/animations/ball-scale-ripple-multiple.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\plugins\loaders\animations\ball-scale-ripple.scss */"./resources/assets/sass/plugins/loaders/animations/ball-scale-ripple.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\plugins\loaders\animations\ball-scale.scss */"./resources/assets/sass/plugins/loaders/animations/ball-scale.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\plugins\loaders\animations\ball-spin-fade-loader.scss */"./resources/assets/sass/plugins/loaders/animations/ball-spin-fade-loader.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\plugins\loaders\animations\ball-spin-loader.scss */"./resources/assets/sass/plugins/loaders/animations/ball-spin-loader.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\plugins\loaders\animations\ball-triangle-trace.scss */"./resources/assets/sass/plugins/loaders/animations/ball-triangle-trace.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\plugins\loaders\animations\ball-zig-zag-deflect.scss */"./resources/assets/sass/plugins/loaders/animations/ball-zig-zag-deflect.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\plugins\loaders\animations\ball-zig-zag.scss */"./resources/assets/sass/plugins/loaders/animations/ball-zig-zag.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\plugins\loaders\animations\cube-transition.scss */"./resources/assets/sass/plugins/loaders/animations/cube-transition.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\plugins\loaders\animations\line-scale-pulse-out-rapid.scss */"./resources/assets/sass/plugins/loaders/animations/line-scale-pulse-out-rapid.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\plugins\loaders\animations\line-scale-pulse-out.scss */"./resources/assets/sass/plugins/loaders/animations/line-scale-pulse-out.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\plugins\loaders\animations\line-scale-random.scss */"./resources/assets/sass/plugins/loaders/animations/line-scale-random.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\plugins\loaders\animations\line-scale.scss */"./resources/assets/sass/plugins/loaders/animations/line-scale.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\plugins\loaders\animations\line-spin-fade-loader.scss */"./resources/assets/sass/plugins/loaders/animations/line-spin-fade-loader.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\plugins\loaders\animations\pacman.scss */"./resources/assets/sass/plugins/loaders/animations/pacman.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\plugins\loaders\animations\semi-circle-spin.scss */"./resources/assets/sass/plugins/loaders/animations/semi-circle-spin.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\plugins\loaders\animations\square-spin.scss */"./resources/assets/sass/plugins/loaders/animations/square-spin.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\plugins\loaders\animations\triangle-skew-spin.scss */"./resources/assets/sass/plugins/loaders/animations/triangle-skew-spin.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\plugins\loaders\loaders.scss */"./resources/assets/sass/plugins/loaders/loaders.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\plugins\pickers\bootstrap-datetimepicker-build.scss */"./resources/assets/sass/plugins/pickers/bootstrap-datetimepicker-build.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\plugins\tour\tour.scss */"./resources/assets/sass/plugins/tour/tour.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\plugins\ui\coming-soon.scss */"./resources/assets/sass/plugins/ui/coming-soon.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\themes\dark-layout.scss */"./resources/assets/sass/themes/dark-layout.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\themes\semi-dark-layout.scss */"./resources/assets/sass/themes/semi-dark-layout.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\pages\aggrid.scss */"./resources/assets/sass/pages/aggrid.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\pages\app-chat.scss */"./resources/assets/sass/pages/app-chat.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\pages\app-ecommerce-details.scss */"./resources/assets/sass/pages/app-ecommerce-details.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\pages\app-ecommerce-shop.scss */"./resources/assets/sass/pages/app-ecommerce-shop.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\pages\app-email.scss */"./resources/assets/sass/pages/app-email.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\pages\app-todo.scss */"./resources/assets/sass/pages/app-todo.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\pages\app-user.scss */"./resources/assets/sass/pages/app-user.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\pages\authentication.scss */"./resources/assets/sass/pages/authentication.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\pages\card-analytics.scss */"./resources/assets/sass/pages/card-analytics.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\pages\colors.scss */"./resources/assets/sass/pages/colors.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\pages\coming-soon.scss */"./resources/assets/sass/pages/coming-soon.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\pages\dashboard-analytics.scss */"./resources/assets/sass/pages/dashboard-analytics.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\pages\dashboard-ecommerce.scss */"./resources/assets/sass/pages/dashboard-ecommerce.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\pages\data-list-view.scss */"./resources/assets/sass/pages/data-list-view.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\pages\error.scss */"./resources/assets/sass/pages/error.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\pages\faq.scss */"./resources/assets/sass/pages/faq.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\pages\invoice.scss */"./resources/assets/sass/pages/invoice.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\pages\knowledge-base.scss */"./resources/assets/sass/pages/knowledge-base.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\pages\register.scss */"./resources/assets/sass/pages/register.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\pages\search.scss */"./resources/assets/sass/pages/search.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\pages\timeline.scss */"./resources/assets/sass/pages/timeline.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\pages\users.scss */"./resources/assets/sass/pages/users.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\core\colors\palette-gradient.scss */"./resources/assets/sass/core/colors/palette-gradient.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\core\colors\palette-noui.scss */"./resources/assets/sass/core/colors/palette-noui.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\core\colors\palette-variables.scss */"./resources/assets/sass/core/colors/palette-variables.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\core\menu\menu-types\horizontal-menu.scss */"./resources/assets/sass/core/menu/menu-types/horizontal-menu.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\core\menu\menu-types\vertical-menu.scss */"./resources/assets/sass/core/menu/menu-types/vertical-menu.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\core\menu\menu-types\vertical-overlay-menu.scss */"./resources/assets/sass/core/menu/menu-types/vertical-overlay-menu.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\core\mixins\alert.scss */"./resources/assets/sass/core/mixins/alert.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\core\mixins\hex2rgb.scss */"./resources/assets/sass/core/mixins/hex2rgb.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\core\mixins\main-menu-mixin.scss */"./resources/assets/sass/core/mixins/main-menu-mixin.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\core\mixins\transitions.scss */"./resources/assets/sass/core/mixins/transitions.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\dcat\sass\dcat-app.scss */"./resources/assets/dcat/sass/dcat-app.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\dcat\extra\markdown.scss */"./resources/assets/dcat/extra/markdown.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\bootstrap.scss */"./resources/assets/sass/bootstrap.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\bootstrap-extended.scss */"./resources/assets/sass/bootstrap-extended.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\colors.scss */"./resources/assets/sass/colors.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\components.scss */"./resources/assets/sass/components.scss");
-__webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\custom-rtl.scss */"./resources/assets/sass/custom-rtl.scss");
-module.exports = __webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\sass\custom-laravel.scss */"./resources/assets/sass/custom-laravel.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\dcat\js\dcat-app.js */"./resources/assets/dcat/js/dcat-app.js");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\plugins\animate\animate.scss */"./resources/assets/sass/plugins/animate/animate.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\plugins\calendars\fullcalendar.scss */"./resources/assets/sass/plugins/calendars/fullcalendar.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\plugins\extensions\context-menu.scss */"./resources/assets/sass/plugins/extensions/context-menu.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\plugins\extensions\drag-and-drop.scss */"./resources/assets/sass/plugins/extensions/drag-and-drop.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\plugins\extensions\media-plyr.scss */"./resources/assets/sass/plugins/extensions/media-plyr.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\plugins\extensions\noui-slider.scss */"./resources/assets/sass/plugins/extensions/noui-slider.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\plugins\extensions\swiper.scss */"./resources/assets/sass/plugins/extensions/swiper.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\plugins\extensions\toastr.scss */"./resources/assets/sass/plugins/extensions/toastr.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\plugins\file-uploaders\dropzone.scss */"./resources/assets/sass/plugins/file-uploaders/dropzone.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\plugins\forms\extended\typeahed.scss */"./resources/assets/sass/plugins/forms/extended/typeahed.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\plugins\forms\form-inputs-groups.scss */"./resources/assets/sass/plugins/forms/form-inputs-groups.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\plugins\forms\validation\form-validation.scss */"./resources/assets/sass/plugins/forms/validation/form-validation.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\plugins\forms\wizard.scss */"./resources/assets/sass/plugins/forms/wizard.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\plugins\loaders\animations\ball-beat.scss */"./resources/assets/sass/plugins/loaders/animations/ball-beat.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\plugins\loaders\animations\ball-clip-rotate-multiple.scss */"./resources/assets/sass/plugins/loaders/animations/ball-clip-rotate-multiple.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\plugins\loaders\animations\ball-clip-rotate-pulse.scss */"./resources/assets/sass/plugins/loaders/animations/ball-clip-rotate-pulse.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\plugins\loaders\animations\ball-clip-rotate.scss */"./resources/assets/sass/plugins/loaders/animations/ball-clip-rotate.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\plugins\loaders\animations\ball-grid-beat.scss */"./resources/assets/sass/plugins/loaders/animations/ball-grid-beat.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\plugins\loaders\animations\ball-grid-pulse.scss */"./resources/assets/sass/plugins/loaders/animations/ball-grid-pulse.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\plugins\loaders\animations\ball-pulse-rise.scss */"./resources/assets/sass/plugins/loaders/animations/ball-pulse-rise.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\plugins\loaders\animations\ball-pulse-round.scss */"./resources/assets/sass/plugins/loaders/animations/ball-pulse-round.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\plugins\loaders\animations\ball-pulse-sync.scss */"./resources/assets/sass/plugins/loaders/animations/ball-pulse-sync.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\plugins\loaders\animations\ball-pulse.scss */"./resources/assets/sass/plugins/loaders/animations/ball-pulse.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\plugins\loaders\animations\ball-rotate.scss */"./resources/assets/sass/plugins/loaders/animations/ball-rotate.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\plugins\loaders\animations\ball-scale-multiple.scss */"./resources/assets/sass/plugins/loaders/animations/ball-scale-multiple.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\plugins\loaders\animations\ball-scale-random.scss */"./resources/assets/sass/plugins/loaders/animations/ball-scale-random.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\plugins\loaders\animations\ball-scale-ripple-multiple.scss */"./resources/assets/sass/plugins/loaders/animations/ball-scale-ripple-multiple.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\plugins\loaders\animations\ball-scale-ripple.scss */"./resources/assets/sass/plugins/loaders/animations/ball-scale-ripple.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\plugins\loaders\animations\ball-scale.scss */"./resources/assets/sass/plugins/loaders/animations/ball-scale.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\plugins\loaders\animations\ball-spin-fade-loader.scss */"./resources/assets/sass/plugins/loaders/animations/ball-spin-fade-loader.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\plugins\loaders\animations\ball-spin-loader.scss */"./resources/assets/sass/plugins/loaders/animations/ball-spin-loader.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\plugins\loaders\animations\ball-triangle-trace.scss */"./resources/assets/sass/plugins/loaders/animations/ball-triangle-trace.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\plugins\loaders\animations\ball-zig-zag-deflect.scss */"./resources/assets/sass/plugins/loaders/animations/ball-zig-zag-deflect.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\plugins\loaders\animations\ball-zig-zag.scss */"./resources/assets/sass/plugins/loaders/animations/ball-zig-zag.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\plugins\loaders\animations\cube-transition.scss */"./resources/assets/sass/plugins/loaders/animations/cube-transition.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\plugins\loaders\animations\line-scale-pulse-out-rapid.scss */"./resources/assets/sass/plugins/loaders/animations/line-scale-pulse-out-rapid.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\plugins\loaders\animations\line-scale-pulse-out.scss */"./resources/assets/sass/plugins/loaders/animations/line-scale-pulse-out.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\plugins\loaders\animations\line-scale-random.scss */"./resources/assets/sass/plugins/loaders/animations/line-scale-random.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\plugins\loaders\animations\line-scale.scss */"./resources/assets/sass/plugins/loaders/animations/line-scale.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\plugins\loaders\animations\line-spin-fade-loader.scss */"./resources/assets/sass/plugins/loaders/animations/line-spin-fade-loader.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\plugins\loaders\animations\pacman.scss */"./resources/assets/sass/plugins/loaders/animations/pacman.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\plugins\loaders\animations\semi-circle-spin.scss */"./resources/assets/sass/plugins/loaders/animations/semi-circle-spin.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\plugins\loaders\animations\square-spin.scss */"./resources/assets/sass/plugins/loaders/animations/square-spin.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\plugins\loaders\animations\triangle-skew-spin.scss */"./resources/assets/sass/plugins/loaders/animations/triangle-skew-spin.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\plugins\loaders\loaders.scss */"./resources/assets/sass/plugins/loaders/loaders.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\plugins\pickers\bootstrap-datetimepicker-build.scss */"./resources/assets/sass/plugins/pickers/bootstrap-datetimepicker-build.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\plugins\tour\tour.scss */"./resources/assets/sass/plugins/tour/tour.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\plugins\ui\coming-soon.scss */"./resources/assets/sass/plugins/ui/coming-soon.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\themes\dark-layout.scss */"./resources/assets/sass/themes/dark-layout.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\themes\semi-dark-layout.scss */"./resources/assets/sass/themes/semi-dark-layout.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\pages\aggrid.scss */"./resources/assets/sass/pages/aggrid.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\pages\app-chat.scss */"./resources/assets/sass/pages/app-chat.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\pages\app-ecommerce-details.scss */"./resources/assets/sass/pages/app-ecommerce-details.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\pages\app-ecommerce-shop.scss */"./resources/assets/sass/pages/app-ecommerce-shop.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\pages\app-email.scss */"./resources/assets/sass/pages/app-email.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\pages\app-todo.scss */"./resources/assets/sass/pages/app-todo.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\pages\app-user.scss */"./resources/assets/sass/pages/app-user.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\pages\authentication.scss */"./resources/assets/sass/pages/authentication.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\pages\card-analytics.scss */"./resources/assets/sass/pages/card-analytics.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\pages\colors.scss */"./resources/assets/sass/pages/colors.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\pages\coming-soon.scss */"./resources/assets/sass/pages/coming-soon.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\pages\dashboard-analytics.scss */"./resources/assets/sass/pages/dashboard-analytics.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\pages\dashboard-ecommerce.scss */"./resources/assets/sass/pages/dashboard-ecommerce.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\pages\data-list-view.scss */"./resources/assets/sass/pages/data-list-view.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\pages\error.scss */"./resources/assets/sass/pages/error.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\pages\faq.scss */"./resources/assets/sass/pages/faq.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\pages\invoice.scss */"./resources/assets/sass/pages/invoice.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\pages\knowledge-base.scss */"./resources/assets/sass/pages/knowledge-base.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\pages\register.scss */"./resources/assets/sass/pages/register.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\pages\search.scss */"./resources/assets/sass/pages/search.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\pages\timeline.scss */"./resources/assets/sass/pages/timeline.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\pages\users.scss */"./resources/assets/sass/pages/users.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\core\colors\palette-gradient.scss */"./resources/assets/sass/core/colors/palette-gradient.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\core\colors\palette-noui.scss */"./resources/assets/sass/core/colors/palette-noui.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\core\colors\palette-variables.scss */"./resources/assets/sass/core/colors/palette-variables.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\core\menu\menu-types\horizontal-menu.scss */"./resources/assets/sass/core/menu/menu-types/horizontal-menu.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\core\menu\menu-types\vertical-menu.scss */"./resources/assets/sass/core/menu/menu-types/vertical-menu.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\core\menu\menu-types\vertical-overlay-menu.scss */"./resources/assets/sass/core/menu/menu-types/vertical-overlay-menu.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\core\mixins\alert.scss */"./resources/assets/sass/core/mixins/alert.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\core\mixins\hex2rgb.scss */"./resources/assets/sass/core/mixins/hex2rgb.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\core\mixins\main-menu-mixin.scss */"./resources/assets/sass/core/mixins/main-menu-mixin.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\core\mixins\transitions.scss */"./resources/assets/sass/core/mixins/transitions.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\dcat\sass\dcat-app.scss */"./resources/assets/dcat/sass/dcat-app.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\dcat\extra\markdown.scss */"./resources/assets/dcat/extra/markdown.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\bootstrap.scss */"./resources/assets/sass/bootstrap.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\bootstrap-extended.scss */"./resources/assets/sass/bootstrap-extended.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\colors.scss */"./resources/assets/sass/colors.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\components.scss */"./resources/assets/sass/components.scss");
+__webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\custom-rtl.scss */"./resources/assets/sass/custom-rtl.scss");
+module.exports = __webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\sass\custom-laravel.scss */"./resources/assets/sass/custom-laravel.scss");
 
 
 /***/ })

+ 3 - 3
resources/dist/js/core/app-menu.js

@@ -81,7 +81,7 @@
 /******/
 /******/
 /******/ 	// Load entry module and return exports
-/******/ 	return __webpack_require__(__webpack_require__.s = 3);
+/******/ 	return __webpack_require__(__webpack_require__.s = 4);
 /******/ })
 /************************************************************************/
 /******/ ({
@@ -1013,14 +1013,14 @@ window.addEventListener('resize', function () {
 
 /***/ }),
 
-/***/ 3:
+/***/ 4:
 /*!****************************************************!*\
   !*** multi ./resources/assets/js/core/app-menu.js ***!
   \****************************************************/
 /*! no static exports found */
 /***/ (function(module, exports, __webpack_require__) {
 
-module.exports = __webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\js\core\app-menu.js */"./resources/assets/js/core/app-menu.js");
+module.exports = __webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\js\core\app-menu.js */"./resources/assets/js/core/app-menu.js");
 
 
 /***/ })

+ 3 - 3
resources/dist/js/core/app.js

@@ -81,7 +81,7 @@
 /******/
 /******/
 /******/ 	// Load entry module and return exports
-/******/ 	return __webpack_require__(__webpack_require__.s = 4);
+/******/ 	return __webpack_require__(__webpack_require__.s = 5);
 /******/ })
 /************************************************************************/
 /******/ ({
@@ -850,14 +850,14 @@
 
 /***/ }),
 
-/***/ 4:
+/***/ 5:
 /*!***********************************************!*\
   !*** multi ./resources/assets/js/core/app.js ***!
   \***********************************************/
 /*! no static exports found */
 /***/ (function(module, exports, __webpack_require__) {
 
-module.exports = __webpack_require__(/*! D:\php-project\laravel\laraveladmin\github-test\pck-dcat-admin\dcat-admin\resources\assets\js\core\app.js */"./resources/assets/js/core/app.js");
+module.exports = __webpack_require__(/*! F:\p\dcat-admin-github\dcat-admin\resources\assets\js\core\app.js */"./resources/assets/js/core/app.js");
 
 
 /***/ })

+ 0 - 9
src/Form.php

@@ -81,10 +81,6 @@ use Symfony\Component\HttpFoundation\Response;
  * @method Field\Timezone               timezone($column, $label = '')
  * @method Field\KeyValue               keyValue($column, $label = '')
  * @method Field\Tel                    tel($column, $label = '')
- * @method Field\BootstrapFile          bootstrapFile($column, $label = '')
- * @method Field\BootstrapImage         bootstrapImage($column, $label = '')
- * @method Field\BootstrapMultipleImage bootstrapMultipleImage($column, $label = '')
- * @method Field\BootstrapMultipleFile  bootstrapMultipleFile($column, $label = '')
  */
 class Form implements Renderable
 {
@@ -159,11 +155,6 @@ class Form implements Renderable
         'timezone'       => Field\Timezone::class,
         'keyValue'       => Field\KeyValue::class,
         'tel'            => Field\Tel::class,
-
-        'bootstrapFile'          => Field\BootstrapFile::class,
-        'bootstrapImage'         => Field\BootstrapImage::class,
-        'bootstrapMultipleFile'  => Field\BootstrapMultipleFile::class,
-        'bootstrapMultipleImage' => Field\BootstrapMultipleImage::class,
     ];
 
     /**

+ 2 - 2
src/Form/Field/Text.php

@@ -18,7 +18,7 @@ class Text extends Field
     {
         $this->initPlainInput();
 
-        $this->prepend('<i class="ti-pencil"></i>')
+        $this->prepend('<i class="feather icon-edit-2"></i>')
             ->defaultAttribute('type', 'text')
             ->defaultAttribute('id', $this->id)
             ->defaultAttribute('name', $this->getElementName())
@@ -105,7 +105,7 @@ class Text extends Field
     {
         Admin::script(
             <<<'JS'
-Dcat.extendValidator('maxlength', function ($el) {
+Dcat.validator.extend('maxlength', function ($el) {
     return $el.val().length > $el.attr('data-maxlength');
 });
 JS

+ 10 - 6
src/Layout/Assets.php

@@ -74,6 +74,9 @@ class Assets
             'js'  => 'dcat-admin/dcat/plugins/nestable/jquery.nestable.min.js',
             'css' => 'dcat-admin/dcat/plugins/nestable/nestable.css',
         ],
+        '@validator' => [
+            'js' => 'dcat-admin/dcat/plugins/bootstrap-validator/validator.min.js',
+        ],
         '@select2' => [
             'js'  => 'dcat-admin/vendors/js/forms/select/select2.full.min.js',
             'css' => 'dcat-admin/vendors/css/forms/select/select2.min.css',
@@ -97,7 +100,7 @@ class Assets
         '@webuploader' => [
             'js' => [
                 'dcat-admin/dcat/plugins/webuploader/webuploader.min.js',
-                'dcat-admin/dcat/plugins/dcat-admin/upload.min.js',
+                'dcat-admin/dcat/extra/upload.js',
             ],
             'css' => 'dcat-admin/dcat/plugins/webuploader/webuploader.min.css',
         ],
@@ -208,11 +211,12 @@ class Assets
      * @var array
      */
     protected $baseJs = [
-        'menu'   => '@menu',
-        'app'    => '@app',
-        'toastr' => '@toastr',
-        'pjax'   => '@pjax',
-        'layer'  => '@layer',
+        'menu'      => '@menu',
+        'app'       => '@app',
+        'toastr'    => '@toastr',
+        'pjax'      => '@pjax',
+        'validator' => '@validator',
+        'layer'     => '@layer',
     ];
 
     /**