自制小autocomplete/tree/上传/下载/html转pdf/layer

/*
随手开发,留作笔记,后面优化
*/
//模糊查询
$(function () {
    /*
var a1 = new aotoFindData();
a1.init('#bigCustomerCompany', {
    url: '/ManageBase/GetCompany',
    key: ['Name'],
    staticStr: '支持汉字查询',
    fillKey: { 'type': 'CompanySearch', 'companyname': $('#bigCustomerCompany') },
    onpicked: function (that, item) {//item:当前点击的this
        var data = jQuery.parseJSON($(item).attr('data'));
        console.log(data.PK_Guid)
    }
});
*/
});
//正则匹配去掉特殊字符
function replaceStr(s) {
    var pattern = new RegExp("[`~!@#$^&*()=|{}':;',\\[\\].<>/?~!@#¥……&*()——|{}【】‘;:”“'。,、?]");
    var rs = "";
    for (var i = 0; i < s.length; i++) {
        rs = rs + s.substr(i, 1).replace(pattern, '');
    }
    return rs;
}

function aotoFindData() {
    this.input = null;
    this.$swraper = null;
    this.pinjieUrls = '';
    this.settings = {
        type: 3,//3:不需要模糊查询,点击查询全部         1:点击默认展示,2:点击的时候不展示,
        url: 'http://admin.fanjiaxing.com/ManageBase/GetCompany.ashx?type=CompanySearch&companyname=',
        width: 'auto',
        key: 'auto',
        staticStr: '支持汉字搜索/拼音',
        fillKey: { 'aa': $('.aa').val(), 'bb': $('.bb').val() },// 实时传入的参数
        onpicked: function (that, item) {
            var data = jQuery.parseJSON($(item).attr('data'));
            //$('#aa').val(data.ChineseName);
        }
    };

};

/* 获取元素位置 */
aotoFindData.prototype.getPos = function (node) {
    var scrollx = document.documentElement.scrollLeft || document.body.scrollLeft,
        scrollt = document.documentElement.scrollTop || document.body.scrollTop;
    var pos = $(node).eq(0)[0].getBoundingClientRect();
    return { top: pos.top + scrollt, right: pos.right + scrollx, bottom: pos.bottom + scrollt, left: pos.left + scrollx }
},
    aotoFindData.prototype.stopPropagation = function (event) {
        event = event || window.event;
        event.stopPropagation ? event.stopPropagation() : event.cancelBubble = true;
    }

aotoFindData.prototype.init = function (input, opt) {
    this.$swraper = $('<div class="auto-swraper"></div>');

    this.input = input;
    //var licalss = replaceStr(input);
    //this.calssLi = 'li' + licalss;
    if (opt) {
        $.extend(this.settings, opt);
    }

    this.inputEvent();


}

aotoFindData.prototype.inputEvent = function () {
    var that = this;
    $('body').on('click', this.input, function (e) {
        that.stopPropagation(e);
        that.$swraper.siblings('.auto-swraper').hide();
        if (!this.b) {
            that.createSwrap();
            this.b = true;
        }
        if (that.$swraper) {
            that.$swraper.show();
        }

        var left = that.getPos(that.input).left;
        var top = that.getPos(that.input).bottom;
        that.$swraper.css({ 'top': top, 'left': left });

        that.$swraper.find('.falid').show();
        that.$swraper.find('.item').remove();
        that.$swraper.find('.falid').html('加载中。。。');
        that.$swraper.find('.falid').css({ 'color': '#333' });
        that.ResetUrl($(this).val());
        that.pushData($(this).val());


    });
    $('body').on('keyup', this.input, function (e) {
        clearTimeout(this.stimer);
        var _this = this;
        that.ResetUrl($(_this).val());
        this.stimer = setTimeout(function () {
            that.pushData($(_this).val());
        }, 500);

        console.log(this.input)
    });
    $('body').on('keydown', this.input, function (e) {
        clearTimeout(this.stimer);
    });

    $('body').on('input propertychange', this.input, function (e) {
        //_this.inputKeyup(this, autoBackcall);
    });


    $(document).on('click', function () {
        if (that.$swraper) {
            that.$swraper.hide();
        }

    });
}

aotoFindData.prototype.addDivEvent = function () {
    var that = this;
    if (that.$swraper) {
        that.$swraper[0].onclick = function (e) {
            that.stopPropagation(e);
        }
    }
}
aotoFindData.prototype.ResetUrl = function (value) {
    this.pinjieUrls = this.settings.url;

    if (/\?/.test(this.pinjieUrls)) { // 如果已经有参数了
        this.pinjieUrls = this.pinjieUrls + '&';
    } else { // 如果没有参数,那么就从第一个加
        this.pinjieUrls = this.pinjieUrls + '?';
    }
    if (this.settings.fillKey) {
        for (var key in this.settings.fillKey) {

            var values = this.settings.fillKey[key];
            if (typeof (values) == 'object') {
                values = values.val();
            }
            this.pinjieUrls += key + '=' + values + '&'
        }
    }
    this.pinjieUrls = this.pinjieUrls.substr(0, this.pinjieUrls.length - 1);
}

aotoFindData.prototype.pushData = function (value) {
    var that = this;
    that.$swraper.find('.falid').show();
    that.$swraper.find('.falid').html('加载中');

    console.log(this.pinjieUrls)

    $.ajaxSetup({ cache: false });
    $.ajax({
        type: "GET",
        url: this.pinjieUrls,
        _FanjiaRepeatForgeryTokeExt: $('#_FanjiaRepeatForgeryTokeExt').val(),
        success: function (msg) {
            if (msg == '' || msg.length == 0) {
                return;
            }
            console.log(typeof (msg) === 'string')
            msg = jQuery.parseJSON(msg);
            if (!msg) {
                return;
            }
            if (msg == "" || msg.length == 0) {
                that.$swraper.find('.falid').show();
                that.$swraper.find('.item').remove();
                that.$swraper.find('.falid').html('未找到此项......');
                that.$swraper.find('.falid').css({ 'color': '#333' });
                return;
            }

            //msg = msg.replace(/'/g, '"');//把单引号替换成双引号
            //msg = jQuery.parseJSON(msg);

            that.$swraper.find('.item').remove();
            //that.$swraper.find('.falid').hide();

            //if (that.$swraper.find('.falid').length > 1) {
            //    that.$swraper.find('.falid').remove();
            //}
            that.$swraper.find('.falid').html(that.settings.staticStr);
            that.$swraper.find('.falid').css({ 'color': '#999' });
            $.each(msg, function (index, element) {
                var $item = $('<div class="item">s</div>');

                $item.attr('data', JSON.stringify(element));
                // $item.html(element.EnglishName + ' ' + element.Passport);
                if (that.settings.key != 'auto') {
                    var strKey = '';
                    $.each(that.settings.key, function (inde, ele) {
                        if (typeof (ele) == "object") {
                            if (inde == that.settings.key.length - 1) {
                                strKey += ele.name + '' + element[ele.key];
                            } else {
                                strKey += ele.name + '' + element[ele.key] + ',  ';
                            }

                        } else {
                            if (inde == that.settings.key.length - 1) {
                                strKey += element[ele];
                            } else {
                                strKey += element[ele] + ',  ';
                            }

                        }

                    });

                    $item.html(strKey);
                }

                that.$swraper.append($item);

                $item[0].onclick = function () {
                    that.$swraper.hide();
                    $(that.input).val($(this).html());
                    if (that.settings.onpicked) {
                        that.settings.onpicked(that.input, this);
                    }
                }
            });
        },
        error: function () {
            that.$swraper.find('.falid').show();
            that.$swraper.find('.item').remove();
            that.$swraper.find('.falid').html('数据加载失败');
            that.$swraper.find('.falid').css({ 'color': '#333' });
        }
    });

}


aotoFindData.prototype.createSwrap = function () {
    var $falid = $('<div class="falid">支持拼音汉字搜索</div>');
    var left = this.getPos(this.input).left;
    var top = this.getPos(this.input).bottom;
    var width = $(this.input).width() + parseInt($(this.input).css('padding-left')) + parseInt($(this.input).css('padding-right'));
    $falid.css({ 'color': '#333' });

    if (this.settings.width != 'auto') {
        width = this.settings.width;
    }
    this.$swraper.css({ 'position': 'absolute', 'top': top, 'left': left, 'z-index': '99999', 'width': width });

    if (!this.input.b) {
        this.$swraper.find('.falid').remove();
        this.$swraper.append($falid);
        this.input.b = true;
    }

    $('body').append(this.$swraper);
    this.addDivEvent();
}


tree 

function fjTree() {
    this.treeParentDom = null;
    this.isfirst = true;
    this._isfirst = true;
    this.treeDeepNum = 0;
    this.set = {
        treeData: [],
        childName: 'ChildNode',
        treeitemName: 'Name',
        keyword:'',
        checkboxIsShow: false,
        develop:true, // 树默认展开
        callback: function () { }
    }
}

fjTree.prototype.init = function (treeParentDom, opt) {
    this.treeParentDom = treeParentDom;
    if (opt) {
        $.extend(this.set, opt);
    }

    $(treeParentDom).html(this.htmltree(this.set.treeData));
}

fjTree.prototype.htmltree = function (result, treeDeepnum) {
    //this.treeDeepNum++;
    var _treeDeepnum = treeDeepnum || 0;
    var style = ''
    var that = this;
    //if (!this.set.develop && !this._isfirst) { style = 'style="display:none"' }

    var firsttreebox = this._isfirst ? "firsttreebox" : "";
    this._isfirst = false;
    
    if (this.isfirst && !this.set.develop) {
        this.isfirst = false;
    }
    var $parentHtml = $('<div class="fj-tree-box ' + firsttreebox + ' " ' + style + '></div>');

    for (var i = 0; i < result.length; i++) {
        var item = result[i];
        var icon = '',arrowdown='';
        if (!item[this.set.childName] || item[this.set.childName] && !item[this.set.childName].length) { icon = "noarrow" }
        if (this.set.develop) { arrowdown = 'down' }
        var $treename = $('<div class="tree-name ' + icon + ' ' + arrowdown + '" ></div>'); // data="' + encodeURI(JSON.stringify(item)) + '"

        if (!this.set.checkboxIsShow) {
            that.arrolabelCheckBoxFn($treename[0], item);
            
        }
        var treeitemName = this.nameHtml(item, _treeDeepnum);
        $treename.append(treeitemName.$cssarrow)
        if (treeitemName.$label) { $treename.append(treeitemName.$label)}
        $parentHtml.append($treename)

        if (this.set.develop) {
            if (item[this.set.childName] != null && item[this.set.childName].length) {
                _treeDeepnum = _treeDeepnum + 1;
                var $child = this.htmltree(item[this.set.childName], _treeDeepnum);
                $parentHtml.append($child)
            }
        }
        _treeDeepnum = treeDeepnum
    }
   
    return $parentHtml
}
fjTree.prototype.nameHtml = function (data, num) {
    var Name = data[this.set.treeitemName];
    var that = this;
    if (this.set.keyword && Name.indexOf(this.set.keyword) == 0) {
        var re = new RegExp('('+this.set.keyword+')')
        Name = Name.replace(re, '<span style="color:#00a0e9">$1</span>')
    }
    if (this.set.checkboxIsShow) {
        var $cssarrow = $('<i class="cssarrow"></i>')
        var $label = $('<label class="label-checkbox"></label>');
        var $checkbox = $('<input type="checkbox" data-num="level_' + num + '" data-guid="' + data.PK_Guid+'"/> <span class="name">' + Name + '</span>')
        $label.append($checkbox)
        $cssarrow[0].onclick = function () {
            that.cssarrowFn(this);
            if (!that.set.develop && $(this).parents('.tree-name').eq(0).next('.fj-tree-box').length==0) {
                if (data[that.set.childName]) { $(this).parents('.tree-name').eq(0).after(that.htmltree(data[that.set.childName])) }
            }
        }

        $checkbox[0].onchange = function () {
            that.labelCheckBoxFn(this);
            var $parents = $(this).parents('.fj-tree-box');
            var b = $(this).prop('checked');
            if (!b) {
                $parents.each(function (index, ele) {
                    $(ele).prev('.tree-name').eq(0).find('[type=checkbox]').prop('checked', false)
                })
            }
            if (that.set.callback) {
                that.set.callback(data, b)
            }
        }

        return { $cssarrow: $cssarrow, $label: $label}
    }
    var $cssarrow = $('<i class="cssarrow"></i><span class="name">' + Name + '</span>')
    return { $cssarrow: $cssarrow }
}
fjTree.prototype.cssarrowFn = function (that) {
    var $parent = $(that).parents('.tree-name').eq(0)
    $parent.toggleClass('down');
    $(this.treeParentDom).find('.tree-name').removeClass('active')
    $parent.addClass('active')
    $parent.next('.fj-tree-box').toggle();
}
fjTree.prototype.labelCheckBoxFn = function (that) {
    var $parent = $(that).parents('.tree-name').eq(0);
    $parent.next('.fj-tree-box').find('[type=checkbox]').prop('checked', $parent.find('[type=checkbox]').prop('checked') == true)  
}

fjTree.prototype.arrolabelCheckBoxFn = function ($dom, data) {
    var that = this
    $dom.onclick = function () {
        $(this).toggleClass('down');
        $(that.treeParentDom).find('.tree-name').removeClass('active')
        $(this).addClass('active')
        $(this).next('.fj-tree-box').toggle();

        if (!that.set.develop && $(this).next('.fj-tree-box').length == 0) {
            if (data[that.set.childName]) { $(this).after(that.htmltree(data[that.set.childName])) }
        }
        if (that.set.callback) {
            that.set.callback(data)
        }
    }
}



document.write('<link href="/Script/fj-tree/fj-tree.css?v=20210729" rel="stylesheet" />');




























.fj-tree-box{padding-left:17px}
.fj-tree-box.firsttreebox{display:block;padding-left:16px}
.fj-tree-box .tree-name{position:relative;display:block;line-height:32px;font-size:14px;color:#333;cursor:pointer;white-space:nowrap;padding-left:10px}
.fj-tree-box .tree-name.active{background:#E6F7FF}
.cssarrow{display:inline-block;width:15px;height:32px;position:absolute;vertical-align:middle;left:-4px;top:50%;margin-top:-15px}
.cssarrow:before{content:'';border:5px solid transparent;border-left:6px solid #000;width:0;height:0;position:absolute;top:50%;margin-top:-6px;margin-left:3px;transition:.1s all;transform-origin:25% 50%;display:inline-block}
.fj-tree-box .tree-name.down .cssarrow:before{transform:rotate(90deg)}
.fj-tree-box .tree-name.noarrow .cssarrow{display:none}
.fj-tree-box .tree-name .label-checkbox{white-space:nowrap;text-overflow:ellipsis;word-break:break-all;max-width:215px;display:inline-block;vertical-align:middle;margin-left:5px}
.fj-tree-box .tree-name input[type=checkbox]{vertical-align:middle}
.fj-tree-box .tree-name .name{vertical-align:middle;padding-left:5px}

上传: 

$("#uploadStaffEdit").change(function (e) {
    uploadImg(e.target, function (file) {
        UploadImageServer(file)
    })
});
function uploadImg(tag, callback) {
    var file = tag.files[0];
    var reader = new FileReader();
    // 此处判断上传的类型,或者在 <input type="file" value="选择文件上传" accept="..."/>中设置
    reader.readAsDataURL(file);
    if (callback) { callback(file) }
    reader.onload = function () {
        $('#img').attr('src', this.result)
    };
}
function UploadImageServer(file) {
    var formData = new FormData();
    // 对象
    formData.append("actionType", file);
    // 数组的方式: arr是参数数组;
    /*
    arr.forEach(function (item, index) {
        formData.append("List[" + index + "].CardType", item.CardType);
        formData.append("List[" + index + "].FormFile", item.File);
    });
    */
    $.ajax({
        url: "/Manage/UpLoadExecl",
        type: 'POST',
        data: formData,
        async: false,
        cache: false,
        contentType: false,
        processData: false,
        success: function (data) { },
        error: function (data) {  }
    });  
}

// angular


 <input type="file" value="" multiple (change)="onFilesSelected($event)" />
  onFilesSelected(event: any) {
    const files: FileList = event.target.files;
    this.uploadFiles(files);
  }

  uploadFiles(files: FileList) {
   
    const formData: FormData = new FormData();
    for (let i = 0; i < files.length; i++) {
      formData.append(`fileName`, files[i], files[i].name);
    }

    const headers = new HttpHeaders({
      Authorization: 'my-auth-token'
    });

    this.http.post(`${environment.path}/seal/ossUpload`, formData, { headers: headers }) //, { headers: headers }
      .subscribe(
        (response) => {
          console.log('Files uploaded:', response);
        },
        (error) => {
          console.error('Upload failed:', error);
        }
      );
  }

下载(网上搜关键字找的): 

// 浏览器下载
window.downloadFile = function (sUrl) {
    //iOS devices do not support downloading. We have to inform user about this.
    if (/(iP)/g.test(navigator.userAgent)) {
        alert('Your device does not support files downloading. Please try again in desktop browser.');
        return false;
    }

    //If in Chrome or Safari - download via virtual link click
    if (window.downloadFile.isChrome || window.downloadFile.isSafari) {
        //Creating new link node.
        var link = document.createElement('a');
        link.href = sUrl;

        if (link.download !== undefined) {
            //Set HTML5 download attribute. This will prevent file from opening if supported.
            var fileName = sUrl.substring(sUrl.lastIndexOf('/') + 1, sUrl.length);
            link.download = fileName;
        }

        //Dispatching click event.
        if (document.createEvent) {
            var e = document.createEvent('MouseEvents');
            e.initEvent('click', true, true);
            link.dispatchEvent(e);
            return true;
        }
    }

    // Force file download (whether supported by server).
    if (sUrl.indexOf('?') === -1) {
        sUrl += '?download';
    }

    window.open(sUrl, '_self');
    return true;
}

window.downloadFile.isChrome = navigator.userAgent.toLowerCase().indexOf('chrome') > -1;
window.downloadFile.isSafari = navigator.userAgent.toLowerCase().indexOf('safari') > -1;


// 调用
$('#downloadStaffEmpty').on('click', function () {
    downloadFile('/Images/excel/employee.xlsx');
})

html转pdf

import html2Canvas from 'html2canvas'
import JsPDF from 'jspdf'

// A4纸的宽高
const width = 794;
const height = 1123;
export const downloadPdf = (id, title) => {
  html2Canvas(document.querySelector(id), {
    allowTaint: true,
    width,height
  }).then(function (canvas) {
    let contentWidth = canvas.width
    let contentHeight = canvas.height
    let pageHeight = contentWidth / 592.28 * 841.89
    let leftHeight = contentHeight
    let position = 0
    let imgWidth = 595.28
    let imgHeight = 592.28 / contentWidth * contentHeight
    let pageData = canvas.toDataURL('image/jpeg', 1.0)
    let PDF = new JsPDF('', 'pt', 'a4')
    if (leftHeight < pageHeight) {
      PDF.addImage(pageData, 'JPEG', 0, 0, imgWidth, imgHeight)
    } else {
      while (leftHeight > 0) {
        PDF.addImage(pageData, 'JPEG', 0, position, imgWidth, imgHeight)
        leftHeight -= pageHeight
        position -= 841.89
        if (leftHeight > 0) {
          PDF.addPage()
        }
      }
    }
    PDF.save(title + '.pdf')
  }
  )
}


<div v-show="reimburseshow">
   <downloadreimburse class="downloadreimburse" />
</div>

// downloadreimburse: 需要转成pdf的html

downloadpdffn(){
	 this.reimburseshow = true;
	 this.$nextTick(() => {
	 downloadPdf('.downloadreimburse', '报销单')
	     this.reimburseshow = false;
	 })			
}
/*pageLayer.yanwu = function () {
                var html = '';
            pageLayer.layerToggle({
                obj1: '.ywdom',
                x: 0,
                data: html,
                left:253,
                right:43,
                overCallback: function (json) {
                    var $layer = json.$Dom.find('.ul').css({height:120});
                    var ywlayer = $(json.that).parents('td').find('[ywlayer]');
                    if (ywlayer.html()) {
                        $layer.html(ywlayer.html());
                        return;
                    }
                    $layer.html('加载中...')
                    setTimeout(function () {
                        ywlayer.html('dddddasas');
                        $layer.html(ywlayer.html());
                    }, 1000)
                }
            });
        }

        pageLayer.yanwu()*/


var pageLayer = {};
//tip的html拼接
pageLayer.html = function () {
    var pageLayerStr = '<div class="layer-many-ourboa">' +
        '<i class="arrow-icon top-arrow"></i>' +
        '<div class="ul-wrapper" style="position:relative;">' +
        '<div class="layer-many-load" style="position:absolute;top:0;left:0;bottom:0;right:0;background:rgba(255,255,255,0.6);color:#fff;display:none;">' +
        '<img src="/Images/loading_black.gif" style="position: absolute;top:50%;left:50%;margin:-49px 0 0 -54px "></div>' +
        '<div class="ul"></div>' +
        '</div>' +
        '</div>';
    return pageLayerStr;
}

/*tip-layer*/
pageLayer.layerToggle = function (opt) {
    var json = {
        obj1: '.a',
        x: 0,
        y: 0,
        data: '加载中',
        overCallback: function (datas) { }
    }
    if (opt) { $.extend(json, opt); }
    $('body').on('mouseover', json.obj1, function (ev) {
        clearTimeout(this.hangsiTimer);

        if (this.hangsiTimer != null) {
            this.hangsiTimer = null;
            return;
        }
        var x = 0, y = 15;
        if (json.x) {
            x = json.x;
        }
        if (json.y) {
            y = json.y;
        }
        var $layerhtml = $(pageLayer.html()).clone();

        $(this).after($layerhtml);
        $layerhtml.find('.ul').html(json.data);

        var data = {
            that: this,
            key: $(this).val(),
            $Dom: $layerhtml
        }

        if (json.overCallback) {
            json.overCallback(data);
        }
        var left = $(this).offset().left - ($layerhtml.width() - $(json.obj1).width()) / 2;
        var top = $(this).offset().top - $(window).scrollTop();
        left = opt.left || left;
        var right = opt.right || 'auto'

        if (top + $layerhtml.height() + 40 > $(window).height()) {//上面显示
            console.log($layerhtml.height())
            $layerhtml.css({ "top": top - $layerhtml.height() + $(json.obj1).height() / 2 - y - 20 - 7, 'left': left + x - 5, 'right': right });
            $layerhtml.find('.arrow-icon').removeClass('top-arrow').addClass('down-arrow');
        } else {//下面显示
            $layerhtml.css({ "top": top + y + $(json.obj1).height() / 2 + 7 - 7, 'left': left + x - 5, 'right': right});
            $layerhtml.find('.arrow-icon').removeClass('down-arrow').addClass('top-arrow');
        }
    });
    $('body').on('mouseout', json.obj1, function (ev) {
        var that = this;
        this.hangsiTimer = setTimeout(function () {
            $(that).next('.layer-many-ourboa').remove();
            $(that).next('.layer-many-ourboa').remove();
            that.hangsiTimer = null;
        }, 100);
    });

    $('body').on('mouseover', json.obj1 + ' + .layer-many-ourboa', function () {
        if ($(document).height() > $(window).height()) {
            $('body').css({ 'overflow': 'hidden', 'padding-right': '17px' });
        }
        clearTimeout($(this).prev(json.obj1)[0].hangsiTimer);
    });
    $('body').on('mouseout', json.obj1 + ' + .layer-many-ourboa', function () {
        var that = this;
        $('body').css({ 'overflow': 'initial', 'padding-right': '0' });

        $(this).prev(json.obj1)[0].hangsiTimer = setTimeout(function () {
            if ($(that).prev(json.obj1)[0]) {
                $(that).prev(json.obj1)[0].hangsiTimer = null;
            }
            $(that).remove();
        }, 100);
    });
}

$(window).scroll(function () {
    $('.layer-many-ourboa').remove();
});

document.write('<link href="/Script/fjLayerTip/fjLayer.css" rel="stylesheet" />');




.layer-many-ourboa {min-width: 168px; max-width: 480px; padding: 7px; line-height: 24px; background: #fff; position: fixed; border: 1px solid #d8d8d8; font-size: 12px; border-radius: 5px; z-index: 9999;box-shadow:2px 3px 5px rgba(0,0,0,.2); }
.layer-many-ourboa .top-arrow {display: block; position: absolute; top: -8px; left: 50%; margin-left: -9px; width: 18px; height: 9px; background: url(../Images/gather_icon.png) no-repeat -52px -227px; }
.layer-many-ourboa .down-arrow {display: block; position: absolute; bottom: -8px; left: 50%; margin-left: -9px; width: 18px; height: 9px; background: url(../Images/gather_icon.png) no-repeat -52px -238px; }
.layer-many-ourboa .ul {max-height: 230px; overflow-y: auto; }
.layer-many-ourboa li { line-height: 24px; }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值