uniapp

您所在的位置:网站首页 uniapp个人页面 uniapp

uniapp

2023-12-19 16:59| 来源: 网络整理| 查看: 265

uniapp-含有后端的登录注册页面编写 创建数据库 数据库结构

表名:user

列名数据类型描述idint自增IDusernamevarchar用户名passwordvarchar密码nicknamevarchar昵称

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

数据库代码 -- 创建 usertable 数据库 CREATE DATABASE IF NOT EXISTS usertable; -- 切换至 usertable 数据库 USE usertable; -- 创建 user 表 CREATE TABLE IF NOT EXISTS user ( id INT(11) NOT NULL AUTO_INCREMENT, username VARCHAR(100) NOT NULL UNIQUE, password VARCHAR(100) NOT NULL, nickname VARCHAR(100) NOT NULL, PRIMARY KEY (id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -- 添加一些测试数据 INSERT INTO user (username, password, nickname) VALUES ('user1', 'password1', '张三'); INSERT INTO user (username, password, nickname) VALUES ('user2', 'password2', '李四'); INSERT INTO user (username, password, nickname) VALUES ('user3', 'password3', '王五');

这段SQL代码用于创建一个名为user的表格,并且添加了一些简单的测试数据。其中,id列使用了自增主键约束,保证数据的唯一性。username列使用了unique约束,确保用户名的唯一性。请注意,utf8mb4是一种更高效和更通用的字符编码,支持更广泛的Unicode字符集,所以它比utf-8更推荐使用。

后端编写 创建项目(准备工作)

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

pom.xml 4.0.0 org.springframework.boot spring-boot-starter-parent 2.7.11 com.example userTable 0.0.1-SNAPSHOT userTable userTable 1.8 org.springframework.boot spring-boot-starter-web 2.7.6 org.springframework.data spring-data-jpa 2.5.6 org.hibernate hibernate-core 5.6.3.Final javax.persistence javax.persistence-api 2.2 org.mybatis.spring.boot mybatis-spring-boot-starter 2.3.0 org.mybatis.spring.boot mybatis-spring-boot-starter 2.3.0 com.mysql mysql-connector-j runtime org.projectlombok lombok true org.springframework.boot spring-boot-starter-test test com.baomidou mybatis-plus-boot-starter 3.4.2 org.apache.shiro shiro-core 1.8.0 io.jsonwebtoken jjwt-api 0.11.2 io.jsonwebtoken jjwt-impl 0.11.2 runtime io.jsonwebtoken jjwt-jackson 0.11.2 runtime org.springframework.boot spring-boot-starter-validation org.apache.shiro shiro-core 1.8.0 org.springframework.boot spring-boot-maven-plugin org.projectlombok lombok 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 import com.baomidou.mybatisplus.annotation.TableName; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @Data @AllArgsConstructor @NoArgsConstructor @TableName("user") // 声明对应的数据库表名(user) public class User { private Long id; private String username; private String password; private String nickname; } Result import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; @Data @Builder @AllArgsConstructor @NoArgsConstructor public class Result { private Integer code; // 状态码 private String message; // 状态信息 private Object data; // 数据 } config CorsConfig import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; @Configuration public class CorsConfig { @Bean public WebMvcConfigurer corsConfigurer() { return new WebMvcConfigurerAdapter() { @Override public void addCorsMappings(CorsRegistry registry) { // 允许来自本地的8080端口发起的跨域请求 registry.addMapping("/api/**") .allowedOrigins("*") .allowedMethods("GET", "POST", "PUT", "DELETE") .allowCredentials(true).maxAge(3600); } }; } } Mapper UserMapper import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.example.usertable.Bean.User; import org.apache.ibatis.annotations.Mapper; @Mapper public interface UserMapper extends BaseMapper { } Service UserService import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.IService; import com.example.usertable.Bean.User; public interface UserService extends IService { /** * 分页查询用户列表 */ IPage selectPage(Page page); /** * 用户注册 */ boolean register(User user); /** * 用户登录 */ User login(String username, String password); } ServiceImpl UserServiceImpl import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.example.usertable.Bean.User; import com.example.usertable.Mapper.UserMapper; import com.example.usertable.Service.UserService; import lombok.AllArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.util.StringUtils; @Service @AllArgsConstructor public class UserServiceImpl extends ServiceImpl implements UserService { @Override public IPage selectPage(Page page) { return baseMapper.selectPage(page, null); } /** * 注册新用户(需先检查用户名是否已被使用) */ @Override public boolean register(User user) { String username = user.getUsername(); // 根据用户名查询用户 User u = this.getOne(new QueryWrapper().eq("username", username)); if (u != null) { // 用户名已存在 return false; } else { // 将用户保存到数据库 return this.save(user); } } /** * 用户登录(根据用户名和密码查询用户) */ @Override public User login(String username, String password) { if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) { // 用户名和密码不能为空 return null; } return this.getOne(new QueryWrapper() .eq("username", username) .eq("password", password)); } } Controller UserController import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.example.usertable.Bean.Result; import com.example.usertable.Bean.User; import com.example.usertable.Service.UserService; import lombok.AllArgsConstructor; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @AllArgsConstructor @RestController @RequestMapping("/users") public class UserController { private final UserService userService; /** * 获取用户列表(分页) */ @GetMapping("/") public Result list(@RequestParam(defaultValue = "1") Integer pageNum, @RequestParam(defaultValue = "10") Integer pageSize) { // 构建分页对象 Page page = new Page(pageNum, pageSize); // 分页查询用户数据 IPage userPage = userService.page(page, null); return Result.builder() .code(200) .message("获取成功") .data(userPage) .build(); } /** * 根据 ID 获取用户信息 */ @GetMapping("/{id}") public Result detail(@PathVariable Long id) { // 查询用户信息 User user = userService.getById(id); if (user != null) { return Result.builder() .code(200) .message("获取成功") .data(user) .build(); } else { return Result.builder() .code(404) .message("用户不存在") .build(); } } /** * 注册 */ @PostMapping("/register") public Result register(@RequestBody @Validated User user) { boolean success = userService.register(user); if (success) { return Result.builder() .code(200) .message("注册成功") .data(user) .build(); } else { return Result.builder() .code(500) .message("用户名已存在") .build(); } } /** * 登录 */ @PostMapping("/login") public Result login(@RequestBody User user) { String username = user.getUsername(); String password = user.getPassword(); // 查询用户 User loginUser = userService.login(username, password); if (loginUser != null) { return Result.builder() .code(200) .message("登录成功") .data(loginUser) .build(); } else { return Result.builder() .code(401) .message("用户名或密码错误") .build(); } } /** * 新增用户 */ @PostMapping("/") public Result add(@RequestBody @Validated User user) { boolean success = userService.save(user); if (success) { return Result.builder() .code(200) .message("新增成功") .data(user) .build(); } else { return Result.builder() .code(500) .message("新增失败") .data(user) .build(); } } /** * 更新用户信息 */ @PutMapping("/{id}") public Result update(@PathVariable Long id, @RequestBody @Validated User user) { user.setId(id); boolean success = userService.updateById(user); if (success) { return Result.builder() .code(200) .message("更新成功") .data(user) .build(); } else { return Result.builder() .code(500) .message("更新失败") .data(user) .build(); } } /** * 删除用户 */ @DeleteMapping("/{id}") public Result delete(@PathVariable Long id) { boolean success = userService.removeById(id); if (success) { return Result.builder() .code(200) .message("删除成功") .build(); } else { return Result.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否[email protected]邮箱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" : [ "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" ] }, /* 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 {{title}} 点击我 export default { data() { return { title: 'Hello' } }, onLoad() { }, methods: { handleClick() { console.log('您点击了该按钮!') } } } .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; } login.vue 登录 注册 import axios from 'axios' export default { 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' }) } } } .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; } register.vue 注册 返回 import axios from 'axios'; export default { data() { return { username: '', password: '', confirmPassword: '', nickname: '' }; }, methods: { async register() { 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(); } } }; .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; }


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3