Guns二次开发(十二):自定义图片上传插件

    关于博客中使用的Guns版本问题请先阅读   Guns二次开发目录   

       

       之前写过一篇替换 Guns 自带的图片上传后端接口的文章,当时测试的,也只是上传头像的功能,随着开发的不断深入,业务需求也越来越复杂,当做当商品管理的时候,发现 Guns 自带的图片上传插件并不能满足当前的业务需求,所以我自己写了一个js插件,方便后期的使用。

1、图片上传的效果图

2、需要引入的文件

要使用这个图片上传接口,需要引入三个文件:

(1)img-upload.css    (2)FileUpload.js    (3)image.tag  

首先是上传图片的页面,引入 css文件和js文件 :

同时,还要在这个页面中,引入这段代码: <#image title="品牌Logo图片<b style='color:red'>*</b>:" id="logoUrl"/>

这个#imgage 是我自定义的tag标签,我把他和原来guns自定义的tag标签放在了一起:

 

image.tag 的实现逻辑也很简单,里面有详细的注释,直接看就可以。

走到这里,图片上传的基本功能就已经实现了,此时还有一个需要注意的,我们上传的图片是保存到一个input隐藏标签中的,我们在最后收集请求参数的时候,如何获取这个字段的图片呢,因为我们引入 tag便签的时候,设置的id是 “logoUrl ”:

<#image title="品牌Logo图片<b style='color:red'>*</b>:" id="logoUrl"/> 

所以,最后图片上传成功之后,URL其实是保存到 id 为 logoUrl 的<input>标签中,如下图:

这一点,在前端html页面中也有所体现:

所以,获取的时候,只需要一行代码就能获取到当前图片的URL:

 var logoUrl = $("#logoUrl").val(); 

3、编辑时图片的回显

前面展示的都是第一次添加时的使用方式,但是修改的时候,我们的逻辑是先回显之前添加的数据,此时就涉及到图片回显,此时既要显示之前的图片,又要实现修改图片的功能。

实现点击旧图的时候,更换新的图片:

具体的代码体现就是,在 <#image> 标签中添加一个属性【src】,并将后端返回的图片URL赋值给这个属性,其它都不需要改变,如下图:

image.tag 文件中的具体实现逻辑就是下面这行代码:

4、一个字段有多张图片

有的时候,可能会出现这种情况,比如商品副图,一个商品可能有多个副图,而这些副图都是保存到一个字段中的,如下图:

前端beetl模板中这段代码的实现方式是:

<div class="content">
   <div id="subImgDiv" class="box">
            @for(var i=1 ;i<6;i++){
                <#image id="subImage_${i}" imgNames="subImages"/>
            @}
  </div>
</div>

image.tag 标签中对 imgNames的处理方式如下,可以发现,这个给多个<input>标签设置相同的名字:

主要为了方便于后面获取这个字段中的所有图片时使用:

在修改时对于多张图片的商品回显,可以参考下面这段代码:

5、源码分享

(1)img-upload.css 

.show_detail img{
    width: 100px;
    height: 100px;
}

/*属性图*/
.content{
    display: flex;
}
.box{
    display: flex;
    width: 600px;
    flex-wrap: wrap;
}
.img_box{
    width: 100px;
    height: 100px;
    border: 1px solid #ccc;
    position: relative;
}
.add_img{
    width: 100%;
    height: 100%;
    position: absolute;
    z-index: 99;
    top: 0;
    color: #999;
    display: flex;
    flex-flow: column;
    justify-content: center;
    cursor: pointer;
}
#file_a,#file_b,#file_c,#file_d,#file_e{
    display: none;
}
.file_box{text-align: center;margin-left: 20px;margin-bottom: 10px;}
/* 文件 */
.file-item{position: relative;margin-right: 15px;}
.file-item .info {
    position: absolute;
    bottom: 0;
    height: 20px;
    line-height: 20px;
    text-indent: 5px;
    background: rgba(0, 0, 0, 0.6);
    color: white;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
    font-size: 12px;
    z-index: 10;
}
.file-item .error {
    position: absolute;
    top: 4px;
    left: 4px;
    right: 4px;
    background: red;
    color: white;
    text-align: center;
    height: 20px;
    font-size: 14px;
    line-height: 23px;
}
.thumbnail{padding: 0;}
.remove-this{
    position: absolute;
    top: -10px;
    right: -10px;
    width: 20px;
    height: 20px;
    line-height: 20px;
    text-align: center;
    background: rgba(0, 0, 0, 0.6);
    color: white;
    font-size: 12px;
    z-index: 10;
    border-radius: 10px;
    cursor: pointer;
}

(2)FileUpload.js   

var FileUpload = {

    
}


/**
 * ajax 图片上传工具
 * @param id 上传图片的id,图片上传成功之后获取图片的URL时需要
 */
FileUpload.ajaxUploadImage=function (id) {

    $("#"+id+"_upload_img").click().unbind('change').on('change',function(event){

        var filepath  = $(this).val();
        var fileType = filepath.substring(filepath.lastIndexOf(".")).toLowerCase();
        var fileTypes = [".jpg", ".gif", ".jpeg", ".png"];//允许上传的图片类型
        if(fileTypes.indexOf(fileType)==-1){
            Feng.error("请选择后缀为【"+fileTypes.toString()+"】类型的图片文件");
            return false;
        }

        var imgFile = event.target.files[0];
        var fileSize = imgFile.size;
        if(fileSize>1*1024*1024){
            Feng.error("请上传小于1M的图片");
            return false;
        }

        var srcUrl = window.URL.createObjectURL(imgFile);
        $("#"+id+"_upload_detail").empty().append("<img style='width: 100%;height: 100%;' src="+ srcUrl +" />");

        var formData = new FormData();
        formData.append("file",imgFile)
        $.ajax({
            url:Feng.ctxPath + '/mgr/upload',
            type:"POST",
            data:formData,
            processData : false,
            contentType : false,
            dataType : 'json',
            async : false,
            success : function (res) {

                //将图片的URL保存到隐藏的input标签中临时保存
                $("#"+id).val(res);
                
            },
            error: function(err) {
                Feng.error(JSON.stringify(err));
            }
        });

        if($(event.target).siblings(".show_detail").children().length>1){
            $(event.target).siblings(".show_detail").children().eq(0).remove();
        }

    });


}

(3)image.tag 

@/*
    表单中input框标签中各个参数的说明:

    title : 图片标题,再图片左侧
    id : 图片上传框的id,上传图片时调用接口时用到;同时也是保存图片url的input隐藏框的id,用户获取图片的URL时使用
    src : 图片的URL,编辑界面时用于回显添加时上传的图片
    imgNames: input隐藏标签的name字段的值,用于多图上传时,获取一个字段多张图片时使用
    topTitle: 图片标题,在图片头顶

@*/
<div class="form-group">

    @if(isNotEmpty(title)){
        <label class="col-sm-3 control-label">${title}</label>
        <div class="col-sm-9">
    @}

        <div class="file_box">
            @if(isNotEmpty(topTitle)){
                <div>${topTitle}</div>
            @}

            <div class="img_box">
                <input style="display: none;" type="file" id="${id}_upload_img" accept="image/gif,image/jpeg,image/jpg,image/png"/>
                <div id="${id}_upload_detail" class="add_img"
                     @if(isNotEmpty(clickFun)){
                        onclick="${clickFun}"
                     @}else{
                        onclick="FileUpload.ajaxUploadImage('${id}')"
                     @}
                >
                    @if(isNotEmpty(src)){
                        <img style="width: 100%;height: 100%;" src="${src}">
                    @}else{
                        <div style="font-size: 40px;">+</div>
                        <div>点击添加</div>
                    @}

                </div>
            </div>

            <input type="hidden"
                @if(isNotEmpty(id)){
                   id="${id}"
                @}
                @if(isNotEmpty(imgNames)){
                   name="${imgNames}"
                @}
                @if(isNotEmpty(src)){
                   value="${src}"
                @}

                    >
        </div>

        @if(isNotEmpty(title)){
            </div>
        @}
</div>
@if(isNotEmpty(underline) && underline == 'true'){
    <div class="hr-line-dashed"></div>
@}


(4)CommonTool.js

var CommonTool={}

/**
 * 判断是字符串是否为null,'undifined',空串,空格 如果是,返回true;
 * 判断对象是否为空,如果为空对象或集合,返回true
 *
 * @param value
 * @returns {boolean}
 */
CommonTool.isEmpty=function (value) {

    //判断是否是undefined和""
    if(!value){
        return true;
    }

    //如果是字符串,还要去掉首尾空格后判断长度是否为0
    if(typeof(value) == 'string' && value.trim().length==0){
        return true;
    }


    //如果是对象
    if(typeof(value) == 'object' || JSON.stringify(value) === '{}'){
        return true;
    }
    return false;

}

至此,分享结束!

该系列更多文章请前往 Guns二次开发目录

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值