• 微信小程序_(校园视)开发用户注册登陆


      微信小程序_(校园视)  开发用户注册登陆  传送门 

      微信小程序_(校园视)  开发上传视频业务  传送门 

      微信小程序_(校园视)  开发视频的展示页-上  传送门 

      微信小程序_(校园视)  开发视频的展示页-下  传送门 

    用户注册界面

    <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>
    register.wxml
    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;
    }
    register.wxss
    {
      "pages":[
        "pages/userRegist/regist",
        "pages/index/index"
      ],
      "window":{
        "backgroundTextStyle":"light",
        "navigationBarBackgroundColor": "#fff",
        "navigationBarTitleText": "校园视",
        "navigationBarTextStyle":"black"
      }
    }
    app.json

    配置项目工程文件

    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);
        }
        
    }
    Application.java
    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~";
        }
        
    }
    HelloWorldController.java

    数据库表设计

      

    八个表

      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();
            }
            
        }
    }
    GeneratorDisplay.java
    <?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>
    generatorConfig.xml

    开发注册用户的接口

      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();
        }
        
    }
    RegistLoginController.java
    package com.imooc.service;
    
    import com.imooc.pojo.Users;
    
    public interface UserService {
    
        //判断用户名是否存在
        public boolean queryUsernameIsExist(String username);
        
        //用户注册
        public void saveUser(Users user);
    
    }
    UserService.java
    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);    
        }
    
    }
    UserServiceImpl.java

    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();
        }
    }
    Swagger2.java

    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;
        }
    }
    User.java
    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();
        }
    }
    Swagger2.java

    小程序注册于后端联调用

      小程序端通过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>
    regist.wxml
    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
                })
              }
            }
          })
        }
    
      }
    
    })
    regist.js
    {
      "pages":[
        "pages/userRegist/regist",
        "pages/index/index"
      ],
      "window":{
        "backgroundTextStyle":"light",
        "navigationBarBackgroundColor": "#fff",
        "navigationBarTitleText": "校园视",
        "navigationBarTextStyle":"black"
      },
      "debug":true
    }
    app.json
    //app.js
    App({
      serverUrl:"http://192.168.1.110:8081",
      userInfo:null
    })
    app.js

    小程序用户登陆

      小程序端页面编写

      后端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>
    login.wxml
    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',
        })
      }
    })
    login.js
    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("用户名或密码不正确, 请重试");
            }
        }
        
    }
    RegistLoginController.java
    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);
        
    }
    UserService.java
    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;
        }
    
        
    }
    UserServiceImpl.java

    添加页面的跳转

      登陆页面跳转到注册页面点击按钮触发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>
    login.wxml
    <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>
    regist.wxml
    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',
        })
      }
    })
    login.js
    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',
        })
      }
    
    })
    regist.js

    无状态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 u914du7f6e
    #
    ############################################################
    
    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
    application.properties

      在注册成功时生成一个无状态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>
    mine.wxml
    var videoUtil = require('../../utils/videoUtil.js')
    
    const app = getApp()
    
    Page({
      data: {
        faceUrl: "../resource/images/noneface.png",
      },
    
      onLoad: function (params) {
      
      }
    
    })
    mine.js

     开发注销接口

      在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("注销成功!!!");
        }
        
    }
    RegistLoginController.java

    小程序端编写注销的逻辑

      在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>
    mine.wxml
    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
              //});
            }
          }
        })
      }
    
    })
    mine.js

      完善用户注销,当接收到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',
              })
            }
          }
        })
      }
    
    })
    mine.js

    用户头像上传

      用户上传头像接口

    @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>
    mine.wxml
    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"
                })
              }
            })
    
          }
        })
      }
    
    })
    mine.js
    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();
        }
        
    }
    UserController.java

      上传头像后更新到数据库

            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();
        }
        
    }
    UserController.java

    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/");
        }
    
        
        
    }
    WebMvcConfig.java

    小程序展示头像

       编写小程序端用户上传头像成功回调函数

     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);
        }
        
    }
    UserController.java
    <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>
    mine.wxml
    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
                  });
                }
              }
            })
    
          }
        })
      }
    
    })
    mine.js

    查询用户

      查询用户接口

    @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);
        }
        
    }
    UserController.java

      在小程序中显示个人信息

        <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);
        }
        
    }
    UserController.java
    <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>
    mine.wxml
    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
                  });
                }
              }
            })
    
          }
        })
      }
    
    })
    mine.js
    (如需转载学习,请标明出处)
  • 相关阅读:
    Android SQLite 建立多表间的主外键关系 Binary
    Android——扩大ImageButton的点击区域 Binary
    Android——刷新媒体库 Binary
    Oracle数据导入导出imp/exp命令 10g以上expdp/impdp命令 转自:南水江的鸽子窝
    在同一应用中混合使用ASP.NET窗体和ASP.NET MVC 转自:geez的个人空间
    ASP.NET WebApplication 发布部署
    Oracle 导出索引Sequence!!
    获取ORACLE 表字段,表名,以及主键之类等等的信息
    FlexGrid 控件的使用 摘自:大道至简
    整合 DZNT到自己网站
  • 原文地址:https://www.cnblogs.com/1138720556Gary/p/10701595.html
Copyright © 2020-2023  润新知