当前位置: 首页 > news >正文

[Vue3:axios]:实现登录跳转页面展示列表(查看教师所承担课程的学生选课情况)

文章目录

  • 一:前置操作
    • 项目结构:
  • 二:登录页面
    • 主要流程说明
    • 运行截图
    • 前端代码Login.vue
  • 三:列表页面
    • 交互逻辑:涉及页面Page02.vue (登录成功跳转学生选课页面)
    • 运行截图

一:前置操作

https://blog.csdn.net/Abraxs/article/details/139552598?spm=1001.2014.3001.5501
在这里插入图片描述

项目结构:

在这里插入图片描述

二:登录页面

主要流程说明

登录交互逻辑:
Login.vue 点击登录发送请求 api /api/base/login 然后localStorage存储登录信息
关键代码:
前端

const submitForm = () => {loginForm.value.validate((valid) => {if (valid) {axios.post("/api/base/login",{jobNumber: form.username,pwd: form.password}).then(resp => {debuggerif (resp.data.code == 500) {alert(resp.data.message)}if (resp.data.code == 200) {localStorage.setItem('id', resp.data.data.id)localStorage.setItem('username', resp.data.data.name)router.push('/page')}})// Handle login logic here} else {alert('登录失败');}});

后端

@ApiOperation(value = "教师登录", notes = "教师登录", produces = MediaType.APPLICATION_JSON_VALUE)
@PostMapping("/login")
public R<BaseTeacher> login(@RequestBody LoginReq req){BaseTeacher back = baseTeacherService.getOne(new LambdaQueryWrapper<BaseTeacher>().eq(BaseTeacher::getJobNumbers, req.getJobNumber()).eq(BaseTeacher::getPwd, req.getPwd()));if (ObjectUtils.isEmpty(back)) {return R.error("教师不存在");}return R.ok( "登录成功",  back);
}

运行截图

在这里插入图片描述

前端代码Login.vue

<template><div><el-form ref="loginForm" :model="form" :rules="rules"><div class="title-container" style="margin-top: 20px;"><h3 class="title">学生管理平台</h3></div><el-form-item prop="username"><el-input v-model="form.jobNumber" placeholder="登录工号"></el-input></el-form-item><el-form-item prop="password"><el-input type="password" v-model="form.password" placeholder="登录密码"></el-input></el-form-item><el-form-item><el-button @click="submitForm">Login</el-button></el-form-item></el-form></div>
</template><script>
import { ref, reactive } from 'vue';
import { useRouter } from 'vue-router';
import axios from "axios";export default {name: 'Login',setup() {const showAlertFlag = ref(false);const alertMessage = ref('');const loginForm = ref(null);const form = reactive({jobNumber: '',password: ''});const rules = {jobNumber: [{ required: true, message: 'Please input username', trigger: 'blur' }],password: [// { required: true, message: 'Please input password', trigger: 'blur' },// { min: 6, message: 'Password length should be greater than 6', trigger: 'blur' }]};const router = useRouter();const submitForm = () => {loginForm.value.validate((valid) => {if (valid) {axios.post("/api/base/login",{jobNumber: form.jobNumber,pwd: form.password}).then(resp => {debuggerif (resp.data.code == 500) {alert(resp.data.message)}if (resp.data.code == 200) {localStorage.setItem('id', resp.data.data.id)localStorage.setItem('username', resp.data.data.name)showAlertFlag.value = true;window.alert(resp.data.message);showAlertFlag.value = false;router.push('/page')}})// Handle login logic here} else {alert('登录失败');}});};return {loginForm,form,rules,submitForm,alertMessage};}
};
</script>

三:列表页面

交互逻辑:涉及页面Page02.vue (登录成功跳转学生选课页面)

登录成功跳转学生选课页面同时发送请求 /api/baseStudentCourse/list
携带当前localStorage登录用户信息
关键代码:

前端:
const tableData = ref([]); // 使用ref来创建响应式数据
onMounted(async () => {const response = await axios.post("/api/baseStudentCourse/list", {id: localStorage.getItem('id')});tableData.value = response.data.data; // 将请求结果赋值给响应式数据
});
后端:
@ApiOperation(value = "列表", notes = "列表", produces = MediaType.APPLICATION_JSON_VALUE)
@PostMapping("/list")
public R<List<BaseStudentCourse>> list(@RequestBody CommonReqById req){// 该教师所绑定课程List<BaseCourse> baseCourses = baseCourseService.list(new LambdaQueryWrapper<BaseCourse>().eq(BaseCourse::getTeacherId, req.getId()));// 判断是否为空,空择返回空数组if (CollectionUtils.isEmpty(baseCourses)) {return R.ok(new ArrayList<>());}// 教师绑定课程idsSet<Long> courseIds = baseCourses.stream().map(BaseCourse::getId).collect(Collectors.toSet());// 传入教师绑定课程参数聚合查询所教课程List<BaseStudentCourse> baseTeacherCourses = baseStudentCourseService.list(new LambdaQueryWrapper<BaseStudentCourse>().in(BaseStudentCourse::getCourseId, courseIds));if (CollectionUtils.isEmpty(baseTeacherCourses)) {return R.ok(new ArrayList<>(0));}Map<Long, String> mapCourse = baseCourseService.list().stream().collect(Collectors.toMap(BaseCourse::getId, BaseCourse::getName));Map<Long, String> mapTeacher = baseTeacherService.list().stream().collect(Collectors.toMap(BaseTeacher::getId, BaseTeacher::getName));Map<Long, BaseStudent> mapStudent = baseStudentService.list().stream().collect(Collectors.toMap(BaseStudent::getId, Function.identity()));baseTeacherCourses.forEach(v -> {v.setCourseName(mapCourse.get(v.getCourseId()));v.setTeacherName(mapTeacher.get(req.getId()));v.setStudentName(mapStudent.get(v.getStudentId()).getName());v.setMajorName(mapStudent.get(v.getStudentId()).getMajorId());});return R.ok(baseTeacherCourses);
}

运行截图

在这里插入图片描述
##页面Page02.vue代码

 <template><div class="container"><div class="title-container" style="margin-top: 20px;"><h3 class="title">学生管理平台</h3></div><div class="user-info"><div class="buttons"><el-button size="mini" class="user-button primary" @click="handleAddCourse()" :closeCourseModal = "closeModal">添加选课</el-button>&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;<span><b>当前用户:</b></span>{{currentUser}}<el-button size="mini" class="user-button" @click="resetUser()">注销当前用户</el-button></div>
<!--      <h5 class="user-name">当前登录用户:{{ localStorageValue }}</h5>--></div><el-table :data="tableData"><el-table-column prop="id" label="编码" width="100"></el-table-column><el-table-column prop="studentId" label="学号" width="100"></el-table-column><el-table-column prop="studentName" label="学生" width="100"></el-table-column><el-table-column prop="courseName" label="课程" width="180"></el-table-column><el-table-column prop="majorName" label="专业" width="100"></el-table-column><el-table-column prop="score" label="分数" width="100"></el-table-column><el-table-column prop="teacherName" label="教师" width="100"></el-table-column><el-table-column label="操作" width="380"><template #default="{ row, $index }"><el-button size="mini" type="warning" @click="editItem(row, $index)"  @updateData="handleData"  >成绩修改</el-button><el-button size="mini" type="warning" @click="addItem(row, $index)"  @updateData="handleData"  >成绩添加</el-button><el-button size="mini" type="danger" @click="handleDeleteCourse(row, $index)"  @updateData="handleData"  >删除选课</el-button></template></el-table-column></el-table><ModalEdit v-model:visible="showModal" :edit-data="editData" :show-flag = "showFlag" @refreshData="refreshData" /><ModalCourseAdd v-model:visible="showModalAddCourse" @refreshData="refreshData" /></div>
</template><script setup>
import { useRouter } from 'vue-router';
import {onMounted, ref} from 'vue';
import axios from "axios";
import ModalEdit from "./ModalEdit.vue";
import ModalCourseAdd from "./ModalCourseAdd.vue";
const tableData = ref([]); // 使用ref来创建响应式数据
onMounted(async () => {const response = await axios.post("/api/baseStudentCourse/list", {id: localStorage.getItem('id')});tableData.value = response.data.data; // 将请求结果赋值给响应式数据
});
const currentUser = localStorage.getItem("username");
const showModal = ref(false);
const showModalAddCourse = ref(false);
const editData = ref(null);
const showFlag = ref(String);
const editItem = (item, index) => {editData.value = item;showModal.value = true;showFlag.value = '成绩修改';
};const addItem = (item, index) => {editData.value = item;showModal.value = true;showFlag.value = '成绩添加';
};const closeModal = () => {showModalAddCourse.value = false
};const handleData = () => {console.log("Page02 handleData")const response = axios.post("/api/baseStudentCourse/list", {id: localStorage.getItem('id')});tableData.value = response.data.data; // 将请求结果赋值给响应式数据;console.log(response)
};const router = useRouter();
const resetUser = () => {// 编辑逻辑const key = 'id'; // 替换为你需要获取的localStorage的keyconst value = localStorage.getItem(key);// 如果需要解析JSON,可以在这里进行解析try {axios.post("/api/base/reset", {id: localStorage.getItem('id')}).then(resp => {if (resp.data.code === 200) {alert(resp.data.message);localStorage.removeItem(localStorage.getItem('id'))router.push('/')} else {alert(resp.data.message);}})} catch (error) {console.error(error);// 处理错误}
};// 添加选课
const handleAddCourse = () => {debugger// editData.value = item;showModalAddCourse.value = true;
};// 删除选课
const handleDeleteCourse = (row, index) => {console.log(row)axios.post("/api/baseStudentCourse/delete", {id: row.id}).then(resp => {if (resp.data.code === 200) {alert(resp.data.message);axios.post("/api/baseStudentCourse/list", {id: localStorage.getItem('id')}).then(resp => {if (resp.data.code === 200) {tableData.value = resp.data.data} else {alert(resp.data.message);}})} else {alert(resp.data.message);}})
};const updateList = (updatedItem) => {// 假设使用index来更新list,但这种方式不推荐,如果数据顺序改变会有问题const index = tableData.value.findIndex(item => item.id === updatedItem.id);tableData.value.splice(index, 1, updatedItem);showModal.value = false;
};// 成绩修改
const refreshData = () => {axios.post("/api/baseStudentCourse/list", {id: localStorage.getItem('id')}).then(resp => {if (resp.data.code === 200) {tableData.value = resp.data.data} else {alert(resp.data.message);}})showModal.value = false;showModalAddCourse.value = false;
} ;// console.log(""")</script>

相关文章:

  • 基于springboot实现交通管理在线服务系统项目【项目源码+论文说明】计算机毕业设计
  • [一] 解释自己思维判断与行为 - 《情报分析心理学》读后感
  • Java中如何调用mysql中函数
  • LVGL移植和图片显示
  • 聚焦新版综合编程能力面试考查汇总
  • Vue18-列表渲染
  • 零基础直接上手java跨平台桌面程序,使用javafx(四)用Apache POI读取excel文件。
  • 【Jenkins+K8s】持续集成与交付 (二十):K8s集群通过Deployment方式部署安装Jenkins
  • 三高系统的架构设计方案:高并发、高可用、高性能
  • WebSphere面试题精选和参考答案(3万字长文)
  • 1789. 员工的直属部门
  • 「前端+鸿蒙」鸿蒙应用开发-TS接口-语法多态
  • 生成式人工智能重置:从初期热潮到战略扩展
  • STM32 ST-LINK Utility的下载安装使用说明如下:
  • 【ai】pycharm远程ssh开发
  • [ JavaScript ] 数据结构与算法 —— 链表
  • Android 架构优化~MVP 架构改造
  • JavaScript 事件——“事件类型”中“HTML5事件”的注意要点
  • JavaScript新鲜事·第5期
  • maya建模与骨骼动画快速实现人工鱼
  • MySQL用户中的%到底包不包括localhost?
  • react-native 安卓真机环境搭建
  • SpiderData 2019年2月16日 DApp数据排行榜
  • Synchronized 关键字使用、底层原理、JDK1.6 之后的底层优化以及 和ReenTrantLock 的对比...
  • tab.js分享及浏览器兼容性问题汇总
  • Vue.js 移动端适配之 vw 解决方案
  • webgl (原生)基础入门指南【一】
  • 笨办法学C 练习34:动态数组
  • 对超线程几个不同角度的解释
  • 翻译--Thinking in React
  • 模型微调
  • 排序算法之--选择排序
  • 试着探索高并发下的系统架构面貌
  • 中国人寿如何基于容器搭建金融PaaS云平台
  • ​520就是要宠粉,你的心头书我买单
  • ​油烟净化器电源安全,保障健康餐饮生活
  • #define,static,const,三种常量的区别
  • (1)(1.13) SiK无线电高级配置(六)
  • (4)事件处理——(2)在页面加载的时候执行任务(Performing tasks on page load)...
  • (C#)一个最简单的链表类
  • (libusb) usb口自动刷新
  • (Redis使用系列) Springboot 使用redis的List数据结构实现简单的排队功能场景 九
  • (SERIES10)DM逻辑备份还原
  • (四)linux文件内容查看
  • (转) Face-Resources
  • ****Linux下Mysql的安装和配置
  • .gitignore文件忽略的内容不生效问题解决
  • .NET 5种线程安全集合
  • .NET C# 配置 Options
  • .NET/C# 使用反射注册事件
  • .net开发引用程序集提示没有强名称的解决办法
  • .NET开源快速、强大、免费的电子表格组件
  • .NET命令行(CLI)常用命令
  • .NET与java的MVC模式(2):struts2核心工作流程与原理
  • /usr/bin/env: node: No such file or directory