微信小程序_(校园视)开发用户注册登陆
微信小程序_(校园视) 开发用户注册登陆 传送门
微信小程序_(校园视) 开发上传视频业务 传送门
微信小程序_(校园视) 开发视频的展示页-上 传送门
微信小程序_(校园视) 开发视频的展示页-下 传送门
用户注册界面
<view> <view class="login-icon"> <image class="login-img" src="../resource/images/dsp.jpg"></image> </view> <view class="login-from"> <form bindsubmit='doRegist'> <!--账号--> <view class="inputView"> <image class="nameImage" src="../resource/images/username.png"></image> <label class="loginLabel">账号</label> <input name="username" class="inputText" placeholder="请输入账号"/> </view> <view class="line"></view> <!--密码--> <view class="inputView"> <image class="keyImage" src="../resource/images/password.png"></image> <label class="loginLabel">密码</label> <input name="password" class="inputText" password="true" placeholder="请输入密码"/> </view> <!--按钮--> <view> <button class="loginBtn" type="primary" form-type='submit'>注册</button> </view> <view> <button class="goLoginBtn" type="warn" bindtap="goLoginPage">返回登录</button> </view> </form> </view> </view>
page { background-color: whitesmoke; } .login-img { width: 750rpx; } /*表单内容*/ .inputView { background-color: white; line-height: 45px; } /*输入框*/ .nameImage, .keyImage { margin-left: 22px; width: 20px; height: 20px; } .loginLabel { margin: 15px 15px 15px 10px; color: gray; font-size: 15px; } .inputText { float: right; text-align: right; margin-right: 22px; margin-top: 11px; font-size: 15px; } .line { width: 100%; height: 1px; background-color: gainsboro; margin-top: 1px; } /*按钮*/ .loginBtn { width: 80%; margin-top: 35px; } .goLoginBtn { width: 80%; margin-top: 15px; }
{ "pages":[ "pages/userRegist/regist", "pages/index/index" ], "window":{ "backgroundTextStyle":"light", "navigationBarBackgroundColor": "#fff", "navigationBarTitleText": "校园视", "navigationBarTextStyle":"black" } }
配置项目工程文件
package com.imooc; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.ComponentScan; import tk.mybatis.spring.annotation.MapperScan; @SpringBootApplication @ComponentScan(basePackages= {"com.imooc"}) public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
package com.imooc.controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class HelloWorldController { @RequestMapping("/hello") public String Hello() { return "Hello Spring Boot~"; } }
数据库表设计
八个表
users用户表
user_fans用户粉丝表
video视频表
users_like_videos用户关注表
user_report用户回复表
bgm背景音乐表
用户留言表
用户关系表
使用SpringBoot版mybatis逆向生成工具生成数据库中表
package com.wx.mybatis.utils; import java.io.File; import java.util.ArrayList; import java.util.List; import org.mybatis.generator.api.MyBatisGenerator; import org.mybatis.generator.config.Configuration; import org.mybatis.generator.config.xml.ConfigurationParser; import org.mybatis.generator.internal.DefaultShellCallback; public class GeneratorDisplay { public void generator() throws Exception{ List<String> warnings = new ArrayList<String>(); boolean overwrite = true; //指定 逆向工程配置文件 File configFile = new File("generatorConfig.xml"); ConfigurationParser cp = new ConfigurationParser(warnings); Configuration config = cp.parseConfiguration(configFile); DefaultShellCallback callback = new DefaultShellCallback(overwrite); MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings); myBatisGenerator.generate(null); } public static void main(String[] args) throws Exception { try { GeneratorDisplay generatorSqlmap = new GeneratorDisplay(); generatorSqlmap.generator(); } catch (Exception e) { e.printStackTrace(); } } }
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd"> <generatorConfiguration> <context id="MysqlContext" targetRuntime="MyBatis3Simple" defaultModelType="flat"> <property name="beginningDelimiter" value="`"/> <property name="endingDelimiter" value="`"/> <plugin type="tk.mybatis.mapper.generator.MapperPlugin"> <property name="mappers" value="com.wx.utils.MyMapper"/> </plugin> <jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://localhost:3306/wx-video-dev" userId="root" password="123456"> </jdbcConnection> <!-- 对应生成的pojo所在包 --> <javaModelGenerator targetPackage="com.wx.pojo" targetProject="src/main/java"/> <!-- 对应生成的mapper所在目录 --> <sqlMapGenerator targetPackage="mapper" targetProject="src/main/resources"/> <!-- 配置mapper对应的java映射 --> <javaClientGenerator targetPackage="com.wx.mapper" targetProject="src/main/java" type="XMLMAPPER"/> <table tableName="bgm"></table> <table tableName="comments"></table> <table tableName="search_records"></table> <table tableName="users"></table> <table tableName="users_fans"></table> <table tableName="users_like_videos"></table> <table tableName="users_report"></table> <table tableName="videos"></table> </context> </generatorConfiguration>
开发注册用户的接口
IMoocJSONResult.java作为数据的传参,MD5Utils.java对密码作为MD5的加密
在mini-api层创建RegistLoginController.java接收regist请求
用户注册请求RegistLoginController.java
@PostMapping("/regist") public IMoocJSONResult regist(@RequestBody Users user) throws Exception { //1.判断用户名和密码必须不为空 if(StringUtils.isBlank(user.getUsername())||StringUtils.isBlank(user.getPassword())) { return IMoocJSONResult.errorMsg("用户名和密码不能为空"); } //2.判断用户名是否存在 boolean usernameIsExist = userService.queryUsernameIsExist(user.getUsername()); //3.保存用户注册信息 if(!usernameIsExist) { user.setNickname(user.getUsername()); user.setPassword(MD5Utils.getMD5Str(user.getPassword())); user.setFansCounts(0); user.setReceiveLikeCounts(0); user.setFollowCounts(0); userService.saveUser(user); }else { return IMoocJSONResult.errorMsg("用户名已经存在,请重新输入"); } return IMoocJSONResult.ok(); }
用户注册接口UserService.java
public interface UserService { //判断用户名是否存在 public boolean queryUsernameIsExist(String username); //用户注册 public void saveUser(Users user); }
实现用户注册接口UserServiceImpl
@Transactional(propagation = Propagation.SUPPORTS) @Override public boolean queryUsernameIsExist(String username) { Users user = new Users(); user.setUsername(username); Users result = userMapper.selectOne(user); return result==null?false:true; } @Transactional(propagation = Propagation.REQUIRED) @Override public void saveUser(Users user) { String userId = sid.nextShort(); user.setId(userId); userMapper.insert(user); }
package com.imooc.controller; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import com.imooc.pojo.Users; import com.imooc.service.UserService; import com.imooc.utils.IMoocJSONResult; import com.imooc.utils.MD5Utils; @RestController public class RegistLoginController { @Autowired private UserService userService; @PostMapping("/regist") public IMoocJSONResult regist(@RequestBody Users user) throws Exception { //1.判断用户名和密码必须不为空 if(StringUtils.isBlank(user.getUsername())||StringUtils.isBlank(user.getPassword())) { return IMoocJSONResult.errorMsg("用户名和密码不能为空"); } //2.判断用户名是否存在 boolean usernameIsExist = userService.queryUsernameIsExist(user.getUsername()); //3.保存用户注册信息 if(!usernameIsExist) { user.setNickname(user.getUsername()); user.setPassword(MD5Utils.getMD5Str(user.getPassword())); user.setFansCounts(0); user.setReceiveLikeCounts(0); user.setFollowCounts(0); userService.saveUser(user); }else { return IMoocJSONResult.errorMsg("用户名已经存在,请重新输入"); } return IMoocJSONResult.ok(); } }
package com.imooc.service; import com.imooc.pojo.Users; public interface UserService { //判断用户名是否存在 public boolean queryUsernameIsExist(String username); //用户注册 public void saveUser(Users user); }
package com.imooc.service; import org.n3r.idworker.Sid; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import com.imooc.mapper.UsersMapper; import com.imooc.pojo.Users; @Service public class UserServiceImpl implements UserService { @Autowired private UsersMapper userMapper; @Autowired private Sid sid; @Transactional(propagation = Propagation.SUPPORTS) @Override public boolean queryUsernameIsExist(String username) { Users user = new Users(); user.setUsername(username); Users result = userMapper.selectOne(user); return result==null?false:true; } @Transactional(propagation = Propagation.REQUIRED) @Override public void saveUser(Users user) { String userId = sid.nextShort(); user.setId(userId); userMapper.insert(user); } }
swagger2的使用与接口配置
在common层pom.xml中配置swagger2
<!-- swagger2配置 --> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>2.4.0</version> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>2.4.0</version> </dependency>
package com.imooc; import java.util.ArrayList; import java.util.List; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.builders.ParameterBuilder; import springfox.documentation.builders.PathSelectors; import springfox.documentation.builders.RequestHandlerSelectors; import springfox.documentation.schema.ModelRef; import springfox.documentation.service.ApiInfo; import springfox.documentation.service.Contact; import springfox.documentation.service.Parameter; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.swagger2.annotations.EnableSwagger2; @Configuration @EnableSwagger2 public class Swagger2 { /** * @Description:swagger2的配置文件,这里可以配置swagger2的一些基本的内容,比如扫描的包等等 */ @Bean public Docket createRestApi() { return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).select() .apis(RequestHandlerSelectors.basePackage("com.imooc.controller")) .paths(PathSelectors.any()).build(); } /** * @Description: 构建 api文档的信息 */ private ApiInfo apiInfo() { return new ApiInfoBuilder() // 设置页面标题 .title("使用swagger2构建短视频后端api接口文档") // 设置联系人 .contact(new Contact("校园视-罗韦武 吉桂言", "https://www.cnblogs.com/1138720556Gary/", "1138720556@qq.com")) // 描述 .description("欢迎访问短视频接口文档,这里是描述信息") // 定义版本号 .version("1.0").build(); } }
package com.imooc.pojo; import javax.persistence.*; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; @ApiModel(value="用户对象",description="这是用户对象") public class Users { @ApiModelProperty(hidden=true) @Id private String id; @ApiModelProperty(value="用户名",name="username",example="imoocuser",required=true) private String username; @ApiModelProperty(value="密码",name="password",example="123456",required=true) private String password; @ApiModelProperty(hidden=true) @Column(name = "face_image") private String faceImage; private String nickname; //粉丝 @ApiModelProperty(hidden=true) @Column(name = "fans_counts") private Integer fansCounts; //收到的赞美 @ApiModelProperty(hidden=true) @Column(name = "receive_like_counts") private Integer receiveLikeCounts; //我关注的总人数 @ApiModelProperty(hidden=true) @Column(name = "follow_counts") private Integer followCounts; /** * @return id */ public String getId() { return id; } /** * @param id */ public void setId(String id) { this.id = id; } /** * @return username */ public String getUsername() { return username; } /** * @param username */ public void setUsername(String username) { this.username = username; } /** * @return password */ public String getPassword() { return password; } /** * @param password */ public void setPassword(String password) { this.password = password; } /** * @return face_image */ public String getFaceImage() { return faceImage; } /** * @param faceImage */ public void setFaceImage(String faceImage) { this.faceImage = faceImage; } /** * @return nickname */ public String getNickname() { return nickname; } /** * @param nickname */ public void setNickname(String nickname) { this.nickname = nickname; } /** * @return fans_counts */ public Integer getFansCounts() { return fansCounts; } /** * @param fansCounts */ public void setFansCounts(Integer fansCounts) { this.fansCounts = fansCounts; } /** * @return receive_like_counts */ public Integer getReceiveLikeCounts() { return receiveLikeCounts; } /** * @param receiveLikeCounts */ public void setReceiveLikeCounts(Integer receiveLikeCounts) { this.receiveLikeCounts = receiveLikeCounts; } /** * @return follow_counts */ public Integer getFollowCounts() { return followCounts; } /** * @param followCounts */ public void setFollowCounts(Integer followCounts) { this.followCounts = followCounts; } }
package com.imooc; import java.util.ArrayList; import java.util.List; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.builders.ParameterBuilder; import springfox.documentation.builders.PathSelectors; import springfox.documentation.builders.RequestHandlerSelectors; import springfox.documentation.schema.ModelRef; import springfox.documentation.service.ApiInfo; import springfox.documentation.service.Contact; import springfox.documentation.service.Parameter; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.swagger2.annotations.EnableSwagger2; @Configuration @EnableSwagger2 public class Swagger2 { /** * @Description:swagger2的配置文件,这里可以配置swagger2的一些基本的内容,比如扫描的包等等 */ @Bean public Docket createRestApi() { return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).select() .apis(RequestHandlerSelectors.basePackage("com.imooc.controller")) .paths(PathSelectors.any()).build(); } /** * @Description: 构建 api文档的信息 */ private ApiInfo apiInfo() { return new ApiInfoBuilder() // 设置页面标题 .title("使用swagger2构建短视频后端api接口文档") // 设置联系人 .contact(new Contact("校园视-罗韦武 吉桂言", "https://www.cnblogs.com/1138720556Gary/", "1138720556@qq.com")) // 描述 .description("欢迎访问短视频接口文档,这里是描述信息") // 定义版本号 .version("1.0").build(); } }
小程序注册于后端联调用
小程序端通过app.js获得url地址
//app.js App({ serverUrl:"http://192.168.1.110:8081", userInfo:null })
小程序端点击注册,调用doRegist()函数
<view> <button class="loginBtn" type="primary" form-type='submit'>注册</button> </view>
register.js中处理小程序注册请求消息
Page({ data: { }, doRegist:function(e){ var formObject = e.detail.value; var username = formObject.username; var password = formObject.password; //简单验证 if(username.length==0||password.length==0){ wx.showToast({ title: '用户名或密码不能为空', icon:'none', duration:3000 }) }else{ var serverUrl = app.serverUrl; wx.request({ url: serverUrl + '/regist', method:"POST", data:{ username: username, password: password }, header:{ 'content-type':'application/json'//默认值 }, success:function(res){ console.log(res.data); var status = res.data.status; if(status == 200){ wx.showToast({ title: "用户注册成功~!!!", icon: 'none', duration: 3000 }), app.userInfo = res.data.data; }else if(status == 500){ wx.showToast({ title: res.data.msg, icon: 'none', duration: 3000 }) } } }) } } })
<view> <view class="login-icon"> <image class="login-img" src="../resource/images/dsp.jpg"></image> </view> <view class="login-from"> <form bindsubmit='doRegist'> <!--账号--> <view class="inputView"> <image class="nameImage" src="../resource/images/username.png"></image> <label class="loginLabel">账号</label> <input name="username" class="inputText" placeholder="请输入账号"/> </view> <view class="line"></view> <!--密码--> <view class="inputView"> <image class="keyImage" src="../resource/images/password.png"></image> <label class="loginLabel">密码</label> <input name="password" class="inputText" password="true" placeholder="请输入密码"/> </view> <!--按钮--> <view> <button class="loginBtn" type="primary" form-type='submit'>注册</button> </view> <view> <button class="goLoginBtn" type="warn" bindtap="goLoginPage">返回登录</button> </view> </form> </view> </view>
const app = getApp() Page({ data: { }, doRegist:function(e){ var formObject = e.detail.value; var username = formObject.username; var password = formObject.password; //简单验证 if(username.length==0||password.length==0){ wx.showToast({ title: '用户名或密码不能为空', icon:'none', duration:3000 }) }else{ var serverUrl = app.serverUrl; wx.request({ url: serverUrl + '/regist', method:"POST", data:{ username: username, password: password }, header:{ 'content-type':'application/json'//默认值 }, success:function(res){ console.log(res.data); var status = res.data.status; if(status == 200){ wx.showToast({ title: "用户注册成功~!!!", icon: 'none', duration: 3000 }), app.userInfo = res.data.data; }else if(status == 500){ wx.showToast({ title: res.data.msg, icon: 'none', duration: 3000 }) } } }) } } })
{ "pages":[ "pages/userRegist/regist", "pages/index/index" ], "window":{ "backgroundTextStyle":"light", "navigationBarBackgroundColor": "#fff", "navigationBarTitleText": "校园视", "navigationBarTextStyle":"black" }, "debug":true }
//app.js App({ serverUrl:"http://192.168.1.110:8081", userInfo:null })
小程序用户登陆
小程序端页面编写
后端springboot接口controller
service-更具用户名密码查询用户是否存在
Swagger2的api配置
小程序登陆JS与后端联调
小程序后端用户登陆逻辑
@ApiOperation(value="用户登录", notes="用户登录的接口") @PostMapping("/login") public IMoocJSONResult login(@RequestBody Users user) throws Exception { String username = user.getUsername(); String password = user.getPassword(); // 1. 判断用户名和密码必须不为空 if (StringUtils.isBlank(username) || StringUtils.isBlank(password)) { return IMoocJSONResult.ok("用户名或密码不能为空"); } // 2. 判断用户是否存在 Users userResult = userService.queryUserForLogin(username, MD5Utils.getMD5Str(user.getPassword())); // 3. 返回 if (userResult != null) { userResult.setPassword(""); return IMoocJSONResult.ok(userResult); } else { return IMoocJSONResult.errorMsg("用户名或密码不正确, 请重试"); } }
小程序端点击登陆调用doLogin()函数
<form bindsubmit='doLogin'> <!--账号--> <view class="inputView"> <image class="nameImage" src="../resource/images/username.png"></image> <label class="loginLabel">账号</label> <input name="username" value='imooc' class="inputText" placeholder="请输入账号" /> </view> <view class="line"></view> <!--密码--> <view class="inputView"> <image class="keyImage" src="../resource/images/password.png"></image> <label class="loginLabel">密码</label> <input name="password" value='imooc' class="inputText" password="true" placeholder="请输入密码" /> </view> <!--按钮--> <view> <button class="loginBtn" type="primary" form-type='submit'>登录</button> </view> <view> <button class="goRegistBtn" type="warn" bindtap="goRegistPage">没有账号?点击注册</button> </view> </form>
login.js中处理登陆请求
// 登录 doLogin: function (e) { var me = this; var formObject = e.detail.value; var username = formObject.username; var password = formObject.password; // 简单验证 if (username.length == 0 || password.length == 0) { wx.showToast({ title: '用户名或密码不能为空', icon: 'none', duration: 3000 }) } else { var serverUrl = app.serverUrl; wx.showLoading({ title: '请等待...', }); // 调用后端 wx.request({ url: serverUrl + '/login', method: "POST", data: { username: username, password: password }, header: { 'content-type': 'application/json' // 默认值 }, success: function (res) { console.log(res.data); wx.hideLoading(); if (res.data.status == 200) { // 登录成功跳转 wx.showToast({ title: '登录成功', icon: 'success', duration: 2000 }); // app.userInfo = res.data.data; // fixme 修改原有的全局对象为本地缓存 app.setGlobalUserInfo(res.data.data); // 页面跳转 var redirectUrl = me.redirectUrl; if (redirectUrl != null && redirectUrl != undefined && redirectUrl != '') { wx.redirectTo({ url: redirectUrl, }) } else { wx.redirectTo({ url: '../mine/mine', }) } } else if (res.data.status == 500) { // 失败弹出框 wx.showToast({ title: res.data.msg, icon: 'none', duration: 3000 }) } } }) }
<view> <view class="login-icon"> <image class="login-img" src="../resource/images/dsp.jpg"></image> </view> <view class="login-from"> <form bindsubmit='doLogin'> <!--账号--> <view class="inputView"> <image class="nameImage" src="../resource/images/username.png"></image> <label class="loginLabel">账号</label> <input name="username" value='Gary' class="inputText" placeholder="请输入账号" /> </view> <view class="line"></view> <!--密码--> <view class="inputView"> <image class="keyImage" src="../resource/images/password.png"></image> <label class="loginLabel">密码</label> <input name="password" value='123456' class="inputText" password="true" placeholder="请输入密码" /> </view> <!--按钮--> <view> <button class="loginBtn" type="primary" form-type='submit'>登录</button> </view> <view> <button class="goRegistBtn" type="warn" bindtap="goRegistPage">没有账号?点击注册</button> </view> </form> </view> </view>
const app = getApp() Page({ data: { }, onLoad: function (params) { var me = this; var redirectUrl = params.redirectUrl; // debugger; if (redirectUrl != null && redirectUrl != undefined && redirectUrl != '') { redirectUrl = redirectUrl.replace(/#/g, "?"); redirectUrl = redirectUrl.replace(/@/g, "="); me.redirectUrl = redirectUrl; } }, // 登录 doLogin: function (e) { var me = this; var formObject = e.detail.value; var username = formObject.username; var password = formObject.password; // 简单验证 if (username.length == 0 || password.length == 0) { wx.showToast({ title: '用户名或密码不能为空', icon: 'none', duration: 3000 }) } else { var serverUrl = app.serverUrl; wx.showLoading({ title: '请等待...', }); // 调用后端 wx.request({ url: serverUrl + '/login', method: "POST", data: { username: username, password: password }, header: { 'content-type': 'application/json' // 默认值 }, success: function (res) { console.log(res.data); wx.hideLoading(); if (res.data.status == 200) { // 登录成功跳转 wx.showToast({ title: '登录成功', icon: 'success', duration: 2000 }); // app.userInfo = res.data.data; // fixme 修改原有的全局对象为本地缓存 app.setGlobalUserInfo(res.data.data); // 页面跳转 var redirectUrl = me.redirectUrl; if (redirectUrl != null && redirectUrl != undefined && redirectUrl != '') { wx.redirectTo({ url: redirectUrl, }) } else { wx.redirectTo({ url: '../mine/mine', }) } } else if (res.data.status == 500) { // 失败弹出框 wx.showToast({ title: res.data.msg, icon: 'none', duration: 3000 }) } } }) } }, goRegistPage:function() { wx.redirectTo({ url: '../userRegist/regist', }) } })
package com.imooc.controller; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import com.imooc.pojo.Users; import com.imooc.service.UserService; import com.imooc.utils.IMoocJSONResult; import com.imooc.utils.MD5Utils; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; @RestController @Api(value="用户注册登录的接口",tags= {"注册和登录的controller"}) public class RegistLoginController { @Autowired private UserService userService; @ApiOperation(value="用户注册",notes="用户注册的接口") @PostMapping("/regist") public IMoocJSONResult regist(@RequestBody Users user) throws Exception { //1.判断用户名和密码必须不为空 if(StringUtils.isBlank(user.getUsername())||StringUtils.isBlank(user.getPassword())) { return IMoocJSONResult.errorMsg("用户名和密码不能为空"); } //2.判断用户名是否存在 boolean usernameIsExist = userService.queryUsernameIsExist(user.getUsername()); //3.保存用户注册信息 if(!usernameIsExist) { user.setNickname(user.getUsername()); user.setPassword(MD5Utils.getMD5Str(user.getPassword())); user.setFansCounts(0); user.setReceiveLikeCounts(0); user.setFollowCounts(0); userService.saveUser(user); }else { return IMoocJSONResult.errorMsg("用户名已经存在,请重新输入"); } user.setPassword(""); return IMoocJSONResult.ok(user); } @ApiOperation(value="用户登录", notes="用户登录的接口") @PostMapping("/login") public IMoocJSONResult login(@RequestBody Users user) throws Exception { String username = user.getUsername(); String password = user.getPassword(); // 1. 判断用户名和密码必须不为空 if (StringUtils.isBlank(username) || StringUtils.isBlank(password)) { return IMoocJSONResult.ok("用户名或密码不能为空"); } // 2. 判断用户是否存在 Users userResult = userService.queryUserForLogin(username, MD5Utils.getMD5Str(user.getPassword())); // 3. 返回 if (userResult != null) { userResult.setPassword(""); return IMoocJSONResult.ok(userResult); } else { return IMoocJSONResult.errorMsg("用户名或密码不正确, 请重试"); } } }
package com.imooc.service; import com.imooc.pojo.Users; public interface UserService { //判断用户名是否存在 public boolean queryUsernameIsExist(String username); //用户注册 public void saveUser(Users user); public Users queryUserForLogin(String username, String password); }
package com.imooc.service; import org.n3r.idworker.Sid; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import com.imooc.mapper.UsersMapper; import com.imooc.pojo.Users; import tk.mybatis.mapper.entity.Example; import tk.mybatis.mapper.entity.Example.Criteria; @Service public class UserServiceImpl implements UserService { @Autowired private UsersMapper userMapper; @Autowired private Sid sid; @Transactional(propagation = Propagation.SUPPORTS) @Override public boolean queryUsernameIsExist(String username) { Users user = new Users(); user.setUsername(username); Users result = userMapper.selectOne(user); return result==null?false:true; } @Transactional(propagation = Propagation.REQUIRED) @Override public void saveUser(Users user) { String userId = sid.nextShort(); user.setId(userId); userMapper.insert(user); } @Transactional(propagation = Propagation.SUPPORTS) @Override public Users queryUserForLogin(String username, String password) { Example userExample = new Example(Users.class); Criteria criteria = userExample.createCriteria(); criteria.andEqualTo("username", username); criteria.andEqualTo("password", password); Users result = userMapper.selectOneByExample(userExample); return result; } }
添加页面的跳转
登陆页面跳转到注册页面点击按钮触发goRegistPage()函数
<view> <button class="goRegistBtn" type="warn" bindtap="goRegistPage">没有账号?点击注册</button> </view>
goRegistPage:function() { wx.redirectTo({ url: '../userRegist/regist', }) }
登陆页面跳转到注册页面点击按钮触发goLoginPage函数
<view> <button class="goLoginBtn" type="warn" bindtap="goLoginPage">返回登录</button> </view>
goLoginPage: function () { wx.redirectTo({ url: '../userLogin/login', }) }
<view> <view class="login-icon"> <image class="login-img" src="../resource/images/dsp.jpg"></image> </view> <view class="login-from"> <form bindsubmit='doLogin'> <!--账号--> <view class="inputView"> <image class="nameImage" src="../resource/images/username.png"></image> <label class="loginLabel">账号</label> <input name="username" value='Gary' class="inputText" placeholder="请输入账号" /> </view> <view class="line"></view> <!--密码--> <view class="inputView"> <image class="keyImage" src="../resource/images/password.png"></image> <label class="loginLabel">密码</label> <input name="password" value='123456' class="inputText" password="true" placeholder="请输入密码" /> </view> <!--按钮--> <view> <button class="loginBtn" type="primary" form-type='submit'>登录</button> </view> <view> <button class="goRegistBtn" type="warn" bindtap="goRegistPage">没有账号?点击注册</button> </view> </form> </view> </view>
<view> <view class="login-icon"> <image class="login-img" src="../resource/images/dsp.jpg"></image> </view> <view class="login-from"> <form bindsubmit='doRegist'> <!--账号--> <view class="inputView"> <image class="nameImage" src="../resource/images/username.png"></image> <label class="loginLabel">账号</label> <input name="username" class="inputText" placeholder="请输入账号"/> </view> <view class="line"></view> <!--密码--> <view class="inputView"> <image class="keyImage" src="../resource/images/password.png"></image> <label class="loginLabel">密码</label> <input name="password" class="inputText" password="true" placeholder="请输入密码"/> </view> <!--按钮--> <view> <button class="loginBtn" type="primary" form-type='submit'>注册</button> </view> <view> <button class="goLoginBtn" type="warn" bindtap="goLoginPage">返回登录</button> </view> </form> </view> </view>
const app = getApp() Page({ data: { }, onLoad: function (params) { var me = this; var redirectUrl = params.redirectUrl; // debugger; if (redirectUrl != null && redirectUrl != undefined && redirectUrl != '') { redirectUrl = redirectUrl.replace(/#/g, "?"); redirectUrl = redirectUrl.replace(/@/g, "="); me.redirectUrl = redirectUrl; } }, // 登录 doLogin: function (e) { var me = this; var formObject = e.detail.value; var username = formObject.username; var password = formObject.password; // 简单验证 if (username.length == 0 || password.length == 0) { wx.showToast({ title: '用户名或密码不能为空', icon: 'none', duration: 3000 }) } else { var serverUrl = app.serverUrl; wx.showLoading({ title: '请等待...', }); // 调用后端 wx.request({ url: serverUrl + '/login', method: "POST", data: { username: username, password: password }, header: { 'content-type': 'application/json' // 默认值 }, success: function (res) { console.log(res.data); wx.hideLoading(); if (res.data.status == 200) { // 登录成功跳转 wx.showToast({ title: '登录成功', icon: 'success', duration: 2000 }); // app.userInfo = res.data.data; // fixme 修改原有的全局对象为本地缓存 app.setGlobalUserInfo(res.data.data); // 页面跳转 var redirectUrl = me.redirectUrl; if (redirectUrl != null && redirectUrl != undefined && redirectUrl != '') { wx.redirectTo({ url: redirectUrl, }) } else { wx.redirectTo({ url: '../mine/mine', }) } } else if (res.data.status == 500) { // 失败弹出框 wx.showToast({ title: res.data.msg, icon: 'none', duration: 3000 }) } } }) } }, goRegistPage:function() { wx.redirectTo({ url: '../userRegist/regist', }) } })
const app = getApp() Page({ data: { }, doRegist:function(e){ var formObject = e.detail.value; var username = formObject.username; var password = formObject.password; //简单验证 if(username.length==0||password.length==0){ wx.showToast({ title: '用户名或密码不能为空', icon:'none', duration:3000 }) }else{ var serverUrl = app.serverUrl; wx.showLoading({ title: '请等待...', }); wx.request({ url: serverUrl + '/regist', method:"POST", data:{ username: username, password: password }, header:{ 'content-type':'application/json'//默认值 }, success:function(res){ console.log(res.data); wx.hideLoading(); var status = res.data.status; if(status == 200){ wx.showToast({ title: "用户注册成功~!!!", icon: 'none', duration: 3000 }), app.userInfo = res.data.data; }else if(status == 500){ wx.showToast({ title: res.data.msg, icon: 'none', duration: 3000 }) } } }) } }, goLoginPage: function () { wx.redirectTo({ url: '../userLogin/login', }) } })
无状态session
Redis-session好处
用户信息存储到redis缓存中,形成无状态会话
便于扩展,当单题应用拓展成集群会相当方便
便于权限验证
在虚拟机中配置好redis后【192.168.1.110:6379】
在Redis Desktop Manager中配置去进行Redis服务测试链接
在imooc-videos-dev-common/pom.xml中引入redis依赖
<!-- 引入 redis 依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.9.0</version> </dependency> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-redis</artifactId> <version>1.8.7.RELEASE</version> </dependency>
############################################################ # # REDIS \u914d\u7f6e # ############################################################ spring.redis.database=1 spring.redis.host=192.168.1.110 spring.redis.port=6379 spring.redis.password=imooc spring.redis.pool.max-active=1000 spring.redis.pool.max-wait=-1 spring.redis.pool.max-idle=10 spring.redis.pool.min-idle=2 spring.redis.timeout=0 ############################################################ spring.datasource.url=jdbc:mysql://localhost:3306/wx-video-dev spring.datasource.username=root spring.datasource.password=123456 spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.datasource.druid.initial-size=1 spring.datasource.druid.min-idle=1 spring.datasource.druid.max-active=20 spring.datasource.druid.test-on-borrow=true spring.datasource.druid.stat-view-servlet.allow=true ############################################################ # # mybatis # ############################################################ # mybatis mybatis.type-aliases-package=com.imooc.pojo mybatis.mapper-locations=classpath:mapper/*.xml mapper.mappers=com.imooc.utils.MyMapper mapper.not-empty=false mapper.identity=MYSQL pagehelper.helperDialect=mysql pagehelper.supportMethodsArguments=true pagehelper.params=count=countSql spring.http.multipart.maxFileSize=100Mb spring.http.multipart.maxRequestSize=1000Mb ############################################################ # # Server # ############################################################ server.port=8081 ############################################################ # Server ############################################################ # tomcat server.tomcat.uri-encoding=UTF-8
在注册成功时生成一个无状态session
@RestController @Api(value="用户注册登录的接口",tags= {"注册和登录的controller"}) public class RegistLoginController extends BasicController { @Autowired private UserService userService; @ApiOperation(value="用户注册",notes="用户注册的接口") @PostMapping("/regist") public IMoocJSONResult regist(@RequestBody Users user) throws Exception { //1.判断用户名和密码必须不为空 if(StringUtils.isBlank(user.getUsername())||StringUtils.isBlank(user.getPassword())) { return IMoocJSONResult.errorMsg("用户名和密码不能为空"); } //2.判断用户名是否存在 boolean usernameIsExist = userService.queryUsernameIsExist(user.getUsername()); //3.保存用户注册信息 if(!usernameIsExist) { user.setNickname(user.getUsername()); user.setPassword(MD5Utils.getMD5Str(user.getPassword())); user.setFansCounts(0); user.setReceiveLikeCounts(0); user.setFollowCounts(0); userService.saveUser(user); }else { return IMoocJSONResult.errorMsg("用户名已经存在,请重新输入"); } user.setPassword(""); //生成一个无状态session String uniqueToken = UUID.randomUUID().toString(); redis.set(USER_REDIS_SESSION + ":" + user.getId(), uniqueToken, 1000 * 60 * 30); UsersVO userVO = new UsersVO(); BeanUtils.copyProperties(user, userVO); userVO.setUserToken(uniqueToken); return IMoocJSONResult.ok(userVO); }
将生成无状态session方法单独抽离出来成setUserRedisSessionToken(User userModel)
public UsersVO setUserRedisSessionToken(Users userModel) { //生成一个无状态session String uniqueToken = UUID.randomUUID().toString(); redis.set(USER_REDIS_SESSION + ":" + userModel.getId(), uniqueToken, 1000 * 60 * 30); UsersVO userVO = new UsersVO(); BeanUtils.copyProperties(userModel, userVO); userVO.setUserToken(uniqueToken); return userVO; }
在小程序端注册一个用户
可以在Redis Desktop Manager中获得一个新的user-redis-session【无状态session】
在登陆的地方也添加UsersVO userVO = setUserRedisSessionToken(user)方法
@ApiOperation(value="用户登录", notes="用户登录的接口") @PostMapping("/login") public IMoocJSONResult login(@RequestBody Users user) throws Exception { String username = user.getUsername(); String password = user.getPassword(); // 1. 判断用户名和密码必须不为空 if (StringUtils.isBlank(username) || StringUtils.isBlank(password)) { return IMoocJSONResult.ok("用户名或密码不能为空"); } // 2. 判断用户是否存在 Users userResult = userService.queryUserForLogin(username, MD5Utils.getMD5Str(user.getPassword())); // 3. 返回 if (userResult != null) { userResult.setPassword(""); UsersVO userVO = setUserRedisSessionToken(userResult); return IMoocJSONResult.ok(userVO); } else { return IMoocJSONResult.errorMsg("用户名或密码不正确, 请重试"); } }
在前台登陆后,可以看到登陆用户userToken是相同的【无状态session】
微信小程序中添加"我的"个人信息页面
在小程序app.json中对页面进行注册
"pages":[ "pages/mine/mine", "pages/userLogin/login", "pages/userRegist/regist", "pages/index/index" ],
<view> <view class='container'> <block wx:if="{{isMe}}"> <image src="{{faceUrl}}" class="face" bindtap='changeFace'></image> </block> <block wx:if="{{!isMe}}"> <image src="{{faceUrl}}" class="face"></image> </block> <label class='nickname'>{{nickname}}</label> <button size='mini' class='primary' bindtap='uploadVideo'> 上传作品</button> <button size='mini' type='' class='logout' bindtap='logout'>注销</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>
var videoUtil = require('../../utils/videoUtil.js') const app = getApp() Page({ data: { faceUrl: "../resource/images/noneface.png", }, onLoad: function (params) { } })
开发注销接口
在RegistLoginController.java中添加用户注销接口
@ApiOperation(value="用户注销", notes="用户注销的接口") @ApiImplicitParam(name="userId",value="用户id",required=true, dataType="String" ,paramType="query") @PostMapping("/logout") public IMoocJSONResult logout(String userId) throws Exception { redis.del(USER_REDIS_SESSION + ":" +userId); return IMoocJSONResult.errorMsg("注销成功!!!"); }
在Swagger UI中测试该接口
package com.imooc.controller; import java.util.UUID; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import com.imooc.pojo.Users; import com.imooc.pojp.vo.UsersVO; import com.imooc.service.UserService; import com.imooc.utils.IMoocJSONResult; import com.imooc.utils.MD5Utils; import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiOperation; @RestController @Api(value="用户注册登录的接口",tags= {"注册和登录的controller"}) public class RegistLoginController extends BasicController { @Autowired private UserService userService; @ApiOperation(value="用户注册",notes="用户注册的接口") @PostMapping("/regist") public IMoocJSONResult regist(@RequestBody Users user) throws Exception { //1.判断用户名和密码必须不为空 if(StringUtils.isBlank(user.getUsername())||StringUtils.isBlank(user.getPassword())) { return IMoocJSONResult.errorMsg("用户名和密码不能为空"); } //2.判断用户名是否存在 boolean usernameIsExist = userService.queryUsernameIsExist(user.getUsername()); //3.保存用户注册信息 if(!usernameIsExist) { user.setNickname(user.getUsername()); user.setPassword(MD5Utils.getMD5Str(user.getPassword())); user.setFansCounts(0); user.setReceiveLikeCounts(0); user.setFollowCounts(0); userService.saveUser(user); }else { return IMoocJSONResult.errorMsg("用户名已经存在,请重新输入"); } user.setPassword(""); UsersVO userVO = setUserRedisSessionToken(user); return IMoocJSONResult.ok(userVO); } public UsersVO setUserRedisSessionToken(Users userModel) { //生成一个无状态session String uniqueToken = UUID.randomUUID().toString(); redis.set(USER_REDIS_SESSION + ":" + userModel.getId(), uniqueToken, 1000 * 60 * 30); UsersVO userVO = new UsersVO(); BeanUtils.copyProperties(userModel, userVO); userVO.setUserToken(uniqueToken); return userVO; } @ApiOperation(value="用户登录", notes="用户登录的接口") @PostMapping("/login") public IMoocJSONResult login(@RequestBody Users user) throws Exception { String username = user.getUsername(); String password = user.getPassword(); // 1. 判断用户名和密码必须不为空 if (StringUtils.isBlank(username) || StringUtils.isBlank(password)) { return IMoocJSONResult.ok("用户名或密码不能为空"); } // 2. 判断用户是否存在 Users userResult = userService.queryUserForLogin(username, MD5Utils.getMD5Str(user.getPassword())); // 3. 返回 if (userResult != null) { userResult.setPassword(""); UsersVO userVO = setUserRedisSessionToken(userResult); return IMoocJSONResult.ok(userVO); } else { return IMoocJSONResult.errorMsg("用户名或密码不正确, 请重试"); } } @ApiOperation(value="用户注销", notes="用户注销的接口") @ApiImplicitParam(name="userId",value="用户id",required=true, dataType="String" ,paramType="query") @PostMapping("/logout") public IMoocJSONResult logout(String userId) throws Exception { redis.del(USER_REDIS_SESSION + ":" +userId); return IMoocJSONResult.errorMsg("注销成功!!!"); } }
小程序端编写注销的逻辑
在mine.js中编写logout()登出方法
logout:function(params){ var user = app.userInfo; var serverUrl = app.serverUrl; wx.showLoading({ title: '请等待...', }); // 调用后端 wx.request({ url: serverUrl + '/logout?userId='+user.id, method: "POST", header: { 'content-type': 'application/json' // 默认值 }, success: function (res) { console.log(res.data); wx.hideLoading(); if (res.data.status == 200) { // 登录成功跳转 //wx.showToast({ // title: '登录成功', // icon: 'success', // duration: 2000 //}); } } }) }
<view> <view class='container'> <block wx:if="{{isMe}}"> <image src="{{faceUrl}}" class="face" bindtap='changeFace'></image> </block> <block wx:if="{{!isMe}}"> <image src="{{faceUrl}}" class="face"></image> </block> <label class='nickname'>{{nickname}}</label> <button size='mini' class='primary' bindtap='uploadVideo'> 上传作品</button> <button size='mini' type='' class='logout' bindtap='logout'>注销</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>
var videoUtil = require('../../utils/videoUtil.js') const app = getApp() Page({ data: { faceUrl: "../resource/images/noneface.png", }, onLoad: function (params) { }, logout:function(params){ var user = app.userInfo; var serverUrl = app.serverUrl; wx.showLoading({ title: '请等待...', }); // 调用后端 wx.request({ url: serverUrl + '/logout?userId='+user.id, method: "POST", header: { 'content-type': 'application/json' // 默认值 }, success: function (res) { console.log(res.data); wx.hideLoading(); if (res.data.status == 200) { // 登录成功跳转 //wx.showToast({ // title: '登录成功', // icon: 'success', // duration: 2000 //}); } } }) } })
完善用户注销,当接收到200码时,提示用户注销成功,清除小程序全局对象,实现页面的跳转
success: function (res) { console.log(res.data); wx.hideLoading(); if (res.data.status == 200) { // 注销成功 wx.showToast({ title: '注销成功', icon: 'success', duration: 2000 }); //清除全局用户对象 app.userInfo = null; //页面跳转 wx.navigateTo({ url: '../userLogin/login', }) } }
var videoUtil = require('../../utils/videoUtil.js') const app = getApp() Page({ data: { faceUrl: "../resource/images/noneface.png", }, onLoad: function (params) { }, logout:function(params){ var user = app.userInfo; var serverUrl = app.serverUrl; wx.showLoading({ title: '请等待...', }); // 调用后端 wx.request({ url: serverUrl + '/logout?userId='+user.id, method: "POST", header: { 'content-type': 'application/json' // 默认值 }, success: function (res) { console.log(res.data); wx.hideLoading(); if (res.data.status == 200) { // 注销成功 wx.showToast({ title: '注销成功', icon: 'success', duration: 2000 }); //清除全局用户对象 app.userInfo = null; //页面跳转 wx.navigateTo({ url: '../userLogin/login', }) } } }) } })
用户头像上传
用户上传头像接口
@RestController @Api(value="用户相关业务的接口",tags= {"用户相关业务的controller"}) @RequestMapping("/user") public class UserController extends BasicController { @Autowired private UserService userService; @ApiOperation(value="用户上传头像", notes="用户上传头像的接口") @ApiImplicitParam(name="userId",value="用户id",required=true, dataType="String" ,paramType="query") @PostMapping("/uploadFace") public IMoocJSONResult uploadFace(String userId, @RequestParam("file") MultipartFile[] files) throws Exception { //文件保存命名空间 String fileSpace = "F:/imooc-video-gary"; //保存到数据库中的相对路径 String uploadPathDB = "/" + userId + "/face"; FileOutputStream fileOutputStream = null; InputStream inputStream = null; try { if( files != null && files.length>0 ) { String fileName = files[0].getOriginalFilename(); if(StringUtils.isNoneBlank(fileName)) { //文件上传的最终保存路径 String finalFacePath = fileSpace + uploadPathDB + "/" + fileName; //设置数据库保存的路径 uploadPathDB += ("/" + fileName); File outFile = new File(finalFacePath); if(outFile.getParentFile()!=null || !outFile.getParentFile().isDirectory()) { //创建父文件夹 outFile.getParentFile().mkdirs(); } fileOutputStream = new FileOutputStream(outFile); inputStream = files[0].getInputStream(); IOUtils.copy(inputStream, fileOutputStream); } } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); }finally { if(fileOutputStream != null) { fileOutputStream.flush(); fileOutputStream.close(); } } return IMoocJSONResult.ok(); } }
微信小程序中上传用户头像逻辑
点击头像触发uploadVideo()函数
<button size='mini' class='primary' bindtap='uploadVideo'> 上传作品</button>
changeFace:function(){ wx.chooseImage({ count: 1, sizeType: ['compressed'], sourceType: ['album'], success:function(res) { var tempFilePaths = res.tempFilePaths; console.log(tempFilePaths); wx.showLoading({ title: '上传中...', }) var serverUrl = app.serverUrl; wx.uploadFile({ url: serverUrl+'/user/uploadFace?userId='+app.userInfo.id, filePath: tempFilePaths[0], name: 'file', header: { 'content-type': 'application/json' // 默认值 }, success: function (res) { var data = res.data console.log(data); wx.hideLoading(); wx.showToast({ title: '上传成功', icon:"success" }) } }) } }) }
<view> <view class='container'> <image src="{{faceUrl}}" class="face" bindtap='changeFace'></image> <label class='nickname'>{{nickname}}</label> <button size='mini' class='primary' bindtap='uploadVideo'> 上传作品</button> <button size='mini' type='' class='logout' bindtap='logout'>注销</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>
var videoUtil = require('../../utils/videoUtil.js') const app = getApp() Page({ data: { faceUrl: "../resource/images/noneface.png", }, onLoad: function (params) { }, logout:function(params){ var user = app.userInfo; var serverUrl = app.serverUrl; wx.showLoading({ title: '请等待...', }); // 调用后端 wx.request({ url: serverUrl + '/logout?userId='+user.id, method: "POST", header: { 'content-type': 'application/json' // 默认值 }, success: function (res) { console.log(res.data); wx.hideLoading(); if (res.data.status == 200) { // 注销成功 wx.showToast({ title: '注销成功', icon: 'success', duration: 2000 }); //清除全局用户对象 app.userInfo = null; //页面跳转 wx.navigateTo({ url: '../userLogin/login', }) } } }) }, changeFace:function(){ wx.chooseImage({ count: 1, sizeType: ['compressed'], sourceType: ['album'], success:function(res) { var tempFilePaths = res.tempFilePaths; console.log(tempFilePaths); wx.showLoading({ title: '上传中...', }) var serverUrl = app.serverUrl; wx.uploadFile({ url: serverUrl+'/user/uploadFace?userId='+app.userInfo.id, filePath: tempFilePaths[0], name: 'file', header: { 'content-type': 'application/json' // 默认值 }, success: function (res) { var data = res.data console.log(data); wx.hideLoading(); wx.showToast({ title: '上传成功', icon:"success" }) } }) } }) } })
package com.imooc.controller; import java.io.File; import java.io.FileOutputStream; import java.io.InputStream; import java.util.UUID; import org.apache.commons.lang3.StringUtils; import org.apache.tomcat.util.http.fileupload.IOUtils; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; 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.imooc.pojo.Users; import com.imooc.pojp.vo.UsersVO; import com.imooc.service.UserService; import com.imooc.utils.IMoocJSONResult; import com.imooc.utils.MD5Utils; import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiOperation; @RestController @Api(value="用户相关业务的接口",tags= {"用户相关业务的controller"}) @RequestMapping("/user") public class UserController extends BasicController { @Autowired private UserService userService; @ApiOperation(value="用户上传头像", notes="用户上传头像的接口") @ApiImplicitParam(name="userId",value="用户id",required=true, dataType="String" ,paramType="query") @PostMapping("/uploadFace") public IMoocJSONResult uploadFace(String userId, @RequestParam("file") MultipartFile[] files) throws Exception { //文件保存命名空间 String fileSpace = "F:/imooc-video-gary"; //保存到数据库中的相对路径 String uploadPathDB = "/" + userId + "/face"; FileOutputStream fileOutputStream = null; InputStream inputStream = null; try { if( files != null && files.length>0 ) { String fileName = files[0].getOriginalFilename(); if(StringUtils.isNoneBlank(fileName)) { //文件上传的最终保存路径 String finalFacePath = fileSpace + uploadPathDB + "/" + fileName; //设置数据库保存的路径 uploadPathDB += ("/" + fileName); File outFile = new File(finalFacePath); if(outFile.getParentFile()!=null || !outFile.getParentFile().isDirectory()) { //创建父文件夹 outFile.getParentFile().mkdirs(); } fileOutputStream = new FileOutputStream(outFile); inputStream = files[0].getInputStream(); IOUtils.copy(inputStream, fileOutputStream); } } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); }finally { if(fileOutputStream != null) { fileOutputStream.flush(); fileOutputStream.close(); } } return IMoocJSONResult.ok(); } }
上传头像后更新到数据库
Users user = new Users(); user.setId(userId); user.setFaceImage(uploadPathDB); userService.updateUserInfo(user);
package com.imooc.controller; import java.io.File; import java.io.FileOutputStream; import java.io.InputStream; import java.util.UUID; import org.apache.commons.lang3.StringUtils; import org.apache.tomcat.util.http.fileupload.IOUtils; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; 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.imooc.pojo.Users; import com.imooc.pojp.vo.UsersVO; import com.imooc.service.UserService; import com.imooc.utils.IMoocJSONResult; import com.imooc.utils.MD5Utils; import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiOperation; @RestController @Api(value="用户相关业务的接口",tags= {"用户相关业务的controller"}) @RequestMapping("/user") public class UserController extends BasicController { @Autowired private UserService userService; @ApiOperation(value="用户上传头像", notes="用户上传头像的接口") @ApiImplicitParam(name="userId",value="用户id",required=true, dataType="String" ,paramType="query") @PostMapping("/uploadFace") public IMoocJSONResult uploadFace(String userId, @RequestParam("file") MultipartFile[] files) throws Exception { if(StringUtils.isBlank(userId)) { return IMoocJSONResult.errorMsg("用户id不能为空..."); } //文件保存命名空间 String fileSpace = "F:/imooc-video-gary"; //保存到数据库中的相对路径 String uploadPathDB = "/" + userId + "/face"; FileOutputStream fileOutputStream = null; InputStream inputStream = null; try { if( files != null && files.length>0 ) { String fileName = files[0].getOriginalFilename(); if(StringUtils.isNoneBlank(fileName)) { //文件上传的最终保存路径 String finalFacePath = fileSpace + uploadPathDB + "/" + fileName; //设置数据库保存的路径 uploadPathDB += ("/" + fileName); File outFile = new File(finalFacePath); if(outFile.getParentFile()!=null || !outFile.getParentFile().isDirectory()) { //创建父文件夹 outFile.getParentFile().mkdirs(); } fileOutputStream = new FileOutputStream(outFile); inputStream = files[0].getInputStream(); IOUtils.copy(inputStream, fileOutputStream); } }else { return IMoocJSONResult.errorMsg("上传出错..."); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); return IMoocJSONResult.errorMsg("上传出错..."); }finally { if(fileOutputStream != null) { fileOutputStream.flush(); fileOutputStream.close(); } } Users user = new Users(); user.setId(userId); user.setFaceImage(uploadPathDB); userService.updateUserInfo(user); return IMoocJSONResult.ok(); } }
Springboot静态资源配置,显示图片
添加WebMvcConfig.java作为设定虚拟路径的类继承WebMvcConfig,并重写addResourceHandlers(ResourceHandlerRegistry registry)方法
@Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/**") .addResourceLocations("file:F:/imooc-video-gary/"); }
此时访问http://localhost:8081/190502AYNKPFRDD4/face/路径去查看用户上传的图片
为让Swagger UI静态资源路径也是访问正确,再添加静态资源路径目录classpath:/META-INF/resources/
@Configuration public class WebMvcConfig extends WebMvcConfigurerAdapter { @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/**") .addResourceLocations("classpath:/META-INF/resources/") .addResourceLocations("file:F:/imooc-video-gary/"); }
package com.imooc; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; @Configuration public class WebMvcConfig extends WebMvcConfigurerAdapter { @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/**") .addResourceLocations("classpath:/META-INF/resources/") .addResourceLocations("file:F:/imooc-video-gary/"); } }
小程序展示头像
编写小程序端用户上传头像成功回调函数
success: function (res) { var data = JSON.parse(res.data); console.log(data); wx.hideLoading(); if(data.status == 200){ wx.showToast({ title: '上传成功', icon: "success" }); var imageUrl = data.data; me.setData({ faceUrl: serverUrl+imageUrl }); } else if (data.status == 500){ wx.showToast({ title: data.msg }); } }
package com.imooc.controller; import java.io.File; import java.io.FileOutputStream; import java.io.InputStream; import java.util.UUID; import org.apache.commons.lang3.StringUtils; import org.apache.tomcat.util.http.fileupload.IOUtils; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; 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.imooc.pojo.Users; import com.imooc.pojp.vo.UsersVO; import com.imooc.service.UserService; import com.imooc.utils.IMoocJSONResult; import com.imooc.utils.MD5Utils; import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiOperation; @RestController @Api(value="用户相关业务的接口",tags= {"用户相关业务的controller"}) @RequestMapping("/user") public class UserController extends BasicController { @Autowired private UserService userService; @ApiOperation(value="用户上传头像", notes="用户上传头像的接口") @ApiImplicitParam(name="userId",value="用户id",required=true, dataType="String" ,paramType="query") @PostMapping("/uploadFace") public IMoocJSONResult uploadFace(String userId, @RequestParam("file") MultipartFile[] files) throws Exception { if(StringUtils.isBlank(userId)) { return IMoocJSONResult.errorMsg("用户id不能为空..."); } //文件保存命名空间 String fileSpace = "F:/imooc-video-gary"; //保存到数据库中的相对路径 String uploadPathDB = "/" + userId + "/face"; FileOutputStream fileOutputStream = null; InputStream inputStream = null; try { if( files != null && files.length>0 ) { String fileName = files[0].getOriginalFilename(); if(StringUtils.isNoneBlank(fileName)) { //文件上传的最终保存路径 String finalFacePath = fileSpace + uploadPathDB + "/" + fileName; //设置数据库保存的路径 uploadPathDB += ("/" + fileName); File outFile = new File(finalFacePath); if(outFile.getParentFile()!=null || !outFile.getParentFile().isDirectory()) { //创建父文件夹 outFile.getParentFile().mkdirs(); } fileOutputStream = new FileOutputStream(outFile); inputStream = files[0].getInputStream(); IOUtils.copy(inputStream, fileOutputStream); } }else { return IMoocJSONResult.errorMsg("上传出错..."); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); return IMoocJSONResult.errorMsg("上传出错..."); }finally { if(fileOutputStream != null) { fileOutputStream.flush(); fileOutputStream.close(); } } Users user = new Users(); user.setId(userId); user.setFaceImage(uploadPathDB); userService.updateUserInfo(user); return IMoocJSONResult.ok(uploadPathDB); } }
<view> <view class='container'> <image src="{{faceUrl}}" class="face" bindtap='changeFace'></image> <label class='nickname'>{{nickname}}</label> <button size='mini' class='primary' bindtap='uploadVideo'> 上传作品</button> <button size='mini' type='' class='logout' bindtap='logout'>注销</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>
var videoUtil = require('../../utils/videoUtil.js') const app = getApp() Page({ data: { faceUrl: "../resource/images/noneface.png", }, onLoad: function (params) { }, logout:function(params){ var user = app.userInfo; var serverUrl = app.serverUrl; wx.showLoading({ title: '请等待...', }); // 调用后端 wx.request({ url: serverUrl + '/logout?userId='+user.id, method: "POST", header: { 'content-type': 'application/json' // 默认值 }, success: function (res) { console.log(res.data); wx.hideLoading(); if (res.data.status == 200) { // 注销成功 wx.showToast({ title: '注销成功', icon: 'success', duration: 2000 }); //清除全局用户对象 app.userInfo = null; //页面跳转 wx.navigateTo({ url: '../userLogin/login', }) } } }) }, changeFace:function(){ var me = this; wx.chooseImage({ count: 1, sizeType: ['compressed'], sourceType: ['album'], success:function(res) { var tempFilePaths = res.tempFilePaths; console.log(tempFilePaths); wx.showLoading({ title: '上传中...', }) var serverUrl = app.serverUrl; wx.uploadFile({ url: serverUrl+'/user/uploadFace?userId='+app.userInfo.id, filePath: tempFilePaths[0], name: 'file', header: { 'content-type': 'application/json' // 默认值 }, success: function (res) { var data = JSON.parse(res.data); console.log(data); wx.hideLoading(); if(data.status == 200){ wx.showToast({ title: '上传成功', icon: "success" }); var imageUrl = data.data; me.setData({ faceUrl: serverUrl+imageUrl }); } else if (data.status == 500){ wx.showToast({ title: data.msg }); } } }) } }) } })
查询用户
查询用户接口
@ApiOperation(value="查询用户信息", notes="查询用户信息的接口") @ApiImplicitParam(name="userId",value="用户id",required=true, dataType="String" ,paramType="query") @PostMapping("/query") public IMoocJSONResult query(String userId) throws Exception { if(StringUtils.isBlank(userId)) { return IMoocJSONResult.errorMsg("用户id不能为空..."); } Users userInfo = userService.queryUserInfo(userId); UsersVO userVO = new UsersVO(); BeanUtils.copyProperties(userInfo, userVO); return IMoocJSONResult.ok(userVO); }
package com.imooc.controller; import java.io.File; import java.io.FileOutputStream; import java.io.InputStream; import java.util.UUID; import org.apache.commons.lang3.StringUtils; import org.apache.tomcat.util.http.fileupload.IOUtils; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; 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.imooc.pojo.Users; import com.imooc.pojp.vo.UsersVO; import com.imooc.service.UserService; import com.imooc.utils.IMoocJSONResult; import com.imooc.utils.MD5Utils; import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiOperation; @RestController @Api(value="用户相关业务的接口",tags= {"用户相关业务的controller"}) @RequestMapping("/user") public class UserController extends BasicController { @Autowired private UserService userService; @ApiOperation(value="用户上传头像", notes="用户上传头像的接口") @ApiImplicitParam(name="userId",value="用户id",required=true, dataType="String" ,paramType="query") @PostMapping("/uploadFace") public IMoocJSONResult uploadFace(String userId, @RequestParam("file") MultipartFile[] files) throws Exception { if(StringUtils.isBlank(userId)) { return IMoocJSONResult.errorMsg("用户id不能为空..."); } //文件保存命名空间 String fileSpace = "F:/imooc-video-gary"; //保存到数据库中的相对路径 String uploadPathDB = "/" + userId + "/face"; FileOutputStream fileOutputStream = null; InputStream inputStream = null; try { if( files != null && files.length>0 ) { String fileName = files[0].getOriginalFilename(); if(StringUtils.isNoneBlank(fileName)) { //文件上传的最终保存路径 String finalFacePath = fileSpace + uploadPathDB + "/" + fileName; //设置数据库保存的路径 uploadPathDB += ("/" + fileName); File outFile = new File(finalFacePath); if(outFile.getParentFile()!=null || !outFile.getParentFile().isDirectory()) { //创建父文件夹 outFile.getParentFile().mkdirs(); } fileOutputStream = new FileOutputStream(outFile); inputStream = files[0].getInputStream(); IOUtils.copy(inputStream, fileOutputStream); } }else { return IMoocJSONResult.errorMsg("上传出错..."); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); return IMoocJSONResult.errorMsg("上传出错..."); }finally { if(fileOutputStream != null) { fileOutputStream.flush(); fileOutputStream.close(); } } Users user = new Users(); user.setId(userId); user.setFaceImage(uploadPathDB); userService.updateUserInfo(user); return IMoocJSONResult.ok(uploadPathDB); } @ApiOperation(value="查询用户信息", notes="查询用户信息的接口") @ApiImplicitParam(name="userId",value="用户id",required=true, dataType="String" ,paramType="query") @PostMapping("/query") public IMoocJSONResult query(String userId) throws Exception { if(StringUtils.isBlank(userId)) { return IMoocJSONResult.errorMsg("用户id不能为空..."); } Users userInfo = userService.queryUserInfo(userId); UsersVO userVO = new UsersVO(); BeanUtils.copyProperties(userInfo, userVO); return IMoocJSONResult.ok(userVO); } }
在小程序中显示个人信息
<label class='nickname'>{{nickname}}</label> <button size='mini' class='primary' bindtap='uploadVideo'> 上传作品</button> <button size='mini' type='' class='logout' bindtap='logout'>注销</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>
编写onLoad()方法,页面加载完毕调用onLoad()
onLoad: function (params) { var me = this; var user = app.userInfo; wx.showLoading({ title: '请等待...', }); // 调用后端 var serverUrl = app.serverUrl; wx.request({ url: serverUrl + '/user/query?userId='+user.id, method: "POST", header: { 'content-type': 'application/json' // 默认值 }, success: function (res) { console.log(res.data); wx.hideLoading(); if (res.data.status == 200) { var userInfo= res.data.data; var faceUrl = "../resource/images/noneface.png"; if (userInfo.faceImage != null && userInfo.faceImage != '' && userInfo.faceImage!=undefined){ faceUrl = serverUrl + userInfo.faceImage; } me.setData({ faceUrl: faceUrl, fansCounts: userInfo.fansCounts, followCounts: userInfo.followCounts, receiveLikeCounts: userInfo.receiveLikeCounts, nickname: userInfo.nickname }); } } }) },
package com.imooc.controller; import java.io.File; import java.io.FileOutputStream; import java.io.InputStream; import java.util.UUID; import org.apache.commons.lang3.StringUtils; import org.apache.tomcat.util.http.fileupload.IOUtils; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; 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.imooc.pojo.Users; import com.imooc.pojp.vo.UsersVO; import com.imooc.service.UserService; import com.imooc.utils.IMoocJSONResult; import com.imooc.utils.MD5Utils; import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiOperation; @RestController @Api(value="用户相关业务的接口",tags= {"用户相关业务的controller"}) @RequestMapping("/user") public class UserController extends BasicController { @Autowired private UserService userService; @ApiOperation(value="用户上传头像", notes="用户上传头像的接口") @ApiImplicitParam(name="userId",value="用户id",required=true, dataType="String" ,paramType="query") @PostMapping("/uploadFace") public IMoocJSONResult uploadFace(String userId, @RequestParam("file") MultipartFile[] files) throws Exception { if(StringUtils.isBlank(userId)) { return IMoocJSONResult.errorMsg("用户id不能为空..."); } //文件保存命名空间 String fileSpace = "F:/imooc-video-gary"; //保存到数据库中的相对路径 String uploadPathDB = "/" + userId + "/face"; FileOutputStream fileOutputStream = null; InputStream inputStream = null; try { if( files != null && files.length>0 ) { String fileName = files[0].getOriginalFilename(); if(StringUtils.isNoneBlank(fileName)) { //文件上传的最终保存路径 String finalFacePath = fileSpace + uploadPathDB + "/" + fileName; //设置数据库保存的路径 uploadPathDB += ("/" + fileName); File outFile = new File(finalFacePath); if(outFile.getParentFile()!=null || !outFile.getParentFile().isDirectory()) { //创建父文件夹 outFile.getParentFile().mkdirs(); } fileOutputStream = new FileOutputStream(outFile); inputStream = files[0].getInputStream(); IOUtils.copy(inputStream, fileOutputStream); } }else { return IMoocJSONResult.errorMsg("上传出错..."); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); return IMoocJSONResult.errorMsg("上传出错..."); }finally { if(fileOutputStream != null) { fileOutputStream.flush(); fileOutputStream.close(); } } Users user = new Users(); user.setId(userId); user.setFaceImage(uploadPathDB); userService.updateUserInfo(user); return IMoocJSONResult.ok(uploadPathDB); } @ApiOperation(value="查询用户信息", notes="查询用户信息的接口") @ApiImplicitParam(name="userId",value="用户id",required=true, dataType="String" ,paramType="query") @PostMapping("/query") public IMoocJSONResult query(String userId) throws Exception { if(StringUtils.isBlank(userId)) { return IMoocJSONResult.errorMsg("用户id不能为空..."); } Users userInfo = userService.queryUserInfo(userId); UsersVO userVO = new UsersVO(); BeanUtils.copyProperties(userInfo, userVO); return IMoocJSONResult.ok(userVO); } }
<view> <view class='container'> <image src="{{faceUrl}}" class="face" bindtap='changeFace'></image> <label class='nickname'>{{nickname}}</label> <button size='mini' class='primary' bindtap='uploadVideo'> 上传作品</button> <button size='mini' type='' class='logout' bindtap='logout'>注销</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>
var videoUtil = require('../../utils/videoUtil.js') const app = getApp() Page({ data: { faceUrl: "../resource/images/noneface.png", }, onLoad: function (params) { var me = this; var user = app.userInfo; wx.showLoading({ title: '请等待...', }); // 调用后端 var serverUrl = app.serverUrl; wx.request({ url: serverUrl + '/user/query?userId='+user.id, method: "POST", header: { 'content-type': 'application/json' // 默认值 }, success: function (res) { console.log(res.data); wx.hideLoading(); if (res.data.status == 200) { var userInfo= res.data.data; var faceUrl = "../resource/images/noneface.png"; if (userInfo.faceImage != null && userInfo.faceImage != '' && userInfo.faceImage!=undefined){ faceUrl = serverUrl + userInfo.faceImage; } me.setData({ faceUrl: faceUrl, fansCounts: userInfo.fansCounts, followCounts: userInfo.followCounts, receiveLikeCounts: userInfo.receiveLikeCounts, nickname: userInfo.nickname }); } } }) }, logout:function(params){ var user = app.userInfo; var serverUrl = app.serverUrl; wx.showLoading({ title: '请等待...', }); // 调用后端 wx.request({ url: serverUrl + '/logout?userId='+user.id, method: "POST", header: { 'content-type': 'application/json' // 默认值 }, success: function (res) { console.log(res.data); wx.hideLoading(); if (res.data.status == 200) { // 注销成功 wx.showToast({ title: '注销成功', icon: 'success', duration: 2000 }); //清除全局用户对象 app.userInfo = null; //页面跳转 wx.navigateTo({ url: '../userLogin/login', }) } } }) }, changeFace:function(){ var me = this; wx.chooseImage({ count: 1, sizeType: ['compressed'], sourceType: ['album'], success:function(res) { var tempFilePaths = res.tempFilePaths; console.log(tempFilePaths); wx.showLoading({ title: '上传中...', }) var serverUrl = app.serverUrl; wx.uploadFile({ url: serverUrl+'/user/uploadFace?userId='+app.userInfo.id, filePath: tempFilePaths[0], name: 'file', header: { 'content-type': 'application/json' // 默认值 }, success: function (res) { var data = JSON.parse(res.data); console.log(data); wx.hideLoading(); if(data.status == 200){ wx.showToast({ title: '上传成功', icon: "success" }); var imageUrl = data.data; me.setData({ faceUrl: serverUrl+imageUrl }); } else if (data.status == 500){ wx.showToast({ title: data.msg }); } } }) } }) } })