使用AI一步一步实现若依(27)

功能27:实现用户登录

text 复制代码
功能26:新增一个新员工培训页面
功能25:角色管理
功能24:菜单管理
功能23:从后端获取路由/菜单数据
功能22:用户管理
功能21:使用axios发送请求
功能20:使用分页插件
功能19:集成MyBatis-Plus
功能18:创建后端工程
功能17:菜单管理
功能16:角色管理
功能15:用户管理
功能14:使用本地SVG图标库
功能13:侧边栏加入Logo
功能12:折叠/展开侧边栏
功能11:实现面包屑功能
功能10:添加首页菜单项
功能9:退出登录功能
功能8:页面权限控制
功能7:路由全局前置守卫
功能6:动态添加路由记录
功能5:侧边栏菜单动态显示
功能4:首页使用Layout布局
功能3:点击登录按钮实现页面跳转
功能2:静态登录界面
功能1:创建前端项目

前言

将登录的功能对接后端。

一.操作步骤

1.修改登录模板

src\views\login.vue

html 复制代码
<template>
  <div class="login-container">
    <div class="login-box">
      <h2 class="title">用户登录</h2>
      <el-form ref="loginForm" :model="formData" :rules="rules" @submit.prevent="handleLogin">
        <el-form-item prop="username">
          <el-input v-model="formData.username" placeholder="请输入用户名" :prefix-icon="User" />
        </el-form-item>

        <el-form-item prop="password">
          <el-input v-model="formData.password" type="password" placeholder="请输入密码" show-password :prefix-icon="Lock" />
        </el-form-item>

        <el-form-item>
          <el-button type="primary" native-type="submit" class="login-btn">
            登录
          </el-button>
        </el-form-item>
      </el-form>
    </div>
  </div>
</template>

<script setup>
import { ref, watch } from 'vue'
import { ElMessage } from 'element-plus'
import { User, Lock } from '@element-plus/icons-vue'
import { useRouter, useRoute } from 'vue-router'
import useUserStore from '@/stores/user'

const userStore = useUserStore()
const router = useRouter()
const route = useRoute()
// 表单数据
const formData = ref({
  username: "",
  password: "",
});

// 表单引用
const loginForm = ref(null)

// 验证规则
const rules = {
  username: [
    { required: true, message: '用户名不能为空', trigger: 'blur' }
  ],
  password: [
    { required: true, message: '密码不能为空', trigger: 'blur' }
  ]
}
const redirect = ref(undefined);

watch(route, (newRoute) => {
  redirect.value = newRoute.query && newRoute.query.redirect;
}, { immediate: true });
// 登录处理
const handleLogin = async () => {
  try {
    // 表单验证
    await loginForm.value.validate()

    // 这里添加实际登录逻辑
    try {
      await userStore.login(formData.value)


      router.push({ path: redirect.value || "/" });
      ElMessage.success('登录成功!')
    } catch (error) {
      ElMessage.error('登录失败')
    }
  } catch (error) {
    ElMessage.error('请正确填写表单')
  }
}
</script>

<style scoped>
.login-container {
  min-height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
  background: url('@/assets/images/login-background.jpg') no-repeat center center;
  background-size: cover;
}

.login-box {
  width: 400px;
  padding: 40px;
  background: rgba(255, 255, 255, 0.9);
  border-radius: 8px;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
}

.title {
  text-align: center;
  margin-bottom: 30px;
  color: #333;
}

.login-btn {
  width: 100%;
  margin-top: 10px;
}

.el-form-item {
  margin-bottom: 28px;
}
</style>

2.修改Store

src\stores\user.js

js 复制代码
import { defineStore } from 'pinia'
import { setToken, removeToken } from '@/utils/auth'
import { ref } from 'vue'
import { login as loginApi } from '@/api/login'

const useUserStore = defineStore('user', () => {
  const permissions = ref(['*:*:*'])

  // 异步操作
  const login = async (userInfo) => {
    const username = userInfo.username.trim()
    const password = userInfo.password

    const res = await loginApi(username, password)
    setToken(res.token)
  }

  const logout = async () => {
    await removeToken()
  }

  return {
    permissions,
    login, logout
  }
})

export default useUserStore

3.API

src\api\login.js

js 复制代码
import request from '@/utils/request'

// 登录方法
export const login = (userName, password) => {
  const data = {
    userName,
    password
  }
  return request({
    url: '/login',
    method: 'post',
    data: data
  })
}

// 获取路由
export const getRouters = () => {
  return request({
    url: '/getRouters',
    method: 'get'
  })
}

后端

4.修改Controller

src/main/java/com/ruoyi/web/controller/system/SysLoginController.java

登录逻辑,根据前端发送的用户名,查询数据库,如果查询到用户则简单比较数据库里的密码和前端发送的密码。(这是一个一堆Bug的逻辑)

java 复制代码
@RestController
public class SysLoginController {
    @Autowired
    private ISysMenuService menuService;

    @Autowired
    private ISysUserService sysUserService;

    @PostMapping("/login")
    public AjaxResult login(@RequestBody SysUserDTO userDTO) {
        LambdaQueryWrapper<SysUser> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        if (userDTO.getUserName() != null) {
            lambdaQueryWrapper.eq(SysUser::getUserName, userDTO.getUserName());
        }

        SysUser sysUser = sysUserService.getOne(lambdaQueryWrapper);

        if (sysUser != null && sysUser.getPassword().equals(userDTO.getPassword())) {
            AjaxResult ajax = AjaxResult.success();
            // 生成令牌
            String token = "test-admin";
            ajax.put(Constants.TOKEN, token);
            return ajax;
        } else {
            throw new RuntimeException();
        }
    }

    /**
     * 获取路由信息
     *
     * @return 路由信息
     */
    @GetMapping("getRouters")
    public AjaxResult getRouters() {
        return AjaxResult.success(menuService.buildMenus(1L));
    }
}

5.DTO

src/main/java/com/ruoyi/common/core/domain/dto/SysUserDTO.java

增加一个password字段,接收登录时的密码。

java 复制代码
    /** 密码 */
    private String password;

6.常量

src/main/java/com/ruoyi/common/constant/Constants.java

java 复制代码
    /**
     * 令牌
     */
    public static final String TOKEN = "token";

二.功能验证

在用户界面新增用户zhangsan,密码123456

将正在登录的用户注销,使用新增用户zhangsan登录。

三.思考

在后端服务器,如何判断每个请求是来自哪个用户呢?相同的请求,例如之前的获取路由/菜单数据接口,不同的用户请求,可能需要返回不同的数据。

相关推荐
明天不下雨(牛客同名)1 小时前
为什么 ThreadLocalMap 的 key 是弱引用 value是强引用
java·jvm·算法
多多*2 小时前
Java设计模式 简单工厂模式 工厂方法模式 抽象工厂模式 模版工厂模式 模式对比
java·linux·运维·服务器·stm32·单片机·嵌入式硬件
猫猫不是喵喵.3 小时前
vue 路由
前端·javascript·vue.js
bin91534 小时前
DeepSeek 助力 Vue3 开发:打造丝滑的表格(Table)之添加行拖拽排序功能示例12,TableView16_12 拖拽动画示例
前端·javascript·vue.js·ecmascript·deepseek
胡图蛋.4 小时前
Spring Boot 支持哪些日志框架?推荐和默认的日志框架是哪个?
java·spring boot·后端
牛马baby4 小时前
Java高频面试之并发编程-01
java·开发语言·面试
小小大侠客4 小时前
将eclipse中的web项目导入idea
java·eclipse·intellij-idea
拉不动的猪4 小时前
vue自定义“权限控制”指令
前端·javascript·vue.js
不再幻想,脚踏实地4 小时前
MySQL(一)
java·数据库·mysql
吃海鲜的骆驼4 小时前
SpringBoot详细教程(持续更新中...)
java·spring boot·后端