ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

SpringBoot+Vue网上摄影工作室毕设全流程解析:从建表到答辩避坑

SpringBoot+Vue网上摄影工作室毕设全流程解析:从建表到答辩避坑 “你选的这个课题代码是不是网上找的答辩的时候能给我讲讲核心表为什么要这么设计吗”这是我带毕设这几年听到最多的一句话。很多学生下载一个“SpringBootVue网上摄影工作室”源码跑通了就觉得万事大吉结果开题报告写得像流水账答辩PPT翻了两页就被老师问住。我见过太多人卡在同一个地方项目功能一大堆但讲不清楚为什么选SpringBoot、为什么用Vue、为什么MySQL要这样建表。这篇文章不会贴一整份“拿过去就能交”的论文我会从选题思路、技术选型、数据库设计、前后端实现到部署答辩完整拆解一个“SpringBootVue网上摄影工作室管理平台”应该怎么做、怎么讲、怎么避坑。这里面的内容就是我带学生做类似全栈项目时反复强调的重点也适合所有正在准备毕设、课设或者想系统学习前后端分离开发的同学。1. 项目定位与核心价值这个平台到底在做什么1.1 业务场景还原网上摄影工作室解决的真实问题先别急着看代码咱们把自己代入到一家真实的摄影工作室里。传统影楼或者个人摄影工作室的日常流程是什么样的客户到店或者电话咨询工作人员把套餐册子拿给客户看客户选套餐、约时间拍摄之后过几天再来选片最后取成片。这套流程线下跑起来有几个痛点作品集太大客户没办法随时翻看排期靠本子记撞档期是常事客户想了解套餐价格必须得等人回复订单状态不透明客户不知道自己的片子修到哪一步了。网上摄影工作室管理平台本质就是把这套线下流程搬到线上做成两个端。用户端是给客户用的可以浏览摄影师的作品、查看套餐价格、在线预约拍摄时间、随时跟进自己订单的处理进度。管理端是给工作室老板或者员工用的用来发布作品、管理套餐、处理预约、维护客户信息。这样一个系统做完业务线是完整闭环的展示 - 咨询 - 下单 - 服务 - 反馈每一个环节都在系统里有数据沉淀。从做毕设的角度看这种“展示交易后台管理”的业务模型非常合适。它比单纯做个博客或者商城更有辨识度因为涉及作品展示、预约排期、订单状态流转功能上有层次感既有C端页面的视觉表现力又有M端业务逻辑的复杂度。你答辩的时候可以很自然地讲出业务痛点而不是干巴巴地说“我做个管理系统”。1.2 功能模块全景用户端和管理端各有哪些页面咱们把这个系统的功能拆开看我习惯把它分成两大块。用户端包括注册登录支持普通客户和管理员区分角色首页放轮播图、热门作品精选、套餐推荐作品集页面按风格分类展示摄影作品支持点击查看大图套餐列表展示不同价位、不同内容的摄影套餐详情在线预约用户选择套餐、挑选拍摄日期和时间段、填写备注信息提交后生成预约订单个人中心查看自己的订单列表和状态比如待确认、已确认、已完成。管理端包括数据看板用图表展示预约趋势、套餐热度、新增客户数量这个在课设和毕设里是加分项作品管理对作品进行新增、编辑、上下架、删除作品要支持多图上传套餐管理配置套餐名称、价格、包含的服务内容、缩略图预约订单管理查看所有客户提交的预约进行确认、完成或者取消操作处理变更拍摄时间等情况客户管理查看注册用户的列表和基本信息。这两块功能加起来大概有十几个页面工作量对于一个课程设计来说刚刚好对于一个毕业设计来说也完全可以扩展开。你觉得功能不够多可以再往里面加“摄影师介绍”模块、加“评论点赞”功能、加“Excel导出订单”。但我建议第一步先把上面这些核心功能跑通再谈扩展。1.3 为什么这个课题适合当毕设/课设难度与展示度之间的平衡选课题就像挑一道菜食材太简单做出来没亮点食材太复杂做不出来只能砸锅。网上摄影工作室这个题目最妙的地方在于它的难度曲线非常平缓你完全可以根据自己的基础来调节深度。如果你是大三课设可以用SpringBoot写接口用Vue写页面数据库只建五六张表把预约流程做通这就算完成。如果你是毕业设计可以往里面加权限拦截、加数据统计图表、加文件上传、加订单状态机甚至可以用Redis做缓存热点作品、用Interceptor做登录鉴权这就能体现出足够的技术深度。从演示效果来看摄影类项目的视觉表现力天然占优势。你找一组高质量的样片放到作品集里页面颜值立刻拉满答辩时的第一印象就好很多。相比之下如果你做一个“学生宿舍管理系统”界面做得再认真展示出来的都是一排排表格视觉效果会弱不少。摄影主题天然适合用好看的图片填充这是其他业务系统比不了的。技术栈上SpringBoot Vue MySQL 是目前国内中小型项目最主流的组合。SpringBoot负责后端接口Vue负责前端渲染MySQL负责数据存储。这个组合学会了到了实习岗位你会发现公司里大部分业务系统都是类似的架构学的东西完全不会白费。2. 技术选型与开发环境先把地基打牢2.1 SpringBoot Vue MySQL 为什么是“黄金组合”我经常和学生说你选技术栈的时候不要只看“哪个火”而是要看“它解决了什么问题”。SpringBoot 解决的问题是 Java 后端开发里的配置地狱。以前用 SSMSpring SpringMVC MyBatis搭建项目光 XML 配置文件就能写几百行SpringBoot 通过自动配置和 starter 机制把大量默认行为封装好了你引入一个 spring-boot-starter-web它就自动帮你配好内嵌 Tomcat 和 SpringMVC开发者只需要关注自己的业务代码。这一点你用 SpringBoot 跑起来第一个项目的时候感受会特别深。Vue 解决的是前端 DOM 操作繁琐、页面状态管理混乱的问题。它的核心是响应式数据绑定你只需要维护数据页面会自动跟着变化。比如订单状态从待确认变成已确认前端只需要把数据里的 status 字段改掉按钮的样式和文字会自动更新不需要手动去操作 DOM。Vue 的组件化开发也特别适合这种多个页面有相似模块的项目比如作品卡片组件、套餐卡片组件写一次到处复用。MySQL 就不用多说了这个项目的业务数据——用户、作品、套餐、订单——都是典型的关系型数据用 MySQL 非常合适因为它支持事务、支持复杂的关联查询而且免费、资料多、社区成熟。网上摄影工作室的业务量级远没有达到需要上分布式数据库的程度单机 MySQL 性能完全够用这也是绝大多数中小型业务系统的现状。再强调一点这三者整合起来是“前后端分离”的架构。后端只提供 JSON 格式的数据接口前端负责页面的渲染和交互二者通过 HTTP 请求通信。这种架构的好处是前端和后端可以并行开发前后端团队只需要约定好接口文档。你做毕设的时候虽然是单兵作战但按企业标准拆分开来写这段经历写在简历上是能加分的。2.2 开发环境版本搭配版本太高反而容易踩坑搜过热词的同学应该都搜过“springboot版本太高”“idea创建springboot项目”“vue安装依赖”这类问题。这里我把版本搭配的经验一次说清楚同学们可以先按这个组合来装。后端环境建议用 JDK 1.8 或者 JDK 11SpringBoot 用 2.7.x 系列这是目前教程资料最多、最稳定的组合。如果你的 JDK 是 17那就用 SpringBoot 3.x但要注意 SpringBoot 3 基于 Jakarta EE很多包名从 javax.* 改成了 jakarta.*网上的旧教程可能对不上报错的时候容易懵。所以我一般建议没有特殊要求就 JDK 8 SpringBoot 2.7.x。IDEA 选择 Spring Initializr 创建项目的时候填好 Group 和 Artifact勾选 Spring Web、MyBatis Framework、MySQL Driver 这几个依赖然后注意看右下角的 Spring Boot 版本不要默认选到 3.x 以上。前端环境需要 Node.js版本建议 16 或者 18对应 npm 版本是 8 左右。Node 版本太高或者太低装依赖的时候容易报 engine 不匹配的警告。脚手架工具我用的是 Vue CLI虽然官方已经在推荐 Vite但 Vue CLI 的 webpack 方案资料更多、更成熟对初学者更友善。安装完 Node.js 后在命令行里执行npm install -g vue/cli然后vue --version验证是否安装成功。创建项目用的是vue create photography-web创建时选择 Vue 2 还是 Vue 3 可以看你自己习惯如果用 Element UI建议配 Vue 2如果用 Element Plus就得配 Vue 3。MySQL 建议安装 5.7 或者 8.0两个版本我都用过整体差别不大。8.0 需要注意连接驱动的版本要对应com.mysql.cj.jdbc.Driver连接 URL 要加时区参数比如jdbc:mysql://localhost:3306/photography?useSSLfalseserverTimezoneAsia/ShanghaicharacterEncodingutf-8不然启动的时候会报时区相关的错误。安装好之后用 Navicat 或者 MySQL Workbench 连上数据库新建一个名为 photography 的数据库后续导入 SQL 脚本就行。2.3 前后端项目结构规划一开始就按规范来创建完前后端两个项目之后我建议你先规划好目录结构不要代码写到哪里算哪里。后端项目的包结构可以这样规划controller 放接口层service 放业务逻辑service 下拆分 impl 存放实现类mapper 放 MyBatis 的 Mapper 接口entity 放数据库实体类dto 放接收前端参数的传输对象vo 放返回给前端的数据对象config 放配置类比如跨域配置、拦截器配置common 放统一返回结果、全局异常处理、工具类。这样分层的逻辑很清晰controller 接收请求参数转发给 serviceservice 处理业务调用 mapper 访问数据库返回的数据经过统一包装后响应给前端。前端项目的目录结构在 Vue CLI 创建的项目基础上调整views 放页面组件每个页面一个文件夹router 放路由配置文件api 放接口请求封装一个模块对应一个 js 文件比如 work.js、order.jscomponents 放公共组件比如作品卡片、分页组件、图片上传组件utils 放 axios 实例封装和工具函数store 放 Vuex 或者 Pinia如果用 Vue3的状态管理。项目结构规划得越清晰后期写代码就越顺。我见过不少学生把几百行代码堆在一个 App.vue 里面后面找 bug 找到怀疑人生。该拆的组件和文件一定要拆开这也是答辩时老师很看重的一个点——代码组织能力。3. 数据库设计与业务建模一张表都不能乱建3.1 核心表结构用户、作品、套餐、预约订单网上摄影工作室系统的核心业务数据可以提炼成“人、货、单”三类。“人”是用户和管理员“货”是作品和套餐“单”是预约订单。基于这个划分我设计了以下核心数据表。用户表 t_user字段包括用户ID、用户名、密码MD5或BCrypt加密、昵称、手机号、头像URL、角色标识1代表管理员0代表普通用户、注册时间、状态。密码绝对不能用明文这是最基本的底线BCrypt 比 MD5 更安全Spring Security 的 BCryptPasswordEncoder 可以直接用。作品表 t_work字段包括作品ID、标题、封面图URL、描述、风格分类、拍摄地点、展示视频URL可空、浏览量、状态1上架0下架、创建时间。注意作品会有多张图片如果直接在作品表里加一个 images 字段用逗号分隔虽然也能实现但不符合数据库设计规范。更合理的做法是单独建一张作品图片表 t_work_image字段包括图片ID、作品ID、图片URL、排序号。这样一张作品对应多张图片查询的时候用 workId 关联即可。套餐表 t_package字段包括套餐ID、套餐名称、价格用 decimal 类型、原价、包含服务内容比如精修多少张、底片是否全送、服装套数、封面图URL、套餐分类、状态、创建时间。摄影工作室的套餐一般有婚纱照套餐、写真套餐、亲子照套餐等可以按分类筛选。预约订单表 t_order这张表是整个系统的核心字段包括订单ID、订单编号可用时间戳加随机数生成、用户ID、套餐ID、拍摄日期、拍摄时间段、联系人姓名、联系电话、备注信息、订单状态0待确认1已确认2已完成3已取消、创建时间、更新时间。这里要注意的是一个用户在同一拍摄日期下如果已经有一个待确认或已确认的订单应该阻止再次提交避免重复预约这个逻辑在订单状态和查询约束里体现。除了这四张核心表如果功能扩展可以考虑添加轮播图表 t_bannerID、图片URL、跳转链接、排序号、状态和公告表 t_noticeID、标题、内容、发布时间。轮播图在首页展示管理端可以配置这个功能实现起来简单但视觉效果好值得加。3.2 字段类型与索引设计为什么这么建建表的时候有几个字段类型容易选错我单独拿出来说一下。价格的字段类型用 decimal(10, 2)不要用 float 或 double因为浮点数在计算金额的时候会产生精度误差。状态字段用 tinyint 类型数值表示不同的含义比如订单状态 0、1、2、3写清楚注释。时间字段用 datetimeJava 实体类对应 LocalDateTime 类型MyBatis 里做一下映射配置或者直接用 String 接收。索引方面建议按查询场景加索引。用户表在 username 上加唯一索引保证用户名不重复作品表在 status 上建普通索引方便筛选上架作品订单表在 user_id 和 order_status 上建普通索引因为个人中心需要按用户查订单管理端需要按状态筛选订单。索引不是为了加而加而是想清楚你的查询语句用到哪些字段。如果一张表只有几百行数据索引带来的提升几乎感觉不到但在答辩时能讲出“我在这张表的哪个字段加了索引、因为什么业务场景”这是一个很大的加分项。外键我没有建议在数据库层面设置原因很简单项目是学习用的业务上通过逻辑代码来控制关联关系就够了。如果设置物理外键删除作品的时候还要考虑外键约束反而是个累赘。这一点如果你在答辩时被问到可以这样回答“数据库层面不加外键是为了降低耦合度由应用层来保证数据的完整性这是目前企业开发中更常见的做法。”3.3 用户与权限普通用户和管理员怎么区分权限这块我用的方案是在 t_user 表里加一个 role 字段0 代表普通用户1 代表管理员。登录成功后后端根据用户的角色生成一个带有角色信息的 Token 返回给前端前端把角色信息存到本地。前端路由配置里加一个 meta 属性比如{ path: /admin, meta: { requiresAdmin: true } }在全局前置守卫里判断用户角色不是管理员就跳转到首页并提示没有权限。后端接口这边可以用拦截器对 /admin/** 开头的请求做拦截判断请求头里的 Token 解析出来的角色是否管理员。这种方案算不上严格意义上基于 RBAC 的权限模型但对这个项目来说够用了。如果你想让项目看起来更有深度可以引入 Spring Security 或者 Sa-Token 来做认证授权但这也意味着学习成本和代码复杂度会上升。我个人的建议是如果做课设用 JWT 拦截器就够了如果做毕设且时间充裕可以尝试集成 Sa-Token框架代码写起来会更简洁。4. 后端核心功能实现接口不只是增删改查4.1 统一返回结果与全局异常处理一个项目有几十个接口如果每个接口返回的数据格式都不一样前端对接时就会非常痛苦。所以项目一开始一定要定义统一的返回格式。我定义了一个 Result 类code 是状态码200 代表成功其他数字代表不同类别的错误msg 是提示信息data 是真正的业务数据。比如登录成功返回Result.ok()带数据就是Result.ok(data)参数校验失败就Result.error(参数不能为空)。全局异常处理我用 RestControllerAdvice 注解。写一个 GlobalExceptionHandler 类里面定义 ExceptionHandler 方法分别处理业务异常、参数校验异常、服务器内部错误。这样做的好处是你写业务代码的时候只管抛异常比如“该时间段已被预约”抛一个 ServiceException 自定义异常异常处理器会统一把这个异常里的信息包装成 Result 返回给前端代码很干净。4.2 JWT登录认证无状态会话怎么做前后端分离架构下Session 机制不太好用因为前端和后端不在同一个域名下跨域请求携带 Cookie 要处理很多问题。我采用的方案是 JWTJSON Web Token。登录成功后后端生成一串 Token 返回给前端Token 里面包含用户ID和用户名等基本信息。前端把 Token 存在 localStorage 里每次请求的时候放到请求头的 Authorization 字段里带上。后端写一个拦截器对需要登录才能访问的接口进行 Token 校验。拦截器在 preHandle 方法里取出请求头里的 Token用 JWT 工具类解析解析成功就把用户信息放到 ThreadLocal 里这样后续的业务代码里随时可以拿到当前登录用户。解析失败就返回一个 401 状态码和提示信息。JWT 方案最核心的优点是“无状态”服务器不需要存储会话信息非常适合分布式部署虽然这个项目用不到但表达出这个认知说明你是理解原理的。4.3 文件上传与作品图片管理作品管理涉及图片上传。我用的是本地存储方案配置一个虚拟路径映射比如把上传的文件保存到服务器的/uploads目录下然后通过 Spring Boot 的WebMvcConfigurer把/upload/**路径映射到这个物理目录。前端上传图片的时候调用/upload接口后端接收 MultipartFile 文件生成一个带时间戳的文件名保存到指定目录返回一个完整的访问 URL 给前端。前端拿到 URL 后把它作为图片地址传给作品的新增接口。这个方案虽然简单但要注意几个问题。一是要限制上传文件的大小在 application.yml 里配置spring.servlet.multipart.max-file-size为 10MB防止有人传大文件把服务器撑爆。二是文件重名问题用 UUID 或者时间戳生成新文件名避免不同用户上传同名文件被覆盖。三是 URL 拼接时的路径分隔符Windows 系统和 Linux 系统不一样建议用File.separator或者直接用/因为 URL 访问统一用/。如果你想用云存储OSS、COS思路是一样的只是把保存到本地换成调用云 SDK 上传返回的 URL 是云存储的地址。这个扩展点写进论文里也能增加技术亮点。4.4 预约与订单状态流转核心业务逻辑预约流程是整个系统业务逻辑最复杂的部分也是你答辩时必须讲清楚的地方。用户在前端选择套餐、选择拍摄日期用日历控件限制当天之前不能选、选择时间段上午、下午、全天填写联系人和备注然后提交预约申请。后端收到请求之后做了这几件事第一校验用户是否登录用户ID从 Token 里取第二查询是否有冲突订单如果同一个拍摄日期和同一个时间段已经存在状态为待确认或已确认的订单就直接返回“该时间段已被预约请选择其他时间”第三生成订单编号我用的是时间戳加三位随机数保证唯一第四初始化订单状态为待确认插入数据库第五返回订单详情给前端。管理端处理预约的时候看到待确认的订单列表点击确认按钮后端校验订单状态必须为待确认然后把状态改成已确认。订单只有从待确认才能变成已确认从已确认才能变成已完成已取消的订单不能再次操作。这种状态流转的控制我写在 service 层里做判断而不是直接让前端传一个状态值过来随便改。你答辩的时候能提到“我的订单状态流转是由后端控制的避免客户端篡改数据”老师对你的印象会好很多。5. 前端页面实现把演示效果做到位5.1 Vue工程搭建与路由设计前端项目我用 Vue CLI 创建选择了 Vue Router 和 Vuex。路由表的设计分两块用户端路由和管理端路由。用户端路由包括首页/home、作品集/works、套餐/packages、预约/reserve、个人中心/profile、登录/login、注册/register。管理端路由嵌套在一个父路由/admin下面包括/admin/dashboard数据看板、/admin/work作品管理、/admin/package套餐管理、/admin/order订单管理、/admin/user客户管理。路由懒加载用到了也就是页面组件通过() import(/views/Admin/Index.vue)这种方式动态加载。这样整个项目打包的时候用户端和管理端的代码会拆分成多个 chunk首屏加载速度会快很多。导航守卫我用来做登录校验需要登录的页面先判断 localStorage 里有没有 token没有就跳转到登录页需要管理员权限的页面再判断用户角色是不是 1不是就跳回首页。5.2 Axios封装与登录态维护Axios 需要封装成一个全局可复用的实例。我在 utils/request.js 里创建了一个 axios 实例设置baseURL为/api开发和部署时通过不同方式处理跨域下面会讲设置全局超时时间为 10 秒然后在请求拦截器里从 localStorage 取 token放到请求头Authorization: Bearer token。响应拦截器里把后端返回的 Result 解出来如果 code 是 200 就 return 里面的 data如果 code 是 401 就清除本地 token 并跳转到登录页如果网络错误就提示“网络异常请稍后重试”。你可能会问为什么要统一封装最直接的好处是所有接口的请求和响应处理逻辑都集中在一个文件里想改超时时间、想改错误提示、想统一加上 loading只需要改一个地方。如果不封装每个页面单独写 axios 请求代码会重复到爆炸。5.3 核心页面首页、作品集、预约页首页设计得简洁大方一点。顶部是导航栏中间放一个轮播组件展示工作室的 Banner 图。轮播图下面分两个区域热门作品和一个四宫格展示推荐套餐三个套餐卡片并排。这三个模块的数据分别从接口获取相当于首页聚合了三个接口的数据。作品集页面做成瀑布流或者栅格布局。左侧是风格分类导航点击分类后重新请求对应分类的作品列表。每张作品卡片显示封面图、标题、浏览量。点击卡片跳转到作品详情页详情页展示多张作品图片、描述文字、拍摄地点还可以嵌入一个视频播放器展示工作室的样片宣传视频。预约页是整个系统的用户转化关键。页面上半部分显示用户选择的套餐信息下半部分是一个预约表单选择拍摄日期用 Element UI 的日期选择器并禁用过去日期、选择时间段单选按钮组、填写联系人和手机号。提交前做前端校验手机号格式对不对、日期有没有选、时间段有没有选。提交成功后跳转到个人中心的“我的预约”列表。5.4 视频展示与 m3u8 流媒体播放思路热词列表里反复出现“vue播放m3u8”说明不少同学遇到过这个需求。摄影工作室有时候需要展示宣传片或者客片视频。如果服务器上的原始视频是 mp4 格式直接用 video 标签播放就能搞定。但如果视频文件比较大或者运营时需要防盗链就会考虑把视频转码成分片的 m3u8 流媒体格式。m3u8 是把整个视频切成无数个小片段通常几秒钟一个播放器逐个加载播放好处是可以实现边下边播加载速度快网络波动时不容易卡顿。前端处理 m3u8 播放最常用的方案是 hls.js。先安装依赖npm install hls.js页面里放一个 video 标签在下一帧获取 video 元素判断浏览器原生是否支持 HLSSafari 支持如果不支持就用Hls.isSupported()判断当前环境是否支持 hls.js调用new Hls()创建实例设置配置项绑定视频元素然后hls.loadSource(m3u8Url)加载视频源hls.attachMedia(video)开始播放。整个过程不复杂但需要在组件的 beforeDestroy 生命周期里调用hls.destroy()释放资源。5.5 管理后台数据看板与表单操作管理后台注重功能性。数据看板用 ECharts 图表展示数据比如近七天的预约订单数量折线图、套餐销量占比饼图。ECharts 引入不复杂安装echarts依赖在组件里初始化一个 DOM 容器配置 option 后setOption(option)。图表数据从后端统计接口获取后端写一个 SQL 分组查询把预约表的数据按日期分组统计数量返回。作品管理页面是一个表格加表单弹窗的结构。页面加载时请求分页查询接口表格每一页显示 10 条数据带分页组件。新增和编辑共用同一个弹窗表单表单里有标题输入框、分类下拉框、封面图上传组件、描述富文本框。图片来源可以是一个自定义的上传组件调用后端的图片上传接口上传成功后把 URL 赋值给表单字段。表格的操作列出编辑和删除按钮删除时需要二次确认。6. 部署联调与常见问题排查从能跑到能讲6.1 本地联调与跨域问题前端和后端分开跑本地开发时前端地址是http://localhost:8080后端地址是http://localhost:9090两者端口不同前端直接发请求会被浏览器的同源策略拦截。解决跨域有几种常见方案我推荐两种结合用。后端在配置类里实现WebMvcConfigurer的addCorsMappings方法设置允许所有来源访问允许所有请求头和方法允许携带凭证这样后端就允许跨域请求了。前端开发环境下vue.config.js里配置 devServer 的 proxy把/api开头的请求代理到http://localhost:9090同时通过pathRewrite把/api前缀去掉。这样前端代码里请求地址只需写/api/user/login代理服务器转发到后端时变成/user/login。部署到服务器时一般用 Nginx 做反向代理。nginx.conf 里配置一个 location /api 的转发规则把前端静态文件的请求和/api接口的请求分别处理。前端打包后得到 dist 目录放到 Nginx 的 html 目录下后端打包成 jar 包用java -jar photography-server.jar启动监听在 9090 端口。这样整个系统只需要一台服务器、一个 Nginx就全部跑起来了。6.2 高频报错与排查经验速查表我整理了项目开发过程中最高频的几个报错和处理方法你可以直接拿来对照报错现象可能原因处理方法IDEA 创建 SpringBoot 项目后启动失败提示某种依赖找不到SpringBoot 版本选太高依赖不兼容改用 2.7.x 版本或检查 JDK 版本是否匹配连接 MySQL 报 Public Key Retrieval is not allowedMySQL 8 驱动与数据库连接握手问题连接 URL 加allowPublicKeyRetrievaltrueuseSSLfalseMyBatis 报 Invalid bound statement (not found)Mapper 接口和 XML 对应关系不对检查 namespace 全限定名检查 XML 文件是否在 resources 目录对应路径前端请求接口报 404跨域代理或路径前缀不匹配检查 vue.config.js 代理和请求地址前缀是否一致前端请求接口报 401token 未携带或已过期检查请求拦截器是否把 token 放入请求头检查 token 过期时间图片上传成功但页面访问不到静态资源映射沒配置检查 WebMvcConfigurer 里 addResourceHandlers 的映射路径Vue 打包后刷新页面 404前端路由是 history 模式服务器没配置回退Nginx 添加try_files $uri $uri/ /index.html;Vue 打包后布局异常、字体图标不显示静态资源路径设置成了绝对路径把 vue.config.js 的publicPath设置为./这里面每一个问题我都实际遇到过尤其是“MyBatis Invalid bound statement”和“Vue 打包后刷新 404”每年都有学生卡在这两个问题上实际上原因都很简单。学会了看报错信息、逐步排查比背一百道面试题都管用。6.3 答辩和面试时怎么把项目讲出亮点项目做完了只是第一步能讲清楚才是拿到高分的关键。我建议你从这几个角度准备答辩词。第一个必考点是 SpringBoot 自动装配的原理。你不需要把源码全背下来但至少要知道SpringBootApplication 是个组合注解其中 EnableAutoConfiguration 通过spring.factoriesSpringBoot 2.x或者AutoConfiguration.importsSpringBoot 3.x文件里列的配置类按照ConditionalOnClass和ConditionalOnProperty的条件来判断是否加载对应的自动配置。比如项目里有 spring-boot-starter-web 依赖自动配置类就会自动配置内嵌 Tomcat 和 SpringMVC。你能把这个逻辑讲出来老师就知道你不是只跑通了项目而是真的去了解过框架原理。第二个必考点是为什么用 JWT 不用 Session。回答思路是前后端分离后后端可能有多个实例Session 需要共享存储要用 Redis 解决而 JWT 校验是无状态的Token 本身包含了用户信息服务器不存储会话天然适合分布式。同时也承认 JWT 的缺点Token 无法在服务端主动失效需要设置合理的过期时间并配合前端做续期。第三个高频问题是数据库为什么这么设计尤其是订单表的状态字段。回答时要强调状态机的思路订单从待确认到已确认再到已完成每一步都有严格的状态流转控制防止用户跳过过程直接修改状态保证业务流程的严谨性。第四个问题是怎么保证预约不冲突。回答时说清楚查询条件同一个拍摄日期 同一个时间段 订单状态在待确认或已确认范围内只要存在一条记录就拒绝预约这本质上是一个唯一业务校验虽然在数据库层面没有加唯一约束但通过事务和状态控制保证了并发下的安全性。把这些准备透了你不仅是在做一个课设而是在系统性地理解一个完整的全栈项目。这对你后面找工作面试的时候讲起项目来也是一个非常好的素材。我在带学生的过程中发现一个规律认认真真把这个项目做完、想明白的学生面试时候讲项目都能讲得很顺畅反而那些只是把源码跑通、没有自己思考过的一被追问就露馅。所以做完项目之后多花点时间在自己的代码上走读一遍每个接口从请求到响应完整地捋一遍这比多写一个功能更有价值。
返回列表