diff --git a/plugin/think-plugs-admin/src/view/api/upload.js b/plugin/think-plugs-admin/src/view/api/upload.js index e1b1dbc67..5a9216764 100644 --- a/plugin/think-plugs-admin/src/view/api/upload.js +++ b/plugin/think-plugs-admin/src/view/api/upload.js @@ -1,40 +1,83 @@ define(['md5', 'notify'], function (SparkMD5, Notify, allowMime) { allowMime = JSON.parse('{$exts|raw}'); + function readOptionValue($elem, name, fallback) { + let value = $elem.attr('data-' + name); + if (typeof value === 'undefined' || value === null) value = $elem.data(name); + return typeof value === 'undefined' || value === null ? fallback : value; + } + + function readOptionBool(value) { + if (typeof value === 'boolean') return value; + if (typeof value === 'number') return value > 0; + return /^(1|true|yes|on)$/i.test(String(value || '')); + } + + function normalizePath(path) { + return String(path || '').replace(/\\/g, '/').split('/').map(function (part) { + return part.replace(/[^\w-]/g, ''); + }).filter(function (part) { + return part.length > 0; + }).join('/'); + } + + function resolveInput($elem) { + let input = $elem.data('input'); + if (input) return $(input); + let field = readOptionValue($elem, 'field', ''); + if (field) { + input = $('input[name="' + field + '"]:not([type=file])'); + $elem.data('input', input.length > 0 ? input.get(0) : null); + } + return input && input.length ? input : $(); + } + + function resolveValue($elem, $input, name, fallback) { + let value = readOptionValue($elem, name); + if ((typeof value === 'undefined' || value === null || value === '') && $input && $input.length) { + value = readOptionValue($input, name); + } + return typeof value === 'undefined' || value === null ? fallback : value; + } + + function resolveOption($elem, current) { + let option = Object.assign({elem: $elem, exts: [], mimes: []}, current || {}); + let $input = resolveInput($elem); + let types = String(resolveValue($elem, $input, 'type', '') || ''); + option.elem = $elem; + option.input = $input.length ? $input : undefined; + option.size = parseInt(resolveValue($elem, $input, 'size', 0)) || 0; + option.safe = readOptionBool(resolveValue($elem, $input, 'safe', 0)) ? 1 : 0; + option.hide = readOptionBool(resolveValue($elem, $input, 'hload', 0)) ? 1 : 0; + option.mult = parseInt(resolveValue($elem, $input, 'multiple', 0)) > 0; + option.path = normalizePath(resolveValue($elem, $input, 'path', '')); + option.type = option.safe ? 'local' : String(resolveValue($elem, $input, 'uptype', '') || ''); + option.quality = parseFloat(resolveValue($elem, $input, 'quality', '1.0') || '1.0'); + option.maxWidth = parseInt(resolveValue($elem, $input, 'max-width', 0)) || 0; + option.maxHeight = parseInt(resolveValue($elem, $input, 'max-height', 0)) || 0; + option.cutWidth = parseInt(resolveValue($elem, $input, 'cut-width', 0)) || 0; + option.cutHeight = parseInt(resolveValue($elem, $input, 'cut-height', 0)) || 0; + option.exts = []; + option.mimes = []; + $(types.split(',')).map(function (i, ext) { + ext = $.trim(String(ext || '').toLowerCase()); + if (allowMime[ext]) option.exts.push(ext), option.mimes.push(allowMime[ext]); + }); + return option; + } + function UploadAdapter(elem, done) { return new (function (elem, done) { let that = this; /*! 初始化变量 */ - this.option = {elem: $(elem), exts: [], mimes: []}; - this.option.size = this.option.elem.data('size') || 0; - this.option.safe = this.option.elem.data('safe') ? 1 : 0; - this.option.hide = this.option.elem.data('hload') ? 1 : 0; - this.option.mult = this.option.elem.data('multiple') > 0; - this.option.path = (this.option.elem.data('path') || '').replace(/\W/g, ''); - this.option.type = this.option.safe ? 'local' : this.option.elem.attr('data-uptype') || ''; - this.option.quality = parseFloat(this.option.elem.data('quality') || '1.0'); - this.option.maxWidth = parseInt(this.option.elem.data('max-width') || '0'); - this.option.maxHeight = parseInt(this.option.elem.data('max-height') || '0'); - this.option.cutWidth = parseInt(this.option.elem.data('cut-width') || '0'); - this.option.cutHeight = parseInt(this.option.elem.data('cut-height') || '0'); - - /*! 查找表单元素, 如果没有找到将不会自动写值 */ - if (this.option.elem.data('input')) { - this.option.input = $(this.option.elem.data('input')) - } else if (this.option.elem.data('field')) { - this.option.input = $('input[name="' + this.option.elem.data('field') + '"]:not([type=file])'); - this.option.elem.data('input', this.option.input.length > 0 ? this.option.input.get(0) : null); - } - - /*! 文件选择筛选,使用 MIME 规则过滤文件列表 */ - $((this.option.elem.data('type') || '').split(',')).map(function (i, e) { - if (allowMime[e]) that.option.exts.push(e), that.option.mimes.push(allowMime[e]); - }); + this.option = resolveOption($(elem)); /*! 初始化上传组件 */ this.adapter = new Adapter(this.option, layui.upload.render({ url: '{:url("admin/api.upload/file",[],false,true)}', auto: false, elem: elem, accept: 'file', multiple: this.option.mult, exts: this.option.exts.join('|'), acceptMime: this.option.mimes.join(','), choose: function (obj) { + that.option = resolveOption(that.option.elem, that.option); + that.adapter.config(that.option); obj.items = [], obj.files = obj.pushFile(); layui.each(obj.files, function (idx, file) { obj.items.push(file); @@ -324,4 +367,4 @@ define(['md5', 'notify'], function (SparkMD5, Notify, allowMime) { }, timeout || 2000), this; }; } -}); \ No newline at end of file +}); diff --git a/plugin/think-plugs-admin/src/view/api/upload/image.html b/plugin/think-plugs-admin/src/view/api/upload/image.html index 9bc6456ff..4a8cafaf5 100644 --- a/plugin/think-plugs-admin/src/view/api/upload/image.html +++ b/plugin/think-plugs-admin/src/view/api/upload/image.html @@ -147,15 +147,19 @@ {if isset($get.file) && $get.file eq 'image'} {else} {/if} - \ No newline at end of file + diff --git a/plugin/think-plugs-static/stc/public/static/admin.js b/plugin/think-plugs-static/stc/public/static/admin.js index 93558e13d..2a1033f18 100644 --- a/plugin/think-plugs-static/stc/public/static/admin.js +++ b/plugin/think-plugs-static/stc/public/static/admin.js @@ -500,6 +500,20 @@ $(function () { return data; }; + function readUploadAttr($elem, name, fallback) { + let value = $elem.attr('data-' + name); + if (typeof value === 'undefined' || value === null) value = $elem.data(name); + return typeof value === 'undefined' || value === null ? fallback : value; + } + + function copyUploadAttrs($source, $target, defaults) { + let attrs = {}; + $.each(defaults || {}, function (name, fallback) { + attrs['data-' + name] = readUploadAttr($source, name, fallback); + }); + return $target.attr(attrs); + } + /*! 全局文件上传 */ $.fn.uploadFile = function (callable, initialize) { return this.each(function (idx, elem) { @@ -525,8 +539,9 @@ $(function () { event.stopPropagation(), $in.val() && $.form.iframe(encodeURI($in.val()), '视频预览'); }).on('click', 'i.layui-icon-close', function (event) { event.stopPropagation(), $bt.attr('style', '').find('span[data-file]').html('') && $in.val('').trigger('change'); - }).find('[data-file]').data('input', this).attr({ - 'data-path': $in.data('path') || '', 'data-size': $in.data('size') || 0, 'data-type': $in.data('type') || 'mp4', + }); + copyUploadAttrs($in, $bt.find('[data-file]').data('input', this), { + 'path': '', 'size': 0, 'type': 'mp4', 'uptype': '', 'safe': 0, 'hload': 0, 'quality': '1.0', }); }); }; @@ -543,10 +558,10 @@ $(function () { event.stopPropagation(), $in.val() && $.previewImage(encodeURI($in.val())); }).on('click', 'i.layui-icon-close', function (event) { event.stopPropagation(), $bt.attr('style', '') && $in.val('').trigger('change'); - }).find('[data-file]').data('input', this).attr({ - 'data-path': $in.data('path') || '', 'data-size': $in.data('size') || 0, 'data-type': $in.data('type') || 'gif,png,jpg,jpeg', - 'data-max-width': $in.data('max-width') || 0, 'data-max-height': $in.data('max-height') || 0, - 'data-cut-width': $in.data('cut-width') || 0, 'data-cut-height': $in.data('cut-height') || 0, + }); + copyUploadAttrs($in, $bt.find('[data-file]').data('input', this), { + 'path': '', 'size': 0, 'type': 'gif,png,jpg,jpeg', 'max-width': 0, 'max-height': 0, + 'cut-width': 0, 'cut-height': 0, 'uptype': '', 'safe': 0, 'hload': 0, 'quality': '1.0', }); }); }; @@ -557,10 +572,9 @@ $(function () { if (this.dataset.inited) return; else this.dataset.inited = 'true'; let $bt = $('
'); let ims = this.value ? this.value.split('|') : [], $in = $(this).after($bt); - $bt.find('[data-file]').attr({ - 'data-path': $in.data('path') || '', 'data-size': $in.data('size') || 0, 'data-type': $in.data('type') || 'gif,png,jpg,jpeg', - 'data-max-width': $in.data('max-width') || 0, 'data-max-height': $in.data('max-height') || 0, - 'data-cut-width': $in.data('cut-width') || 0, 'data-cut-height': $in.data('cut-height') || 0, + copyUploadAttrs($in, $bt.find('[data-file]'), { + 'path': '', 'size': 0, 'type': 'gif,png,jpg,jpeg', 'max-width': 0, 'max-height': 0, + 'cut-width': 0, 'cut-height': 0, 'uptype': '', 'safe': 0, 'hload': 0, 'quality': '1.0', }).on('push', function (evt, src) { ims.push(src), $in.val(ims.join('|')).trigger('change'), showImageContainer([src]); }) && (ims.length > 0 && showImageContainer(ims)); @@ -1060,4 +1074,4 @@ $(function () { /*! 初始化系统菜单及表单验证 */ $.menu.listen() && $.form.reInit($body); -}); \ No newline at end of file +});