给新手,微信JS-SDK上传图片

微信JS-SDK上传图片 优点

不用考虑兼容问题

微信JS-SDK上传图片 优点

流程略繁琐,多图上传速度很慢(因为服务器间反复存取)
回调略多,不过我利用了Promise,基本避开了回调地狱

微信JS-SDK上传图片 简单逻辑介绍

1.手机本地选择图片
2.发送至微信服务器,获得localIds
3.循环localIds,【分别】获得微信服务器上的serverIds
4.得到的的serverIds提交你的项目后台接口,后台去微信服务器下载图片
5.后台下载成功后,把你图片存到你项目的服务器,返回给图片的存储地址
6.你插入图片到页面

总之一句话:你把图片给了微信,你后台要去微信拿图片

DEMO 代码

功能介绍

在这里插入图片描述
1、图片选择后直接上传到服务器,无需再统一上传
2、可以多图同时上传【我这个限制了一次最多选择3张,否则请求返回太慢】
3、直接可以删除图片

项目要点

要有 Promise 的基础 ,jq操作
可以去 后盾人 学习
单图上传+预览+删除 很好做
多图上传+删除 也还好,
但是 多图 上传+预览+删除 就有点麻烦了,
但 多图上传+预览+删除 往往是基本需求,
所以封装一下还是很有必要的!

提示

用了layui
所有layer.msg 可以换成alert
layer.load()是加载动画,也可去掉

HTML


<body>
    <div id="addBanner" class="mobile_restrction">
        <div class="top_title">
            <img src="/public/yz/wenzhang/img/addpic_title.png">
        </div>
        <ul class="addBanner_pic_box">
            <li> 
                <img src="http://yuezhuantest.kelebao.com.cn/public/uploads/20200108/1578471199926216.png"
                    class="add_pic_item">
                <div class="img_delet_btn" onclick="deletImg(this)">
                    删除
                </div>
            </li>
            <li>
                <img src="http://yuezhuantest.kelebao.com.cn/public/uploads/20200108/1578471199926216.png"
                    class="add_pic_item">
                <div class="img_delet_btn">
                    删除
                </div>
            </li>
            <li class="append_node" id="imgUpload">
                <div class="btn_bx" >
                    点击添加图片
                </div>
            </li>
        </ul>
    </div>
    <input type="text" hidden id="identity" value="school">
</body>

css

#addBanner {
  min-height: 100vh;
  padding-top: 24px;
  box-sizing: border-box;
  background-color: #fff;
}
#addBanner .top_title {
  width: 158px;
  margin: 0px auto 24px;
}
#addBanner .top_title > img {
  width: 100%;
  height: 100%;
  display: block;
}
#addBanner .addBanner_pic_box {
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  padding: 0 5px;
}
#addBanner .addBanner_pic_box li {
  position: relative;
  width: 47%;
  margin: 0 5px 5px;
  height: 100px;
  border-radius: 10px;
  overflow: hidden;
}
#addBanner .addBanner_pic_box li .img_delet_btn {
  position: absolute;
  bottom: 4px;
  right: 4px;
  z-index: 99;
  width: 50px;
  height: 28px;
  line-height: 28px;
  text-align: center;
  background-color: #f50;
  color: #fff;
}
#addBanner .addBanner_pic_box li .add_pic_item {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
#addBanner .addBanner_pic_box li .btn_bx {
  height: 96px;
  text-align: center;
  line-height: 96px;
  color: #6d6d6d;
  background-color: #edecec;
  border-radius: 5px;
}
#addBanner .addBanner_bot {
  margin-top: 40px;
  margin-left: 20px;
  font-size: 14px;
  line-height: 20px;
  letter-spacing: 0px;
  color: #666666;
}

JS

·· // 全局localIds 用于图片预览
    let globalLocalIds = []
    const baseUrl = 'http://www.xxxx.com/'
  	const totalNum = 8 // Number
    $('ul .add_pic_item').each(function () {
      globalLocalIds.push(baseUrl + $(this).parents('li').attr('serverpath')) // wx预览接口要带上完整访问地址
    })
    // 原有图片执行预览删除事件
    previewImage()
    deletImage()

    myWxUploadImg()

    function myWxUploadImg() {
      /**
       * event listening
       */
      $('#imgUpload').click(async function () {
        let remainingNum = totalNum - $('ul .add_pic_item').length
        // 获取了线上 serveid
        let gatherIds = await pickImgHandle(remainingNum)
        // alert(JSON.stringify(gatherIds))
        // 上传后台,
        let serverPath = await sendServe(gatherIds).catch(err => {
          layer.msg(err)
        }).finally(() => {
          layer.closeAll()
        })
        // alert(JSON.stringify(serverPath))
        if (!serverPath.length) {
          layer.msg('上传照片失败')
          return false
        }
        // ############### Render ##################
        let picDom = ``
        gatherIds.map((item, index) => {
          let localId_item = item['localId']
          let serverId_item = item['serverId']
          globalLocalIds.push(localId_item)
          picDom +=
            `
                <li serverPath="${serverPath[index]}">
                    <img src="${localId_item}"
                        class="add_pic_item">
                    <div class="img_delet_btn">
                        删除
                    </div>
                    <input type="text" name="thumbnail" value="${serverId_item}" hidden>
                </li>
                `
        })

        $('.append_node').before(picDom)
        totalNum === parseInt($('ul .add_pic_item').length) ? $("#imgUpload").hide() : $("#imgUpload").show()
        // 图片预览
        previewImage()
        // 删除图片
        deletImage()
      })
    }

    /**
     * asnyc
     * 选择本地图片
     * 返回 localIds
     */
    function getLocIds(remainingNum) {
      return new Promise((resolve, reject) => {
        wx.chooseImage({
          count: remainingNum, // 默认9
          sizeType: ['compressed'], // 可以指定是原图还是压缩图,默认二者都有'original', 'compressed'
          sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
          success: function (res) {
            var localIds = res.localIds; // 返回选定照片的本地ID列表,localId可以作为img标签的src属性显示图片
            if (parseInt(localIds.length) > 3) {
              layer.msg('建议每次上传不要超过3张图片')
              reject()
            } else {
              layer.load(0, {
                shade: [0.4, '#000'] //0.1透明度的白色背景
              }); //0代表加载的风格,支持0-2
              resolve(localIds)
            }
          }
        });
      })
    }
    /**
     * asnyc
     * ${localIds} string 本地图片数组
     * 返回 线上ids
     */
    function getServeId(localId) {
      return new Promise((resolve, reject) => {
        wx.uploadImage({
          localId: localId, // 需要上传的图片的本地ID,由chooseImage接口获得
          isShowProgressTips: 0, // 默认为1,显示进度提示
          success: function (res) {
            var serverId = res.serverId; // 返回图片的服务器端ID
            resolve(serverId)
          }
        });
      })
    }
    /**
     * 
     * @param {汇总的本地localId} gatherIds String
     */
    function sendServe(gatherIds) {
      // 局部serverIds,用于传服务器,服务器从微信服务器获取图片存入数据库
      let partServerIds = []
      gatherIds.map(item => partServerIds.push(item['serverId']))
      // alert(partServerIds)
      return new Promise((resolve, reject) => {
        $.post(
          wall.$api.bannerUpload, {
            arr: partServerIds
          },
          res => {
            if (res.code === '1') {
              resolve(res.data)
            } else {
              reject(res.msg)
            }
          }, 'json')
      })
    }

    /**
     * 点击取图片
     */
    async function pickImgHandle(remainingNum) {
      // #step1
      const localIds = await getLocIds(remainingNum)
      // #step2
      let gatherIds = []
      for (const item of localIds) {
        let serverId = await getServeId(item)
        gatherIds.push({
          localId: item,
          serverId: serverId
        })
      }
      return gatherIds
    }

    /**
     * 图片预览放大
     */
    function previewImage() {
      $('ul .add_pic_item').off().click(function () {
        let index = $(this).parents('li').index()
        let currentLocId = globalLocalIds[index]
        wx.previewImage({
          current: currentLocId, // 当前显示图片的http链接
          urls: globalLocalIds // 需要预览的图片http链接列表
        });
      })
    }
    /**
     * 删除图片
     */
    function deletImage() {
      $('ul .img_delet_btn').off().click(function () {
        const domElem = $(this).parents('li')
        const serverPath = domElem.attr('serverpath')
        $.post(wall.$api.deletImgUrl, {
          serverPath: serverPath
        }, res => {
          if (res.code == 1) {
            globalLocalIds.splice(domElem.index(), 1)
            // 移除dom
            domElem.remove()
            totalNum === parseInt($('ul .add_pic_item').length) ? $("#imgUpload").hide() : $("#imgUpload").show()
          } else {
            layer.msg('删除失败')
          }
        }, 'json')
      })
    }

学习、JS-SDK文档链接

地址
后盾人 => http://houdunren.gitee.io/note/
微信 => JS-SDK官方 https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html#17

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值