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

一:前置操作

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 => {
        debugger
          if (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 => {
            debugger
              if (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<>());
    }
    // 教师绑定课程ids
    Set<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的key
  const 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>

相关推荐

  1. [Vue3]-router实现基本页面

    2024-06-14 20:38:03       53 阅读
  2. Vue3+ts实现页面及参数传递

    2024-06-14 20:38:03       414 阅读
  3. Vue3+Ts项目——登录页面到首页

    2024-06-14 20:38:03       69 阅读
  4. UniApp登录后如何实现页面

    2024-06-14 20:38:03       64 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-06-14 20:38:03       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-06-14 20:38:03       100 阅读
  3. 在Django里面运行非项目文件

    2024-06-14 20:38:03       82 阅读
  4. Python语言-面向对象

    2024-06-14 20:38:03       91 阅读

热门阅读

  1. llama factory 大数据量下训练失败

    2024-06-14 20:38:03       43 阅读
  2. 【AI原理解析】— Meta Llama-3模型

    2024-06-14 20:38:03       41 阅读
  3. 个人 PCB 设计规范

    2024-06-14 20:38:03       27 阅读
  4. SQLServer按照年龄段进行分组查询数据

    2024-06-14 20:38:03       34 阅读
  5. RAID分析及举例

    2024-06-14 20:38:03       38 阅读
  6. Spring boot开启跨域配置

    2024-06-14 20:38:03       32 阅读
  7. 创建型-单例模式(Singleton)

    2024-06-14 20:38:03       33 阅读
  8. [HGAME 2022 week3]Multi Prime RSA(欧拉函数)

    2024-06-14 20:38:03       29 阅读
  9. redis清空list

    2024-06-14 20:38:03       34 阅读
  10. spark mllib 特征学习笔记 (二)

    2024-06-14 20:38:03       39 阅读
  11. C语言经典例题-4

    2024-06-14 20:38:03       28 阅读
  12. 从后端到智能合约开发:需要多久

    2024-06-14 20:38:03       32 阅读
  13. Hash算法、MD5算法、HashMap

    2024-06-14 20:38:03       35 阅读