飞算JavaAI的在线图书借阅平台的设计与实现,一文吃透!

飞算JavaAI的在线图书借阅平台的设计与实现,一文吃透!
在这里插入图片描述
🎁个人主页:User_芊芊君子
🎉欢迎大家点赞👍评论📝收藏⭐文章
🔍系列专栏:AI
在这里插入图片描述


在这里插入图片描述
在这里插入图片描述

一、需求分析与规划

1.1 命题背景与功能需求

在线图书借阅平台旨在解决传统图书馆线下借阅效率低、用户查询不便等问题,目标用户覆盖在校师生及公共图书馆读者。通过需求调研,平台需实现 五大核心功能模块 ,具体如下表所示:

模块名称核心功能点用户角色
用户管理注册(含邮箱验证)、登录(密码加密)、个人信息维护、角色权限分级(普通用户/管理员)所有用户
图书检索支持关键词(书名/作者)、分类(文学/科技/历史)、库存状态(可借/已借出)多条件组合查询所有用户
借阅管理借书申请(校验库存)、续借操作(延长应还日期)、归还确认(更新库存与记录状态)普通用户
逾期管理自动计算逾期天数、生成违约金(如每日0.5元)、黑名单控制(逾期超3次禁用借阅权限)系统自动/管理员
数据统计借阅量月度报表、热门图书TOP10排行、用户活跃度分析管理员

技术选型依据

  • 后端:Spring Boot 2.7(快速构建RESTful API)、MyBatis-Plus(简化数据库CRUD)、JWT(用户认证令牌)、BCrypt(密码加密)
  • 前端:Vue 3 + Element Plus
  • 数据库:MySQL 8.0(支持事务、索引优化及复杂查询)
  • 开发工具:飞算JavaAI

1.2 核心模块拆解与流程可视化

否是否是否是用户访问平台是否注册?调用注册模块: 输入用户名/密码/邮箱生成用户ID, 写入user表, 发送验证邮件调用登录模块: 校验账号密码校验成功返回 用户名或密码错误生成JWT令牌, 加载用户主页输入关键词 分类 库存条件调用图书检索模块 查询book表+库存关联表返回图书列表及可借状态选择目标图书, 提交借阅申请调用借阅管理模块: 检查库存&生成借阅记录库存充足提示暂无库存更新库存数量, 写入borrow_record表, 返回应还日期借阅到期前3天, 系统自动触发续借提醒用户未续借且逾期, 计算违约金并更新用户状态

二、飞算JavaAI开发

操作步骤:打开飞算JavaAI,选择智能引导:

在这里插入图片描述
  • 这里输入我们需要的项目。
在这里插入图片描述
  • 给我们分析了几个关键点。
在这里插入图片描述
  • 下面等待接口设计。
在这里插入图片描述
  • 可以看到生成了很多;这里只需要等待即可。
在这里插入图片描述
  • 该系统具备用户、图书资源、借阅、还书、预约及搜索查询管理功能,可实现用户身份认证与访问安全保障,对图书信息进行全流程管理,规范借阅归还流程,提升图书利用率与用户体验,满足多样化查找需求;下面只需要下一步。
在这里插入图片描述
  • 等待处理接口的生成。
在这里插入图片描述
  • 可以看到已经生成完了。
在这里插入图片描述
  • 这里还是比较长的;因此等待会。
在这里插入图片描述
  • 最后进行部署即可。

部分代码展示

2.2.2 生成的实体类与控制器
// 实体类 User.java(自动生成Lombok注解与字段)@Data@TableName("user")publicclassUser{@TableId(type =IdType.AUTO)privateInteger id;privateString username;privateString password;// 实际存储BCrypt加密值privateString email;privateInteger role;// 0-普通用户, 1-管理员@JsonFormat(pattern ="yyyy-MM-dd HH:mm:ss")privateLocalDateTime createTime;}// 控制器 UserController.java(自动生成注册/登录逻辑)@RestController@RequestMapping("/api/user")publicclassUserController{@AutowiredprivateUserService userService;@PostMapping("/register")publicResultregister(@RequestBodyUserRegisterDTO dto){if(userService.checkUsernameExists(dto.getUsername())){returnResult.error("用户名已存在");}User user =newUser(); user.setUsername(dto.getUsername()); user.setPassword(BCrypt.hashpw(dto.getPassword(),BCrypt.gensalt()));// 密码加密 user.setEmail(dto.getEmail()); user.setRole(0);// 默认普通用户 user.setCreateTime(LocalDateTime.now()); userService.save(user);returnResult.success("注册成功");}@PostMapping("/login")publicResultlogin(@RequestBodyUserLoginDTO dto){User user = userService.getByUsername(dto.getUsername());if(user ==null||!BCrypt.checkpw(dto.getPassword(), user.getPassword())){returnResult.error("用户名或密码错误");}String token =JwtUtil.generateToken(user.getId(), user.getRole());// JWT生成returnResult.success(token);}}
2.2.3 借阅管理部分:
packagecom.feisuanyz.dto;importjakarta.validation.constraints.NotNull;importlombok.*;/** * <p> * 借阅审批数据传输对象 * </p> * @author z2222 */@Data@NoArgsConstructor@AllArgsConstructorpublicclassBorrowApproveDTO{@NotNull(message ="申请ID不能为空")privateLong applyId;@NotNull(message ="审批状态不能为空")privateInteger approveStatus;// 0-拒绝, 1-通过}
packagecom.feisuanyz.service.impl;importcom.feisuanyz.dto.BookDTO;importcom.feisuanyz.dto.BookQuery;importcom.feisuanyz.dto.RestResult;importcom.feisuanyz.entity.BookDO;importcom.feisuanyz.repository.BookRepository;importcom.feisuanyz.service.BookService;importjava.util.List;importjava.util.stream.Collectors;importlombok.extern.slf4j.Slf4j;importorg.springframework.beans.BeanUtils;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.stereotype.Service;importorg.springframework.transaction.annotation.Transactional;/** * <p> * 图书服务实现类,实现业务逻辑 * </p> * @author z2222 */@Slf4j@ServicepublicclassBookServiceImplimplementsBookService{@AutowiredprivateBookRepository bookRepository;@Override@TransactionalpublicRestResultaddBook(BookDTO bookDTO){if(bookDTO.getIsbn()==null|| bookDTO.getTitle()==null|| bookDTO.getAuthor()==null){returnRestResult.failure("000001","参数不完整");}if(bookRepository.existsByIsbn(bookDTO.getIsbn())){returnRestResult.failure("000001","该图书已存在");}BookDO bookDO =newBookDO();BeanUtils.copyProperties(bookDTO, bookDO); bookRepository.save(bookDO);returnRestResult.success("000000","调用成功", bookDTO);}@Override@TransactionalpublicRestResultupdateBook(BookDTO bookDTO){BookDO bookDO = bookRepository.findById(bookDTO.getId()).orElse(null);if(bookDO ==null){returnRestResult.failure("000001","图书不存在");}BeanUtils.copyProperties(bookDTO, bookDO,"id","isbn"); bookRepository.save(bookDO);returnRestResult.success("000000","调用成功", bookDTO);}@Override@TransactionalpublicRestResultdeleteBook(Long id){BookDO bookDO = bookRepository.findById(id).orElse(null);if(bookDO ==null){returnRestResult.failure("000001","图书不存在");} bookRepository.delete(bookDO);returnRestResult.success("000000","调用成功",null);}@OverridepublicRestResultgetBooksByCategory(BookQuery bookQuery){List<BookDO> books;if(bookQuery.getCategory()!=null&&!bookQuery.getCategory().isEmpty()){ books = bookRepository.findByCategory(bookQuery.getCategory());}else{ books = bookRepository.findAll();}List<BookDTO> bookDTOS = books.stream().map(bookDO ->{BookDTO bookDTO =newBookDTO();BeanUtils.copyProperties(bookDO, bookDTO);return bookDTO;}).collect(Collectors.toList());returnRestResult.success("000000","调用成功", bookDTOS);}}
packagecom.feisuanyz.dto;importjakarta.validation.constraints.NotNull;importlombok.*;/** * <p> * 借阅审批数据传输对象 * </p> * @author z2222 */@Data@NoArgsConstructor@AllArgsConstructorpublicclassBorrowApproveDTO{@NotNull(message ="申请ID不能为空")privateLong applyId;@NotNull(message ="审批状态不能为空")privateInteger approveStatus;// 0-拒绝, 1-通过}
2.2.4 图书资源管理:
packagecom.feisuanyz.controller;importcom.feisuanyz.dto.BookDTO;importcom.feisuanyz.dto.BookQuery;importcom.feisuanyz.dto.RestResult;importcom.feisuanyz.service.BookService;importlombok.extern.slf4j.Slf4j;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.validation.annotation.Validated;importorg.springframework.web.bind.annotation.*;/** * <p> * 图书控制器,处理HTTP请求与响应 * </p> * @author z2222 */@Slf4j@RestController@RequestMapping("/books")publicclassBookController{@AutowiredprivateBookService bookService;/** * 新增图书 * @param bookDTO 图书信息 * @return 返回处理结果 */@PostMapping("/add")publicRestResultaddBook(@Validated@RequestBodyBookDTO bookDTO){return bookService.addBook(bookDTO);}/** * 编辑图书 * @param bookDTO 图书信息 * @return 返回处理结果 */@PutMapping("/update")publicRestResultupdateBook(@Validated@RequestBodyBookDTO bookDTO){return bookService.updateBook(bookDTO);}/** * 删除图书 * @param id 图书ID * @return 返回处理结果 */@DeleteMapping("/delete/{id}")publicRestResultdeleteBook(@PathVariableLong id){return bookService.deleteBook(id);}/** * 按分类展示图书 * @param category 图书分类 * @return 返回处理结果 */@GetMapping("/list")publicRestResultgetBooksByCategory(@RequestParam(required =false)String category){BookQuery bookQuery =newBookQuery(); bookQuery.setCategory(category);return bookService.getBooksByCategory(bookQuery);}}
packagecom.feisuanyz.repository;importcom.feisuanyz.entity.UserDO;importjava.util.Optional;importorg.springframework.data.jpa.repository.JpaRepository;importorg.springframework.stereotype.Repository;/** * <p> * 用户数据访问层接口 * </p> * @author z2222 */@RepositorypublicinterfaceUserRepositoryextendsJpaRepository<UserDO,Long>{/** * 根据用户名查找用户 * * @param username 用户名 * @return Optional包装的UserDO对象 */Optional<UserDO>findByUsername(String username);/** * 判断是否存在指定用户名的用户 * * @param username 用户名 * @return 是否存在该用户名 */booleanexistsByUsername(String username);}
<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.feisuanyz</groupId><artifactId>JavaProject</artifactId><version>0.0.1-SNAPSHOT</version><name>JavaProject</name><description>Demo project forSpringBoot</description><properties><java.version>17</java.version><spring.boot.version>3.1.0</spring.boot.version></properties><dependencyManagement><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>${spring.boot.version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement><dependencies><!--WebStarter--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--Data JPA Starter--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency><!--MySQLDriver--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.33</version></dependency><!--Lombok--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><!--Validation--><dependency><groupId>jakarta.validation</groupId><artifactId>jakarta.validation-api</artifactId><version>3.0.2</version></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>
2.2.5生成的控制器与查询逻辑
// BookController.java@GetMapping("/search")publicResultsearchBooks(@RequestParam(required =false)String keyword,@RequestParam(required =false)String category,@RequestParam(required =false)Boolean available // true-可借, false-已借出){LambdaQueryWrapper<Book> wrapper =newLambdaQueryWrapper<>();if(StringUtils.hasText(keyword)){ wrapper.like(Book::getTitle, keyword).or().like(Book::getAuthor, keyword);}if(StringUtils.hasText(category)){ wrapper.eq(Book::getCategory, category);}if(available !=null){ wrapper.eq(Book::getAvailableCount, available ?1:0);}// 仅返回必要字段,优化性能 wrapper.select(Book::getId,Book::getTitle,Book::getAuthor,Book::getCategory,Book::getAvailableCount);List<Book> books = bookService.list(wrapper);returnResult.success(books);}// Book实体类关键字段@Data@TableName("book")publicclassBook{privateInteger id;privateString title;privateString author;privateString isbn;privateString category;privateInteger total_count;privateInteger available_count;}
2.2.6 生成的事务性代码
// BorrowController.java@PostMapping("/borrow")@Transactional// 飞算AI自动添加事务注解publicResultborrowBook(@RequestParamInteger userId,@RequestParamInteger bookId){Book book = bookService.getById(bookId);if(book ==null|| book.getAvailableCount()<=0){returnResult.error("该图书暂无库存");}// 减少可借库存(原子操作) book.setAvailableCount(book.getAvailableCount()-1); bookService.updateById(book);// 生成借阅记录BorrowRecordrecord=newBorrowRecord();record.setUserId(userId);record.setBookId(bookId);record.setBorrowDate(LocalDateTime.now());record.setDueDate(LocalDateTime.now().plusDays(30));record.setStatus(0);// 0-未归还 borrowRecordService.save(record);returnResult.success("借书成功,应还日期:"+record.getDueDate());}

2.3 逾期管理与数据统计

2.3.1 逾期计算逻辑

需求输入:“每天凌晨检查借阅记录中due_date < 当前日期且status=0的记录,计算逾期天数(当前日期-due_date),若逾期天数>0则更新用户违约金(累计),若逾期天数>30则将用户role标记为1(黑名单)。”

在这里插入图片描述

AI生成代码(定时任务):

// OverdueTask.java(飞算AI生成)@ComponentpublicclassOverdueTask{@AutowiredprivateBorrowRecordService borrowRecordService;@AutowiredprivateUserService userService;@Scheduled(cron ="0 0 0 * * ?")// 每天凌晨执行publicvoidcheckOverdue(){LocalDateTime now =LocalDateTime.now();List<BorrowRecord> overdueRecords = borrowRecordService.list(newLambdaQueryWrapper<BorrowRecord>().lt(BorrowRecord::getDueDate, now).eq(BorrowRecord::getStatus,0)); overdueRecords.forEach(record->{long daysOverdue =ChronoUnit.DAYS.between(record.getDueDate(), now);// 更新用户违约金(简化逻辑:累计1元/天)User user = userService.getById(record.getUserId()); user.setFineAmount(user.getFineAmount()+(int) daysOverdue);if(daysOverdue >30){ user.setRole(1);// 标记为黑名单} userService.updateById(user);record.setStatus(1);// 标记为已逾期 borrowRecordService.updateById(record);});}}

2.4 工程结构全景

最终生成的工程目录结构如下:

online_library/ ├── src/main/java/com/library/online/ │ ├── controller/ # 接口层(UserController, BookController...) │ ├── entity/ # 实体类(User, Book, BorrowRecord...) │ ├── mapper/ # 数据访问层(UserMapper, BookMapper...) │ ├── service/ # 业务逻辑层(UserService, BookService...) │ ├── dto/ # 数据传输对象(UserRegisterDTO, UserLoginDTO...) │ ├── util/ # 工具类(JwtUtil, Result...) │ └── OnlineLibraryApplication.java # 启动类 ├── src/main/resources/ │ ├── application.yml # 数据库配置(spring.datasource.url等) │ └── mapper/ # MyBatis XML文件(如BorrowRecordMapper.xml) 

三、优化与调试心得

3.1 典型问题1:SQL性能瓶颈(库存查询慢)

问题现象:当图书总量超过1万条时,SELECT * FROM book WHERE available_count > 0 查询耗时超过2秒。

解决方案

  • 添加索引:执行SQL ALTER TABLE book ADD INDEX idx_available (available_count);
  • 优化查询:修改生成的BookController.java,限定返回字段(仅id, title, available_count)。

优化后效果:查询时间从2.1s降至120ms。

3.2 典型问题2:JWT令牌过期处理缺失

问题现象:用户登录后,若30分钟内无操作,再次请求接口返回401未授权。

解决步骤

  1. 通过飞算JavaAI的「智能会话」功能,定位到JwtUtil.java中的过期时间配置(原为30分钟)。
  2. 调整配置:修改JwtUtil.generateToken()方法中的expiration参数为2小时(new Date(System.currentTimeMillis() + 2 * 60 * 60 * 1000))。
  3. 前端配合:在Vue中存储JWT时,通过拦截器自动刷新令牌(本文聚焦后端,前端逻辑略)。

3.3 其他优化:代码规范性调整

飞算AI生成的初始代码虽功能完整,但部分命名可读性不足(如Result类未明确区分成功/失败字段)。通过手动调整:

  • 统一响应格式:修改Result.java{code: 200, msg: "success", data: {...}} 结构。
  • 日志增强:在关键业务方法(如借阅、归还)中添加@Slf4j注解,记录操作流水(例如:“用户ID 1001 借阅图书ID 2001,应还日期 202X-XX-XX”)。

四、成果展示与总结

4.1 最终工程结构图

首页展示:

在这里插入图片描述

可以对图书进行管理操作:

在这里插入图片描述

对于类型的管理操作:

在这里插入图片描述

在图书信息管页面中可以查看图书名称、图书分类、图片、作者、出版社、数量、可借天数、可借数量、图书简介等信息进行入库、出库、操作盘点,并可根据需要对已有图书信息进行修改或删除等详细操作:

在这里插入图片描述
在这里插入图片描述

查看对应借阅状态:

在这里插入图片描述
还有很多功能这里就不一一展示了。

4.2 飞算JavaAI的优势与不足

优势总结:
  1. 需求驱动开发:通过自然语言描述功能需求,自动生成符合Spring Boot规范的代码(包括实体类、控制器、DTO),减少60%以上的重复编码工作量。
  2. 智能引导精准:对复杂业务逻辑(如借阅事务、定时任务)的描述支持度高,生成的代码可直接运行并通过基础测试。
  3. 调试辅助强大:内置性能分析、接口测试、智能会话功能,快速定位SQL慢查询、令牌过期等问题。
  4. 工程结构标准:自动生成的分层结构符合企业级开发规范(controller-service-mapper),降低后期维护成本。
不足与改进建议:
  1. 复杂逻辑扩展性:对于高度定制化的业务规则(如多级权限校验),生成的代码可能需要手动补充逻辑(例如:管理员与普通用户的借阅限额差异)。
  2. 前端集成局限:当前版本更聚焦后端开发,若需前后端联调,需额外手动编写前端调用代码。

4.3 个人使用体会

本次通过飞算JavaAI开发在线图书借阅平台,深刻体会到智能化工具对开发效率的提升:

  • 新手友好:即使对Spring Boot或MyBatis-Plus不熟悉,也能通过需求描述快速生成可用代码,降低了学习曲线。
  • 效率革命:原本需要3-5天完成的基础功能开发(用户+图书+借阅),通过飞算AI实现核心链路打通,剩余时间用于业务逻辑优化。

未来若结合飞算JavaAI那些高级功能,可进一步缩短全流程开发周期,值得在更多项目中推广使用。

飞算你值得拥有。 点击网页

Read more

AI大模型学习之基础数学:正态分布-AI大模型中的概率统计基石

🧑 博主简介:ZEEKLOG博客专家、ZEEKLOG平台优质创作者,高级开发工程师,数学专业,10年以上C/C++, C#, Java等多种编程语言开发经验,拥有高级工程师证书;擅长C/C++、C#等开发语言,熟悉Java常用开发技术,能熟练应用常用数据库SQL server,Oracle,mysql,postgresql等进行开发应用,熟悉DICOM医学影像及DICOM协议,业余时间自学JavaScript,Vue,qt,python等,具备多种混合语言开发能力。撰写博客分享知识,致力于帮助编程爱好者共同进步。欢迎关注、交流及合作,提供技术支持与解决方案。\n技术合作请加本人wx(注明来自ZEEKLOG):xt20160813 正态分布:AI大模型中的概率统计基石 人工智能(AI)大模型的理论基础离不开线性代数、概率统计和微积分,其中概率统计为数据建模、不确定性分析和模型优化提供了核心工具。在概率统计中,正态分布(Normal Distribution)因其广泛的存在性和数学性质,成为最重要的分布之一。本文将深入讲解正态分布的概念、原理、

By Ne0inhk

AI股票分析师daily_stock_analysis的Python入门教程

AI股票分析师daily_stock_analysis的Python入门教程 1. 前言:让AI帮你分析股票 你是不是经常盯着股票行情看花了眼?各种技术指标、新闻资讯、市场情绪,想要全面分析一只股票真的不容易。现在有个好消息:用Python和AI工具,你可以轻松搭建自己的智能股票分析系统。 今天我要介绍的daily_stock_analysis就是一个很棒的工具,它能够自动获取股票数据、分析技术指标、解读市场新闻,然后给你一份清晰的决策建议。最重要的是,这个工具完全免费,用Python就能快速上手。 无论你是编程新手还是有一定经验的开发者,跟着这篇教程,你都能在30分钟内搭建起自己的AI股票分析系统。我们会从最基础的环境配置开始,一步步实现完整的分析流程。 2. 环境准备与安装 2.1 系统要求 首先确认你的电脑环境: * Python 3.8 或更高版本 * 至少4GB内存(分析多只股票时建议8GB) * 稳定的网络连接(需要获取实时数据) 2.2 快速安装步骤 打开你的命令行工具(Windows用CMD或PowerShell,Mac/Linux用Ter

By Ne0inhk
OpenClaw 多机器人多 Agent 模式:打造你的 AI 助手团队

OpenClaw 多机器人多 Agent 模式:打造你的 AI 助手团队

OpenClaw 多机器人多 Agent 模式:打造你的 AI 助手团队 完整教程:https://awesome.tryopenclaw.asia/docs/04-practical-cases/15-solo-entrepreneur-cases.html 16.1 为什么需要多 Agent? 作为超级个体创业者,你可能需要不同类型的 AI 助手来处理不同的工作: * 主助理:使用最强大的模型(Claude Opus)处理复杂任务 * 内容创作助手:专注于文章写作、文案创作 * 技术开发助手:处理代码开发、技术问题 * AI 资讯助手:快速获取和整理 AI 行业动态 传统的单 Agent 模式需要频繁切换模型和上下文,效率低下。多 Agent 模式让你可以同时拥有多个专业助手,各司其职。

By Ne0inhk
【AI 大模型】LangChain 框架 ① ( LangChain 简介 | LangChain 模块 | LangChain 文档 )

【AI 大模型】LangChain 框架 ① ( LangChain 简介 | LangChain 模块 | LangChain 文档 )

文章目录 * 一、LangChain 简介 * 1、LangChain 概念 * 2、LangChain 定位 * 3、LangChain 开发语言与应用场景 * 4、LangChain 核心组件 * 5、LangChain 学习路径 * 二、LangChain 模块 * 1、模型输入 / 输出 ( Models ) * 2、提示词模板 ( Prompts ) * 3、索引 ( Indexes ) * 4、链 ( Chains ) * 5、记忆 ( Memory ) * 6、代理 ( Agents ) * 7、 工具 ( Tools ) * 8、 文档加载器 ( Document Loaders ) * 9、评估

By Ne0inhk