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

前端

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

使用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-password
          v-model="form.userPassword"
          placeholder="请输入密码"
        />
      </a-form-item>

这边调用

之前生成的代码

我们在js里面写代码

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

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

再统一发给后端这个接口

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

把未登录替换成多多

我们这边还是未登录

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

可以看到

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

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

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

然后就能获取

<template>
  <div id="userLoginView" class="Login">
    <h2 style="margin-bottom: 16px">用户登录</h2>
    <a-form
      style="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-password
          v-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 对象并返回。

     @Override
     public 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 可以只包含必要的字段,避免泄露敏感信息(如密码)。

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

相关推荐
qq_3901617710 分钟前
防抖函数--应用场景及示例
前端·javascript
time never ceases22 分钟前
使用docker方式进行Oracle数据库的物理迁移(helowin/oracle_11g)
数据库·docker·oracle
饮浊酒27 分钟前
Linux操作系统 ------(3.文本编译器Vim)
linux·vim
lihuhelihu36 分钟前
第3章 CentOS系统管理
linux·运维·服务器·计算机网络·ubuntu·centos·云计算
John.liu_Test39 分钟前
js下载excel示例demo
前端·javascript·excel
Yaml41 小时前
智能化健身房管理:Spring Boot与Vue的创新解决方案
前端·spring boot·后端·mysql·vue·健身房管理
PleaSure乐事1 小时前
【React.js】AntDesignPro左侧菜单栏栏目名称不显示的解决方案
前端·javascript·react.js·前端框架·webstorm·antdesignpro
哟哟耶耶1 小时前
js-将JavaScript对象或值转换为JSON字符串 JSON.stringify(this.SelectDataListCourse)
前端·javascript·json
getaxiosluo1 小时前
react jsx基本语法,脚手架,父子传参,refs等详解
前端·vue.js·react.js·前端框架·hook·jsx
理想不理想v1 小时前
vue种ref跟reactive的区别?
前端·javascript·vue.js·webpack·前端框架·node.js·ecmascript