ARTICLE DETAIL

资讯详情

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

SpringBoot+Vue+MySQL旅游管理系统毕设全流程实战指南

SpringBoot+Vue+MySQL旅游管理系统毕设全流程实战指南 每年到了三、四月份我都会在后台收到一堆类似的问题学长SpringBootVueMySQL做旅游管理系统当毕业设计到底行不行表怎么建才不会被答辩老师问倒前端路由老出问题怎么办部署文档该怎么写正好去年我完整带过一个用这套技术栈做的旅游管理系统毕设项目从需求文档、数据库设计、后端接口、前端页面一路到最终的部署和论文答辩全程没有走捷径也没有硬凑功能。这篇内容就把整个项目的推进思路、关键代码、踩过的坑和论文写作的注意点全部拆开讲一遍希望能帮正在做毕设或者准备做毕设的同学少走点弯路。先说清楚这套选题为什么经久不衰。旅游管理系统覆盖了用户注册登录、景点与线路展示、订单生成与状态流转、评论收藏、后台数据管理这些最常见的业务场景既有典型的增删改查又有稍微复杂的多表关联和状态变更正好卡在毕业设计要求的难度线上——你说它复杂吧没有高并发没有分布式你说它简单吧又完整覆盖了前后端分离开发的全流程。对大多数本科同学来说这是性价比非常高的选择。这套东西能做什么我用一句话概括游客在网页端浏览景点和旅游线路下单后生成订单管理员在后台维护景点、线路、轮播图、订单状态和用户数据。当然如果你们学校要求更高还可以在数据统计页面增加订单趋势图和热门景点排行。下文所有设计都围绕这个核心范围展开功能不贪多但每一个模块都做得完整闭合。本文适合两种人看一种是完全零基础、打算从零手写这个系统的同学另一种是已经写了部分代码但卡在接口对接或部署环节的人。我不会只贴代码让你抄更重要的是解释每一步为什么这么设计遇到报错时你应该往哪个方向排查。1. 为什么旅游管理系统适合做毕设技术栈、业务复杂度和答辩评分逻辑1.1 技术栈的理由SpringBootVueMySQL为什么是黄金三角如果你去翻一遍近几年的课程设计和毕业设计选题SpringBoot、Vue、MySQL这三个词出现的频率高得离谱几乎成了JavaWeb方向的事实标准。但大家选它不只是因为参考资料多而是这个组合本身就自带合理性。后端用SpringBoot是因为它去掉了传统SSH和SSM框架里大量繁琐的XML配置内嵌Tomcat、自动装配、Starter机制让项目可以非常快地跑起来。SpringBoot的约定大于配置理念意味着你只需要很少的配置就能拥有一个可运行的Web服务这对毕设周期来说太重要了。你想想如果还在用传统的Servlet手写请求分发光是一个登录功能就要写十几层代码根本没有时间处理业务逻辑。前端选Vue是因为它天然适合做前后端分离的单页应用。旅游管理系统的用户端需要频繁切换页面——首页、景点详情、线路列表、个人中心、购物车结算Vue的组件化开发让每一个页面独立维护路由负责页面切换Axios负责接口请求开发体验非常顺畅。数据库选MySQL就没什么好说的了开源免费、资料海量、Workbench和Navicat可视化工具成熟学校机房也基本预装。更重要的是MySQL在单机应用场景下性能和稳定性足够不需要像Oracle那样去做复杂调优能把精力集中在业务本身。1.2 站在答辩老师的角度这个题目的评分点在哪里很多同学以为答辩看的是功能数量功能越多分越高其实不是。我参与过几次模拟答辩老师真正关注的是几个点第一你的系统有没有完整的业务流程闭环比如用户下单之后订单状态是不是一直能追踪到第二数据库设计是否合理有没有明显冗余或者逻辑错误第三代码分层是否清晰Controller、Service、Mapper是否各司其职第四你对自己的项目有没有解释能力能不能说明白一个接口从请求到返回数据的完整链路。旅游管理系统在这几点上天然有优势。业务流程上有用户、景点、线路、订单、评论五类核心实体订单又涉及创建、支付、完成、取消等状态变化这足以展示你对业务状态机的理解。数据库设计上至少要有六张以上的表其中订单表和订单明细表的拆分以及多表关联查询都是可以拿出来讲的亮点。代码分层上只要是规范的前后端分离项目Controller只管接收参数、Service管业务逻辑、Mapper管数据库访问这个标准结构本身就符合答辩预期。所以你选这个题目表面上是在选一个旅游主题实际上选的是一个评分点全面覆盖的经典Web系统。它不会让老师眼前一亮但也不会让老师觉得你在糊弄只要细节做得扎实中等偏上的分数完全可以拿到。2. 先把角色和业务流程理清楚模块划分比写代码更重要2.1 用户角色与功能边界毕设通关的第一步不是建项目而是画角色用例图把谁在用这个系统、各自能干什么搞清楚。旅游管理系统最常见的角色划分是两类前台用户和管理员。前台用户指的是游客和注册用户。游客可以浏览首页、查看景点详情和旅游线路但下单前必须登录。注册用户可以修改个人资料、收藏景点、对游览过的景点发表评论、创建订单并查看订单状态。这里我强烈建议采用JWT无状态认证而不是传统的Session。原因有两点前后端分离项目里前端可能部署在Nginx上后端是单独的SpringBoot应用Session跨域处理起来很麻烦而JWT把用户信息放在Token里前端存到localStorage请求时放在Authorization头里后端用一个拦截器解析Token就能识别用户身份。管理员角色可以继续细分但建议毕设中控制在两类超级管理员和普通管理员。超级管理员负责管理后台的用户账号、角色分配普通管理员负责景点、线路、酒店等业务数据维护。如果你们学校对用户角色没有硬性要求做成一类管理员完全够用否则权限这块会消耗很多时间。2.2 核心功能模块与业务流程一个能拿得出手的旅游管理系统我建议至少包含以下功能模块模块前端页面核心后端接口涉及数据表用户认证登录页、注册页登录、注册、获取当前用户sys_user景点管理景点列表页、景点详情页景点分页查询、详情查询、热门景点scenic_spot线路管理线路列表页、线路详情页线路分页、按条件筛选、线路详情含行程安排travel_route、route_item酒店管理酒店列表页酒店分页、区域筛选hotel订单系统下单确认页、订单列表页、订单详情页创建订单、订单列表、订单详情、取消订单、状态更新order_info、order_item评论与收藏详情页评论区域、个人中心收藏列表发布评论、评论列表、收藏与取消comment、favorite后台管理后台布局页、各管理表格各实体后台CRUD、订单状态处理、数据统计全部数据表我叫大家在开发前先画这个功能矩阵是因为很多同学一上来就急着建表写接口做着做着发现我这功能好像缺个页面或者这两张表结构对不上返工成本极高。先确定边界才知道数据库里该放哪些字段接口该返回哪些数据。业务流程上最核心的一条链路是下单流程用户选择景点或线路加入订单确认页填写联系人和出行日期提交订单后订单状态为待支付模拟支付成功后状态变为已支付管理员后台确认出票后变为已完成如果用户在出行前取消则变为已取消。这条链路的每一步都在订单状态字段上体现而状态字段的变更记录是答辩时最容易讲出内容的细节。3. 数据库设计表结构、字段类型和那些后来才能体会的坑3.1 核心数据表设计数据库是整个项目的地基地基歪了后面写再漂亮的代码也是白搭。我给出一个经过实际验证的表结构方案你可以直接在这个基础上按自己的业务微调。第一张表是用户表sys_user字段包括id主键自增、username用户名唯一、password加密存储、nickname昵称、avatar头像URL、phone手机号、role角色标识区分管理员和普通用户、status账号状态是否禁用、create_time、update_time、deleted逻辑删除标记。这里密码一定要用加密算法我推荐BCryptSpring Security里自带这个工具不能把明文密码存进数据库这是答辩老师非常看重的一个安全细节。第二组是景点表和线路表。scenic_spot包括id、spot_name、spot_picture封面图、spot_area所在地区、open_time开放时间、ticket_price门票价格Decimal类型、description富文本描述、star_rating评分、view_count浏览量、status是否上架。travel_route包括id、route_name、days行程天数比如5天4晚、price成人价格、start_city出发城市、route_type线路类型比如跟团游、自由行、cover_image、route_desc、status。如果你的线路要展示每天的行程安排就再加一张route_item子表字段为route_id、day_num、spot_name、spot_desc、stay_hotel。第三组是订单相关。order_info主表字段有id、order_no订单编号唯一用时间戳加随机数生成、user_id下单用户、order_type订单类型景点门票还是线路、link_name联系人、link_phone、order_amount订单总金额、status订单状态0待支付、1已支付、2已完成、3已取消、remark、create_time、pay_time。order_item子表字段有id、order_id、item_type、item_name、item_price、quantity、travel_date。为什么要把订单拆成主表和子表因为一个订单可能包含多个项目和多种出行日期如果不拆为了存多条数据就要重复创建订单主记录统计订单总额时会乱成一团。第四组是互动表。comment包括id、spot_id、user_id、content、rating总体评分、reply_content管理员回复、create_timefavorite包括id、user_id、spot_id、create_timeuser_id和spot_id要建联合唯一索引防止用户重复收藏。3.2 五大字段设计原则做过实际项目的人都会告诉你表结构里真正影响开发体验的是下面几个细节第一个是逻辑删除。所有核心业务表都加一个deleted字段值0为正常1为已删除。删除操作永远用UPDATE语句把字段置为1而不是执行物理DELETE。这样做的最大好处是数据可恢复一旦管理员误删了景点或线路还有回旋余地。数据统计的时候也不会出现数据突然蒸发的情况。配合MyBatis-Plus内置的逻辑删除配置代码层面根本不需要手动判断deleted插件会自动拼接条件。第二个是时间字段类型。不要用VARCHAR存日期直接使用datetime类型。MySQL中datetime的默认格式是YYYY-MM-DD HH:mm:ss前端拿到后可以直接展示。同时建议create_time和update_time设默认值为CURRENT_TIMESTAMP或者通过MyBatis-Plus的自动填充功能在插入和更新时赋值避免每写一次接口都手动set时间。第三个是金额字段。价格不要用double或者float用decimal(10,2)。浮点数在计算金额时会有精度误差这是计算机基础课就讲过的问题答辩时如果被问到还有理有据。10表示总位数2表示小数位数单价99.9、总价9999.99都能存下。第四个是图片路径。不要在数据库里存整张图片的base64编码那样会让每个接口返回的数据量膨胀几十倍。正确做法是存相对路径比如 /upload/scenic/20250320153001.jpg前端拿到的完整访问地址由服务器域名或Nginx映射拼接而成这样页面加载更流畅也方便以后迁移文件到对象存储。第五个是外键和索引。我在设计时通常不在数据库层面加外键约束而是在应用层保证引用关系。为什么因为实际业务里外键约束会严重影响删除和修改的灵活性比如你想删除一个景点但它下面还有评论记录有外键的话删除操作会报错前端就得先删评论再删景点业务逻辑复杂且容易出问题。但索引一定要加经常用来查询的字段都要建立适当索引比如订单表按user_id查用户订单、评论表按spot_id查景点评论、线路表按route_type筛选这些字段建完索引后分页查询的性能提升非常明显。4. SpringBoot后端搭建版本选择、分层结构、认证授权和通用组件4.1 项目初始化与依赖配置后端我用的是SpringBoot 2.7.x系列。这里要特别提醒一句不要一上来就选择最新的3.x版本。SpringBoot 3.0之后底层Java版本要求17以上而且很多第三方starter还没有完全适配。如果你实验室电脑上装的是JDK 8选3.x版本后第一步就卡死连启动都起不来。2.7.x是目前最成熟的稳定版本无论是网上教程数量还是各类依赖兼容性都是最优解。如果你用的是JDK 8SpringBoot 2.7.18完全够用。依赖方面我用的是以下组合MyBatis-Plus作为ORM框架Hutool作为工具库JWT使用jjwt库密码加密用spring-security-crypto里自带BCrypt参数校验用spring-boot-starter-validation文件上传依赖不用额外引SpringBoot自带了MultipartFile能力。还有Lombok不解释谁用谁知道Entity和DTO能省掉一半的样板代码。Maven的pom.xml里核心依赖大致如下dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency dependency groupIdcom.baomidou/groupId artifactIdmybatis-plus-boot-starter/artifactId version3.5.3.2/version /dependency dependency groupIdmysql/groupId artifactIdmysql-connector-java/artifactId scoperuntime/scope /dependency dependency groupIdio.jsonwebtoken/groupId artifactIdjjwt-api/artifactId version0.11.5/version /dependency dependency groupIdorg.projectlombok/groupId artifactIdlombok/artifactId /dependency4.2 前后端分离下的分层目录结构后端目录我建议按照这样的结构组织这也是行业里最常见、答辩老师最容易看懂的分层方式com.example.travel ├── controller # 接收前端请求参数校验返回统一响应 ├── service # 业务逻辑层事务管理 │ └── impl ├── mapper # MyBatis-Plus的Mapper接口数据库操作 ├── entity # 实体类与数据库表一一对应 ├── dto # 前端请求参数封装避免直接传Map ├── vo # 前端展示数据封装可组合多表数据 ├── config # 配置类如跨域配置、MyBatis-Plus配置 ├── interceptor # 拦截器处理JWT登录校验 ├── utils # 工具类如JWT工具、返回结果工具 └── common # 通用类如统一返回对象、枚举、异常处理这个分层其实是对标阿里的Java开发规范来的Controller层禁止写业务逻辑只做参数接收和结果返回Service层写核心业务逻辑并且加上Transactional事务注解Mapper层只用MyBatis-Plus封装好的方法复杂的多表查询可以写XML自定义SQL。分层清晰的好处是可以分阶段测试Controller不依赖业务细节Service可以单独单元测试答辩时也更容易表达。4.3 统一返回结构与全局异常处理前后端分离项目的接口和数据约定一定会被答辩老师问到。我的做法是定义统一的返回体 ResultData public class ResultT { private Integer code; // 200成功400参数错误401未登录500服务器异常 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(Integer code, String msg) { ResultT result new Result(); result.setCode(code); result.setMsg(msg); return result; } }所有Controller的返回值都是Result类型前端Axios拦截器拿到响应后先判断code是否为200再做后续处理。这样一个接口的返回格式统一前端不用针对每个接口单独处理错误情况这是正规项目中非常基础也极其重要的规范。全局异常处理我用RestControllerAdvice注解统一拦截。业务异常定义成自定义的BusinessException携带错误码和提示信息未登录访问受保护接口时拦截器抛出401数据库操作异常、参数校验失败分别处理。很多同学的代码把异常处理散落在每个Service里try-catch包了一层又一层不仅代码难看答辩时也很难讲清楚。用统一异常处理后业务代码里只需要抛出异常不需要关心异常如何处理。4.4 JWT登录认证与拦截器的实现细节登录认证我选了JWT方案。用户登录成功后服务端生成一个TokenToken里包含了用户id、用户名、角色和过期时间用密钥签名后返回给前端。前端把Token保存到localStorage中后续每次请求都在header中带上Authorization: Bearer token。后端通过一个拦截器校验Token的合法性和过期时间。Token工具类的核心就是生成和解析两个方法生成部分用jjwt库public String generateToken(Long userId, String username, String role) { Date now new Date(); Date expireDate new Date(now.getTime() 7 * 24 * 3600 * 1000L); // 7天有效期 return Jwts.builder() .setSubject(username) .claim(userId, userId) .claim(role, role) .setIssuedAt(now) .setExpiration(expireDate) .signWith(secretKey, SignatureAlgorithm.HS256) .compact(); }拦截器里做校验时要区分白名单接口和受保护接口。登录、注册、景点列表、线路列表这些公开接口不需要Token直接放行创建订单、发布评论、个人中心接口必须校验。我在WebMvcConfig里注册拦截器的时候用excludePathPatterns方法把公开接口路径排除掉比在拦截器内部手动判断要清爽得多。这里有个容易踩的坑JWT的密钥不要写死在前端也不要存数据库应该配置在application.yml里。还有Token过期以后前端需要跳回登录页处理方式是后端返回401状态码Axios响应拦截器判断为401时清除本地Token并跳转到登录路由。4.5 图片上传与访问路径配置旅游管理系统的景点封面、线路图片、用户头像都涉及文件上传。我的方案是上传到本地磁盘的一个固定目录比如项目根目录下的upload文件夹然后把文件访问路径映射成URL。配置方式是在application.yml中指定一个上传路径再通过WebMvcConfigurer把 /upload/** 访问路径映射到物理目录。Configuration public class WebMvcConfig implements WebMvcConfigurer { Override public void addResourceHandlers(ResourceHandlerRegistry registry) { String uploadPath System.getProperty(user.dir) /upload/; registry.addResourceHandler(/upload/**) .addResourceLocations(file: uploadPath); } }上传接口用MultipartFile接收文件保存时用UUID重新生成文件名避免中文名引起的乱码和路径问题。文件类型就检查后缀名比如.jpg、.png大小限制在application.yml中通过spring.servlet.multipart.max-file-size配置为10MB。考虑到毕设项目并不会涉及存储扩容这个方案完全够用。如果你们的部署环境是只能跑jar的服务器记得把上传路径配置在外部不要打包进jar内部否则重启项目后文件会丢失这是本地开发最常见的隐形坑。5. Vue前端开发构建方案、路由设计、Axios封装和页面实现顺序5.1 环境准备和构建工具选择前端我用的组合是Vue3 Vite Element Plus。如果你之前只接触过Vue2的Options API也不要慌Vue3的Composition API并没有那么难理解它只是把原来data、methods、computed这些选项统一成setup函数里的变量和方法写法更集中。我用Vite而不是Vue CLI是因为Vite用ES模块加载开发服务器启动速度比Webpack快一个量级刚才我们说的毕设周期本来就紧每次等几十秒打包重启确实熬人。创建项目直接用官方命令npm create vitelatest travel-front -- --template vue创建后安装依赖vue-router路由管理注意版本要4.x以上才支持Vue3、pinia状态管理替代Vuex、axios、element-plus、element-plus/icons-vue。Element Plus的按需导入我建议用官方推荐的unplugin-auto-import和unplugin-vue-components插件不用在main.js里全量引入打包体积小启动速度也快。很多同学在npm install这一步就能卡一个下午最常见的报错是Invalid package.json和ECONNRESET。前者通常是node_modules缓存损坏删掉node_modules重装就好后者多半是网络问题可以把npm镜像切换到国内镜像命令行执行npm config set registry https://registry.npmmirror.com然后再重新安装。5.2 路由设计与登录守卫旅游管理系统的页面可以分成两部分用户前端和后台管理端。用户端的路由有首页、景点列表、景点详情、线路列表、线路详情、酒店列表、登录页、注册页、个人中心、我的订单、订单详情后台管理端路由有数据看板、景点管理、线路管理、酒店管理、订单管理、评论管理、用户管理。这两组路由的公共路径可以都放在/下面但后台管理页面需要统一加上/layout作为布局组件前缀。路由守卫是整个前端最容易被忽略但答辩必问的部分。它的作用是判断用户访问受保护页面时是否已登录。我用的是vue-router的beforeEach全局前置守卫router.beforeEach((to, from, next) { const token localStorage.getItem(token) if (to.meta.requiresAuth !token) { next({ path: /login, query: { redirect: to.fullPath } }) return } if (to.meta.isAdmin localStorage.getItem(role) ! ADMIN) { next({ path: /403 }) return } next() })这里我把路由meta字段里配置好requiresAuth和isAdmin分别标识需要登录和需要管理员角色的页面。路由守卫的执行顺序是先判断是否登录再判断角色是否符合。登录成功后如果有redirect参数就跳回原页面否则跳首页。这个细节能让用户的体验感好很多也是答辩时的加分项。5.3 Axios封装与接口对接规范Axios封装我的建议是拆成两个文件一个是request.js负责创建axios实例、设置baseURL、添加请求拦截器携带Token、处理响应拦截器的统一错误另一个是api文件夹下按业务模块拆分的接口定义文件。比如有用户模块的user.js、景点模块的spot.js、订单模块的order.js每个模块导出一组函数页面里直接调用这些函数不需要每个页面重复写请求代码。请求拦截器处理Token的细节service.interceptors.request.use(config { const token localStorage.getItem(token) if (token) { config.headers[Authorization] Bearer token } return config })响应拦截器拿到后端统一返回的Result数据后先看code字段。如果code是200直接返回response.data.data给业务页面如果是401清空localStorage并跳转到登录页其他错误码统一ElMessage提示错误信息。这样页面里写代码就非常干净比如获取景点列表的函数直接返回数据不需要每个页面都写try-catch。5.4 页面开发优先级和关键交互前端页面数量多我建议按照用户能完成一次完整下单流程的路径来安排开发顺序注册登录页、首页含轮播图和热门景点、景点列表页、景点详情页含评论和收藏、线路列表页、线路详情页、下单确认页、我的订单页、后台各管理页面。列表页的分页交互是必做的前端要传current和pageSize给后端后端返回分页对象后前端用Element Plus的Pagination组件展示。详情页的数据如果不复杂直接通过路由参数传递id然后调用详情接口即可。下单确认页要注意用户从景点详情页跳转过来时携带景点id和门票价格从线路详情页跳转过来时携带线路id和人数前端需要根据订单类型动态展示结算信息——我建议后端的能力下拉时根据order_type返回不同的内容。评论模块很容易被忽略。景点详情页底部做一个评论区登录用户可以发布评论和评分未登录用户点击评论框时提示先登录。评论区本身支持分页加载这个功能虽然小但涉及登录校验、数据插入和列表刷新三端联动非常能反映一个开发者对完整业务流程的把控。图片路径问题我在联调阶段遇到最多次。景点封面的URL如果是在开发环境下通过Vite代理访问的那么页面里的图片地址相对路径直接写/upload/scenic/xxx.jpg就能访问到但打包部署后前端挂在Nginx下Nginx需要额外配置一个location把/upload请求代理到后端或者本地目录。我在开发时图方便很多图片字段直接存了相对路径上线时忘了在Nginx加配置结果首页图片全裂了排查了半天才想起来是路径映射少了一段。6. 联调、部署与论文写作毕设最后三关的细节与经验6.1 前后端联调的常见问题排查当后端和前端分别跑起来之后就会进入我认为整个项目中看起来没技术含量、实际上最折磨人的联调阶段。排第一的永远是跨域问题。后端的跨域配置如果只在开发环境下写死生产环境的域名一换又会有问题反过来前端Vite代理配置如果没写对接口请求就会因为端口不一致被浏览器拦截。我的建议是后端直接封装一个CorsConfig允许所有来源这在前端安全级别不高的毕设场景下足够前端开发环境则统一配置Vite服务器代理把/api开头的请求转发到后端地址这样联调时两边都感觉不到跨域的存在。第二个高频问题就是参数命名不一致。后端接口定义接收的参数是String orderNo前端Axios传输时字段名变成了order_no或者orderNo写成了orderNo2结果导致后端接收不到值。前后端没约定字段命名规范的情况下这个问题几乎无法避免。我的经验是后端出接口文档时把入参和出参字段列表写清楚前端在Api文件里对照着定义参数对象联调时再核对一遍。2024年我的建议就是所有接口文档都用Swagger生成前端可以访问/swagger-ui/index.html看到每个接口的参数定义从根上杜绝这种低级错误。第三个坑是时间类型序列化问题。后端LocalDateTime默认序列化成数组或者带T的字符串前端格式化起来很麻烦。解决方案有两个在application.yml里配置Jackson的时间格式或者在前端写一个时间格式化过滤器。我建议两个都做后端统一返回 YYYY-MM-DD HH:mm:ss 格式前端展示时做空值兜底这样订单详情页的时间显示非常干净。6.2 后端打包与部署流程部署是很多同学从没做过的事情但毕业论文页面里必须有部署说明所以一定要亲自跑通一遍。前端打包非常简单在项目根目录执行npm run build生成dist文件夹里面都是静态文件。后端打包用Maven的package命令先在含pom.xml的目录执行mvn clean package -DskipTests生成一个可执行jar文件比如travel-system.jar。实际部署时有两种常见方案一种是把后端jar直接丢到云服务器上跑另一种是前端静态文件用Nginx托管后端jar用命令启动。我强烈推荐第二种因为Nginx处理静态文件效率高同时可以配置反向代理把/api请求转发给后端的8080端口这样浏览器访问80端口就能完整使用系统也比较符合生产环境的真实形态。一个简单的Nginx配置片段如下server { listen 80; server_name yourdomain.com; location / { root /usr/local/travel/dist; index index.html; try_files $uri $uri/ /index.html; } location /api/ { proxy_pass http://127.0.0.1:8080/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } location /upload/ { alias /usr/local/travel/upload/; } }后端的启动命令需要指定端口和数据库配置如果MySQL也装在云服务器上需要注意MySQL默认绑定127.0.0.1本地可以连、外网连不了这是默认安全策略配置文件里的bind-address确认一下能不能满足需求。启动jar后养成看日志的习惯日志停在什么位置一般就能判断模块是否加载成功。6.3 论文结构与写作顺序安排论文这一块很多功能开发完的同学反而倒下了。我见过太多把毕业设计论文写成操作手册的例子全篇都在讲点击这个按钮弹出对话框却没有讲这个功能为什么要这么做。我建议论文按这样的章节结构写第一章绪论讲选题背景和研究意义第二章相关技术介绍把SpringBoot、Vue、MySQL、前后端分离的概念说清楚注意一定要跟本系统结合着讲不要变成纯概念背诵第三章需求分析写角色需求、功能性需求、非功能性需求并且给出用例图第四章系统设计写总体架构图、功能模块图、数据库ER图和核心表结构第五章系统实现按模块逐一介绍实现思路、关键代码和运行截图第六章系统测试写测试计划、测试用例和执行结果。最后是总结和致谢。写作顺序上我的人生建议是第三章需求分析必须趁开发前写完因为你需要它来理清思路第五章系统实现放在开发完成之后写这时候你手里有代码有截图写起来素材充足第二章相关技术介绍可以放在最后乱序整理它其实是整篇论文里最好写但又最容易套路化的部分。写实现的时候不要大段贴完整代码贴关键方法即可并且每一段代码后面必须跟一段文字解释这段代码解决了什么问题这是答辩前你能给自己留的讲解稿。6.4 答辩前的准备和常见提问点答辩前我建议准备两个东西一个是一分钟到三分钟的项目演示脚本另一个是跟项目相关的八到十个拓展问题的答案。演示脚本要按用户端到后台端操作一遍完整业务中间等着数据加载的时候说清楚当前模块的设计思路。常见提问点无非就是你的表之间是什么关系订单状态怎么流转为什么用JWT不用Session如果并发高你怎么办有没有做防SQL注入的过滤这些内容其实在系统实现过程中都已经涉及最终回答时要把设计考虑和实现方案分开讲就能体现思路清晰。我的体会是答辩老师考察的深度并没有网上传的那么可怕只要你能够沿着我是谁、我设计了什么、为什么这么设计、最终效果怎么样这条线把项目讲清楚就能拿到正常的分数。最后再分享一个小技巧如果时间实在来不及优先保证主线流程完整也就是注册登录浏览景点下单查看订单这条主链路绝对不能断后台管理只用简单列表和编辑也能过基础分但千万不要为了加一个花哨的大屏统计把主流程做残了。我现实中见过好几个反例花了大量时间做数据大屏结果订单流程提交不了最后只能是推倒重来。系统的完整性永远比单个炫酷页面重要这个道理在毕业设计里比在商业项目里体现得更彻底。
返回列表