尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

SpringBoot+Vue+AI图书管理系统:从数据库到部署全流程实战

SpringBoot+Vue+AI图书管理系统:从数据库到部署全流程实战 SpringBootVue的图书管理系统说实话在毕设和课设里已经属于“烂大街”的选题了。但这次不一样的点在于项目名字里带了“AI”——把大模型能力接进图书管理系统之后整个项目的技术含量、可讲解的内容、以及答辩/汇报时的亮点一下子就拉开了。这篇就把我从零完整做这套系统的过程拆开讲从数据库设计、后端接口、前端页面到AI功能落地、文档编写和指导视频录制全部覆盖。目标读者是做毕设、课设、或者想拿一套完整项目练手的同学只要照着做能实打实复现出来。1. 项目立项这件“烂大街”的事怎么做出新意1.1 图书管理系统的功能全景图先把需求盘清楚。图书管理系统最核心的业务闭环是图书入库、读者注册、借书、还书、逾期处理、统计报表。这套闭环跑通之后再考虑扩展功能。我做的版本功能模块如下图书管理图书信息的新增、修改、删除、批量导入、封面上传、库存管理读者管理读者账号的注册、审核、信息维护、借阅证状态管理分类管理图书分类的树形结构支持多级分类借阅管理借书登记、还书登记、续借、逾期自动计算预约管理图书被借出时可以预约还书后按预约顺序通知公告管理发布系统公告、新书推荐统计报表借阅量排行、图书分类占比、读者活跃度系统管理用户管理、角色管理、操作日志AI助手基于大模型的智能荐书、阅读答疑、逾期催还文案生成提示功能不要一开始就全做。先把借阅闭环跑通再往上面叠加预约、统计、AI这些亮点功能。这样开发周期可控论文/文档也好写。这套功能对应到数据库里核心表大概是这几类图书表、读者表、借阅记录表、分类表、预约表、公告表、用户表、角色权限表。具体怎么拆我放在第2章详细讲。1.2 为什么选SpringBootVue这套组合技术选型不是拍脑袋要考虑三点学习成本、社区生态、以及答辩/面试时的解释成本。后端用SpringBoot理由很直接。SpringBoot把Spring繁琐的XML配置简化成了“约定优于配置”内置Tomcat一个jar包就能跑开发效率高。图书管理系统这种典型CRUD项目SpringBoot配合MyBatis-PlusService层几乎不用手写通用SQL代码量能减少三分之一以上。而且SpringBoot的项目结构非常规矩Controller-Service-Mapper三层分下来答辩时讲架构也清晰。前端用Vue3 Vite Element Plus是目前前后端分离项目里最主流的组合之一。Vue的响应式数据绑定、组件化开发配合Element Plus的现成组件表格、表单、弹窗、分页这些后台管理页面的常规操作基本都是“拼积木”式开发。Vite做开发服务器比Webpack快很多热更新体验很好。说实话JavaEE JSP那套老技术也能做图书管理系统但做出来之后你很难解释“为什么用这个”而SpringBootVue这套组合市场认可度高教程多踩坑了也容易搜到答案。1.3 AI不是噱头功能点怎么落才有价值“带AI”这个标签很多项目是硬凑的——放一个聊天框就算AI了这种方案答辩时很容易被问住。我建议AI功能往这三个方向落第一AI荐书。用户输入“我想看悬疑推理类的小说文风轻松一点”系统通过分词和关键词匹配从书库中推荐符合条件的图书。这个功能逻辑清晰能讲清楚推荐原理属于“AI业务”的典型结合。第二智能借阅助手。基于大模型的对话接口让它只回答和本系统相关的问题比如“怎么续借”“逾期了怎么罚款”“图书馆几点关门”超出知识范围的主动拒绝回答。这个功能的关键是提示词工程和知识库约束。第三运营辅助。给管理员用的比如自动生成逾期催还文案、新书上架推荐文案、月度借阅分析总结。这些功能实现成本低但使用场景很真实做进系统里不违和。注意AI功能要“懂业务”才有价值。只做一个通用聊天框用户随便问什么都能答那叫Demo不叫项目功能。要让AI的回答内容和图书、借阅、馆藏强相关。2. 数据库设计与SpringBoot后端核心实现2.1 拆表从一页纸需求到8张核心表数据库设计是整个项目的地基表拆不好后面写接口、做统计都会很痛苦。按照业务闭环我一共设计了8张核心表。-- 图书表 CREATE TABLE book_info ( id BIGINT PRIMARY KEY AUTO_INCREMENT, isbn VARCHAR(20) UNIQUE, title VARCHAR(200) NOT NULL, author VARCHAR(100), category_id BIGINT, publisher VARCHAR(100), publish_date DATE, price DECIMAL(10,2), total_count INT DEFAULT 0, remain_count INT DEFAULT 0, cover_url VARCHAR(500), description TEXT, ai_tags VARCHAR(500), status TINYINT DEFAULT 1, create_time DATETIME ); -- 读者表 CREATE TABLE reader ( id BIGINT PRIMARY KEY AUTO_INCREMENT, reader_no VARCHAR(20) UNIQUE, name VARCHAR(50), phone VARCHAR(20), email VARCHAR(100), password VARCHAR(100), status TINYINT DEFAULT 1, create_time DATETIME ); -- 借阅记录表 CREATE TABLE borrow_record ( id BIGINT PRIMARY KEY AUTO_INCREMENT, reader_id BIGINT, book_id BIGINT, borrow_time DATETIME, due_time DATETIME, return_time DATETIME DEFAULT NULL, status TINYINT DEFAULT 0, renew_count INT DEFAULT 0 ); -- 分类表 CREATE TABLE category ( id BIGINT PRIMARY KEY AUTO_INCREMENT, parent_id BIGINT DEFAULT 0, name VARCHAR(50) ); -- 预约表 CREATE TABLE reservation ( id BIGINT PRIMARY KEY AUTO_INCREMENT, reader_id BIGINT, book_id BIGINT, reserve_time DATETIME, status TINYINT DEFAULT 0 ); -- 公告表 CREATE TABLE announcement ( id BIGINT PRIMARY KEY AUTO_INCREMENT, title VARCHAR(200), content TEXT, create_time DATETIME ); -- 用户表 CREATE TABLE sys_user ( id BIGINT PRIMARY KEY AUTO_INCREMENT, username VARCHAR(50) UNIQUE, password VARCHAR(100), role TINYINT DEFAULT 1, status TINYINT DEFAULT 1 ); -- 操作日志表 CREATE TABLE operation_log ( id BIGINT PRIMARY KEY AUTO_INCREMENT, user_id BIGINT, action VARCHAR(200), detail TEXT, ip VARCHAR(50), create_time DATETIME );几个设计要点解释一下。book_info表里的ai_tags字段是给AI荐书功能预留的存的是这本书的标签比如“悬疑|推理|东野圭吾|日系”这样AI在推荐时不需要实时调用大模型分析每一本书直接查字段匹配就行性能好很多。total_count是总库存remain_count是可借数量这两个字段分开存借书时减remain_count还书时加回去统计报表直接查就行不用每次count记录表。borrow_record的status字段我用0表示借出1表示已还2表示逾期未还。这里有个经验状态不要用字符用数字后续做统计SQL时WHERE status 2这种写起来很干净。实操心得设计借阅表时一定要把due_time应还时间单独存不要用borrow_time 30天来计算因为续借会改变应还时间而且逾期判断要反复用到这个字段单独存最省事。还有一个扩展点如果你的数据库用了MyBatis-Plus可以开启auto-init-tables之类的自动建表机制服务启动时自动执行DDL。不过我更推荐把SQL脚本单独维护交给Flyway或者手动执行方便在文档里展示。毕竟毕设文档要求有“数据库设计”这一章SQL脚本是要贴进去的。2.2 后端分层架构与接口设计SpringBoot后端我按标准的Controller-Service-Mapper三层来分另外加了common包放统一返回结果、异常处理、工具类config包放配置类dto包放接收参数的VO。项目的包结构大致如下com.example.library ├── controller │ ├── BookController.java │ ├── BorrowController.java │ ├── ReaderController.java │ ├── AuthController.java │ └── AiController.java ├── service │ ├── BookService.java │ ├── BorrowService.java │ └── AiService.java ├── mapper │ ├── BookMapper.java │ ├── BorrowRecordMapper.java │ └── ReaderMapper.java ├── entity │ ├── BookInfo.java │ ├── BorrowRecord.java │ └── SysUser.java ├── dto │ ├── LoginDTO.java │ ├── BorrowDTO.java │ └── AiChatDTO.java ├── common │ ├── Result.java │ ├── BusinessException.java │ └── GlobalExceptionHandler.java └── config ├── JwtInterceptor.java ├── WebConfig.java └── MybatisPlusConfig.java统一返回结构Result非常重要。前后端分离时接口要统一返回格式前端才好做拦截和处理。public class ResultT { private Integer code; private String msg; private T data; public static T ResultT success(T data) { ResultT result new Result(); result.setCode(200); result.setMsg(success); result.setData(data); return result; } public static T ResultT error(String msg) { ResultT result new Result(); result.setCode(500); result.setMsg(msg); return result; } }借书这个核心接口逻辑上要处理多步操作校验读者状态是否正常校验图书库存是否大于0检查读者是否已有未归还的同名图书插入借阅记录更新图书剩余库存记录操作日志这6步如果用简单的Service方法硬写也能跑但有个问题中间任何一步失败数据就会不一致。所以我用Transactional事务注解包住整个方法保证要么全部成功要么全部回滚。这块在答辩时也值得重点讲事务是面试高频问题。2.3 JWT登录与权限拦截的实现思路图书管理系统是双角色系统管理员和读者。管理员能管理图书、查看所有借阅记录读者只能借书、还书、查看自己的记录。所以权限控制不能省。我用的是JWT方案。流程不复杂用户登录成功后后端生成一个JWT token返回给前端。token里带上用户ID和角色信息。前端拿到token后存到localStorage之后每次请求都在Authorization请求头里带上。后端定义一个拦截器拦截需要登录的接口从请求头里解析token校验合法性再把用户信息放到请求上下文里。核心拦截器大概是这个样子public class JwtInterceptor implements HandlerInterceptor { Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String token request.getHeader(Authorization); if (token null || !token.startsWith(Bearer )) { throw new BusinessException(401, 未登录或登录已过期); } // 解析token校验签名和过期时间 Claims claims JwtUtil.parseToken(token.replace(Bearer , )); request.setAttribute(userId, claims.get(userId)); request.setAttribute(role, claims.get(role)); return true; } }拦截器里我额外加了角色判断的逻辑在需要管理员权限的接口上用自定义注解RequireRole(admin)标记拦截器里解析注解校验当前用户的角色不匹配直接返回403。这样做的好处是权限逻辑集中在拦截器里业务代码不用重复写角色判断。注意JWT的密钥一定要放到配置文件里用环境变量或者jasypt加密存储不要硬编码在代码里。硬编码密钥等于把系统的后门暴露给所有能看代码的人。2.4 锦上添花的扩展能力除了核心的CRUD和借阅我还做了一些扩展这里挑几个值得讲的。图书批量导入。管理员经常要一次性录入几十上百本书手工填写表单不现实。我用的是EasyExcel或者POI上传一个Excel文件后端解析后批量插入数据库。注意点Excel列要跟数据库字段对应导入前先校验isbn是否重复重复的跳过并在返回结果里提示。大文件上传下载。如果系统里有电子书资源需要考虑大文件上传问题。SpringBoot默认的spring.servlet.multipart.max-file-size是1MB必须调大。我一般配合前端做分片上传文件切成5MB一片后端合并。做这个功能的好处是能顺便讲一下断点续传和分片合并的原理答辩时很加分。关于Flowable的扩展。如果你想把预约借书的流程做得更规范可以集成Flowable工作流引擎把“预约申请→管理员审批→通知读者”这个流程建模出来。但我要说实话图书管理系统这种体量硬上工作流引擎反而是过度设计除非你论文里需要讲工作流相关的内容否则不推荐为了炫技加这个。3. Vue3前端从环境搭建到核心页面落地3.1 环境准备一次把Node、npm、Vite配置到位前端环境配置看起来简单实际卡住不少新手。我用的是Vue3 Vite Element Plus Pinia这套组合比较新配起来也简单。Node.js版本建议用18以上。版本太低Vite跑不起来版本太高某些老依赖又会报错。装完之后先用node -v和npm -v确认版本。创建项目npm create vitelatest library-front -- --template vue cd library-front npm installnpm install这一步很多同学会遇到两个坑。一个是安装速度极慢那是因为默认走的npm官方源建议先用npm config set registry https://registry.npmmirror.com换成国内镜像源。另一个是依赖版本冲突尤其element-plus和vue版本不匹配解决办法是安装时指定大版本号npm install element-plus2.x。然后安装路由、状态管理和UI库npm install vue-router4 pinia element-plus axios npm install element-plus/icons-vue这样一个干净的前端项目就起来了。启动命令是npm run dev默认端口5173。3.2 路由、布局与登录状态控制图书管理系统的前端页面整体是一个后台管理布局左侧菜单栏右侧内容区。Vue Router负责页面跳转Pinia负责存登录状态和用户信息。路由设计上我用了嵌套路由父路由是Layout组件子路由是各个具体页面const routes [ { path: /, component: Layout, redirect: /dashboard, children: [ { path: dashboard, component: Dashboard }, { path: book/list, component: BookList }, { path: borrow/list, component: BorrowList }, { path: reader/list, component: ReaderList }, { path: ai/assistant, component: AiAssistant } ] }, { path: /login, component: Login } ]前端路由守卫也很重要。未登录用户访问/book/list直接踢回登录页router.beforeEach((to, from, next) { const token localStorage.getItem(token) if (to.path ! /login !token) { next(/login) } else { next() } })这里有个小经验前端路由守卫只是体验优化真正的权限校验必须依赖后端的接口拦截。前端的判断可以被绕过后端才是安全底线。3.3 图书列表、借阅弹窗与AI对话页实现要点图书列表页是系统使用频率最高的页面。我用了Element Plus的el-table组件来展示配合el-pagination做分页。列表页的关键点在于搜索条件支持按书名、作者、ISBN模糊搜索按分类下拉筛选。这些都是通过一个searchForm对象绑定表单提交时把参数传给后端接口。借阅操作我设计成弹窗形式点击“借阅”按钮弹出确认框显示书名、读者、应还日期确认后调后端接口。这样做的好处是操作路径短用户体验好。还有一个细节借阅成功后要把列表里那本书的remain_count减掉我是在接口返回后重新调用一次列表查询保证页面数据是最新的。AI对话页是项目的亮点页面。页面结构简单左侧是可选的对话历史右侧是消息列表和输入框。消息列表用了一个v-for循环渲染用户消息靠右AI回复靠左。输入框支持回车发送发送过程中按钮置灰等待后端返回。这里前端要注意流式输出的处理很多大模型接口是SSE流式返回文字的我用fetch的getReader方法逐步读取数据边读边更新页面效果比一次性等完整回复好得多。如果你在系统里做了“视频教程”模块需要用Vue播放m3u8格式的视频推荐用hls.js或vue-video-player。m3u8是HLS直播/点播协议的文件格式浏览器原生不支持直接播放需要hls.js转封装处理代码不算复杂但确实是Vue项目里的一个常见坑。3.4 跨域联调与调试工具前后端分离开发时前端跑在5173端口后端跑在8080端口直接请求必然跨域。处理跨域有两个方案我推荐用Vite的代理而不是在后端加CrossOrigin。在vite.config.js里配置export default defineConfig({ server: { proxy: { /api: { target: http://localhost:8080, changeOrigin: true } } } })这样前端请求/api/book/list会被Vite开发服务器转发到http://localhost:8080/api/book/list浏览器看到的始终是同源请求不会触发跨域。为什么不用后端CrossOrigin因为生产环境前后端部署在不同服务器时还是要靠Nginx转发来解决开发阶段用代理更接近生产形态。前端调试强烈建议装Vue Devtools浏览器插件。它能直接查看组件的props、data、computed还能看Vuex/Pinia的状态变更排查数据流问题效率翻倍。4. AI图书助手从方案选型到功能落地4.1 直接用大模型API还是Spring AI到了AI功能落地阶段第一个问题就是技术选型后端起一个SpringBoot服务怎么和大模型对接现在有两条路。一条是直接用HTTP调用大模型API用RestTemplate或OpenFeign发请求拿结果。另一条是集成Spring AI框架它是Spring官方出的AI开发工具包把对接各大模型API的细节封装好了。我的建议是如果只是做一个AI问答接口直接用RestTemplate/OpenFeign调API就行代码量不大逻辑清晰出了问题也容易排查。Spring AI虽然封装了很多东西但如果你只是接一个对话和文本生成它反而增加了一层学习成本。而且Spring AI版本演进比较快不同版本API差异大查资料对不上号的情况很常见。我在项目里用的是OpenFeign因为它写起来最简洁——定义一个接口加几个注解就能像调本地方法一样调远程API。FeignClient(name ai-service, url ${ai.api.url}) public interface AiClient { PostMapping(/v1/chat/completions) String chat(RequestBody ChatRequest request); }配置放到application.yml里ai: api: url: https://api.example.com key: ${AI_API_KEY}密钥不要写死在配置文件里用环境变量引用。生产环境甚至可以用jasypt对yml里的密钥加密存储SpringBoot启动时自动解密这样即使配置文件泄露密钥也不会直接暴露。4.2 AI荐书HanLP分词标签匹配实现AI荐书功能我的实现思路是“分词标签匹配排序”不涉及复杂模型但效果好还容易讲清楚。流程分三步第一步用户输入推荐请求比如“想读悬疑推理类的小说文风轻松”。后端把这个文本交给HanLP做关键词提取得到“悬疑”“推理”“小说”“轻松”这几个词。第二步从图书表里找出带这些标签的书。book_info表的ai_tags字段在录入图书时就有了比如“悬疑|推理|东野圭吾”。查询时用LIKE %悬疑% OR LIKE %推理%把候选图书捞出来。第三步算匹配度排序。匹配到标签数量越多排越前再辅以借阅量、评分等信息做二次排序。HanLP的引入很简单dependency groupIdcom.hankcs/groupId artifactIdhanlp/artifactId versionportable-1.8.4/version /dependency用的时候ListString keywords HanLP.extractKeyword(userInput, 5);实操心得AI荐书的核心不是分词而是图书标签的维护。图书入库时把标签录好后期推荐效果才会好。我建议标签做成半自动图书基本信息里填“题材”“风格”“适读人群”几个字段系统自动拼接成ai_tags。4.3 智能借阅助手上下文、流式输出与安全兜底智能借阅助手本质是一个有“知识约束”的对话机器人。我不能让用户随便问什么AI都答要把它限制在图书和图书馆业务的范围内。实现上主要做了三件事。第一系统提示词约束。每次调大模型时系统消息里明确写“你是一个高校图书馆智能助手只回答与图书、借阅、馆藏、图书馆服务相关的问题。用户问无关内容时礼貌拒绝并引导回图书话题。”这样做能解决90%的越界问题。第二多轮上下文。用户上一句问“怎么借书”下一句问“能借几本”AI要能理解“这个问题问的是借书”。实现方法很简单把最近几轮对话拼成一个消息数组一次性传给大模型。ListChatMessage messages new ArrayList(); messages.add(new ChatMessage(system, SYSTEM_PROMPT)); for (ChatItem item : chatHistory) { messages.add(new ChatMessage(user, item.getQuestion())); messages.add(new ChatMessage(assistant, item.getAnswer())); } messages.add(new ChatMessage(user, currentQuestion));第三安全兜底。在AI接口外层我用正则和敏感词库做了输入过滤明显违法违规的输入直接在网关层拦掉不让它进到大模型。同时AI输出的内容系统里不让原样展示而是先经过一层后端的内容安全检测。这一点在做任何AI类项目时都是必备的不要省略。4.4 AI能力拆得更细编目、催还文案、报表解读除了读者能看到的荐书和问答我还给管理员加了三类AI能力篇幅不长但很实用。AI辅助编目。管理员录入新书时只需要填书名和作者点击“AI自动补全”系统调用大模型补齐ISBN、出版社、分类、简介等信息。这个功能能显著提高录书效率也展示了AI在业务提效上的价值。AI生成催还文案。筛选出即将到期或已经逾期的借阅记录一键生成催还短信/邮件的文案文案里带上读者姓名、书名、应还日期。文案内容由AI生成但参数是后端拼好的保证信息准确。月度借阅分析。管理员选一个月系统拉取借阅统计数据让AI生成一段文字报告“本月借阅量Top3的图书是……分类占比最大的是……建议补充采购……方向的书籍。”这个功能很能唬人但其实实现成本很低——把统计数据拼成prompt调一次大模型接口而已。注意这些AI能力最好做成可插拔的。如果某天大模型API不可用系统要能降级——AI功能提示“服务暂不可用”但核心的借阅、图书管理功能完全不受影响。这个设计思路答辩时会被认为是考虑得比较周全的。5. 联调部署与“文档指导视频”怎么一次性补齐5.1 前后端打包与部署前后端联调没问题之后就是打包部署。后端打jar包mvn clean package -DskipTests打出来的jar在target目录下直接java -jar library-system.jar就能跑。前端打包npm run build生成的是dist静态文件目录。生产环境我推荐用Nginx部署前端同时把后端接口反向代理到8080端口server { listen 80; server_name your-domain.com; location / { root /usr/share/nginx/html; index index.html; try_files $uri $uri/ /index.html; } location /api/ { proxy_pass http://localhost:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }这里有一个前端路由的经典坑如果没有try_files $uri $uri/ /index.html;这一行刷新/book/list页面就会404。因为前端是SPA单页应用/book/list这个路径在后端服务器上并不存在Nginx必须把所有未知路径都指回index.html由前端路由接管。5.2 配套文档写哪些、怎么写才专业这套项目标配套文档一般指课程设计/毕设论文或者项目说明书。文档结构建议这样安排需求分析部分画出系统的用例图、功能结构图写明每个角色的功能边界数据库设计部分贴出E-R图和核心表结构每张表的字段含义都要注释后端设计部分分层架构图、核心接口的时序图、JWT认证流程前端设计部分页面原型图、路由结构、组件划分AI模块部分为什么选大模型、提示词怎么设计、推荐算法思路测试与部署部分核心功能测试用例、部署环境、访问方式文档写作有几个技巧。截图一定要多每个关键页面都放一张截图再配一段文字说明。文字必须和代码对齐不能让读者对着文档找不到对应代码位置。数据库表的说明可以用表格列出字段、类型、说明比一大段文字清楚得多。实操心得写文档最忌讳“对着代码翻译”。比如“管理员点击借阅按钮后端收到请求调用BorrowService.borrow()方法然后插入一条记录……”这种写法答辩老师看了会很烦躁。正确的写法是先讲业务逻辑为什么借书要校验库存和逾期状态再给出关键代码辅助说明。5.3 指导搭建视频的录制节奏与工具“指导搭建视频”是这个项目的另一个配套交付物。录视频的目的不是炫技而是让一个拿到项目的人按着操作能跑起来。所以视频脚本比录屏操作更重要。我录的时候分了三段。第一段是环境准备5分钟以内讲清楚JDK版本、Maven配置、Node版本、MySQL初始化把该装的装好。第二段是后端启动10分钟左右讲怎么改application.yml里的数据库连接、怎么执行SQL脚本、怎么启动SpringBoot、怎么用Postman验证接口通没通。第三段是前端启动和整体验证10分钟左右讲npm install、npm run dev、登录系统、走一遍借书还书流程。录屏工具我用的是OBS Studio免费且支持高清录制录鼠标操作没问题。导出视频时建议同时出两个版本一个竖屏短视频方便手机速览一个完整版。如果你想把视频放到系统里做“在线教学”模块可以转成m3u8格式切片配合hls.js在前端播放这样整个系统的功能闭环还能再自洽一点——系统里的教学视频就是教你用这个系统的视频。6. 高频踩坑实录环境、联调、部署三类问题速查6.1 环境搭建阶段最容易卡住的地方IDEA创建SpringBoot项目超时。这是新人遇到最多的坑。默认创建项目时从spring.io下载元数据国内网络经常连不上。解决方案是新建项目时把Server URL改成阿里云镜像https://start.aliyun.com。npm安装依赖太慢或卡死。换源是最有效的前面也提到过。另外node_modules不要用网盘同步同步几万个文件会把人搞疯。MySQL时区报错。连接数据库时遇到Server returns invalid timezone在JDBC连接串上加参数?serverTimezoneAsia/ShanghaiuseUnicodetruecharacterEncodingutf8。这个问题很常见加上就对了。SpringBoot版本太高导致的依赖不兼容。我建议用SpringBoot 2.7.x稳定且教程最多。3.x虽然新但部分老教程的代码和依赖需要调整对新手不友好。6.2 联调阶段的高频报错跨域请求被拦截。先确认是浏览器报的CORS错误还是后端日志报错。多数情况是前端代理没配好或者后端没有允许对应来源。用Vite代理基本能一把过。中文乱码。后端接口返回中文在页面上显示成问号问题出在数据库连接串没加characterEncodingutf8或者响应头没设置编码。SpringBoot里在application.yml加上server.servlet.encoding.forcetrue基本能解决。接口返回404。先确认前端请求路径和后端Controller的RequestMapping路径是不是完全一致。我在联调时经常遇到前端/api/book/delete/1后端却是/api/book/delete?id1这种路径对不上的问题。建议前端统一用RESTful风格接口路径要规范化不要混用。静态资源404。前端打包部署后找不到js/css文件一般是publicPath配置问题。Vite里设置base: ./用相对路径引资源部署到任意子路径都能访问。6.3 部署和安全上的几点忠告配置密码不要明文。数据库密码、AI接口密钥都用环境变量或配置中心管理。至少在application.yml里用${DB_PASSWORD}引用环境变量不要把真实密码提交到代码仓库。接口要做好防刷。图书管理系统虽然是内部项目但登录接口、AI对话接口如果暴露到公网建议加个简单的IP限流比如一分钟同一个IP最多调用30次。SpringBoot可以用拦截器配一个计数器实现也可以用现成的Bucket4j库。密码不能明文存储。读者和管理员的密码要加盐做哈希处理。推荐用BCryptPasswordEncoderSpringSecurity里现成的工具类使用成本很低。AI接口的输出要做内容安全检测。前面提到过再强调一次大模型的输出不能直接展示给用户必须有兜底检测这是AI项目合规的底线。另外还有一个容易被忽略的点借阅相关的接口后端一定要校验当前用户的角色和资源所有权。不能出现“读者A把读者B的借阅记录还了”这种越权操作。这种漏洞在答辩演示时只需要一个请求就能测出来非常尴尬。这套系统做下来我最深的体会是技术点不在多而在每一个技术点都要能讲清楚“为什么”。SpringBootVue解决的是前后端分离和开发效率问题AI解决的是业务体验和运营效率问题文档和视频解决的是项目交付和可复现问题。把这几个问题串成一个完整的故事项目才真正算作完成。如果后续你还想扩展一个方向是把图书推荐从“标签匹配”升级成“协同过滤”根据用户历史借阅记录算相似用户推荐更个性化另一个方向是引入消息队列比如Kafka做借阅流水的异步处理和统计顺便把流量削峰的性能优化思路讲清楚。这些都是可以继续深入的点不过那就是下一个版本的事了。
返回列表