用飞算JavaAI做项目:在线图书借阅平台设计与实现

用飞算JavaAI做项目:在线图书借阅平台设计与实现

目录

一、引言

作为一名计算机专业的大二学生,图书馆是我每周必去的学习场所。但传统的图书借阅流程总让我感到困扰:想借一本专业参考书,要先在图书馆官网查馆藏,再到书架前按编号找书,遇到热门书还得排队预约;还书时偶尔忘记到期时间,超期罚款不说,还影响后续借阅权限。

恰逢《Java程序设计》课程要求完成一个“贴近生活的小型系统开发”作业,我便萌生了开发一款轻量化在线图书借阅平台的想法——既能实现“查书、借书、续借、预约”全流程线上化,又能通过到期提醒避免超期。但作为编程经验不算丰富的学生,我常因“需求梳理混乱”“表结构设计不合理”“重复编写基础代码”陷入瓶颈。

直到同学推荐了飞算JavaAI,这款工具彻底改变了我的开发体验:它不仅能生成规范代码,还能像“编程助教”一样引导我拆解需求、优化设计。接下来,我将以学生视角,完整记录用飞算JavaAI实现在线图书借阅平台的全过程,希望能给同样做课程设计的同学提供参考。

二、环境准备

参考学长分享的开发经验,结合学生常用的Windows环境,我用3步就完成了环境搭建,全程没遇到复杂配置,特别适合新手:

1. 下载并安装IntelliJ IDEA

作为学生,我优先选择IDEA社区版(免费且功能满足课程设计需求)。打开JetBrains中文官网(www.jetbrains.com.cn),在“开发者工具”中找到“IntelliJ IDEA”,选择“Community”版本下载Windows安装包。

安装时注意两个细节:一是勾选“Add launchers dir to the PATH”(添加到环境变量),方便后续启动;二是勾选“Create Desktop Shortcut”(创建桌面快捷方式),避免后续找不到启动图标。全程点击“下一步”即可,约5分钟完成安装,比安装Photoshop简单多了。

在这里插入图片描述


在这里插入图片描述

2. 安装飞算JavaAI插件

打开IDEA后,点击顶部菜单栏“File → Settings → Plugins”,在右侧搜索框输入“飞算JavaAI”,找到红色的的插件,点击“Install”。

在这里插入图片描述

3. 登录飞算JavaAI

重启IDEA后,点击右侧“飞算JavaAI”面板中的“立即登录”,用学生邮箱(QQ邮箱、校园邮箱均可)注册账号,完成手机验证后登录。登录成功后,面板会显示“需求分析→软件设计→工程代码生成”的全流程引导,和我之前用过的“只生成代码片段”的工具完全不同,更符合学生“从想法到落地”的开发需求。

在这里插入图片描述

三、模块设计与编码

在飞算JavaAI的辅助下,我不再像以前那样“想到哪写到哪”,而是按“需求描述→拆解分析→设计→编码”的流程系统化开发。以下是在线图书借阅平台的完整开发过程:

1. 飞算JavaAI生成基础模块

飞算JavaAI最让我惊喜的是“支持口语化需求”——不需要专业术语,用学生的日常表达就能精准生成代码。我在插件面板的“需求编辑器”中输入:

“生成在线图书借阅平台基础模块,包含3类核心实体:用户(区分学生/管理员角色,学生有学号、班级,管理员有工号)、图书(图书编号、书名、作者、分类、馆藏数量、剩余可借数量)、借阅记录(记录ID、关联学号、关联图书编号、借阅时间、到期时间、归还状态);实现核心功能:学生注册/登录、图书查询(按书名/分类筛选)、图书借阅/续借/归还、超期提醒、管理员添加/编辑图书;技术栈:Spring Boot 3.x + MyBatis-Plus + MySQL 8.0,前端用Thymeleaf+Bootstrap(适配电脑端,方便学生在图书馆使用)。”
在这里插入图片描述

点击“提交需求”后,飞算JavaAI自动开始解析需求,不到10秒就将我的口语化描述拆解成7个可执行的关键点,还标了“必填”和“可优化”(学生可根据课程设计要求调整):

  • ☑ 用户管理:需要用户管理功能,包括学生注册、登录以及管理员账户管理
  • ☑ 图书管理:需要图书信息管理功能,支持添加、编辑图书信息
  • ☑ 图书查询:学生按书名/分类筛选图书,显示图书详情和可借状态
  • ☑ 借阅管理:需要借阅记录管理功能,包括图书借阅、续借和归还操作
  • ☑ 历史记录 :需要借阅状态跟踪功能,支持查看当前借阅情况及历史记录
  • ☑ 超期提醒:需要超期提醒功能,自动检测并通知逾期未还的图书

△ 控制功能:需要权限控制功能,区分学生与管理员角色访问不同模块

在这里插入图片描述


确认需求后,飞算JavaAI自动进入“接口设计→表结构设计→处理逻辑→生成源码”环节,全程无需手动干预。最终生成的项目结构清晰,核心包与类已完整创建,省去了我手动建包、写基础类的麻烦:

在这里插入图片描述


在这里插入图片描述


在这里插入图片描述


在这里插入图片描述


在这里插入图片描述
com.student.library ├─ entity // 实体类(映射数据库表) │ ├─ User.java // 用户实体(学生/管理员) │ ├─ Book.java // 图书实体 │ ├─ BorrowRecord.java // 借阅记录实体 │ └─ Category.java // 图书分类实体 ├─ dto // 数据传输对象(接收前端请求参数) │ ├─ UserRegisterDTO.java // 注册请求DTO │ ├─ BookAddDTO.java // 图书添加DTO │ ├─ BorrowBookDTO.java // 图书借阅DTO │ └─ BookQueryDTO.java // 图书查询DTO ├─ vo // 视图对象(向前端返回数据) │ ├─ BookDetailVO.java // 图书详情VO │ ├─ BorrowRecordVO.java // 借阅记录VO │ └─ UserBorrowVO.java // 学生借阅列表VO ├─ mapper // 数据访问接口(MyBatis-Plus) │ ├─ UserMapper.java │ ├─ BookMapper.java │ └─ BorrowRecordMapper.java ├─ service // 业务逻辑层 │ ├─ UserService.java │ ├─ BookService.java │ └─ BorrowService.java ├─ controller // 接口控制层 │ ├─ UserController.java │ ├─ BookController.java │ └─ BorrowController.java └─ config // 配置类(数据库、静态资源映射) └─ WebConfig.java 
在这里插入图片描述

2. 核心代码展示

飞算JavaAI生成的代码不仅结构规范,还自带参数校验、事务控制和详细注释,我仅需根据课程设计需求补充少量业务逻辑(比如超期提醒的时间计算),以下是关键模块的代码示例:

(1)entity包:核心实体类

User.java(用户实体,区分学生/管理员角色)

packagecom.student.library.entity;importcom.baomidou.mybatisplus.annotation.IdType;importcom.baomidou.mybatisplus.annotation.TableId;importcom.baomidou.mybatisplus.annotation.TableName;importlombok.AllArgsConstructor;importlombok.Data;importlombok.NoArgsConstructor;importjava.time.LocalDateTime;/** * <p> * 用户实体类:映射user表,区分学生(role=0)和管理员(role=1)角色 * </p> * @author feisuan-javaai(学生开发者二次优化) */@Data@NoArgsConstructor@AllArgsConstructor@TableName("user")// 关联数据库表名publicclassUser{/** * 用户ID:主键,自增 */@TableId(type =IdType.AUTO)privateLong id;/** * 账号:学生填学号,管理员填工号,唯一非空 */privateString account;/** * 密码:存储BCrypt加密后的字符串(飞算提示:避免明文存储) */privateString password;/** * 姓名:用户真实姓名 */privateString name;/** * 角色:0=学生,1=管理员(控制权限,学生不能添加图书) */privateInteger role;/** * 班级:仅学生有值,格式如“2024-计算机1班” */privateString className;/** * 邮箱:用于接收超期提醒、密码找回 */privateString email;/** * 创建时间:用户注册时间,自动填充 */privateLocalDateTime createTime;}

Book.java(图书实体,含馆藏与可借数量)

packagecom.student.library.entity;importcom.baomidou.mybatisplus.annotation.IdType;importcom.baomidou.mybatisplus.annotation.TableId;importcom.baomidou.mybatisplus.annotation.TableName;importlombok.AllArgsConstructor;importlombok.Data;importlombok.NoArgsConstructor;importjava.time.LocalDateTime;/** * <p> * 图书实体类:映射book表,记录图书基本信息与库存状态 * </p> * @author feisuan-javaai(学生开发者二次优化) */@Data@NoArgsConstructor@AllArgsConstructor@TableName("book")publicclassBook{/** * 图书编号:主键,自增(也可手动录入ISBN) */@TableId(type =IdType.AUTO)privateLong bookNo;/** * 书名:非空,如《Java编程思想》 */privateString bookName;/** * 作者:非空,多个作者用逗号分隔 */privateString author;/** * 图书分类:关联category表,如“计算机类”“文学类” */privateLong categoryId;/** * 出版社:图书出版机构 */privateString publisher;/** * 出版日期:图书出版时间 */privateLocalDateTime publishDate;/** * 馆藏总数:图书馆拥有的该图书总数量 */privateInteger totalCount;/** * 剩余可借数量:totalCount - 已借出数量 */privateInteger availableCount;/** * 图书简介:描述图书内容,帮助学生判断是否需要借阅 */privateString description;}

(2)dto包:数据传输对象(带参数校验)

BorrowBookDTO.java(学生借阅图书的请求DTO)

packagecom.student.library.dto;importjakarta.validation.constraints.NotNull;importlombok.Data;/** * <p> * 图书借阅请求DTO:接收学生借阅时的参数,含参数校验 * </p> * @author feisuan-javaai */@DatapublicclassBorrowBookDTO{/** * 学生ID:必填,从登录态获取,避免手动输入 */@NotNull(message ="学生ID不能为空")privateLong studentId;/** * 图书编号:必填,从图书详情页获取 */@NotNull(message ="图书编号不能为空")privateLong bookNo;/** * 借阅天数:必填,默认30天,最多60天(图书馆规则) */@NotNull(message ="借阅天数不能为空")privateInteger borrowDays =30;}

BookAddDTO.java(管理员添加图书的请求DTO)

packagecom.student.library.dto;importjakarta.validation.constraints.NotBlank;importjakarta.validation.constraints.NotNull;importjakarta.validation.constraints.Positive;importlombok.Data;importjava.time.LocalDateTime;/** * <p> * 图书添加请求DTO:接收管理员添加图书的参数,含参数校验 * </p> * @author feisuan-javaai */@DatapublicclassBookAddDTO{/** * 书名:必填,长度不超过100字 */@NotBlank(message ="书名不能为空")privateString bookName;/** * 作者:必填,多个作者用逗号分隔 */@NotBlank(message ="作者不能为空")privateString author;/** * 分类ID:必填,关联已有的图书分类 */@NotNull(message ="图书分类不能为空")privateLong categoryId;/** * 出版社:必填 */@NotBlank(message ="出版社不能为空")privateString publisher;/** * 出版日期:必填 */@NotNull(message ="出版日期不能为空")privateLocalDateTime publishDate;/** * 馆藏总数:必填,且必须为正整数 */@NotNull(message ="馆藏总数不能为空")@Positive(message ="馆藏总数必须大于0")privateInteger totalCount;/** * 图书简介:非必填,为空时默认填充“暂无简介” */privateString description;}

(3)vo包:视图对象(向前端隐藏敏感字段)

BookDetailVO.java(图书详情VO,给学生展示)

packagecom.student.library.vo;importlombok.Data;importjava.time.LocalDateTime;/** * <p> * 图书详情VO:封装学生查看图书时需要的信息,隐藏敏感字段(如分类ID) * </p> * @author feisuan-javaai */@DatapublicclassBookDetailVO{/** * 图书编号 */privateLong bookNo;/** * 书名 */privateString bookName;/** * 作者 */privateString author;/** * 图书分类名称:展示“计算机类”,而非分类ID */privateString categoryName;/** * 出版社 */privateString publisher;/** * 出版日期 */privateLocalDateTime publishDate;/** * 剩余可借数量:学生最关心的字段,优先展示 */privateInteger availableCount;/** * 图书简介 */privateString description;/** * 是否可借:true=可借(availableCount>0),false=不可借(需预约) */privateBoolean canBorrow;}

(4)service包:业务逻辑实现(含核心校验)

BorrowServiceImpl.java(借阅服务实现类,含借阅/续借逻辑)

packagecom.student.library.service.impl;importcom.baomidou.mybatisplus.extension.service.impl.ServiceImpl;importcom.student.library.dto.BorrowBookDTO;importcom.student.library.entity.Book;importcom.student.library.entity.BorrowRecord;importcom.student.library.entity.User;importcom.student.library.mapper.BookMapper;importcom.student.library.mapper.BorrowRecordMapper;importcom.student.library.mapper.UserMapper;importcom.student.library.service.BorrowService;importcom.student.library.vo.BorrowRecordVO;importlombok.RequiredArgsConstructor;importlombok.extern.slf4j.Slf4j;importorg.springframework.beans.BeanUtils;importorg.springframework.stereotype.Service;importorg.springframework.transaction.annotation.Transactional;importjava.time.LocalDate;importjava.time.temporal.ChronoUnit;importjava.util.List;importjava.util.stream.Collectors;/** * <p> * 借阅服务实现类:处理图书借阅、续借、归还等核心业务 * </p> * @author feisuan-javaai(学生开发者补充超期提醒逻辑) */@Slf4j@Service@RequiredArgsConstructorpublicclassBorrowServiceImplextendsServiceImpl<BorrowRecordMapper,BorrowRecord>implementsBorrowService{privatefinalBorrowRecordMapper borrowRecordMapper;privatefinalBookMapper bookMapper;privatefinalUserMapper userMapper;/** * 学生借阅图书(核心逻辑:校验库存、计算到期时间) */@Override@Transactional// 事务控制:确保借阅失败时回滚,避免库存异常publicBorrowRecordborrowBook(BorrowBookDTO borrowBookDTO){ log.info("学生借阅图书:学生ID={},图书编号={},借阅天数={}", borrowBookDTO.getStudentId(), borrowBookDTO.getBookNo(), borrowBookDTO.getBorrowDays());// 1. 校验学生身份(必须是role=0的用户)User student = userMapper.selectById(borrowBookDTO.getStudentId());if(student ==null|| student.getRole()!=0){thrownewRuntimeException("无效的学生账号,无法借阅图书");}// 2. 校验图书状态(是否存在、是否可借)Book book = bookMapper.selectById(borrowBookDTO.getBookNo());if(book ==null){thrownewRuntimeException("该图书不存在");}if(book.getAvailableCount()<=0){thrownewRuntimeException("该图书已无库存,可尝试预约");}// 3. 校验借阅天数(最多60天,符合图书馆规则)if(borrowBookDTO.getBorrowDays()>60){thrownewRuntimeException("单次借阅最多60天,请调整借阅天数");}// 4. 生成借阅记录BorrowRecord borrowRecord =newBorrowRecord(); borrowRecord.setStudentId(borrowBookDTO.getStudentId()); borrowRecord.setBookNo(borrowBookDTO.getBookNo()); borrowRecord.setBorrowDate(LocalDate.now());// 计算到期时间:借阅日期 + 借阅天数 borrowRecord.setDueDate(LocalDate.now().plusDays(borrowBookDTO.getBorrowDays())); borrowRecord.setReturnStatus(0);// 0=未归还,1=已归还// 5. 更新图书剩余可借数量 book.setAvailableCount(book.getAvailableCount()-1); bookMapper.updateById(book);// 6. 保存借阅记录save(borrowRecord); log.info("图书借阅成功:借阅记录ID={},到期时间={}", borrowRecord.getId(), borrowRecord.getDueDate());return borrowRecord;}/** * 学生续借图书(核心逻辑:校验是否超期、限制续借次数) */@Override@TransactionalpublicBorrowRecordrenewBook(Long recordId){ log.info("学生续借图书:借阅记录ID={}", recordId);// 1. 查询借阅记录(必须存在且未归还)BorrowRecordrecord=getById(recordId);if(record==null){thrownewRuntimeException("借阅记录不存在");}if(record.getReturnStatus()==1){thrownewRuntimeException("该图书已归还,无需续借");}// 2. 校验是否超期(超期后不能续借,需先归还并缴纳罚款)if(LocalDate.now().isAfter(record.getDueDate())){thrownewRuntimeException("图书已超期,请先归还并处理罚款");}// 3. 校验续借次数(最多续借1次,避免长期占用图书)if(record.getRenewCount()>=1){thrownewRuntimeException("该图书已续借1次,无法再次续借");}// 4. 更新到期时间(续借30天)和续借次数record.setDueDate(record.getDueDate().plusDays(30));record.setRenewCount(record.getRenewCount()+1);updateById(record); log.info("图书续借成功:借阅记录ID={},新到期时间={}", recordId,record.getDueDate());returnrecord;}/** * 查询学生的借阅记录(含超期提醒) */@OverridepublicList<BorrowRecordVO>getStudentBorrowRecords(Long studentId){// 1. 查询该学生的所有未归还借阅记录List<BorrowRecord> recordList =lambdaQuery().eq(BorrowRecord::getStudentId, studentId).eq(BorrowRecord::getReturnStatus,0).list();// 2. 转换为VO,补充图书名称、作者,添加超期提醒return recordList.stream().map(record->{BorrowRecordVO vo =newBorrowRecordVO();BeanUtils.copyProperties(record, vo);// 补充图书信息Book book = bookMapper.selectById(record.getBookNo()); vo.setBookName(book.getBookName()); vo.setAuthor(book.getAuthor());// 计算剩余天数,添加超期提醒long daysLeft =ChronoUnit.DAYS.between(LocalDate.now(),record.getDueDate()); vo.setDaysLeft((int) daysLeft);if(daysLeft <0){ vo.setOverdueReminder("已超期"+(-daysLeft)+"天,请尽快归还");}elseif(daysLeft <=3){ vo.setOverdueReminder("即将超期,剩余"+ daysLeft +"天");}else{ vo.setOverdueReminder("正常借阅中");}return vo;}).collect(Collectors.toList());}}

四、网页展示

为了贴合学生在图书馆使用电脑的场景,前端采用Bootstrap实现响应式布局,界面简洁清晰,避免冗余功能。以下是核心页面的功能与设计:

1. 图书查询页

  • 布局:顶部是搜索栏(支持按书名、作者搜索),左侧是分类筛选栏(计算机类、文学类、经管类等),中间是图书列表(卡片式展示);
  • 核心功能:点击分类筛选栏的“计算机类”,会自动筛选出该分类下的所有图书;图书卡片显示书名、作者、剩余可借数量,点击“查看详情”可进入图书详情页;
  • 细节设计:剩余可借数量为0时,卡片右上角显示“无库存”红色标签,避免学生白跑一趟;支持分页(每页12本图书),符合学生浏览习惯。
<!DOCTYPEhtml><htmllang="zh-CN"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width, initial-scale=1.0"><title>图书查询 - 校园图书馆系统</title><linkhref="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"rel="stylesheet"><linkhref="https://cdn.jsdelivr.net/npm/[email protected]/css/font-awesome.min.css"rel="stylesheet"><style>.category-item{transition: all 0.2s;}.category-item:hover, .category-item.active{background-color: #0d6efd;color: white !important;}.book-card{transition: transform 0.3s, box-shadow 0.3s;}.book-card:hover{transform:translateY(-5px);box-shadow: 0 10px 20px rgba(0,0,0,0.1);}.no-stock{position: absolute;top: 10px;right: 10px;}</style></head><body><!-- 导航栏 --><navclass="navbar navbar-expand-lg navbar-dark bg-primary mb-4"><divclass="container"><aclass="navbar-brand"href="#"><iclass="fa fa-book mr-2"></i>校园图书馆 </a><buttonclass="navbar-toggler"type="button"data-bs-toggle="collapse"data-bs-target="#navbarNav"><spanclass="navbar-toggler-icon"></span></button><divclass="collapse navbar-collapse"id="navbarNav"><ulclass="navbar-nav ms-auto"><liclass="nav-item"><aclass="nav-link active"href="book-search.html">图书查询</a></li><liclass="nav-item"><aclass="nav-link"href="borrowing-record.html">借阅记录</a></li><liclass="nav-item"><aclass="nav-link"href="#">个人中心</a></li><liclass="nav-item dropdown"><aclass="nav-link dropdown-toggle"href="#"role="button"data-bs-toggle="dropdown"><iclass="fa fa-user-circle"></i> 张同学 </a><ulclass="dropdown-menu dropdown-menu-end"><li><aclass="dropdown-item"href="#">个人信息</a></li><li><aclass="dropdown-item"href="#">修改密码</a></li><li><hrclass="dropdown-divider"></li><li><aclass="dropdown-item"href="#">退出登录</a></li></ul></li></ul></div></div></nav><divclass="container"><h3class="mb-4">图书查询</h3><!-- 搜索栏 --><divclass="row mb-4"><divclass="col-md-8 offset-md-2"><divclass="input-group"><inputtype="text"class="form-control"placeholder="请输入书名或作者进行搜索..."id="searchInput"><buttonclass="btn btn-primary"type="button"id="searchBtn"><iclass="fa fa-search mr-1"></i>搜索 </button></div></div></div><divclass="row"><!-- 分类筛选栏 --><divclass="col-md-3 mb-4"><divclass="card"><divclass="card-header bg-light"><h5class="mb-0">图书分类</h5></div><divclass="list-group list-group-flush"><ahref="#"class="list-group-item list-group-item-action category-item active"> 全部图书 </a><ahref="#"class="list-group-item list-group-item-action category-item"> 计算机类 </a><ahref="#"class="list-group-item list-group-item-action category-item"> 文学类 </a><ahref="#"class="list-group-item list-group-item-action category-item"> 经管类 </a><ahref="#"class="list-group-item list-group-item-action category-item"> 理工类 </a><ahref="#"class="list-group-item list-group-item-action category-item"> 医学类 </a><ahref="#"class="list-group-item list-group-item-action category-item"> 历史类 </a><ahref="#"class="list-group-item list-group-item-action category-item"> 艺术类 </a></div></div></div><!-- 图书列表 --><divclass="col-md-9"><divclass="row"><!-- 图书卡片1 --><divclass="col-md-4 mb-4"><divclass="card book-card h-100 position-relative"><imgsrc="https://picsum.photos/id/24/300/400"class="card-img-top"alt="Java编程思想"><divclass="card-body"><h5class="card-title">Java编程思想</h5><pclass="card-text text-muted">作者:Bruce Eckel</p><pclass="card-text"><small>剩余可借:<spanclass="text-success">5</span>/10</small></p><ahref="#"class="btn btn-primary btn-sm w-100">查看详情</a></div></div></div><!-- 图书卡片2 --><divclass="col-md-4 mb-4"><divclass="card book-card h-100 position-relative"><imgsrc="https://picsum.photos/id/20/300/400"class="card-img-top"alt="百年孤独"><divclass="card-body"><h5class="card-title">百年孤独</h5><pclass="card-text text-muted">作者:加西亚·马尔克斯</p><pclass="card-text"><small>剩余可借:<spanclass="text-success">3</span>/8</small></p><ahref="#"class="btn btn-primary btn-sm w-100">查看详情</a></div></div></div><!-- 图书卡片3 --><divclass="col-md-4 mb-4"><divclass="card book-card h-100 position-relative"><spanclass="badge bg-danger no-stock">无库存</span><imgsrc="https://picsum.photos/id/180/300/400"class="card-img-top"alt="微观经济学"><divclass="card-body"><h5class="card-title">微观经济学</h5><pclass="card-text text-muted">作者:曼昆</p><pclass="card-text"><small>剩余可借:<spanclass="text-danger">0</span>/5</small></p><ahref="#"class="btn btn-primary btn-sm w-100">查看详情</a></div></div></div><!-- 图书卡片4 --><divclass="col-md-4 mb-4"><divclass="card book-card h-100 position-relative"><imgsrc="https://picsum.photos/id/99/300/400"class="card-img-top"alt="数据结构与算法分析"><divclass="card-body"><h5class="card-title">数据结构与算法分析</h5><pclass="card-text text-muted">作者:Mark Allen Weiss</p><pclass="card-text"><small>剩余可借:<spanclass="text-success">2</span>/6</small></p><ahref="#"class="btn btn-primary btn-sm w-100">查看详情</a></div></div></div><!-- 图书卡片5 --><divclass="col-md-4 mb-4"><divclass="card book-card h-100 position-relative"><imgsrc="https://picsum.photos/id/106/300/400"class="card-img-top"alt="明朝那些事儿"><divclass="card-body"><h5class="card-title">明朝那些事儿</h5><pclass="card-text text-muted">作者:当年明月</p><pclass="card-text"><small>剩余可借:<spanclass="text-success">7</span>/12</small></p><ahref="#"class="btn btn-primary btn-sm w-100">查看详情</a></div></div></div><!-- 图书卡片6 --><divclass="col-md-4 mb-4"><divclass="card book-card h-100 position-relative"><imgsrc="https://picsum.photos/id/119/300/400"class="card-img-top"alt="高等数学(第七版)"><divclass="card-body"><h5class="card-title">高等数学(第七版)</h5><pclass="card-text text-muted">作者:同济大学数学系</p><pclass="card-text"><small>剩余可借:<spanclass="text-success">10</span>/20</small></p><ahref="#"class="btn btn-primary btn-sm w-100">查看详情</a></div></div></div></div><!-- 分页 --><navaria-label="Page navigation"><ulclass="pagination justify-content-center"><liclass="page-item disabled"><aclass="page-link"href="#"tabindex="-1">上一页</a></li><liclass="page-item active"><aclass="page-link"href="#">1</a></li><liclass="page-item"><aclass="page-link"href="#">2</a></li><liclass="page-item"><aclass="page-link"href="#">3</a></li><liclass="page-item"><aclass="page-link"href="#">下一页</a></li></ul></nav></div></div></div><scriptsrc="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script><script>// 分类筛选功能 document.querySelectorAll('.category-item').forEach(item=>{ item.addEventListener('click',function(e){ e.preventDefault();// 移除所有active类 document.querySelectorAll('.category-item').forEach(i=>{ i.classList.remove('active');});// 给当前点击项添加active类this.classList.add('active');// 这里可以添加实际筛选逻辑});});// 搜索功能 document.getElementById('searchBtn').addEventListener('click',function(){const searchText = document.getElementById('searchInput').value.trim();if(searchText){alert(`搜索内容: ${searchText}`);// 这里可以添加实际搜索逻辑}else{alert('请输入搜索内容');}});</script></body></html>
在这里插入图片描述

2. 借阅记录页

  • 布局:表格形式展示所有未归还的借阅记录,列包含“图书名称”“作者”“借阅时间”“到期时间”“剩余天数”“操作”;
  • 核心功能:剩余天数小于3天时,“剩余天数”列显示红色字体并标注“即将超期”;点击“续借”按钮可完成续借,点击“归还”按钮可预约归还(管理员确认后完成归还);
  • 细节设计:表格上方有“超期提醒”模块,显示该学生所有超期未还的图书,避免学生遗漏。
<!DOCTYPEhtml><htmllang="zh-CN"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width, initial-scale=1.0"><title>借阅记录 - 校园图书馆系统</title><linkhref="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"rel="stylesheet"><linkhref="https://cdn.jsdelivr.net/npm/[email protected]/css/font-awesome.min.css"rel="stylesheet"><style>.overdue-alert{border-left: 4px solid #dc3545;}.soon-expire{color: #dc3545;font-weight: bold;}.table-hover tbody tr:hover{background-color:rgba(0,0,0,0.05);}</style></head><body><!-- 导航栏 --><navclass="navbar navbar-expand-lg navbar-dark bg-primary mb-4"><divclass="container"><aclass="navbar-brand"href="#"><iclass="fa fa-book mr-2"></i>校园图书馆 </a><buttonclass="navbar-toggler"type="button"data-bs-toggle="collapse"data-bs-target="#navbarNav"><spanclass="navbar-toggler-icon"></span></button><divclass="collapse navbar-collapse"id="navbarNav"><ulclass="navbar-nav ms-auto"><liclass="nav-item"><aclass="nav-link"href="book-search.html">图书查询</a></li><liclass="nav-item"><aclass="nav-link active"href="borrowing-record.html">借阅记录</a></li><liclass="nav-item"><aclass="nav-link"href="#">个人中心</a></li><liclass="nav-item dropdown"><aclass="nav-link dropdown-toggle"href="#"role="button"data-bs-toggle="dropdown"><iclass="fa fa-user-circle"></i> 张同学 </a><ulclass="dropdown-menu dropdown-menu-end"><li><aclass="dropdown-item"href="#">个人信息</a></li><li><aclass="dropdown-item"href="#">修改密码</a></li><li><hrclass="dropdown-divider"></li><li><aclass="dropdown-item"href="#">退出登录</a></li></ul></li></ul></div></div></nav><divclass="container"><h3class="mb-4">借阅记录</h3><!-- 超期提醒 --><divclass="alert alert-danger overdue-alert mb-4"><h5class="alert-heading"><iclass="fa fa-exclamation-circle mr-2"></i>超期提醒</h5><p>您有1本图书已超期未还,请尽快归还,以免影响您的借阅权限。</p><ul><li>《C程序设计》 - 已超期3天</li></ul></div><!-- 借阅记录表格 --><divclass="card"><divclass="card-body"><divclass="table-responsive"><tableclass="table table-hover"><theadclass="table-light"><tr><th>图书名称</th><th>作者</th><th>借阅时间</th><th>到期时间</th><th>剩余天数</th><th>操作</th></tr></thead><tbody><tr><td>Java编程思想</td><td>Bruce Eckel</td><td>2023-05-10</td><td>2023-06-10</td><tdclass="soon-expire">2天 <spanclass="badge bg-danger">即将超期</span></td><td><buttonclass="btn btn-sm btn-primary"onclick="renewBook(1)">续借</button><buttonclass="btn btn-sm btn-secondary ms-1"onclick="reserveReturn(1)">归还预约</button></td></tr><tr><td>数据结构与算法分析</td><td>Mark Allen Weiss</td><td>2023-05-15</td><td>2023-06-15</td><td>7天</td><td><buttonclass="btn btn-sm btn-primary"onclick="renewBook(2)">续借</button><buttonclass="btn btn-sm btn-secondary ms-1"onclick="reserveReturn(2)">归还预约</button></td></tr><tr><td>明朝那些事儿</td><td>当年明月</td><td>2023-05-20</td><td>2023-06-20</td><td>12天</td><td><buttonclass="btn btn-sm btn-primary"onclick="renewBook(3)">续借</button><buttonclass="btn btn-sm btn-secondary ms-1"onclick="reserveReturn(3)">归还预约</button></td></tr><tr><td>C程序设计</td><td>谭浩强</td><td>2023-04-25</td><td>2023-05-25</td><tdclass="soon-expire">-3天 <spanclass="badge bg-danger">已超期</span></td><td><buttonclass="btn btn-sm btn-primary"disabled>续借</button><buttonclass="btn btn-sm btn-secondary ms-1"onclick="reserveReturn(4)">归还预约</button></td></tr></tbody></table></div></div></div></div><scriptsrc="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script><script>// 续借功能functionrenewBook(bookId){if(confirm('确定要续借这本书吗?续借将延长30天借阅期。')){alert('续借成功!新的到期时间将延长30天。');// 这里可以添加实际续借逻辑}}// 归还预约功能functionreserveReturn(bookId){if(confirm('确定要预约归还这本书吗?管理员确认后,请在3天内到图书馆归还。')){alert('归还预约已提交,请留意系统通知。');// 这里可以添加实际归还预约逻辑}}</script></body></html>
在这里插入图片描述

3. 图书管理页

  • 布局:顶部有“添加图书”按钮,下方是图书管理表格,列包含“图书编号”“书名”“作者”“馆藏总数”“剩余可借数量”“操作”;
  • 核心功能:点击“添加图书”跳转至添加页面(带参数校验,比如馆藏数量必须为正整数);点击“编辑”可修改图书信息(如更新简介),点击“下架”可将图书设为“不可借”(用于图书维护);
  • 细节设计:剩余可借数量小于总数量的1/3时,“剩余可借数量”列显示黄色字体,提醒管理员补充馆藏。
<!DOCTYPEhtml><htmllang="zh-CN"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width, initial-scale=1.0"><title>图书管理 - 校园图书馆系统</title><linkhref="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"rel="stylesheet"><linkhref="https://cdn.jsdelivr.net/npm/[email protected]/css/font-awesome.min.css"rel="stylesheet"><style>.low-stock{color: #fd7e14;font-weight: bold;}.sidebar{min-height:calc(100vh - 56px);background-color: #f8f9fa;border-right: 1px solid #dee2e6;}.sidebar .nav-link{color: #333;transition: all 0.2s;}.sidebar .nav-link.active{background-color: #0d6efd;color: white;}.sidebar .nav-link:hover:not(.active){background-color: #e9ecef;}</style></head><body><!-- 顶部导航栏 --><navclass="navbar navbar-expand-lg navbar-dark bg-primary"><divclass="container-fluid"><aclass="navbar-brand"href="#"><iclass="fa fa-book mr-2"></i>图书馆管理系统 </a><buttonclass="navbar-toggler"type="button"data-bs-toggle="collapse"data-bs-target="#navbarNav"><spanclass="navbar-toggler-icon"></span></button><divclass="collapse navbar-collapse"id="navbarNav"><ulclass="navbar-nav ms-auto"><liclass="nav-item dropdown"><aclass="nav-link dropdown-toggle"href="#"role="button"data-bs-toggle="dropdown"><iclass="fa fa-user-circle"></i> 管理员 </a><ulclass="dropdown-menu dropdown-menu-end"><li><aclass="dropdown-item"href="#">个人信息</a></li><li><aclass="dropdown-item"href="#">修改密码</a></li><li><hrclass="dropdown-divider"></li><li><aclass="dropdown-item"href="#">退出登录</a></li></ul></li></ul></div></div></nav><divclass="container-fluid"><divclass="row"><!-- 侧边栏 --><divclass="col-md-2 d-none d-md-block sidebar p-3"><ulclass="nav flex-column"><liclass="nav-item mb-1"><aclass="nav-link active"href="admin-book-management.html"><iclass="fa fa-book mr-2"></i>图书管理 </a></li><liclass="nav-item mb-1"><aclass="nav-link"href="#"><iclass="fa fa-users mr-2"></i>读者管理 </a></li><liclass="nav-item mb-1"><aclass="nav-link"href="#"><iclass="fa fa-exchange mr-2"></i>借阅管理 </a></li><liclass="nav-item mb-1"><aclass="nav-link"href="#"><iclass="fa fa-bar-chart mr-2"></i>统计分析 </a></li><liclass="nav-item mb-1"><aclass="nav-link"href="#"><iclass="fa fa-cog mr-2"></i>系统设置 </a></li></ul></div><!-- 主内容区 --><mainclass="col-md-10 ms-sm-auto px-md-4 py-4"><divclass="d-flex justify-content-between align-items-center mb-4"><h3>图书管理</h3><buttonclass="btn btn-primary"data-bs-toggle="modal"data-bs-target="#addBookModal"><iclass="fa fa-plus mr-1"></i>添加图书 </button></div><!-- 图书管理表格 --><divclass="card"><divclass="card-body"><divclass="table-responsive"><tableclass="table table-hover"><theadclass="table-light"><tr><th>图书编号</th><th>书名</th><th>作者</th><th>分类</th><th>馆藏总数</th><th>剩余可借</th><th>状态</th><th>操作</th></tr></thead><tbody><tr><td>BOOK001</td><td>Java编程思想</td><td>Bruce Eckel</td><td>计算机类</td><td>10</td><tdclass="low-stock">3</td><td><spanclass="badge bg-success">可借</span></td><td><buttonclass="btn btn-sm btn-primary"onclick="editBook('BOOK001')">编辑</button><buttonclass="btn btn-sm btn-warning ms-1"onclick="下架图书('BOOK001')">下架</button></td></tr><tr><td>BOOK002</td><td>百年孤独</td><td>加西亚·马尔克斯</td><td>文学类</td><td>8</td><td>3</td><td><spanclass="badge bg-success">可借</span></td><td><buttonclass="btn btn-sm btn-primary"onclick="editBook('BOOK002')">编辑</button><buttonclass="btn btn-sm btn-warning ms-1"onclick="下架图书('BOOK002')">下架</button></td></tr><tr><td>BOOK003</td><td>微观经济学</td><td>曼昆</td><td>经管类</td><td>5</td><tdclass="low-stock">1</td><td><spanclass="badge bg-success">可借</span></td><td><buttonclass="btn btn-sm btn-primary"onclick="editBook('BOOK003')">编辑</button><buttonclass="btn btn-sm btn-warning ms-1"onclick="下架图书('BOOK003')">下架</button></td></tr><tr><td>BOOK004</td><td>高等数学(第七版)</td><td>同济大学数学系</td><td>理工类</td><td>20</td><td>10</td><td><spanclass="badge bg-success">可借</span></td><td><buttonclass="btn btn-sm btn-primary"onclick="editBook('BOOK004')">编辑</button><buttonclass="btn btn-sm btn-warning ms-1"onclick="下架图书('BOOK004')">下架</button></td></tr><tr><td>BOOK005</td><td>C程序设计</td><td>谭浩强</td><td>计算机类</td><td>15</td><tdclass="low-stock">4</td><td><spanclass="badge bg-danger">不可借</span></td><td><buttonclass="btn btn-sm btn-primary"onclick="editBook('BOOK005')">编辑</button><buttonclass="btn btn-sm btn-success ms-1"onclick="上架图书('BOOK005')">上架</button></td></tr></tbody></table></div><!-- 分页 --><navaria-label="Page navigation"class="mt-4"><ulclass="pagination justify-content-center"><liclass="page-item disabled"><aclass="page-link"href="#"tabindex="-1">上一页</a></li><liclass="page-item active"><aclass="page-link"href="#">1</a></li><liclass="page-item"><aclass="page-link"href="#">2</a></li><liclass="page-item"><aclass="page-link"href="#">3</a></li><liclass="page-item"><aclass="page-link"href="#">下一页</a></li></ul></nav></div></div></main></div></div><!-- 添加图书模态框 --><divclass="modal fade"id="addBookModal"tabindex="-1"aria-labelledby="addBookModalLabel"aria-hidden="true"><divclass="modal-dialog modal-lg"><divclass="modal-content"><divclass="modal-header"><h5class="modal-title"id="addBookModalLabel">添加图书</h5><buttontype="button"class="btn-close"data-bs-dismiss="modal"aria-label="Close"></button></div><divclass="modal-body"><formid="addBookForm"><divclass="row mb-3"><divclass="col-md-6"><labelfor="bookName"class="form-label">书名 <spanclass="text-danger">*</span></label><inputtype="text"class="form-control"id="bookName"required></div><divclass="col-md-6"><labelfor="author"class="form-label">作者 <spanclass="text-danger">*</span></label><inputtype="text"class="form-control"id="author"required></div></div><divclass="row mb-3"><divclass="col-md-6"><labelfor="category"class="form-label">分类 <spanclass="text-danger">*</span></label><selectclass="form-select"id="category"required><optionvalue="">请选择分类</option><optionvalue="计算机类">计算机类</option><optionvalue="文学类">文学类</option><optionvalue="经管类">经管类</option><optionvalue="理工类">理工类</option><optionvalue="医学类">医学类</option><optionvalue="历史类">历史类</option><optionvalue="艺术类">艺术类</option></select></div><divclass="col-md-6"><labelfor="publisher"class="form-label">出版社</label><inputtype="text"class="form-control"id="publisher"></div></div><divclass="row mb-3"><divclass="col-md-6"><labelfor="totalCopies"class="form-label">馆藏总数 <spanclass="text-danger">*</span></label><inputtype="number"class="form-control"id="totalCopies"min="1"required><divclass="form-text">请输入正整数</div></div><divclass="col-md-6"><labelfor="publicationDate"class="form-label">出版日期</label><inputtype="date"class="form-control"id="publicationDate"></div></div><divclass="mb-3"><labelfor="description"class="form-label">图书简介</label><textareaclass="form-control"id="description"rows="3"></textarea></div></form></div><divclass="modal-footer"><buttontype="button"class="btn btn-secondary"data-bs-dismiss="modal">取消</button><buttontype="button"class="btn btn-primary"onclick="saveBook()">保存</button></div></div></div></div><scriptsrc="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script><script>// 编辑图书functioneditBook(bookId){alert(`编辑图书:${bookId}`);// 这里可以添加实际编辑逻辑,通常会打开编辑模态框并填充数据}// 下架图书function下架图书(bookId){if(confirm(`确定要将图书 ${bookId} 下架吗?下架后读者将无法借阅。`)){alert(`图书 ${bookId} 已成功下架`);// 这里可以添加实际下架逻辑}}// 上架图书function上架图书(bookId){if(confirm(`确定要将图书 ${bookId} 上架吗?上架后读者可以正常借阅。`)){alert(`图书 ${bookId} 已成功上架`);// 这里可以添加实际上架逻辑}}// 保存图书functionsaveBook(){// 简单的表单验证const bookName = document.getElementById('bookName').value;const author = document.getElementById('author').value;const category = document.getElementById('category').value;const totalCopies = document.getElementById('totalCopies').value;if(!bookName ||!author ||!category ||!totalCopies){alert('请填写所有必填字段');return;}if(parseInt(totalCopies)<=0){alert('馆藏总数必须为正整数');return;}// 模拟保存成功alert('图书添加成功!');// 关闭模态框const modal = bootstrap.Modal.getInstance(document.getElementById('addBookModal')); modal.hide();// 重置表单 document.getElementById('addBookForm').reset();}</script></body></html>
在这里插入图片描述

五、优化与调试

生成源码后,我根据课程设计要求做了3处关键优化,并解决了2个常见问题:

1. 核心优化点

  • 密码加密:飞算在代码注释中提醒“密码需加密存储”,我集成了Spring Security的BCrypt加密,在UserServiceImpl的register方法中,将user.setPassword(request.getPassword())改为user.setPassword(bCryptPasswordEncoder.encode(request.getPassword())),登录时用bCryptPasswordEncoder.matches()校验,避免明文存储密码。
  • 超期提醒:在BorrowServiceImpl的getStudentBorrowRecords方法中,添加“剩余天数计算”逻辑,当剩余天数≤3天时,在前端显示红色提醒;超期后,禁止续借并提示“需先归还”,符合图书馆实际规则。
  • 图书分类管理:飞算生成的基础模块中没有“图书分类添加”功能,我在管理员端补充了CategoryController和CategoryService,支持管理员添加/编辑图书分类(如“考研类”“小说类”),让图书分类更灵活。

2. 调试中遇到的问题及解决

  • 问题1:启动项目时提示“数据库连接失败”——原因是application.yml中MySQL的password是默认值,我改成自己本地数据库的密码后,重启项目恢复正常。
  • 问题2:学生借阅图书后,图书的“剩余可借数量”未减少——检查代码发现,BorrowServiceImpl的borrowBook方法中,忘记调用bookMapper.updateById(book)更新图书信息,补充该代码后问题解决。

六、自我感想

作为一名学生,这次用飞算JavaAI开发在线图书借阅平台,让我收获远超“完成课程设计”的目标:

  1. 需求梳理不再“迷茫”:以前做项目总把“想要一个借阅平台”停留在模糊想法阶段,不知道怎么拆分成“学生能查书”“管理员能加书”等具体功能。飞算的“需求拆解”环节帮我把口语化描述转化为6个可执行关键点,还补充了“续借次数限制”“超期校验”等我没考虑到的细节,让我明白“好的需求是能落地的小功能集合”。
  2. 基础代码不再“重复写”:实体类的get/set方法、Mapper的CRUD接口、DTO的参数校验——这些以前要写1天的基础代码,飞算20分钟就生成了,而且代码带完整注释(比如“剩余可借数量=总数量-已借出数量”)。我不需要再纠结“表结构字段怎么设计”,而是能专注于“超期提醒”“续借逻辑”等核心业务,开发效率提升了3倍。
  3. 解决问题更“有思路”:调试时遇到“借阅后库存不更新”,我顺着飞算生成的代码注释“需更新图书的availableCount”,很快定位到“忘记调用update方法”的问题;以前遇到bug会慌,现在知道从“业务逻辑流程”和“代码注释提示”中找解决方向,这种思维对后续学习很有帮助。

七、总结

这次开发让我明白,对学生而言,飞算JavaAI不是“代替编程”,而是“降低开发门槛”——它帮我们解决了“基础代码繁琐”“需求梳理混乱”的痛点,让我们能在有限的课程设计时间内,开发出功能完整、逻辑规范的系统。

当然,这个平台还有很多可优化的地方:比如添加“图书预约”功能(热门图书无库存时学生可预约)、对接图书馆的罚款系统(超期后自动计算罚款金额)。后续我会继续用飞算JavaAI迭代,比如在“需求编辑器”中输入“添加图书预约功能,支持学生预约无库存图书,有库存时自动提醒”,进一步完善平台功能。

最后,我想给其他做课程设计的同学一个建议:如果遇到“不知道怎么开始”“代码写不下去”的问题,不妨试试飞算JavaAI——它不仅能帮你生成代码,更能引导你养成“先梳理需求、再设计、最后编码”的规范开发习惯,这对我们未来的学习和工作都至关重要。

Read more

如何高效微调视觉语言模型?Qwen3-VL-WEBUI镜像一键部署指南

如何高效微调视觉语言模型?Qwen3-VL-WEBUI镜像一键部署指南 一、前言:从零开始的视觉语言模型微调实践 随着多模态大模型在图像理解、视频分析和跨模态推理等领域的广泛应用,高效微调(Efficient Fine-Tuning) 已成为开发者落地应用的核心能力。阿里云推出的 Qwen3-VL 系列模型,作为 Qwen 视觉语言模型的最新迭代,在文本生成、视觉感知、空间推理与长上下文处理方面实现了全面升级。 本文将围绕官方提供的 Qwen3-VL-WEBUI 镜像,手把手带你完成从环境部署到 LoRA 微调再到 WebUI 推理的全流程操作。该镜像内置了 Qwen3-VL-4B-Instruct 模型,并集成了 LLaMA-Factory 等主流训练框架,真正实现“一键启动 + 可视化微调”,极大降低多模态模型的应用门槛。 通过阅读本文,你将掌握: - 如何快速部署 Qwen3-VL-WEBUI 容器镜像 - 使用 LLaMA-Factory 实现参数高效微调(PEFT) -

By Ne0inhk
【踩坑记录】使用 Layui 框架时解决 Unity WebGL 渲染在 Tab 切换时黑屏问题

【踩坑记录】使用 Layui 框架时解决 Unity WebGL 渲染在 Tab 切换时黑屏问题

【踩坑记录】使用 Layui 框架时解决 Unity WebGL 渲染在 Tab 切换时黑屏问题 在开发 Web 应用时,尤其是集成了 Unity WebGL 内容的页面,遇到一个问题:当 Unity WebGL 渲染内容嵌入到一个 Tab 中时,切换 Tab 后画面会变黑,直到用户点击黑屏区域,才会恢复显示。 这个问题通常是因为 Unity 渲染在 Tab 切换时被暂停或未能获得焦点所致。 在本文中,我们将介绍如何在使用 Layui 框架时,通过监听 Tab 切换事件并强制 Unity WebGL 渲染恢复,来解决这一问题。 1. 问题描述 当 Unity WebGL 内容嵌入到页面中的多个

By Ne0inhk
【数据结构副本篇】顺序表 链表OJ

【数据结构副本篇】顺序表 链表OJ

🏝️专栏:【数据结构实战篇】 🌅主页:f狐o狸x 目录         一、移除元素         1.1 题目分析         1.2 解题代码 二、删除有序数组中的重复项         2.1 题目分析         2.2 解题代码 三、合并两个有序数组         3.1 题目分析                 3.2 解题代码 四、移除链表元素         4.1 题目分析         4.2 解题代码 五、反转一个链表         5.1 题目分析         5.2 解题代码         六、链表的中间节点         6.1 题目分析

By Ne0inhk