OJ在线评测系统 登录页面开发 前端后端联调实现全栈开发

news/2024/9/23 20:11:41/

前端

登录页面就是一个让用户输入账号和密码的表单

使用acro组件

先写布局

  <a-form-item field="userAccount" label="账号"><a-input v-model="form.userAccount" placeholder="请输入账号" /></a-form-item><a-form-item field="userPassword" tooltip="密码不少于 8 位" label="密码"><a-input-passwordv-model="form.userPassword"placeholder="请输入密码"/></a-form-item>

这边调用

之前生成的代码

我们在js里面写代码

这边是把表单提交到这个请求上去

我们实际上在这边是进行表单的填写

再统一发给后端这个接口

但是我们还是要执行一下全局状态管理

把未登录替换成多多

我们这边还是未登录

我们要从前端的请求出发开始排查

可以看到

我们这边还是未登录的状态

原因是前端和后端根本就没有任何关联

我们要去修改openapi里面的配置

然后就能获取

<template><div id="userLoginView" class="Login"><h2 style="margin-bottom: 16px">用户登录</h2><a-formstyle="max-width: 480px; margin: 0 auto"label-align="left"auto-label-width:model="form"@submit="handleSubmit"><a-form-item field="userAccount" label="账号"><a-input v-model="form.userAccount" placeholder="请输入账号" /></a-form-item><a-form-item field="userPassword" tooltip="密码不少于 8 位" label="密码"><a-input-passwordv-model="form.userPassword"placeholder="请输入密码"/></a-form-item><a-form-item><div style="display: flex; justify-content: center" class="register"><a-space class="wrapper" direction="vertical"><a-button type="primary" html-type="submit" style="width: 120px">登录</a-button></a-space></div></a-form-item></a-form></div>
</template><style>
.wrapper {width: 360px;/*padding: 20px;*/border-radius: 4px;
}.Login {background: linear-gradient(to bottom, #f0f2f5, #ffffff); /* 示例渐变背景 */padding: 20px;border-radius: 8px;box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}
</style><script setup lang="ts">
import { reactive } from "vue";
import { UserControllerService, UserLoginRequest } from "../../../generated";
import message from "@arco-design/web-vue/es/message";
import { useRouter } from "vue-router";
import { useStore } from "vuex";/*** 表单信息*/
const form = reactive({userAccount: "",userPassword: "",
} as UserLoginRequest);const router = useRouter();
const store = useStore();/*** 提交表单* @param data*/
const handleSubmit = async () => {const res = await UserControllerService.userLoginUsingPost(form);// 登录成功,跳转到主页if (res.code === 0) {await store.dispatch("user/getLoginUser");message.success("登陆成功 欢迎你!");router.push({path: "/questions",replace: true,});} else {message.error("登陆失败," + res.message);}
};
</script>

改了一晚上的前端布局

后端

我们来看一下这个接口的具体实现

Controller层

我们传入的参数有两个

UserLoginRequest 是包含用户登录信息的请求体,通常包括账号和密码等字段;HttpServletRequest 是代表HTTP请求的对象,提供有关请求的各种信息,如请求头、参数和会话等。这两个参数共同支持用户的登录过程。

可以,只使用 UserLoginRequest 参数也是可行的。你可以在 UserLoginRequest 中添加必要的上下文信息,比如会话ID或其他请求信息。不过,通常使用 HttpServletRequest 可以提供更多的灵活性和功能。

核心逻辑判断了一些是否为空的内容

已经控制台输出

我们看一下service层的核心代码逻辑

接口

实现类

  1. 校验输入:检查 userAccountuserPassword 是否为空,确保账号长度不小于4,密码长度不小于8。如果不符合条件,抛出 BusinessException

  2. 加密密码:使用MD5加密算法对用户输入的密码进行加密,结合一个盐值 SALT,以增强安全性。

  3. 查询用户:构造数据库查询条件,通过 userAccount 和加密后的 userPassword 查找用户。如果找不到匹配的用户,记录失败信息并抛出异常。

  4. 记录登录状态:如果用户存在,将用户信息存储在HTTP会话中,以维护用户的登录状态。

  5. 返回用户信息:调用 getLoginUserVO 方法,将用户信息转换为 LoginUserVO 对象并返回。

    @Overridepublic LoginUserVO userLogin(String userAccount, String userPassword, HttpServletRequest request) {// 1. 校验if (StringUtils.isAnyBlank(userAccount, userPassword)) {throw new BusinessException(ErrorCode.PARAMS_ERROR, "参数为空");}if (userAccount.length() < 4) {throw new BusinessException(ErrorCode.PARAMS_ERROR, "账号错误");}if (userPassword.length() < 8) {throw new BusinessException(ErrorCode.PARAMS_ERROR, "密码错误");}// 2. 加密String encryptPassword = DigestUtils.md5DigestAsHex((SALT + userPassword).getBytes());// 查询用户是否存在QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.eq("userAccount", userAccount);queryWrapper.eq("userPassword", encryptPassword);User user = this.baseMapper.selectOne(queryWrapper);// 用户不存在if (user == null) {log.info("user login failed, userAccount cannot match userPassword");throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户不存在或密码错误");}// 3. 记录用户的登录态request.getSession().setAttribute(USER_LOGIN_STATE, user);return this.getLoginUserVO(user);}

LoginUserVO 是一个数据传输对象(DTO),通常用于封装用户登录后的信息,比如用户ID、用户名、角色、权限等。它的主要目的是在用户成功登录后,向客户端返回必要的用户信息,以便于后续操作。

 

注意

使用 LoginUserVO 而不是直接封装 User 主要是为了提高安全性和灵活性。LoginUserVO 可以只包含必要的字段,避免泄露敏感信息(如密码)。

此外,它允许在不同场景中定制返回的数据结构,以满足前端需求或简化数据传输。


http://www.ppmy.cn/news/1529470.html

相关文章

STM32 通过软件模拟 I2C 驱动 24Cxx 系列存储器

目录 一、AT24CXXX 系列存储器介绍1、基本信息2、寻址方式3、页地址与页内单元地址4、I2C 地址5、AT24CXX 的数据读写5.1 写操作5.1.1 按字节写5.1.2 按页写 5.2 读操作5.2.1 当前地址读取5.2.2 随机地址读取5.2.3 顺序读取 二、代码实现1、ctl_i2c2、at24c3、测试程序 I2C 相关…

C语言编译四大阶段

目录 一、引言 二、预处理阶段 三、编译阶段 四、汇编阶段 五、链接阶段 六、总结 本文将详细介绍C语言编译的四个阶段&#xff0c;包括预处理、编译、汇编和链接。通过学习这些阶段&#xff0c;读者可以更好地理解C语言程序的编译过程&#xff0c;提高编程效率。 一、引…

Linux自主学习篇

用户及权限管理 sudo 是 "superuser do" 的缩写&#xff0c;是一个在类 Unix 操作系统&#xff08;如 Linux 和 macOS&#xff09;中使用的命令。它允许普通用户以超级用户&#xff08;root 用户&#xff09;的身份执行命令&#xff0c;从而获得更高的权限。 useradd…

gin参数绑定panic错误分析

gin参数绑定panic错误分析 经过长期实践 func (e *SubscribeApi) FnExample(c *gin.Context) {//获取参数并检验var req *request.FnReqif err : c.ShouldBindQuery(&req); err ! nil {response.FailWithMsg(c, "Parameter validation error: "err.Error())retu…

VS code EXPLORER 中不显示指定文件及文件夹设置(如.pyc, __pycache__, .vscode 文件)

VS code EXPLORER 中不显示指定文件及文件夹设置 引言正文方法1打开方式1打开方式2 方法2 引言 VS code 号称地表最强轻量级编译器&#xff0c;其最大的优势在于用户可以根据自己的需求下载适合自己的 extension。从而定制个性化的编译器。然而&#xff0c;本人今天遇到了一个…

spark 广播和累加器

广播变量允许开发者将一个较大的、只读的变量缓存到每个工作节点&#xff08;Executor&#xff09;的内存中&#xff0c;而不是在每个任务&#xff08;Task&#xff09;中复制一份。这样做可以显著减少数据的传输量&#xff0c;提高计算效率&#xff0c;特别是在处理大型数据集…

如何使用 Helm 管理 Kubernetes 集群

Helm 是 Kubernetes 的包管理工具&#xff0c;简化了在 Kubernetes 上安装、更新、管理应用的流程。通过 Helm&#xff0c;开发者可以快速部署复杂的应用程序&#xff0c;类似于使用 apt、yum 或 Homebrew 安装软件包。在本文中&#xff0c;我们将详细介绍如何安装和配置 Helm&…

vue 中互相不关联的两个组件怎么进行通信(数据传输)

1、Vuex Vuex 是 Vue 官方的状态管理模式与库。通过使用 Vuex&#xff0c;可以将组件间共享的数据存储在一个全局的状态树中&#xff0c;任何组件都可以读取这个状态&#xff0c;通过提交 mutations 或 dispatch actions 来修改状态。 2、Event Bus (事件总线) 创建一个全局的…