0


uniapp-含有后端的登录注册页面编写

uniapp-含有后端的登录注册页面编写

创建数据库

数据库结构

表名:user
列名数据类型描述idint自增IDusernamevarchar用户名passwordvarchar密码nicknamevarchar昵称
这个方案只保留了id、username、password和nickname四个字段,以最简单的方式存储用户基本信息。需要注意的是,密码应该进行安全处理(如加密),避免泄露敏感信息。如果后续有新增信息需求,则可以随时更改表结构,添加相应的列即可。

数据库代码

-- 创建 usertable 数据库CREATEDATABASEIFNOTEXISTS usertable;-- 切换至 usertable 数据库USE usertable;-- 创建 user 表CREATETABLEIFNOTEXISTSuser(
  id INT(11)NOTNULLAUTO_INCREMENT,
  username VARCHAR(100)NOTNULLUNIQUE,
  password VARCHAR(100)NOTNULL,
  nickname VARCHAR(100)NOTNULL,PRIMARYKEY(id))ENGINE=InnoDBDEFAULTCHARSET=utf8mb4;-- 添加一些测试数据INSERTINTOuser(username, password, nickname)VALUES('user1','password1','张三');INSERTINTOuser(username, password, nickname)VALUES('user2','password2','李四');INSERTINTOuser(username, password, nickname)VALUES('user3','password3','王五');

这段SQL代码用于创建一个名为

user

的表格,并且添加了一些简单的测试数据。其中,

id

列使用了自增主键约束,保证数据的唯一性。

username

列使用了

unique

约束,确保用户名的唯一性。请注意,

utf8mb4

是一种更高效和更通用的字符编码,支持更广泛的Unicode字符集,所以它比utf-8更推荐使用。

后端编写

创建项目(准备工作)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

pom.xml

<?xml version="1.0" encoding="UTF-8"?><projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.11</version><relativePath/><!-- lookup parent from repository --></parent><groupId>com.example</groupId><artifactId>userTable</artifactId><version>0.0.1-SNAPSHOT</version><name>userTable</name><description>userTable</description><properties><java.version>1.8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><version>2.7.6</version></dependency><dependency><groupId>org.springframework.data</groupId><artifactId>spring-data-jpa</artifactId><version>2.5.6</version></dependency><dependency><groupId>org.hibernate</groupId><artifactId>hibernate-core</artifactId><version>5.6.3.Final</version></dependency><dependency><groupId>javax.persistence</groupId><artifactId>javax.persistence-api</artifactId><version>2.2</version></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.3.0</version></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.3.0</version></dependency><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><scope>runtime</scope></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.4.2</version></dependency><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-core</artifactId><version>1.8.0</version></dependency><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt-api</artifactId><version>0.11.2</version></dependency><!-- 如果要使用 jjwt 的实现,还需要添加以下依赖 --><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt-impl</artifactId><version>0.11.2</version><scope>runtime</scope></dependency><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt-jackson</artifactId><version>0.11.2</version><scope>runtime</scope></dependency><!-- Hibernate Validator --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId></dependency><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-core</artifactId><version>1.8.0</version></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><excludes><exclude><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></exclude></excludes></configuration></plugin></plugins></build></project>

application.properties

# ?????
spring.datasource.url=jdbc:mysql://localhost:3306/usertable?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

# ???????
server.port=8081

# MyBatis-Plus ??
mybatis-plus.mapper-locations=classpath:/mapper/*.xml
mybatis-plus.type-aliases-package=com.example.demo.entity
mybatis-plus.global-config.db-config.id-type=auto
mybatis-plus.configuration.map-underscore-to-camel-case=true
mybatis-plus.configuration.use-generated-keys=true
mybatis-plus.configuration.map-enum-as-ordinal=false
mybatis-plus.configuration.enum-handler=com.baomidou.mybatisplus.extension.handlers.MybatisEnumTypeHandler

Bean

User
importcom.baomidou.mybatisplus.annotation.TableName;importlombok.AllArgsConstructor;importlombok.Data;importlombok.NoArgsConstructor;@Data@AllArgsConstructor@NoArgsConstructor@TableName("user")// 声明对应的数据库表名(user)publicclassUser{privateLong id;privateString username;privateString password;privateString nickname;}
Result
importlombok.AllArgsConstructor;importlombok.Builder;importlombok.Data;importlombok.NoArgsConstructor;@Data@Builder@AllArgsConstructor@NoArgsConstructorpublicclassResult{privateInteger code;// 状态码privateString message;// 状态信息privateObject data;// 数据}

config

CorsConfig
importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importorg.springframework.web.servlet.config.annotation.CorsRegistry;importorg.springframework.web.servlet.config.annotation.WebMvcConfigurer;importorg.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;@ConfigurationpublicclassCorsConfig{@BeanpublicWebMvcConfigurercorsConfigurer(){returnnewWebMvcConfigurerAdapter(){@OverridepublicvoidaddCorsMappings(CorsRegistry registry){// 允许来自本地的8080端口发起的跨域请求
                registry.addMapping("/api/**").allowedOrigins("*").allowedMethods("GET","POST","PUT","DELETE").allowCredentials(true).maxAge(3600);}};}}

Mapper

UserMapper
importcom.baomidou.mybatisplus.core.mapper.BaseMapper;importcom.example.usertable.Bean.User;importorg.apache.ibatis.annotations.Mapper;@MapperpublicinterfaceUserMapperextendsBaseMapper<User>{}

Service

UserService
importcom.baomidou.mybatisplus.core.metadata.IPage;importcom.baomidou.mybatisplus.extension.plugins.pagination.Page;importcom.baomidou.mybatisplus.extension.service.IService;importcom.example.usertable.Bean.User;publicinterfaceUserServiceextendsIService<User>{/**
     * 分页查询用户列表
     */IPage<User>selectPage(Page<User> page);/**
     * 用户注册
     */booleanregister(User user);/**
     * 用户登录
     */Userlogin(String username,String password);}

ServiceImpl

UserServiceImpl
importcom.baomidou.mybatisplus.core.conditions.query.QueryWrapper;importcom.baomidou.mybatisplus.core.metadata.IPage;importcom.baomidou.mybatisplus.extension.plugins.pagination.Page;importcom.baomidou.mybatisplus.extension.service.impl.ServiceImpl;importcom.example.usertable.Bean.User;importcom.example.usertable.Mapper.UserMapper;importcom.example.usertable.Service.UserService;importlombok.AllArgsConstructor;importorg.springframework.stereotype.Service;importorg.springframework.util.StringUtils;@Service@AllArgsConstructorpublicclassUserServiceImplextendsServiceImpl<UserMapper,User>implementsUserService{@OverridepublicIPage<User>selectPage(Page<User> page){return baseMapper.selectPage(page,null);}/**
     * 注册新用户(需先检查用户名是否已被使用)
     */@Overridepublicbooleanregister(User user){String username = user.getUsername();// 根据用户名查询用户User u =this.getOne(newQueryWrapper<User>().eq("username", username));if(u !=null){// 用户名已存在returnfalse;}else{// 将用户保存到数据库returnthis.save(user);}}/**
     * 用户登录(根据用户名和密码查询用户)
     */@OverridepublicUserlogin(String username,String password){if(StringUtils.isEmpty(username)||StringUtils.isEmpty(password)){// 用户名和密码不能为空returnnull;}returnthis.getOne(newQueryWrapper<User>().eq("username", username).eq("password", password));}}

Controller

UserController
importcom.baomidou.mybatisplus.core.metadata.IPage;importcom.baomidou.mybatisplus.extension.plugins.pagination.Page;importcom.example.usertable.Bean.Result;importcom.example.usertable.Bean.User;importcom.example.usertable.Service.UserService;importlombok.AllArgsConstructor;importorg.springframework.validation.annotation.Validated;importorg.springframework.web.bind.annotation.*;@AllArgsConstructor@RestController@RequestMapping("/users")publicclassUserController{privatefinalUserService userService;/**
     * 获取用户列表(分页)
     */@GetMapping("/")publicResultlist(@RequestParam(defaultValue ="1")Integer pageNum,@RequestParam(defaultValue ="10")Integer pageSize){// 构建分页对象Page<User> page =newPage<>(pageNum, pageSize);// 分页查询用户数据IPage<User> userPage = userService.page(page,null);returnResult.builder().code(200).message("获取成功").data(userPage).build();}/**
     * 根据 ID 获取用户信息
     */@GetMapping("/{id}")publicResultdetail(@PathVariableLong id){// 查询用户信息User user = userService.getById(id);if(user !=null){returnResult.builder().code(200).message("获取成功").data(user).build();}else{returnResult.builder().code(404).message("用户不存在").build();}}/**
     * 注册
     */@PostMapping("/register")publicResultregister(@RequestBody@ValidatedUser user){boolean success = userService.register(user);if(success){returnResult.builder().code(200).message("注册成功").data(user).build();}else{returnResult.builder().code(500).message("用户名已存在").build();}}/**
     * 登录
     */@PostMapping("/login")publicResultlogin(@RequestBodyUser user){String username = user.getUsername();String password = user.getPassword();// 查询用户User loginUser = userService.login(username, password);if(loginUser !=null){returnResult.builder().code(200).message("登录成功").data(loginUser).build();}else{returnResult.builder().code(401).message("用户名或密码错误").build();}}/**
     * 新增用户
     */@PostMapping("/")publicResultadd(@RequestBody@ValidatedUser user){boolean success = userService.save(user);if(success){returnResult.builder().code(200).message("新增成功").data(user).build();}else{returnResult.builder().code(500).message("新增失败").data(user).build();}}/**
     * 更新用户信息
     */@PutMapping("/{id}")publicResultupdate(@PathVariableLong id,@RequestBody@ValidatedUser user){
        user.setId(id);boolean success = userService.updateById(user);if(success){returnResult.builder().code(200).message("更新成功").data(user).build();}else{returnResult.builder().code(500).message("更新失败").data(user).build();}}/**
     * 删除用户
     */@DeleteMapping("/{id}")publicResultdelete(@PathVariableLong id){boolean success = userService.removeById(id);if(success){returnResult.builder().code(200).message("删除成功").build();}else{returnResult.builder().code(500).message("删除失败").build();}}}

Postman测试

测试所有的接口
以下是基于8081端口号的 Postman 测试:

1. 获取用户列表(分页)

请求地址:

http://localhost:8081/users/

请求方法:GET

请求参数:
参数名称参数类型是否必须默认值参数说明pageNumInteger否1当前页码pageSizeInteger否10每页记录数
成功响应:

{"code":200,"message":"获取成功","data":{"records":[{"id":1,"username":"user1","password":"password1","nickname":"张三"},{"id":2,"username":"user2","password":"password2","nickname":"李四"},{"id":3,"username":"user3","password":"password3","nickname":"王五"}],"total":0,"size":10,"current":1,"orders":[],"optimizeCountSql":true,"hitCount":false,"countId":null,"maxLimit":null,"searchCount":true,"pages":0}}

2. 根据 ID 获取用户信息

请求地址:

http://localhost:8081/users/{id}

请求方法:GET

请求路径参数:
参数名称参数类型是否必须示例值参数说明idLong是1用户 ID
成功响应:

{"code":200,"message":"获取成功","data":{"id":1,"username":"user1","password":"password1","nickname":"张三"}}

3. 注册

请求地址:

http://localhost:8081/users/register

请求方法:POST

请求参数:
参数名称参数类型是否必须示例值参数说明usernameString是user-11用户名passwordString是pass-11密码nicknameString否lihua昵名
请求示例:

{"username":"user-11","password":"pass-11","nickname":"lihua"}

成功响应:

{"code":200,"message":"注册成功","data":{"id":4,"username":"user-11","password":"pass-11","nickname":"lihua"}}

失败响应:

{"code":500,"message":"用户名已存在"}

4. 登录

请求地址:

http://localhost:8081/users/login

请求方法:POST

请求参数:
参数名称参数类型是否必须示例值参数说明usernameString是user-1用户名passwordString是pass-1密码
请求示例:

{"username":"user2","password":"password2"}

成功响应:

{"code":200,"message":"登录成功","data":{"password":"password2","nickname":"李四","id":2,"username":"user2"}}

失败响应:

{"code":401,"message":"用户名或密码错误","data":null}

5. 新增用户

请求地址:

http://localhost:8081/users/

请求方法:POST

请求参数:
参数名称参数类型是否必须示例值参数说明usernameString是user-12用户名passwordString是pass-12密码nicknameString否小李昵名
请求示例:

{"username":"user-12","password":"pass-12","nickname":"小李"}

成功响应:

{"code":200,"message":"新增成功","data":{"id":5,"username":"user-12","password":"pass-12","nickname":"小李"}}

失败响应:

{"code":500,"message":"新增失败"}

6. 更新用户信息

请求地址:

http://localhost:8081/users/{id}

请求方法:PUT

请求路径参数:
参数名称参数类型是否必须示例值参数说明usernameString否user-12-update用户名passwordString否pass-12-update密码emailString否user-12-update@example.com邮箱phoneString否12345678901手机号
请求示例:

{"username":"user-13","password":"pass-13","nickname":"小李"}

成功响应:

{"code":200,"message":"更新成功","data":{"id":1,"username":"user-13","password":"pass-13","nickname":"小李"}}

失败响应:

{"code":500,"message":"更新失败"}

7. 删除用户

请求地址:

http://localhost:8081/users/{id}

请求方法:DELETE

请求路径参数:
参数名称参数类型是否必须示例值参数说明idLong是12用户 ID
成功响应:

{"code":200,"message":"删除成功"}

失败响应:

{"code":500,"message":"删除失败"}

前端编写

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

页面编写

效果展示

在这里插入图片描述
在这里插入图片描述

文件目录

在这里插入图片描述

pages.json

在这里插入图片描述

manifest.json

{"name":"LoginAndRegister","appid":"","description":"","versionName":"1.0.0","versionCode":"100","transformPx":false,/* 5+App特有相关 */"app-plus":{"usingComponents":true,"nvueStyleCompiler":"uni-app","compilerVersion":3,"splashscreen":{"alwaysShowBeforeRender":true,"waiting":true,"autoclose":true,"delay":0},/* 模块配置 */"modules":{},/* 应用发布信息 */"distribute":{/* android打包配置 */"android":{"permissions":["<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>","<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>","<uses-permission android:name=\"android.permission.VIBRATE\"/>","<uses-permission android:name=\"android.permission.READ_LOGS\"/>","<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>","<uses-feature android:name=\"android.hardware.camera.autofocus\"/>","<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>","<uses-permission android:name=\"android.permission.CAMERA\"/>","<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>","<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>","<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>","<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>","<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>","<uses-feature android:name=\"android.hardware.camera\"/>","<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"]},/* ios打包配置 */"ios":{},/* SDK配置 */"sdkConfigs":{}}},/* 快应用特有相关 */"quickapp":{},/* 小程序特有相关 */"mp-weixin":{"appid":"","setting":{"urlCheck":false},"usingComponents":true},"mp-alipay":{"usingComponents":true},"mp-baidu":{"usingComponents":true},"mp-toutiao":{"usingComponents":true},"uniStatistics":{"enable":false},"vueVersion":"2","h5":{"devServer":{"port":8080,//浏览器运行端口"disableHostCheck":true,//设置跳过host检查"proxy":{"/api":{"target":"http://localhost:8081",//目标接口域名"changeOrigin":true,//是否跨域"secure":false,// 设置支持https协议的代理"pathRewrite":{"^/api":""}}}}}}

index.vue

<template><viewclass="content"><imageclass="logo"src="/static/logo.png"></image><viewclass="text-area"><textclass="title">{{title}}</text><button@click="handleClick">点击我</button></view></view></template><script>exportdefault{data(){return{title:'Hello'}},onLoad(){},methods:{handleClick(){
                console.log('您点击了该按钮!')}}}</script><style>.content{display: flex;flex-direction: column;align-items: center;justify-content: center;}.logo{height: 200rpx;width: 200rpx;margin-top: 200rpx;margin-left: auto;margin-right: auto;margin-bottom: 50rpx;}.text-area{display: flex;justify-content: center;}.title{font-size: 36rpx;color: #8f8f94;}</style>

login.vue

<template><viewclass="login"><imageclass="logo"src="/static/logo.png"></image><viewclass="input-item"><inputtype="text"v-model="username"placeholder="请输入用户名"></view><viewclass="input-item"><inputtype="password"v-model="password"placeholder="请输入密码"></view><button@click="login"class="login-btn">登录</button><button@click="goToRegister"class="register-btn">注册</button></view></template><script>import axios from'axios'exportdefault{data(){return{username:'',password:''}},methods:{login(){if(!this.username ||!this.password){
        uni.showToast({title:'请填写用户名和密码',icon:'none'})return}// 发送请求验证用户
      axios.post('/api/users/login',{username:this.username,password:this.password
      }).then(res=>{
        console.log(res.data.code)if(res.data.code ===200){// 将用户信息保存到客户端本地缓存中
          uni.setStorageSync('userInfo',{id: res.data.data.id,username: res.data.data.username,password: res.data.data.password,nickname: res.data.data.nickname
          })// 跳转到首页
          uni.navigateTo({url:'/pages/index/index'})}else{
          uni.showToast({title: res.data.message,icon:'none'})}}).catch(err=>{
        uni.showToast({title:'网络请求失败,请重试',icon:'none'})})},goToRegister(){
      uni.navigateTo({url:'/pages/register/register'})}}}</script><stylescoped>.login{display: flex;flex-direction: column;justify-content: center;align-items: center;margin-top: 100rpx;}.logo{width: 200rpx;height: 200rpx;margin-bottom: 20rpx;}.login-form{width: 90%;padding: 40rpx;background-color: #fff;border-radius: 5rpx;}.input-item{width: 80%;margin: 10rpx 0;border-bottom: 1rpx solid #ddd;}input{width: 100%;height: 50rpx;padding: 10rpx;font-size: 16rpx;outline: none;border: none;}.login-btn{display: block;margin: 30rpx auto 0;width: 80%;height: 80rpx;line-height: 80rpx;text-align: center;background-color: #007aff;color: #fff;border-radius: 5rpx;font-size: 20rpx;}.register-btn{margin-top: 20rpx;color: #007aff;width: 60%;height: 80rpx;}</style>

register.vue

<template><viewclass="register"><imageclass="logo"src="/static/logo.png"></image><formclass="register-form"><viewclass="input-item"><inputtype="text"v-model="nickname"placeholder="请输入昵称"></view><viewclass="input-item"><inputtype="text"v-model="username"placeholder="请输入用户名"></view><viewclass="input-item"><inputtype="password"v-model="password"placeholder="请输入密码"></view><viewclass="input-item"><inputtype="password"v-model="confirmPassword"placeholder="请确认密码"></view><buttontype="button"class="register-btn"@click="register">注册</button></form><buttonclass="back-btn"@click="goBack">返回</button></view></template><script>import axios from'axios';exportdefault{data(){return{username:'',password:'',confirmPassword:'',nickname:''};},methods:{asyncregister(){if(!this.username ||!this.password ||!this.nickname){
        uni.showToast({title:'请填写完整信息',icon:'none'});return;}if(this.password !==this.confirmPassword){
        uni.showToast({title:'两次输入密码不一致',icon:'none'});return;}try{const response =await axios.post('/api/users/register',{username:this.username,password:this.password,nickname:this.nickname
        });const responseData = response.data;if(responseData.code ===200){
          uni.showToast({title: responseData.message,icon:'success'});
          uni.navigateTo({url:'/pages/login/login'});}else{
          uni.showToast({title: responseData.message,icon:'none'});}}catch(error){let errorMessage ='注册失败,请稍后再试';if(error.response){if(error.response.status ===500){
            errorMessage = error.response.data.message;}}

        uni.showToast({title: errorMessage,icon:'none'});}},goBack(){
      uni.navigateBack();}}};</script><stylescoped>.register{display: flex;flex-direction: column;justify-content: center;align-items: center;margin-top: 100rpx;}.logo{width: 200rpx;height: 200rpx;margin-bottom: 20rpx;}.register-form{width: 90%;padding: 40rpx;background-color: #fff;border-radius: 5rpx;}.input-item{margin: 10rpx 0;border-bottom: 1rpx solid #ddd;}input{width: 100%;height: 50rpx;padding: 10rpx;font-size: 16rpx;outline: none;border: none;}.register-btn{display: block;margin: 30rpx auto 0;width: 90%;height: 80rpx;line-height: 80rpx;text-align: center;background-color: #007aff;color: #fff;border-radius: 5rpx;font-size: 20rpx;}.back-btn{margin-top: 20rpx;color: #007aff;width: 60%;height: 80rpx;}</style>
标签: uni-app 数据库 java

本文转载自: https://blog.csdn.net/qq_51447496/article/details/130637299
版权归原作者 极客李华 所有, 如有侵权,请联系我们删除。

“uniapp-含有后端的登录注册页面编写”的评论:

还没有评论