转自:https://idig8.com/2018/09/08/xiaochengxujavashizhanxiaochengxutouxiangtupianshangchuan40/

在微信小程序中,有很多的场景是用来上传图片的,有的图片是拍摄获得,有的直接选择手机端的相册。源码:https://github.com/limingios/wxProgram.git 中No.15

官方组件的介绍

  • 图片选择API

官方网站:https://developers.weixin.qq.com/miniprogram/dev/api/media-picture.html

  • 文件上传API
    > 官方网站:https://developers.weixin.qq.com/miniprogram/dev/api/network-file.html

增加头像的点击事件

<view>

  <view class='container'>
<image src="{{faceUrl}}" class="face" bindtap='uploadFace'></image>
<label class='nickname'>{{nickname}}</label>
<button size='mini' class='primary' bindtap='uploadVideo'> 上传作品</button>
<button size='mini' type='' class='logout' bindtap='logout'>注销</button> <button size='mini' type='' class='follow' data-followType='0' bindtap='followMe'>已关注</button> <button size='mini' type='primary' class='follow' data-followType='1' bindtap='followMe'>关注我</button> <view class='container-row'>
<label class='info-items'>{{fansCounts}} 粉丝</label>
<label class='info-items'>{{followCounts}} 关注</label>
<label class='info-items'>{{receiveLikeCounts}} 获赞</label>
</view>
</view> </view> <view class="line"></view>

// pages/mine/mine.js
const app = getApp()
Page({ /**
* 页面的初始数据
*/
data: {
faceUrl: "../../resource/images/noneface.png",
nickname: "昵称",
fansCounts: 0,
followCounts: 0,
receiveLikeCounts: 0,
},
/**
* 用户注销
*/
logout:function(e){
var user = app.userInfo;
wx.showLoading({
title: '正在注销中。。。'
});
wx.request({
url: app.serverUrl + "/logout?userId="+user.id,
method: "POST",
header: {
'content-type': 'application/json' // 默认值
},
success: function (res) {
console.log(res.data);
var status = res.data.status;
wx.hideLoading();
if (status == 200) {
wx.showToast({
title: "用户注销成功~!",
icon: 'none',
duration: 3000
})
app.userInfo = null;
wx.redirectTo({
url: '../userRegister/userRegister',
}) } else if (status == 500) {
wx.showToast({
title: res.data.msg,
icon: 'none',
duration: 3000
})
}
}
})
},
/**
* 头像上传
*/
uploadFace:function(e){
var user = app.userInfo;
var me = this;
wx.chooseImage({
count: 1, // 默认9
sizeType: ['compressed'], // 可以指定是原图还是压缩图,默认二者都有
sourceType: ['camera'], // 可以指定来源是相册还是相机,默认二者都有
success: function (res) {
// 返回选定照片的本地文件路径列表,tempFilePath可以作为img标签的src属性显示图片
var tempFilePaths = res.tempFilePaths
if (tempFilePaths.length>0){
console.log(tempFilePaths[0]);
wx.uploadFile({
url: app.serverUrl + "/user/uploadFace?userId=" + user.id, //仅为示例,非真实的接口地址
filePath: tempFilePaths[0],
name: 'file',
success: function (res) {
var data = JSON.parse(res.data);
console.log(data);
wx.hideLoading();
if (data.status == 200) {
wx.showToast({
title: "用户上传成功~!",
icon: 'none',
duration: 3000
})
me.setData({
faceUrl: app.serverUrl+data.data
}) } else if (data.status == 500) {
wx.showToast({
title: data.msg,
icon: 'none',
duration: 3000
})
}
}
})
} }
})
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) { }, /**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () { }, /**
* 生命周期函数--监听页面显示
*/
onShow: function () { }, /**
* 生命周期函数--监听页面隐藏
*/
onHide: function () { }, /**
* 生命周期函数--监听页面卸载
*/
onUnload: function () { }, /**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () { }, /**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () { }, /**
* 用户点击右上角分享
*/
onShareAppMessage: function () { }
})

后端spring boot文件的处理

增加文件上传的工具类,时刻要记住我们是代码的搬运工,不是代码的制造者。能用现成的工具,绝对不手动开发一个。

  • common中
    FileUtil.java
package com.idig8.utils.file;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Calendar;
import java.util.UUID;
import javax.imageio.ImageIO; import com.idig8.utils.file.enums.FileEnum; public class FileUtil {
public static String uploadFile(byte[] file, String filePath, String fileName) throws Exception {
String newDir = getDirAndDateDir(fileName);
File targetFile = new File(filePath + newDir);
if (!targetFile.exists()) {
targetFile.mkdirs();
}
FileOutputStream out = new FileOutputStream(filePath + newDir + fileName);
out.write(file);
out.flush();
out.close();
return newDir + fileName;
} // 物理删除;
public static boolean deleteFile(String fileName) {
File file = new File(fileName);
// 如果文件路径所对应的文件存在,并且是一个文件,则直接删除
if (file.exists() && file.isFile()) {
if (file.delete()) {
return true;
} else {
return false;
}
} else {
return false;
}
} public static String renameToUUID(String fileName) {
return UUID.randomUUID() + "." + fileName.substring(fileName.lastIndexOf(".") + 1);
} public static String renameToUUID() {
return UUID.randomUUID().toString();
} public static boolean isImage(InputStream inputStream) throws IOException {
BufferedImage bufferedImage = ImageIO.read(inputStream);
if(bufferedImage == null) {
return false;
}
return true;
} public static boolean isImage(File file) throws IOException {
BufferedImage bufferedImage = ImageIO.read(file);
if(bufferedImage == null) {
return false;
}
return true;
} public static String getDirAndDateDir(String fileName){
String suffix = fileName.substring(fileName.lastIndexOf(".") + 1);
String dir = "";
for (FileEnum f : FileEnum.values()) {
if(suffix.equals(f.getSuffix())){
dir = f.getDir();
}
}
Calendar now = Calendar.getInstance();
int year = now.get(Calendar.YEAR);
int month = now.get(Calendar.MONTH) + 1;
int day = now.get(Calendar.DAY_OF_MONTH);
String dateTime = year+"-"+month+"-"+day;
return dir+"/"+dateTime+"/";
}
}

  • api 增加java类
package com.idig8.controller;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile; import com.idig8.service.UserService;
import com.idig8.utils.JSONResult;
import com.idig8.utils.file.FileUtil; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation; @RestController
@Api(value="用户接口",tags={"用户的controller"})
@RequestMapping(value = "/user")
public class UserController extends BasicController{ @Autowired
private UserService userService; @Value("${server.face.path}")
private String fileSpace; @ApiOperation(value="用户上传头像",notes="用户上传头像的接口") @ApiImplicitParams({
@ApiImplicitParam(name="userId",value="用户id",required=true,dataType="String",paramType="query"),
@ApiImplicitParam(name="file",value="文件上传",required=true,dataType="String",paramType="query"),
})
@PostMapping("/uploadFace")
public JSONResult uploadFace(String userId,@RequestParam("file") MultipartFile file) {
if (StringUtils.isBlank(userId)) {
return JSONResult.errorMsg("用户id不能为空...");
} // 文件保存的命名空间
String fileName = file.getOriginalFilename();
// 保存到数据库中的相对路径
try {
FileUtil.uploadFile(file.getBytes(), fileSpace, fileName);
} catch (Exception e) {
e.getStackTrace();
return JSONResult.errorMsg(e.getMessage());
} return JSONResult.ok();
} }

另外需要注意的是:在controller里面我增加了一个读配置文件里面属性的参数。 @Value(“${server.face.path}”)

  • 上传后的路径

PS:基本头像上传已经完毕,主要是springboot和小微信API的使用。对于用户表中的头像更新和交互式弹框,我后来都在源码上做了升级。建议观看源码。

「小程序JAVA实战」小程序头像图片上传(上)(43)的更多相关文章

  1. 「小程序JAVA实战」小程序的举报功能开发(68)

    转自:https://idig8.com/2018/09/25/xiaochengxujavashizhanxiaochengxudeweixinapicaidancaozuo66-2/ 通过点击举报 ...

  2. 「小程序JAVA实战」小程序的个人信息作品,收藏,关注(66)

    转自:https://idig8.com/2018/09/24/xiaochengxujavashizhanxiaochengxudegerenxinxizuopinshoucangguanzhu65 ...

  3. 「小程序JAVA实战」小程序的关注功能(65)

    转自:https://idig8.com/2018/09/24/xiaochengxujavashizhanxiaochengxudeguanzhugongneng64/ 在个人页面,根据发布者个人和 ...

  4. 「小程序JAVA实战」小程序的视频点赞功能开发(62)

    转自:https://idig8.com/2018/09/24/xiaochengxujavashizhanxiaochengxudeshipindianzangongnengkaifa61/ 视频点 ...

  5. 「小程序JAVA实战」小程序的springboot后台拦截器(61)

    转自:https://idig8.com/2018/09/24/xiaochengxujavashizhanxiaochengxudespringboothoutailanjieqi60/ 之前咱们把 ...

  6. 「小程序JAVA实战」小程序首页视频(49)

    转自:https://idig8.com/2018/09/21/xiaochengxujavashizhanxiaochengxushouyeshipin48/ 视频显示的内容是视频的截图,用户的头像 ...

  7. 「小程序JAVA实战」小程序视频封面处理(48)

    转自:https://idig8.com/2018/09/16/xiaochengxujavashizhanxiaochengxushipinfengmianchuli47/ 截图这块,在微信小程序工 ...

  8. 「小程序JAVA实战」小程序上传短视频(46)

    转自:https://idig8.com/2018/09/14/xiaochengxujavashizhanxiaochengxushangchuanduanshipin45/ 个人信息:用户上传短视 ...

  9. 「小程序JAVA实战」小程序头像图片上传(下)(45)

    转自:https://idig8.com/2018/09/09/xiaochengxujavashizhanxiaochengxutouxiangtupianshangchuan44/ 接下来,我们应 ...

随机推荐

  1. c# mysql and sqlserver数据库连接字符串

    .net 项目访问sqlserver 和mysql 两种数据库时,连接字符串有些不一样 具体配置如下 <connectionStrings> <add name="mysq ...

  2. VMWare安装Ubuntu及配置开发环境遇到的问题集

    安装完Ubuntu改为中文,发现是中英文混搭的界面 sudo apt-get install $(check-language-support --language=zh_CN)更新语言包. Ecli ...

  3. #Eclipse web工程 部署 三种方式 3

    Eclipse web工程 部署 三种方式 3.热部署 在Eclipse中,实现 修改一个.java文件或者.jsp文件甚至是配置文件,不需要重启WEB服务器的前提下让修改生效,实现tomcat自动加 ...

  4. JPA无法删除对象【实际项目解决办法】

    并非通用, 根据自己实际情况来 不能删除前的dao方法 public void delete(CmsProjectNew bean); 可以删除后的dao方法 @Modifying @Query(&q ...

  5. Loj 2028 随机序列

    Loj 2028 随机序列 连续的乘号会将序列分成若干个块,块与块之间用加减号连接: \[ (a_1*a_2*...a_i)\pm(a_{i+1}*a_{i+2}*...a_j)\pm... \] 除 ...

  6. vector 中的clear()

    为什么clear之后,还是输出fdsafdsa.有什么办法可以真正清空之? 因为对于vector,clear并不真正释放内存(这是为优化效率所做的事),clear实际所做的是为vector中所保存的所 ...

  7. 《DSP using MATLAB》示例Example7.25

    今天清明放假的第二天,早晨出去吃饭时天气有些阴,十点多开始“清明时节雨纷纷”了. 母亲远在他乡看孙子,挺劳累的.父亲照顾生病的爷爷…… 我打算今天把<DSP using MATLAB>第7 ...

  8. [Luogu4233]射命丸文的笔记

    luogu description 对于\(x\in[1,n]\)求\(x\)点强联通竞赛图中的哈密顿回路的期望个数膜\(998244353\). \(n\le10^5\) sol 首先\(n\)点竞 ...

  9. java中线程安全问题

    在java中单线程和多线程是什么意思,他们有什么区别,分别的作用是什么? 在一个程序中,这些独立运行的程序片断叫作“线程”(Thread),利用它编程的概念就叫作“多线程处理”.多线程处理一个常见的例 ...

  10. [语法]C语言中二维数组做输入参数

    C语言中二维数组做输入参数时, 可以同时指定各维长度, 可以只指定第二维的长度, 不可以只指定第一维的长度, 不可以各维长度都不指定. 一句话总结:要指定至少指定第二维,都不指定是不行的. 具体栗子如 ...