SpringBoot+Vue实现的高校图书馆管理系统 附带详细运行指导视频

这篇具有很好参考价值的文章主要介绍了SpringBoot+Vue实现的高校图书馆管理系统 附带详细运行指导视频。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、项目演示

项目演示地址: 视频地址

二、项目介绍

项目描述:这是一个基于SpringBoot+Vue框架开发的高校图书馆管理系统。首先,这是一个前后端分离的项目,代码简洁规范,注释说明详细,易于理解和学习。其次,这项目功能丰富,具有一个高校图书馆管理系统该有的所有功能。

项目功能:此项目分为两个角色:学生管理员学生有登录注册、管理个人信息、浏览座位信息、预约选座、浏览图书信息、借阅图书、浏览借阅信息、管理预约信息等等功能。管理员有管理所有用户新息、管理所有座位信息、管理所有时刻信息、管理所有信誉积分信息、管理所有图书信息、管理所有预约选座、借阅信息等等功能。

应用技术:SpringBoot + Vue + MySQL + MyBatis + Redis + ElementUI

运行环境:IntelliJ IDEA2019.3.5 + MySQL5.7(项目压缩包中自带) + Redis5.0.5(项目压缩包中自带) + JDK1.8 + Gradle5.6.4(项目压缩包中自带)+ Node14.16.1(项目压缩包中自带)

三、项目运行截图

项目运行截图:
SpringBoot+Vue实现的高校图书馆管理系统 附带详细运行指导视频
SpringBoot+Vue实现的高校图书馆管理系统 附带详细运行指导视频
SpringBoot+Vue实现的高校图书馆管理系统 附带详细运行指导视频
SpringBoot+Vue实现的高校图书馆管理系统 附带详细运行指导视频
SpringBoot+Vue实现的高校图书馆管理系统 附带详细运行指导视频
SpringBoot+Vue实现的高校图书馆管理系统 附带详细运行指导视频
SpringBoot+Vue实现的高校图书馆管理系统 附带详细运行指导视频
SpringBoot+Vue实现的高校图书馆管理系统 附带详细运行指导视频
SpringBoot+Vue实现的高校图书馆管理系统 附带详细运行指导视频
SpringBoot+Vue实现的高校图书馆管理系统 附带详细运行指导视频
SpringBoot+Vue实现的高校图书馆管理系统 附带详细运行指导视频
SpringBoot+Vue实现的高校图书馆管理系统 附带详细运行指导视频
SpringBoot+Vue实现的高校图书馆管理系统 附带详细运行指导视频
SpringBoot+Vue实现的高校图书馆管理系统 附带详细运行指导视频
SpringBoot+Vue实现的高校图书馆管理系统 附带详细运行指导视频

四、主要代码

1.前端预约选座页面代码:

<template>
    <div>
        <!-- 面包屑导航 -->
        <el-breadcrumb separator-class="el-icon-arrow-right">
            <el-breadcrumb-item :to="{ path: '/home/dash-board' }">首页</el-breadcrumb-item>
            <el-breadcrumb-item>选座页面</el-breadcrumb-item>
        </el-breadcrumb>
        <!-- 搜索筛选 -->
        <el-form :inline="true" :model="searchParams" class="user-search">
            <el-form-item label="搜索:">
                <el-date-picker
                        value-format="yyyy-MM-dd"
                        format="yyyy-MM-dd"
                        size="small"
                        v-model="searchParams.openTime"
                        type="date"
                        :picker-options="pickerOptions"
                        :clearable="false"
                        :editable="false">
                </el-date-picker>
            </el-form-item>
            <el-form-item>
                <el-select v-model="searchParams.scheduleId" size="small" placeholder="请选择时刻">
                    <el-option v-for="(item, index) in scheduleList" :key="index" :label="item.name + '(' + item.rangeTime + ')'" :value="item.id"></el-option>
                </el-select>
            </el-form-item>
            <el-form-item>
                <el-button size="small" type="primary" icon="el-icon-search" @click="searchByTime">搜索</el-button>
                <el-button size="small" v-if="loginUser.roleId === 1" type="primary" icon="el-icon-date" @click="pickOrderSeat">预约</el-button>
            </el-form-item>
        </el-form>
        <el-table :key="index" v-if="seat.row !== 0 && seat.col !== 0" size="small" :data="tableData" v-loading="loading" border element-loading-text="拼命加载中" style="width: 100%;">
            <el-table-column width="55">
                <template slot-scope="scope">
                    <span style="color: #909399; font-weight: bold;">第{{scope.$index + 1}}行</span>
                </template>
            </el-table-column>
            <el-table-column :width="seat.col > 9 ? 150 : ''" v-for="n in seat.col" :key="n"  align="center" :label="'第' + n + '列'" >
                <template slot-scope="scope">

                    <el-badge v-if="scope.row.picked[n-1] === 0" type="danger" value="占座" style="margin-top: 10px">
                        <img style="width: 30px; height: 30px; margin-top: 10px"
                             src="../../assets/img/sold_seat.jpg" />
                        <div>第{{scope.$index + 1}}行第{{n}}列</div>
                    </el-badge>
                    <el-badge v-else-if="scope.row.picked[n-1] === 1" type="primary" value="可选" style="margin-top: 10px">
                        <div @click="pickSeat(scope.$index, n-1)">
                            <img style="width: 30px; height: 30px; margin-top: 10px"
                                 src="../../assets/img/selectable_seat.jpg" />
                            <div>第{{scope.$index + 1}}行第{{n}}列</div>
                        </div>
                    </el-badge>
                    <el-badge v-else-if="scope.row.picked[n-1] === 2" type="success" value="选中" style="margin-top: 10px">
                        <div @click="cancelSeat(scope.$index + 1, n)">
                            <img style="width: 30px; height: 30px; margin-top: 10px"
                                 src="../../assets/img/selected_seat.jpg" />
                            <div>第{{scope.$index + 1}}行第{{n}}列</div>
                        </div>
                    </el-badge>
                </template>
            </el-table-column>
        </el-table>

        <el-empty v-else :image-size="200"></el-empty>
    </div>
</template>

<script>
    export default {
        name: 'PickList',
        data() {
            return {
                pickerOptions: {
                    disabledDate: (time) => {
                        return time.getTime() < Date.now() - 8.64e7
                    }
                },
                searchParams: {
                    openTime: '',
                    scheduleId: ''
                },
                seat: {
                    row: 0,
                    col: 0
                },
                scheduleList: [],
                loading: false,
                tableData: [],
                pickSeatList: [],
                seatItemList: [],
                index: 0,
                loginUser: {}
            }
        },
        created() {
            this.searchParams.openTime = this.getNowDay();
            this.getLoginUser();
            this.getAllScheduleList();
        },
        methods: {
            getNowDay() {
                let date = new Date();
                let y = date.getFullYear();
                let m = date.getMonth() + 1;
                m = m < 10 ? ('0' + m) : m;
                let d = date.getDate();
                d = d < 10 ? ('0' + d) : d;
                return  y + '-' + m + '-' + d;
            },
            getLoginUser() {
                this.$ajax.post("/user/getLoginUser", {token: Tool.getLoginUser()}).then((response)=>{
                    let resp = response.data;
                    if(resp.code === 0){
                        if(resp.data) {
                            this.loginUser = resp.data;
                        } else {
                            this.$message.error(resp.msg);
                            this.$router.push("/login");
                        }
                    }
                });
            },
            pickSeat(row, col) {
                if(this.pickSeatList.length >= 1) {
                    this.$message.warning("一次最多只能选1个座位!");
                    return false;
                }
                this.tableData[row].picked[col] = 2;
                // 动态刷新表格
                this.index = this.index + 1;
                this.pickSeatList.push({row: row + 1, col: col + 1});
            },
            cancelSeat(row, col) {
                this.tableData[row-1].picked[col-1] = 1;
                // 动态刷新表格
                this.index = this.index + 1;
                let nowSeatList = [];
                this.pickSeatList.forEach(item => {
                    if(item.col !== col || item.row !== row) {
                        nowSeatList.push(item);
                    }
                });
                this.pickSeatList = nowSeatList;
            },
            getSeatBySearch() {
                this.loading = true;
                this.$ajax.post("/seat/getByTime", this.searchParams).then((response)=>{
                    let resp = response.data;
                    if(resp.code === 0){
                        if(resp.data) {
                            this.seat = resp.data;
                            this.getSeatItem();
                        } else {
                            this.seat = {row: 0, col: 0};
                        }
                    }
                });
            },
            initSeatDetailList() {
                this.tableData = [];
                for(let i=1; i<=this.seat.row; i++) {
                    let item = {picked: []};
                    for(let j=1; j<=this.seat.col; j++) {
                        item.picked.push(this.isPicked(i, j));
                    }
                    this.tableData.push(item);
                }
                this.loading = false;
            },
            isPicked(row, col) {
                let result = 1;
                this.seatItemList.forEach(item => {
                    if(item.row === row && item.col === col) {
                        result =  0; // 已被占座
                    }
                });
                return result; // 未被占座
            },
            getSeatItem() {
                this.$ajax.post("/seat/getItemBySeatId", {id: this.seat.id}).then((response)=>{
                    let resp = response.data;
                    if(resp.code === 0){
                        this.seatItemList = resp.data;
                        this.initSeatDetailList();
                    } else {
                        this.$message.error(resp.msg);
                    }
                });
            },
            pickOrderSeat() {
                 if(this.pickSeatList.length === 0) {
                     this.$message.warning("请至少选择一个座位!");
                     return false;
                 }
                 let seat = this.pickSeatList[0];
                 this.$confirm('确定要预约第'+ seat.row +'行第'+ seat.col +'列的座位?', '提示', {
                    confirmButtonText: '确定',
                    cancelButtonText: '取消',
                    type: 'warning'
                 }).then(() => {
                     this.$ajax.post("/seat/pick", {...seat, seatId: this.seat.id, userId: this.loginUser.id}).then((response)=>{
                         let resp = response.data;
                         if(resp.code === 0){
                             this.$message.success(resp.msg);
                             this.getSeatBySearch();
                             this.pickSeatList = [];
                         } else {
                             this.$message.error(resp.msg);
                         }
                     });
                 });
            },
            searchByTime() {
                this.$confirm('搜索将导致当前选中的记录丢失,确认继续此操作?', '提示', {
                    confirmButtonText: '确定',
                    cancelButtonText: '取消',
                    type: 'warning'
                }).then(() => {
                    this.pickSeatList = [];
                    this.getSeatBySearch();
                });
            },
            getAllScheduleList() {
                this.$ajax.post("/schedule/all").then((response)=>{
                    let resp = response.data;
                    if(resp.code === 0){
                        this.scheduleList = resp.data;
                        this.searchParams.scheduleId = this.scheduleList[0] ? this.scheduleList[0].id : '';
                        this.getSeatBySearch();
                    }
                });
            }
        }
    }
</script>

<style scoped>
    .user-search {
        margin-top: 20px;
    }
    /deep/ .el-table tbody tr:hover>td {
        background-color:unset !important
    }
</style>

2.借阅图书业务逻辑代码:

	/**
     * 借阅图书操作
     * @param rentalItemDTO
     * @return
     */
    @Override
    public ResponseDTO<Boolean> rentalBook(RentalItemDTO rentalItemDTO) {
        // 进行统一表单验证
        CodeMsg validate = ValidateEntityUtil.validate(rentalItemDTO);
        if(!validate.getCode().equals(CodeMsg.SUCCESS.getCode())){
            return ResponseDTO.errorByMsg(validate);
        }
        User user = userMapper.selectByPrimaryKey(rentalItemDTO.getUserId());
        if(user == null) {
            return ResponseDTO.errorByMsg(CodeMsg.USER_NOT_EXIST);
        }
        if (user.getCreditRate() < 80) {
            return ResponseDTO.errorByMsg(CodeMsg.CREDIT_RENTAL_ERROR);
        }
        Book book = bookMapper.selectByPrimaryKey(rentalItemDTO.getBookId());
        if(book == null) {
            return ResponseDTO.errorByMsg(CodeMsg.BOOK_NOT_EXIST);
        }
        if(CommonUtil.differentDaysByMillisecond(new Date(), rentalItemDTO.getPredictTime()) > 180) {
            return  ResponseDTO.errorByMsg(CodeMsg.BOOK_RENTAL_TIME_OVER);
        }
        // 修改图书状态 乐观锁控制
        BookExample bookExample = new BookExample();
        bookExample.createCriteria().andIdEqualTo(book.getId()).andVersionEqualTo(book.getVersion());
        book.setState(BookStateEnum.RENTAL.getCode());
        book.setVersion(book.getVersion() + 1);
        if(bookMapper.updateByExampleSelective(book, bookExample) == 0) {
            return ResponseDTO.errorByMsg(CodeMsg.BOOK_EDIT_ERROR);
        }
        // 写入借阅详情信息
        RentalItem rentalItem = CopyUtil.copy(rentalItemDTO, RentalItem.class);
        rentalItem.setId(UuidUtil.getShortUuid());
        rentalItem.setCreateTime(new Date());
        rentalItem.setBookName(book.getName());
        rentalItem.setBookPhoto(book.getPhoto());
        rentalItem.setState(RentalItemStateEnum.RENTAL.getCode());
        if(rentalItemMapper.insertSelective(rentalItem) == 0) {
            throw new RuntimeException(CodeMsg.BOOK_RENTAL_ERROR.getMsg());
        }
        return ResponseDTO.successByMsg(true, "借阅成功!");
    }

3.用户登录业务逻辑代码:文章来源地址https://www.toymoban.com/news/detail-425895.html

 	/**
     * 用户登录操作
     * @param userDTO
     * @return
     */
    @Override
    public ResponseDTO<UserDTO> login(UserDTO userDTO) {
        // 进行是否为空判断
        if(CommonUtil.isEmpty(userDTO.getUsername())){
            return ResponseDTO.errorByMsg(CodeMsg.USERNAME_EMPTY);
        }
        if(CommonUtil.isEmpty(userDTO.getPassword())){
            return ResponseDTO.errorByMsg(CodeMsg.PASSWORD_EMPTY);
        }
        if(CommonUtil.isEmpty(userDTO.getCaptcha())){
            return ResponseDTO.errorByMsg(CodeMsg.CAPTCHA_EMPTY);
        }
        if(CommonUtil.isEmpty(userDTO.getCorrectCaptcha())){
            return ResponseDTO.errorByMsg(CodeMsg.CAPTCHA_EXPIRED);
        }
        // 比对验证码是否正确
        String value = stringRedisTemplate.opsForValue().get((userDTO.getCorrectCaptcha()));
        if(CommonUtil.isEmpty(value)){
            return ResponseDTO.errorByMsg(CodeMsg.CAPTCHA_EXPIRED);
        }
        if(!value.toLowerCase().equals(userDTO.getCaptcha().toLowerCase())){
            return ResponseDTO.errorByMsg(CodeMsg.CAPTCHA_ERROR);
        }
        // 对比昵称和密码是否正确
        UserExample userExample = new UserExample();
        // select * from user where username = ? and password = ?
        userExample.createCriteria().andUsernameEqualTo(userDTO.getUsername()).andPasswordEqualTo(userDTO.getPassword());
        List<User> userList = userMapper.selectByExample(userExample);
        if(userList == null || userList.size() != 1){
            return ResponseDTO.errorByMsg(CodeMsg.USERNAME_PASSWORD_ERROR);
        }
        // 生成登录token并存入Redis中
        UserDTO selectedUserDto = CopyUtil.copy(userList.get(0), UserDTO.class);
        String token = UuidUtil.getShortUuid();
        selectedUserDto.setToken(token);
        //把token存入redis中 有效期1小时
        stringRedisTemplate.opsForValue().set("USER_" + token, JSON.toJSONString(selectedUserDto), 3600, TimeUnit.SECONDS);
        return ResponseDTO.successByMsg(selectedUserDto, "登录成功!");
    }

到了这里,关于SpringBoot+Vue实现的高校图书馆管理系统 附带详细运行指导视频的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 基于高校图书馆的用户画像、可视化、模型预测、推荐算法项目实现

    需要本项目的可以私信博主获取源码及项目!!! 本研究基于高校图书馆的借阅信息、馆藏图书信息、读者入馆信息、用户信息等多维度的数据表,首先将不同年份的数据拼接在一起,按照时间维度进行整合,并保证数据维度字段一致性。然后对数据进行清洗,其中包括空值

    2024年02月12日
    浏览(48)
  • Java 实现图书馆管理系统

    目录 一:创建对象 1.学生类对象Student : 2.图书类对象book : 3.管理员类对象OP: 二.创建主要交互界面MainMenu,并实现主界面功能 1.创建交互界面: 2.实现主界面功能: 三:创建OP管理界面: 1.创建主要交互界面及实现\\\"管理学生\\\"功能OPmenu: (1).交互界面: (2):实现\\\"管理学生\\\"功能: 2.实现\\\"管理

    2024年02月12日
    浏览(48)
  • 用C++实现图书馆管理系统

    该程序包含一个 `Book` 类,代表图书馆中的书籍,具有标题、作者、出版商、出版年份和可用性属性。程序中还定义了一个 `bookList` 向量,用于存储图书馆中的所有书籍。 程序的 `main` 函数通过循环显示菜单,然后根据用户的选择调用相应的函数。用户可以选择添加新书籍、

    2024年02月12日
    浏览(50)
  • 用C++实现一个图书馆管理系统

    下图为普通读者的功能 下图为图书馆管理员所拥有的功能 图中所示功能均已实现,不再一一展示,文末有项目源码 1 、 用户进入系统 用户进入系统的前提是必须先登录或者注册 2、 不同身份有不同功能的使用权 普通读者权限较小,图书管理者拥有较高权限,还设有高级管

    2023年04月13日
    浏览(46)
  • 学校图书馆管理系统的架构设计与实现

    随着大学生越来越多,学校图书馆的管理变得愈发复杂。为了更好地管理和服务于学生和教职工,学校需要建立一个高效的图书馆管理系统。本文将介绍学校图书馆管理系统的架构设计与实现。 1. 架构设计 学校图书馆管理系统的架构设计主要分为三个部分: 展示层:展示层

    2024年02月22日
    浏览(54)
  • 基于JAVA图书馆管理系统设计与实现

    【后台管理员功能】 广告管理:设置小程序首页轮播图广告和链接 留言列表:所有用户留言信息列表,支持删除 会员列表:查看所有注册会员信息,支持删除 资讯分类:录入、修改、查看、删除资讯分类 录入资讯:录入资讯标题、内容等信息 管理资讯:查看已录入资讯列

    2024年02月13日
    浏览(56)
  • 基于SpringBoot+Vue+uniapp微信小程序的图书馆自习室座位预约管理的详细设计和实现

    💗 博主介绍 :✌全网粉丝10W+,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌💗 👇🏻 精彩专栏 推荐订阅 👇🏻 2023-2024年最值得选的微信小程序毕业设

    2024年04月25日
    浏览(52)
  • 【HTML】原生js实现的图书馆管理系统

    1、引言 设计结课作业,课程设计无处下手,网页要求的总数量太多?没有合适的模板?数据库,java,python,vue,html作业复杂工程量过大?毕设毫无头绪等等一系列问题。你想要解决的问题,在微信公众号“coding加油站”中全部会得到解决 2、作品介绍 原生js实现的图书馆管理

    2024年02月06日
    浏览(43)
  • 33基于Java简单实现图书馆借书管理系统设计与实现

    本章节给大家介绍一个基于Java简单实现图书馆借书管理系统的设计与实现 项目总体分为俩种角色,分别是管理员和阅读者,管理员可以登录系统中,进行图书管理,上架下架图书,对用户进行管理、对读者进行管理、查看借阅记录管理等,读者角色可以登录系统查询图书信息

    2024年02月03日
    浏览(65)
  • 【计算机毕业设计】图书馆管理系统设计与实现

            以往的图书馆管理事务处理主要使用的是传统的人工管理方式,这种管理方式存在着管理效率低、操作流程繁琐、保密性差等缺点,长期的人工管理模式会产生大量的文本借书与文本数据,这对事务的查询、更新以及维护带来不少困难。随着互联网时代的到来,现如

    2024年02月04日
    浏览(53)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包