微信小程序多图片上传全栈实战

本篇教程技术栈:springBoot(Java后端)+  微信小程序。完整的图片上传教程。

页面截图,点击图片右上角按钮可以删除图片。

1、图片上传需要使用wx.uploadFile(Object object)接口

官方示例代码如下:

wx.chooseImage({
  success(res) {
    const tempFilePaths = res.tempFilePaths
    wx.uploadFile({
      url: 'https://example.weixin.qq.com/upload', // 仅为示例,非真实的接口地址
      filePath: tempFilePaths[0],
      name: 'file',
      formData: {
        user: 'test'
      },
      success(res) {
        const data = res.data
        // do something
      }
    })
  }
})

参数说明如下图所示:

有三个是必填的参数,url、filePath、name。其中name的需要和Java后台的保持一致,切记!!!本历程还使用了formData参数,上传文本数据。

2、小程序完整代码如下:

①js文件

// pages/lost-found/lost-found.js
var api = require("../../utils/api.js");
var that;
var app = getApp();
var adds = {};
Page({
  data: {
    image_width: 0,
    nickName: "",
    avatarUrl: "",
    loading: false,
    images: [],
    urlArr: [],
    publishList: ["拾到物品", "丢失物品"],
    reasonList: ["卡类", "钥匙", "数码产品", "U盘", "其他物品"],
    idP: null,
    idR: null,
    choseReason: '',
    formdata: '',
    content: '',
    tel: "",
    extracontent: '',
  },

  onLoad: function () {
    that = this;
    wx.getSystemInfo({
      success: function (res) {
        // console.log(res);
        that.setData({
          image_width: (res.windowWidth / 4) - 10
        });
      }
    });
  },

  bindSubmit: function (e) {
    // 判断是否正在上传图片
    // if (that.data.loading) {
    // 	return;
    // }
    var reason = that.data.choseReason;
    var content = e.detail.value.content;
    var nickName = app.globalData.wxuserInfo.nickName;
    var publish = that.data.chosePublish;
    var tel = e.detail.value.tel;
    if (!reason) {
      wx.showToast({
        title: '请选择物品类型',
        image: '../../images/more/about.png',
        duration: 2000
      })
    }
    else if (!content) {
      wx.showToast({
        title: '请填写拾到/丢失地点',
        image: '../../images/more/about.png',
        duration: 2000
      })
    } else if (!tel) {
      wx.showToast({
        title: '请填写正确的联系方式',
        image: '../../images/more/about.png',
        duration: 2000
      })
    }
    else {
      nickName = app.globalData.wxuserInfo.nickName;
      publish = that.data.chosePublish;
      reason = that.data.choseReason;
      content = e.detail.value.content;//拾到或者丢失地点
      that.setData({
        content: e.detail.value.content,
        extracontent: e.detail.value.extracontent,
        tel: e.detail.value.tel
      })
      this.uploadViews()
    }
  },
  chosePublish: function (e) {
    var index1 = e.currentTarget.dataset.index;  //获取自定义的ID值  
    this.setData({
      idP: index1,
      chosePublish: that.data.publishList[index1]
    })
    console.log(that.data.idP);
    // console.log(that.data.chosePublish);
  },

  choseReason: function (e) {
    var index2 = e.currentTarget.dataset.index;  //获取自定义的ID值  
    this.setData({
      idR: index2,
      choseReason: that.data.reasonList[index2]
    })
  },

  upImg: function () {
    var that = this;
    wx.chooseImage({
      count: 9, // 默认9
      sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
      sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
      success: function (res) {
        wx.showNavigationBarLoading()
        that.setData({
          loading: false
        })
        var urlArr = that.data.urlArr;
        // var urlArr={};
        var tempFilePaths = res.tempFilePaths;
        var images = that.data.images;
        // console.log(tempFilePaths);
        that.setData({
          images: images.concat(tempFilePaths),
        });
      }
    })
    console.log(that.data.urlArr)
  },
  uploadViews: function () {
    var that = this
    if (this.data.images.length == 0) {
      wx.request({
        url: api.lostfoundNoImgUrl,
        data: {
          nickName: app.globalData.wxuserInfo.nickName,
          publish: that.data.chosePublish,
          reason: that.data.choseReason,
          content: that.data.content,
          extracontent: that.data.extracontent,
          tel: that.data.tel,
        }, //表单数据
        method: 'POST',
        header: {
          "Content-Type": "application/x-www-form-urlencoded"
        },
        name: 'views',
        success: function (res) {
          console.log(res);
          if (res.statusCode == 200) {
            wx.showToast({
              title: '反馈成功,感谢!',
              icon: "success",
              duration: 1500,
            })
          } else {
            wx.showToast({
              title: '提交失败',
              icon: "fail",
              duration: 1500,
            });
            that.setData({
              reason: '',
              content: '',
            })

          }
          setTimeout(function () {
            wx.switchTab({
              url: '../index/index',
            })
          }, 2000)
        },
      })
    } else {
      for (var i = 0; i < this.data.images.length; i++) {
        wx.uploadFile({
          url: api.lostfoundUrl,
          filePath: that.data.images[i],
          name: 'lostfound',
          formData: {
            'nickName': app.globalData.wxuserInfo.nickName,
            'publish': that.data.chosePublish,
            'reason': that.data.choseReason,
            'content': that.data.content,
            'extracontent': that.data.extracontent,
            'tel': that.data.tel,
          },
          header: {
            'content-type': 'multipart/form-data'
          },
          success: function (res) {
            console.log(res)
            if (res.statusCode == 200) {
              wx.showToast({
                title: '反馈成功,感谢!',
                duration: 1500
              });
            } else {
              wx.showToast({
                title: '提交失败',
                icon: "fail",
                duration: 1500,
              });
            }
            setTimeout(function () {
              wx.switchTab({
                url: '../index/index',
              })
            }, 2000)
          }

        })
        this.setData({
          adds: {},
        })
      }
    }
    this.setData({
      adds: {},
      images: ''
    })
  },

 // 获取本地显示的图片数组
  delete: function (e) {
    var index = e.currentTarget.dataset.index;
    var images = that.data.images;
    var urlArr = that.data.urlArr;
    urlArr.splice(index, 1);
    images.splice(index, 1);
    that.setData({
      images: images,
      urlArr: urlArr
    });
    console.log(that.data.urlArr)
  },

  // 检查字符串是否为合法手机号码
  isPhone: function (str) {
    var reg = /^1(3|4|5|7|8|9)\d{9}$/;
    if (reg.test(str)) {
      return 1;
    } else {
      return -1;
    }
  },
  /**
   * 用户点击右上角分享
   */
  onShareAppMessage: function () {

  }
})

代码中,分了两种情况,带图片上传和不带图片上传。默认选择图片上传数量为9张,修改count的值就可以了。

②wxml文件

<view class="page">
  <form bindsubmit="bindSubmit">
    <view class="head">
      <view class="headText">* 请选择发布类型</view>
    </view>

    <view class="chosePublish">
      <view class="reasonItem" wx:for="{{publishList}}" data-index="{{index}}" bindtap="chosePublish" style="{{index==idP?'background-color: #2782D7;color:#fff':' background-color: #efefef;' }}">
        <view bindtap="falseInformation">{{item}}</view>
      </view>
    </view>

    <view class="remark">
      <view class="headText">* 请选择物品类型</view>
    </view>

    <view class="choseReason">
      <view class="reasonItem" wx:for="{{reasonList}}" data-index="{{index}}" bindtap="choseReason" style="{{index==idR?'background-color: #2782D7;color:#fff':' background-color: #efefef;' }}">
        <view bindtap="falseInformation">{{item}}</view>
      </view>
    </view>

    <view class="remark">
      <text class="remark-title">* 拾到/丢失地点:</text>
      <textarea name="content" class="inputRemark" bindblur="bindTextAreaBlur" maxlength="500" placeholder="请简单说明" />
    </view>

    <view class="remark">
      <text class="remark-title">* 额外说明:<text style="color:#737373;font-size:30rpx;">(若无可不填)</text></text>
      <textarea name="extracontent" class="inputRemark" bindblur="bindTextAreaBlur" maxlength="500" placeholder="如有其他情况,可简要说明" />
    </view>

    <view class="remark_tel">
      <text class="tel-title">* 联系方式:</text>
      <input name="tel" class="input" type='number' maxlength="100" value='{{tel}}' placeholder="QQ/微信/手机号" />
    </view>

    <text class="imageTitle">* 相关图片:<text style="color:#737373;font-size:30rpx;">(若无则可不上传)</text></text>
    <view class="gallery">
      <view class="itemImage" wx:for="{{images}}">
        <!-- <image class="thumb" data-current="{{item}}"  style="width: {{2*image_width}}rpx; height: {{2*image_width}}rpx" src="{{item.url}}" /> -->
        <!-- 默认数组的当前项的下标变量名默认为 index,数组当前项的变量名默认为 item -->
        <image class="thumb" data-current="{{item}}" style="width: {{2*image_width}}rpx; height: {{2*image_width}}rpx" src="{{item}}" />
        <image class="delete" src="../../images/more/deleteImage.png" data-index="{{index}}" bindtap="delete"></image>
      </view>
      <image class="thumb" style="width: {{2*image_width}}rpx; height: {{2*image_width}}rpx" src="../../images/more/upload.png" bindtap="upImg" />
    </view>
    <button class="submitButton" formType="submit">发布</button>
  </form>

</view>

③wxss文件

page{
     height: 100%;
 }
.page{
    font-family: 'PingFang SC', 'Helvetica Neue', Helvetica, 'Droid Sans Fallback', 'Microsoft Yahei', sans-serif;
    height: 100%;
    background-color: #efefef;
}

.head{

  background-color: #fff;
}

.headText{
  padding: 20rpx 0rpx 0rpx 20rpx;
  color: #2782D7;
}

.chosePublish{
  padding: 10rpx 0rpx 30rpx 0rpx; 
  display: flex;
  flex-direction: row;
  background-color: #fff;
}
.choseReason{

  padding: 10rpx 0rpx 30rpx 0rpx; 
  display: flex;
  flex-direction: row;
  background-color: #fff;
  /* display:inline-block; */
}

.reasonItem{
  margin:15rpx;
  padding: 15rpx;
  background-color: #efefef;
  float:left;
  display:inline;
  color: #7a7a7a;

}

.remark{
  margin-top: 20rpx;
  background-color: #fff;
}
.remark_tel{
  display: flex;
  margin-top: 20rpx;
  height: 80rpx;
  line-height: 80rpx;
  align-items: center;
  background-color: #fff;
}
.tel-title{
  float: left; 
  padding-left: 20rpx;
  height: 60rpx;
  line-height: 60rpx; 
  width: 40%;
  color: #2782D7;
}

.input {
  height: 60rpx;
  line-height: 60rpx;
  padding-left: 10rpx;
}

.remark-title{
  display: flex;
  color: #2782D7;
  padding: 30rpx 0rpx 30rpx 20rpx;
}

.inputRemark{
  padding: 0rpx 20rpx 0rpx 20rpx;
  width: 90%;
  height: 80rpx;
}

.imageTitle{
  display: flex;
  color: #2782D7;
  margin-top: 20rpx;
  padding: 30rpx 0rpx 30rpx 20rpx;
  background-color: #fff;
}
.gallery {
    display: flex;
    flex-direction: row;
    justify-content: flex-start;
    flex-wrap: wrap;
    background-color: #fff;

}

/*每张图片所占容器*/
.itemImage {
    position: relative;
}


/*小图片*/
.thumb {
	margin: 10rpx;
  position: relative;
}

/*删除按钮*/
.delete {
	position: absolute;
	height: 40rpx;
	top: 0rpx;
  right:0;
	width: 40rpx;
}

.delete image {
	position: absolute;
	width: 30rpx;
	height: 30rpx;
}

.photo{
 text-align: center;
 margin: 30rpx 0rpx 20rpx 0rpx;
}

.submitButton{   
    width:80%;
    height:90rpx;
    background-color:#2782D7;
    border-radius:30px;
    color:#fff;
   margin: auto;
   margin-top: 30rpx;
   margin-bottom: 50rpx;
   display:flex;
    justify-content:center;
    align-items:center;
}

3、Java后端,springboot搭建

controller文件

package com.ahu.controller;

import com.ahu.Repository.LostFoundApplyRepository;
import com.ahu.domain.LostFoundApply;
import com.ahu.exception.ExceptionManager;
import com.ahu.utils.Response;
import io.swagger.annotations.ApiOperation;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @author R
 * UPLOAD请求修改为POST请求
 * 可支持图片上传 2018-12-5 【xrq】
 */
@RestController
@RequestMapping("/v1")
public class UploadController {
    private final ExceptionManager exceptionManager;
    private final LostFoundApplyRepository lostFoundApplyRepository;
    private Logger logger = Logger.getLogger(UploadController.class);
    @Autowired
    public UploadController(ExceptionManager exceptionManager, LostFoundApplyRepository lostFoundApplyRepository) {
        this.userInfoRepository = userInfoRepository;
        this.exceptionManager = exceptionManager;
        this.lostFoundApplyRepository=lostFoundApplyRepository;
    }

    @Transactional
    @ApiOperation(value = "失物招领上传无图")
    @RequestMapping(value = "lostfoundNoImg", method = RequestMethod.POST)
    public Response lostFoundInfo(
            @RequestParam(value = "nickName") String nickName,
            @RequestParam(value = "publish") String publish,
            @RequestParam(value = "reason") String reason,
            @RequestParam(value = "content") String content,
            @RequestParam(value = "extracontent") String extracontent,
            @RequestParam(value = "tel") String tel
    ) {
        Date now = new Date();
        LostFoundApply lostFoundApply = new LostFoundApply();
        lostFoundApply.setNickName(nickName);
        lostFoundApply.setPublish(publish);
        lostFoundApply.setReason(reason);
        lostFoundApply.setContent(content);
        lostFoundApply.setExtracontent(extracontent);
        lostFoundApply.setTel(tel);
        lostFoundApply.setApplytime(now);
        lostFoundApplyRepository.save(lostFoundApply);
        return new Response().success();
    }

    @ResponseBody
    @ApiOperation(value = "失物招领上传多图")
    @RequestMapping(value = "/lostfound")
    public String lostFoundInfo(
            HttpServletRequest request,
            HttpServletResponse response,
              @RequestParam(value = "nickName") String nickName,
              @RequestParam(value = "publish") String publish,
              @RequestParam(value = "reason") String reason,
              @RequestParam(value = "content") String content,
              @RequestParam(value = "extracontent") String extracontent,
              @RequestParam(value = "tel") String tel
              @RequestParam(value = "lostfound") MultipartFile file
    ) throws IOException {
        request.setCharacterEncoding("UTF-8");
        BufferedOutputStream stream = null;
        logger.info("file:" + file);
        String nickName=request.getParameter("nickName");
        String publish=request.getParameter("publish");
        String reason=request.getParameter("reason");
        String content=request.getParameter("content");
        String extracontent=request.getParameter("extracontent");
        String tel=request.getParameter("tel");
        logger.info("nickName:" + nickName);
        Date now = new Date();
        LostFoundApply lostFoundApply = new LostFoundApply();
        lostFoundApply.setNickName(nickName);
        lostFoundApply.setPublish(publish);
        lostFoundApply.setReason(reason);
        lostFoundApply.setContent(content);
        lostFoundApply.setExtracontent(extracontent);
        lostFoundApply.setTel(tel);
        lostFoundApply.setApplytime(now);
        lostFoundApplyRepository.save(lostFoundApply);
        if(!file.isEmpty()) {
            String fileName = file.getOriginalFilename();
            String path = null;
            String type = null;
            type = fileName.indexOf(".") != -1 ? fileName.substring(fileName.lastIndexOf(".") + 1, fileName.length()) : null;
            logger.info("图片初始名称为:" + fileName + " 类型为:" + type);
            if (type != null) {
                logger.info("成功获取照片");
                if ("GIF".equals(type.toUpperCase())||"PNG".equals(type.toUpperCase())||"JPG".equals(type.toUpperCase())) {
                    // 项目在容器中实际发布运行的根路径
//                    String realPath = request.getSession().getServletContext().getRealPath("/");
                    // 自定义的文件名称
//                    String trueFileName = String.valueOf(System.currentTimeMillis()) + fileName;
                    String trueFileName = String.valueOf(nickName) + fileName;
                    // 设置存放图片文件的路径
//                    path = realPath + "uploads\\" + trueFileName;
                    path="C:\\java\\LostFound\\"+ trueFileName;
                    logger.info("存放图片文件的路径:" + path);
                    file.transferTo(new File(path));
                    logger.info("文件成功上传到指定目录下!");
                }else {
                    logger.info("不是我们想要的文件类型,请按要求重新上传");
                    return "error";
                }
            }else {
                logger.info("文件类型为空");
                return "error";
            }
        }
        else {
            logger.info("没有找到相对应的文件");
            return "error";
        }
        return "success";
    }
}

以上是完整的多图片教程,感兴趣的可以一起交流学习啊

QQ交流群:678239065    

个人微信:

个人作品:

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大猩猩爱分享

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值