Web 毕设篇-适合小白、初级入门练手的 Spring Boot Web 毕业设计项目:教室信息管理系统

        1.0 项目介绍
        开发工具:IDEA、VScode

        服务器:Tomcat, JDK 17

        项目构建:maven

        数据库:mysql 8.0

系统用户前台和管理后台两部分,项目采用前后端分离

        前端技术:vue3 + elementUI

        服务端技术:springboot + mybatis + redis + mysql

        1.1 项目功能
后台功能:

        1)登录、退出系统、首页

        2)教室管理

                (1) 教室管理:添加、修改、删除、查询等功能。

        3)教师管理

                (1) 教师管理:添加、修改、删除、查询等功能。

        4)课程管理

                (1) 课程管理:添加、修改、删除、查询等功能。

        5)设施管理

                (1) 设施管理:添加、修改、删除、查询等功能。

        6)教室设施信息

                (1) 教室设施信息:添加、修改、删除、查询等功能。

        7)课程安排

                (1) 课程安排:添加、修改、删除、查询等功能。

        8)教室使用记录

                (1)教室使用记录:添加、修改、删除、查询等功能。

        9)系统管理

                用户信息管理

                        (1)用户信息管理:添加、修改、删除、查询等功能。

                角色管理

                        (2)角色信息管理:添加、修改、删除、查询等功能。

                菜单管理

                        (3)菜单信息管理:添加、修改、删除、查询等功能。

                日志管理

                        (4)日志信息管理:添加、修改、删除、查询等功能。

        10)系统监控

                        查看在先用户、设置定时任务、数据监控、缓存监控、查看缓存列表等。

        11)权限管理

                (1) 角色信息管理:添加、修改、删除、分配权限等功能。

                (2) 资源信息管理:添加、修改、删除等功能。

注意:不一定非要完全符合开发环境,有稍微的差别也是可以开发的。

         若需要项目完整源码,可以在 优快云 私信给我,我每天都有查看消息的,感谢大家支持,希

望可以帮助到大家!

        2.0 用户登录
        用户根据正确的用户名、密码且通过正确的校验码进行登录。使用了高质量的背景图片,希

望你喜欢。

        整体的主题颜色为:猛男粉

        实现了登录校验,还有用户注册功能:

        用到了 Spring Security 框架来实现登录、校验、验证等功能。 

相关的部分源码:

@RestController
public class SysLoginController
{
    @Autowired
    private SysLoginService loginService;
 
    @Autowired
    private ISysMenuService menuService;
 
    @Autowired
    private SysPermissionService permissionService;
 
    /**
     * 登录方法
     * 
     * @param loginBody 登录信息
     * @return 结果
     */
    @PostMapping("/login")
    public AjaxResult login(@RequestBody LoginBody loginBody)
    {
        AjaxResult ajax = AjaxResult.success();
        // 生成令牌
        String token = loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(),
                loginBody.getUuid());
        ajax.put(Constants.TOKEN, token);
        return ajax;
    }
 
    /**
     * 获取用户信息
     * 
     * @return 用户信息
     */
    @GetMapping("getInfo")
    public AjaxResult getInfo()
    {
        SysUser user = SecurityUtils.getLoginUser().getUser();
        // 角色集合
        Set<String> roles = permissionService.getRolePermission(user);
        // 权限集合
        Set<String> permissions = permissionService.getMenuPermission(user);
        AjaxResult ajax = AjaxResult.success();
        ajax.put("user", user);
        ajax.put("roles", roles);
        ajax.put("permissions", permissions);
        return ajax;
    }
 
    /**
     * 获取路由信息
     * 
     * @return 路由信息
     */
    @GetMapping("getRouters")
    public AjaxResult getRouters()
    {
        Long userId = SecurityUtils.getUserId();
        List<SysMenu> menus = menuService.selectMenuTreeByUserId(userId);
        return AjaxResult.success(menuService.buildMenus(menus));
    }
}

    public String login(String username, String password, String code, String uuid)
    {
        // 验证码校验
        validateCaptcha(username, code, uuid);
        // 登录前置校验
        loginPreCheck(username, password);
        // 用户验证
        Authentication authentication = null;
        try
        {
            UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, password);
            AuthenticationContextHolder.setContext(authenticationToken);
            // 该方法会去调用UserDetailsServiceImpl.loadUserByUsername
            authentication = authenticationManager.authenticate(authenticationToken);
        }
        catch (Exception e)
        {
            if (e instanceof BadCredentialsException)
            {
                AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
                throw new UserPasswordNotMatchException();
            }
            else
            {
                AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, e.getMessage()));
                throw new ServiceException(e.getMessage());
            }
        }
        finally
        {
            AuthenticationContextHolder.clearContext();
        }
        AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
        recordLoginInfo(loginUser.getUserId());
        // 生成token
        return tokenService.createToken(loginUser);
    }

        3.0 首页界面
        使用了各种各样的统计图表来直观展示数据。

相关的前端源码:

<template>
  <div class="dashboard-container">
    <div class="chart-container">
      <div class="chart-header">
        <h2>教室使用情况统计</h2>
      </div>
      <div class="charts">
        <div id="barChart" class="chart"></div>
        <div id="pieChart" class="chart"></div>
        <div id="lineChart" class="chart"></div>
        <div id="gaugeChart" class="chart"></div>
      </div>
    </div>
  </div>
</template>
 
<script>
import * as echarts from 'echarts';
 
export default {
  name: 'Dashboard',
  mounted() {
    this.initBarChart();
    this.initPieChart();
    this.initLineChart();
    this.initGaugeChart();
  },
  methods: {
    initBarChart() {
      const barChart = echarts.init(document.getElementById('barChart'));
      const option = {
        title: {
          text: '各教室使用次数',
          left: 'center',
          textStyle: {
            color: '#fff'
          }
        },
        tooltip: {
          trigger: 'axis',
          axisPointer: {
            type: 'shadow'
          }
        },
        xAxis: {
          type: 'category',
          data: ['教室3B-413', '教室3B-414', '教室3B-415', '教室3B-416', '教室3B-417'],
          axisLabel: {
            color: '#fff'
          }
        },
        yAxis: {
          type: 'value',
          axisLabel: {
            color: '#fff'
          }
        },
        series: [{
          data: [120, 200, 150, 80, 70],
          type: 'bar',
          itemStyle: {
            color: '#FF69B4'
          }
        }]
      };
      barChart.setOption(option);
    },
    initPieChart() {
      const pieChart = echarts.init(document.getElementById('pieChart'));
      const option = {
        title: {
          text: '教室使用比例',
          left: 'center',
          textStyle: {
            color: '#fff'
          }
        },
        tooltip: {
          trigger: 'item'
        },
        legend: {
          orient: 'vertical',
          left: 'left',
          textStyle: {
            color: '#fff'
          }
        },
        series: [
          {
            name: '教室',
            type: 'pie',
            radius: '50%',
            data: [
              { value: 335, name: '教室3B-413' },
              { value: 310, name: '教室3B-414' },
              { value: 234, name: '教室3B-415' },
              { value: 135, name: '教室3B-416' },
              { value: 1548, name: '教室3B-417' }
            ],
            emphasis: {
              itemStyle: {
                shadowBlur: 10,
                shadowOffsetX: 0,
                shadowColor: 'rgba(0, 0, 0, 0.5)'
              }
            },
            itemStyle: {
              color: function(params) {
                const colorList = ['#FF69B4', '#FF1493', '#DB7093', '#C71585', '#DA70D6'];
                return colorList[params.dataIndex];
              }
            }
          }
        ]
      };
      pieChart.setOption(option);
    },
    initLineChart() {
      const lineChart = echarts.init(document.getElementById('lineChart'));
      const option = {
        title: {
          text: '教室使用时间趋势',
          left: 'center',
          textStyle: {
            color: '#fff'
          }
        },
        tooltip: {
          trigger: 'axis'
        },
        xAxis: {
          type: 'category',
          data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日'],
          axisLabel: {
            color: '#fff'
          }
        },
        yAxis: {
          type: 'value',
          axisLabel: {
            color: '#fff'
          }
        },
        series: [{
          data: [120, 200, 150, 80, 70, 110, 130],
          type: 'line',
          itemStyle: {
            color: '#FF69B4'
          }
        }]
      };
      lineChart.setOption(option);
    },
    initGaugeChart() {
      const gaugeChart = echarts.init(document.getElementById('gaugeChart'));
      const option = {
        title: {
          text: '总使用次数',
          left: 'center',
          textStyle: {
            color: '#fff'
          }
        },
        tooltip: {
          formatter: '{a} <br/>{b} : {c}'
        },
        series: [
          {
            name: '使用次数',
            type: 'gauge',
            detail: {
              formatter: '{value}',
              color: '#fff'
            },
            data: [{ value: 2500, name: '总次数' }],
            axisLabel: {
              color: '#fff'
            },
            axisLine: {
              lineStyle: {
                color: [[0.2, '#FF69B4'], [0.8, '#FF1493'], [1, '#DB7093']],
                width: 12
              }
            },
            pointer: {
              width: 5
            },
            axisTick: {
              length: 10,
              lineStyle: {
                color: 'auto'
              }
            },
            splitLine: {
              length: 15,
              lineStyle: {
                color: 'auto'
              }
            }
          }
        ]
      };
      gaugeChart.setOption(option);
    }
  }
};
</script>
 
<style lang="scss">
$theme_color: #FF69B4;
 
.dashboard-container {
  min-height: 100vh;
  width: 100%;
  background-image: url('../../assets/images/6.jpg'); /* 使用占位图片,你可以替换为实际图片 */
  background-size: cover;
  background-position: center;
  display: flex;
  justify-content: center;
  align-items: center;
 
  .chart-container {
    background-color: rgba(0, 0, 0, 0.7); /* 半透明背景 */
    border-radius: 20px;
    box-shadow: 0 0 40px rgba(0, 0, 0, 0.5);
    width: 80%;
    max-width: 1200px;
    padding: 40px;
    color: #fff;
 
    .chart-header {
      text-align: center;
      margin-bottom: 30px;
 
      h2 {
        color: $theme_color;
        font-weight: bold;
      }
    }
 
    .charts {
      display: flex;
      flex-wrap: wrap;
      justify-content: space-between;
 
      .chart {
        width: 48%;
        height: 400px;
        margin-bottom: 20px;
      }
    }
  }
}
</style>

        4.0 教室管理功能


        上传图片使用了第三方接口:x-File-Storage 框架。

相关源码:

@RestController
@RequestMapping("/manage/Classrooms")
public class ClassroomsController extends BaseController
{
    @Autowired
    private IClassroomsService classroomsService;
 
    /**
     * 查询教室信息列表
     */
    @PreAuthorize("@ss.hasPermi('manage:Classrooms:list')")
    @GetMapping("/list")
    public TableDataInfo list(Classrooms classrooms)
    {
        startPage();
        List<Classrooms> list = classroomsService.selectClassroomsList(classrooms);
        return getDataTable(list);
    }
 
    /**
     * 导出教室信息列表
     */
    @PreAuthorize("@ss.hasPermi('manage:Classrooms:export')")
    @Log(title = "教室信息", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, Classrooms classrooms)
    {
        List<Classrooms> list = classroomsService.selectClassroomsList(classrooms);
        ExcelUtil<Classrooms> util = new ExcelUtil<Classrooms>(Classrooms.class);
        util.exportExcel(response, list, "教室信息数据");
    }
 
    /**
     * 获取教室信息详细信息
     */
    @PreAuthorize("@ss.hasPermi('manage:Classrooms:query')")
    @GetMapping(value = "/{classroomId}")
    public AjaxResult getInfo(@PathVariable("classroomId") Long classroomId)
    {
        return success(classroomsService.selectClassroomsByClassroomId(classroomId));
    }
 
    /**
     * 新增教室信息
     */
    @PreAuthorize("@ss.hasPermi('manage:Classrooms:add')")
    @Log(title = "教室信息", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody Classrooms classrooms)
    {
        return toAjax(classroomsService.insertClassrooms(classrooms));
    }
 
    /**
     * 修改教室信息
     */
    @PreAuthorize("@ss.hasPermi('manage:Classrooms:edit')")
    @Log(title = "教室信息", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody Classrooms classrooms)
    {
        return toAjax(classroomsService.updateClassrooms(classrooms));
    }
 
    /**
     * 删除教室信息
     */
    @PreAuthorize("@ss.hasPermi('manage:Classrooms:remove')")
    @Log(title = "教室信息", businessType = BusinessType.DELETE)
    @DeleteMapping("/{classroomIds}")
    public AjaxResult remove(@PathVariable Long[] classroomIds)
    {
        return toAjax(classroomsService.deleteClassroomsByClassroomIds(classroomIds));
    }
}

        5.0 教师管理功能


相关源码:

@RestController
@RequestMapping("/manage/Teachers")
public class TeachersController extends BaseController
{
    @Autowired
    private ITeachersService teachersService;
 
    /**
     * 查询教师信息列表
     */
    @PreAuthorize("@ss.hasPermi('manage:Teachers:list')")
    @GetMapping("/list")
    public TableDataInfo list(Teachers teachers)
    {
        startPage();
        List<Teachers> list = teachersService.selectTeachersList(teachers);
        return getDataTable(list);
    }
 
    /**
     * 导出教师信息列表
     */
    @PreAuthorize("@ss.hasPermi('manage:Teachers:export')")
    @Log(title = "教师信息", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, Teachers teachers)
    {
        List<Teachers> list = teachersService.selectTeachersList(teachers);
        ExcelUtil<Teachers> util = new ExcelUtil<Teachers>(Teachers.class);
        util.exportExcel(response, list, "教师信息数据");
    }
 
    /**
     * 获取教师信息详细信息
     */
    @PreAuthorize("@ss.hasPermi('manage:Teachers:query')")
    @GetMapping(value = "/{teacherId}")
    public AjaxResult getInfo(@PathVariable("teacherId") Long teacherId)
    {
        return success(teachersService.selectTeachersByTeacherId(teacherId));
    }
 
    /**
     * 新增教师信息
     */
    @PreAuthorize("@ss.hasPermi('manage:Teachers:add')")
    @Log(title = "教师信息", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody Teachers teachers)
    {
        return toAjax(teachersService.insertTeachers(teachers));
    }
 
    /**
     * 修改教师信息
     */
    @PreAuthorize("@ss.hasPermi('manage:Teachers:edit')")
    @Log(title = "教师信息", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody Teachers teachers)
    {
        return toAjax(teachersService.updateTeachers(teachers));
    }
 
    /**
     * 删除教师信息
     */
    @PreAuthorize("@ss.hasPermi('manage:Teachers:remove')")
    @Log(title = "教师信息", businessType = BusinessType.DELETE)
    @DeleteMapping("/{teacherIds}")
    public AjaxResult remove(@PathVariable Long[] teacherIds)
    {
        return toAjax(teachersService.deleteTeachersByTeacherIds(teacherIds));
    }
}

        6.0 课程管理功能


相关源码:

@RestController
@RequestMapping("/manage/Courses")
public class CoursesController extends BaseController
{
    @Autowired
    private ICoursesService coursesService;
 
    /**
     * 查询课程信息列表
     */
    @PreAuthorize("@ss.hasPermi('manage:Courses:list')")
    @GetMapping("/list")
    public TableDataInfo list(Courses courses)
    {
        startPage();
        List<Courses> list = coursesService.selectCoursesList(courses);
        return getDataTable(list);
    }
 
    /**
     * 导出课程信息列表
     */
    @PreAuthorize("@ss.hasPermi('manage:Courses:export')")
    @Log(title = "课程信息", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, Courses courses)
    {
        List<Courses> list = coursesService.selectCoursesList(courses);
        ExcelUtil<Courses> util = new ExcelUtil<Courses>(Courses.class);
        util.exportExcel(response, list, "课程信息数据");
    }
 
    /**
     * 获取课程信息详细信息
     */
    @PreAuthorize("@ss.hasPermi('manage:Courses:query')")
    @GetMapping(value = "/{courseId}")
    public AjaxResult getInfo(@PathVariable("courseId") Long courseId)
    {
        return success(coursesService.selectCoursesByCourseId(courseId));
    }
 
    /**
     * 新增课程信息
     */
    @PreAuthorize("@ss.hasPermi('manage:Courses:add')")
    @Log(title = "课程信息", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody Courses courses)
    {
        return toAjax(coursesService.insertCourses(courses));
    }
 
    /**
     * 修改课程信息
     */
    @PreAuthorize("@ss.hasPermi('manage:Courses:edit')")
    @Log(title = "课程信息", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody Courses courses)
    {
        return toAjax(coursesService.updateCourses(courses));
    }
 
    /**
     * 删除课程信息
     */
    @PreAuthorize("@ss.hasPermi('manage:Courses:remove')")
    @Log(title = "课程信息", businessType = BusinessType.DELETE)
    @DeleteMapping("/{courseIds}")
    public AjaxResult remove(@PathVariable Long[] courseIds)
    {
        return toAjax(coursesService.deleteCoursesByCourseIds(courseIds));
    }
}

        7.0 设施管理功能


相关源码:

@RestController
@RequestMapping("/manage/Facilities")
public class FacilitiesController extends BaseController
{
    @Autowired
    private IFacilitiesService facilitiesService;
 
    /**
     * 查询教室设施列表
     */
    @PreAuthorize("@ss.hasPermi('manage:Facilities:list')")
    @GetMapping("/list")
    public TableDataInfo list(Facilities facilities)
    {
        startPage();
        List<Facilities> list = facilitiesService.selectFacilitiesList(facilities);
        return getDataTable(list);
    }
 
    /**
     * 导出教室设施列表
     */
    @PreAuthorize("@ss.hasPermi('manage:Facilities:export')")
    @Log(title = "教室设施", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, Facilities facilities)
    {
        List<Facilities> list = facilitiesService.selectFacilitiesList(facilities);
        ExcelUtil<Facilities> util = new ExcelUtil<Facilities>(Facilities.class);
        util.exportExcel(response, list, "教室设施数据");
    }
 
    /**
     * 获取教室设施详细信息
     */
    @PreAuthorize("@ss.hasPermi('manage:Facilities:query')")
    @GetMapping(value = "/{facilityId}")
    public AjaxResult getInfo(@PathVariable("facilityId") Long facilityId)
    {
        return success(facilitiesService.selectFacilitiesByFacilityId(facilityId));
    }
 
    /**
     * 新增教室设施
     */
    @PreAuthorize("@ss.hasPermi('manage:Facilities:add')")
    @Log(title = "教室设施", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody Facilities facilities)
    {
        return toAjax(facilitiesService.insertFacilities(facilities));
    }
 
    /**
     * 修改教室设施
     */
    @PreAuthorize("@ss.hasPermi('manage:Facilities:edit')")
    @Log(title = "教室设施", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody Facilities facilities)
    {
        return toAjax(facilitiesService.updateFacilities(facilities));
    }
 
    /**
     * 删除教室设施
     */
    @PreAuthorize("@ss.hasPermi('manage:Facilities:remove')")
    @Log(title = "教室设施", businessType = BusinessType.DELETE)
    @DeleteMapping("/{facilityIds}")
    public AjaxResult remove(@PathVariable Long[] facilityIds)
    {
        return toAjax(facilitiesService.deleteFacilitiesByFacilityIds(facilityIds));
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值