ARTICLE DETAIL

资讯详情

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

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

SpringBoot+Vue+MySQL旅游管理系统毕设全流程实战教程 如果点开这篇文章你的状态多半和我当年一样毕业设计题目定了“旅游管理系统”坐在电脑前盯着空荡荡的IDE不知道第一行代码该写在哪。翻了一圈CSDN和Gitee要么是卖源码的广告要么是零散到没法拼起来的教程片段好不容易找到一个能跑的工程解压一看还是JSP心凉了半截。这篇文章不卖源码也不贴什么“三分钟部署成功”的夸张标题。我把自己从选题、技术选型、数据库设计到前后端联调再到服务器部署、论文撰写最后答辩现场老师提问的完整过程一条线全拆开来讲。包括我当时踩过哪些坑、哪几个地方最容易翻车、哪些设计是你可以在答辩时主动抛出来加分的点。文章围绕SpringBootVueMySQL这套旅游管理系统展开适合正在做毕业设计的学生也适合想拿这个项目练手、往简历里填一个完整项目经验的初学者。我写得很细可以直接把它当成一份操作手册来读。1. 项目立项与整体规划1.1 为什么旅游管理系统是毕设里的“安全牌”在计算机专业的毕设题库里旅游管理系统属于非常典型的“管理信息系统”MIS。它不像电商系统那样要处理复杂的库存、秒杀、支付回调也不像社交平台那样要操心实时消息推送但它的业务链足够长用户注册登录、景点展示、线路搜索、下单预订、订单状态流转、后台数据维护、统计报表。这些场景正好覆盖了一门软件工程课程里最核心的知识点拿来佐证你的开发能力刚刚好。我当时选这个题还有个很现实的原因就是它的资料足够多。SpringBoot和Vue的资料一搜一大把MySQL的表结构设计也有成熟案例可以参考。对于一个只有几个月时间的毕业生来说“可参考性”是比“炫酷程度”重要得多的因素。你选个冷门的图像识别题目遇到问题连问都没地方问论文中期检查还可能被质疑可行性。旅游管理系统不一样它的逻辑是公认的清晰老师一看题目就知道你大概要做什么答辩时不会在选题意义上刁难你。不过“安全牌”不等于“不用动脑”。我见过有同学把系统做成了纯CRUD就只有增删改查没有任何业务规则答辩时老师问一句“你这个系统解决了什么实际问题”他半天接不上话。所以选题即使普通也要在功能设计上做出层次感把这个系统从“玩具”变成“作品”。这也是我后面反复强调的旅游管理系统的价值不在于功能多而在于每个功能成体系、每张表之间有关联、每个接口背后有完整的业务逻辑。1.2 技术栈选型SpringBootVueMySQL 赢在哪现在很多学校还在教JSPServletMySQL但说实话这套组合放在今天的毕设环境里已经不太撑得住场面了。老师在看毕设答辩的时候默认都会扫一眼你的技术栈SpringBoot几乎成了默认起点。它内置了Tomcat不用单独去配置一个web服务器自动配置机制省掉了一大堆XML文件配合Maven管理依赖基本上一个项目从创建到跑通十分钟就能完成。我用它做完这个旅游管理系统之后最大的感受是SpringBoot让开发者把注意力从“踩配置的坑”转移到“写业务逻辑”上这恰恰是毕设阶段最应该被锻炼的能力。Vue这边它和SpringBoot简直是天作之合。Vue的核心是组件化开发一个页面可以拆成若干个组件每个组件只管自己那一块数据和交互。我在做后台管理系统的时候把侧边栏菜单、表格、弹窗都拆成了独立组件后面再开发新页面时直接复用效率提升是很明显的。而且Vue解决了我最头疼的DOM操作问题数据变了页面自动更新不用像jQuery那样手动拼HTML字符串。MySQL这个选择没什么争议免费、轻量、稳定而且几乎每个大学的计算机实验室都装了。数据库用MySQL还有个容易被忽视的好处你遇到问题的时候只要把报错信息往搜索引擎里一贴答案基本都有。对毕设来说生态成熟有时候比技术先进更重要。为什么不推荐RuoYi这类快速开发框架这里想认真说一下。我知道很多同学喜欢用若依这类脚手架因为自带权限、代码生成器能在一天之内拼出一个管理后台。但我个人不推荐在毕设里直接套这种框架。一来你很难在答辩时把框架里的每一行代码都讲清楚老师随口问一个“Spring Security的过滤器链是怎么执行的”你就可能卡壳二来如果整个项目你只写了几个业务接口其他全靠代码生成器老师对工作量是有判断的。自己从零搭一个SpringBootVue项目虽然前期进度慢一点但是每一个配置文件、每一个拦截器你都心里有数这是你答辩时最大的底气。1.3 模块划分动手前先把功能边界划清楚我刚开始做这个项目的时候脑子里只有一个模糊的概念用户能看景点、能订票、管理员能管理后台。但当我开始建表的时候就卡住了因为功能边界不清晰根本不知道该建几张表。后来我静下心来画了一张功能清单把所有要做的功能全部列出来再按角色分组事情立刻明朗了。用户端的功能大致是这些注册/登录游客也可以直接浏览景点和线路首页轮播图、热门景点推荐、公告通知景点列表分页展示、按名称或分类搜索景点详情多张图片、文字介绍、门票价格、开放时间旅游线路列表与详情线路天数、行程安排、费用说明在线预订线路生成订单个人中心修改个人资料、查看我的订单、取消订单管理端的功能大致是这些管理员登录景点管理景点的增删改查、图片上传、上下架线路管理线路的增删改查、关联景点、设置价格库存订单管理查看所有用户订单、修改订单状态待支付、已支付、已取消、已完成用户管理查看用户列表、禁用/启用账号数据统计用图表展示近一周/近一月的订单量、热门景点排行把这份清单往Excel里一贴数据库要建什么表、后端要写多少个接口、前端要画多少个页面全都一目了然。我后来帮学弟改项目的时候发现九成的问题都出在前期没有做好功能划分上。有人做到一半突然想加一个“评论功能”结果数据库要加表、后端要加接口、前端要加页面连登录状态的关联都得重新理一遍整条线全被打乱。所以我的建议是功能可以少但边界必须清晰。先把范围定死后面的每一周都按照这个需求表去推进就不会做着做着就失去了方向。2. 系统架构与数据库设计2.1 前后端分离架构的关键设计旅游管理系统采用的是典型的前后端分离架构。后端SpringBoot运行在8081端口提供RESTful API只返回JSON数据前端Vue运行在8080端口负责页面渲染和用户交互MySQL在3306端口存数据。前后端之间通过HTTP协议通信。这里有个关键点就是开发环境下怎么解决跨域问题。当时我一开始使用在后端加CrossOrigin注解的方式确实简单但后来发现这种方式在拦截器、文件上传、复杂请求场景下偶尔会出现预检请求失败的情况。后来我把方案换成了前端代理方式在vue.config.js里配置proxy把所有/api开头的请求转发到后端的8081端口。这种方式更干净因为它在开发环境模拟了同源请求前端代码里不用写死后端地址后面部署到服务器只要把代理规则改成Nginx代理配置就可以无缝切换。下面是这个项目开发环境的前端代理配置以Vue CLI项目为例// vue.config.js module.exports { devServer: { port: 8080, proxy: { /api: { target: http://localhost:8081, changeOrigin: true, pathRewrite: { ^/api: /api } } } } }changeOrigin: true的作用是把请求头里的Host字段改成目标地址的Host这样后端收到的请求就像从8081端口自己发出来的不会触发跨域策略。这个配置我在本地跑的时候几乎零报错强烈推荐。另外为什么要用前后端分离而不是传统的服务端渲染理由有两个。第一职责边界清晰。后端只关心数据处理和业务逻辑前端只关心页面展示和用户交互出问题的时候定位很快。比如首页数据没加载出来我只需要打开浏览器F12看Network面板看请求是没发出去、还是返回了500、还是前端渲染报错马上就能分清楚是后端的锅还是前端的锅。第二可以同时展示两种能力。毕设答辩时你说“我这个项目是前后端分离架构前端使用Vue构建SPA应用后端提供RESTful API”老师一听就知道你接触过现代Web开发的常见实践比单纯说“我用JSP写了几个页面”要有说服力得多。2.2 数据库表结构设计详解数据库是整个系统的地基表设计得好不好直接决定后面开发顺不顺畅。我一开始设计表结构的时候踩过一个坑就是想把所有字段都塞进一张表里结果后面加功能的时候不得不反复改表结构。后来我重新梳理了一遍业务把核心表确定为五张sys_user用户表、scenic_spot景点表、travel_line旅游线路表、order_info订单表、line_spot_relation线路与景点关联表。先说用户表。这个表不需要太多字段但要注意密码字段的长度。因为我用的是BCrypt加密加密后的字符串长度是60个字符所以password字段必须预留足够空间。另外要有一个role字段区分管理员和普通用户我这里用的是tinyint类型0代表管理员1代表普通用户。下面是我当时建表用的SQL可以直接参考CREATE TABLE sys_user ( id bigint(20) NOT NULL AUTO_INCREMENT COMMENT 主键ID, username varchar(50) NOT NULL COMMENT 用户名, password varchar(100) NOT NULL COMMENT 密码BCrypt加密, nickname varchar(50) DEFAULT NULL COMMENT 昵称, phone varchar(20) DEFAULT NULL COMMENT 手机号, email varchar(100) DEFAULT NULL COMMENT 邮箱, avatar varchar(255) DEFAULT NULL COMMENT 头像地址, role tinyint(1) DEFAULT 1 COMMENT 角色0-管理员 1-普通用户, status tinyint(1) DEFAULT 1 COMMENT 状态1-正常 0-禁用, create_time datetime DEFAULT CURRENT_TIMESTAMP COMMENT 创建时间, update_time datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 更新时间, deleted tinyint(1) DEFAULT 0 COMMENT 逻辑删除0-未删除 1-已删除, PRIMARY KEY (id) ) ENGINEInnoDB AUTO_INCREMENT1 DEFAULT CHARSETutf8mb4 COMMENT用户表;这里有个细节想多说一句就是逻辑删除字段deleted。为什么要用逻辑删除而不是物理删除因为用户数据经常要被订单表引用如果你直接把用户从表里删掉历史订单就变成了“无主数据”查询的时候会非常麻烦。逻辑删除的意思是删除时只是把deleted字段变成1查询的时候自动过滤掉数据其实还在。MyBatis-Plus对这个功能的支持很完善配置好策略之后删除操作会自动变成更新语句非常方便。景点表包括景点名称、景点分类、景区图片、详细描述、门票价格、所在城市、开放时间等字段。线路表包括线路名称、线路天数、出发城市、目的地、价格、线路介绍、封面图、出发日期、余位数量等字段。订单表则记录了用户预订线路的具体信息包括用户ID、线路ID、订单号、订单金额、出行人数、联系人、联系电话、订单状态、创建时间。订单号要单独说一下它是order_no字段我用的是时间戳加随机数的形式生成类似“20250513123055123456”这样既能保证唯一性又能从订单号里看出下单时间。主键id是用来自增的但订单号不能直接用自增ID替代因为那会暴露系统的订单量对外展示不友好。删外键还是留外键这是我的答案不要用物理外键。很多教科书画ER图的时候喜欢画外键关系但实际开发中物理外键会影响插入性能而且在删除数据时容易引发约束冲突。我在表里只存user_id、line_id这些逻辑外键字段业务层面的关联关系放在Service层去保证。比如删除一个景点之前先查询一下有没有线路或者订单引用了它如果有关联数据就不允许删除并提示前端“该景点下有线路订单不能删除”。这个逻辑在答辩时讲出来比单纯说“我建了外键”高级很多因为体现了你在真实项目中的工程判断。2.3 统一返回结构容易被忽略但极加分的细节前后端联调最怕什么最怕数据格式不一致。后端写接口的人和前端写页面的人如果事先没有约定好返回格式联调现场就会出现这种对话“你这个接口是直接返回数组的吗”“有时候返回数组但查不到的时候返回字符串。”“那你让我怎么判断”。为了避免这种混乱我提前定义了一个统一的返回类Result。它的结构非常简单{ code: 200, message: 操作成功, data: { id: 1, name: 张家界经典三日游, price: 1588 } }code是状态码200表示成功401表示未登录权限不足500表示服务异常。message是给前端提示的信息前端拿到code之后如果发现不是200就直接弹出message内容。data就是真正要返回的业务数据可以是对象、列表也可以是空。使用统一返回结构到底有什么好处第一前端不用每个接口分别处理返回格式axios响应拦截器里统一判断code就行。第二后端接口签名非常清晰一个接口返回什么结构一目了然。第三答辩的时候老师一看到你的接口文档和返回示例就知道你考虑过代码的规范性和可维护性这一下就能和那些“接口返回值随心所欲”的项目拉开差距。3. 核心功能实现与代码解析3.1 后端SpringBoot分层设计与关键实现后端我采用的是三层架构Controller、Service、Mapper。Controller负责接收HTTP请求、参数校验、把结果封装成Result返回Service层写业务逻辑Mapper层用MyBatis-Plus操作数据库。为什么一定要分出Service层而不直接在Controller里写业务代码因为有些逻辑不是一次就能写完的。我举一个很典型的例子用户下单这个操作表面上就是往order_info表里插一条数据但它背后至少要经过四步校验用户是否登录、线路是否还存在、线路是否还有余位、该用户是否已经下过同一日期的线路。这些逻辑如果都堆在Controller里Controller会变得非常臃肿而且难以复用。我把这些判断全部封装到OrderService.createOrder()方法里面Controller里一行代码就能调用清晰又安全。下面是下单接口的Controller和Service核心代码RestController RequestMapping(/api/order) public class OrderController { Resource private OrderService orderService; PostMapping(/create) public Result? create(RequestBody Valid OrderCreateRequest req, RequestAttribute Long userId) { OrderInfo order orderService.createOrder(userId, req); return Result.success(order); } }Service public class OrderServiceImpl implements OrderService { Resource private OrderInfoMapper orderInfoMapper; Resource private TravelLineMapper travelLineMapper; Override Transactional(rollbackFor Exception.class) public OrderInfo createOrder(Long userId, OrderCreateRequest req) { TravelLine line travelLineMapper.selectById(req.getLineId()); if (line null) { throw new BizException(线路不存在); } if (line.getStock() req.getCount()) { throw new BizException(余位不足); } if (line.getStatus() 0) { throw new BizException(该线路已下架); } int updated travelLineMapper.reduceStock(line.getId(), req.getCount()); if (updated 0) { throw new BizException(线路余位不足请刷新后重试); } OrderInfo order new OrderInfo(); order.setOrderNo(generateOrderNo()); order.setUserId(userId); order.setLineId(line.getId()); order.setLineName(line.getLineName()); order.setPrice(line.getPrice()); order.setCount(req.getCount()); order.setTotalAmount(line.getPrice() * req.getCount()); order.setContactName(req.getContactName()); order.setContactPhone(req.getContactPhone()); order.setStatus(0); orderInfoMapper.insert(order); return order; } }这里有一个很关键的细节Transactional注解。为什么下单必须加事务因为这里有两步写操作先扣减线路库存再插入订单记录。如果第二步插入失败而第一步没有回滚就会出现“库存扣了但订单没生成”的严重问题。加上事务之后两步要么一起成功要么一起失败数据一致性就有了保证。答辩时老师很可能问你“为什么这个接口要加事务”你要能答出这道题就已经赢了大多数人。还有一个细节是扣减库存的方法travelLineMapper.reduceStock()它是自己写的一条SQLUPDATE travel_line SET stock stock - #{count} WHERE id #{lineId} AND stock #{count}这条SQL用数据库的行锁机制解决了超卖问题。在高并发场景下两个用户同时下单同一张票如果只是先查库存再更新可能两个人都查到有余票最后超卖。用这条SQL数据库会锁定这行记录affected rows等于0就表示扣减失败业务层就知道库存不够了。虽然毕设系统一般不会有那么大的并发量但你这个设计思路在答辩时可以直接加分。3.2 前端Vue核心业务实现前端部分我用的是Vue 2 Element UI组合这也是目前大部分毕设项目的标配。如果你用的是Vue 3也可以把Element UI换成Element Plus逻辑是一样的。Vue这边的核心工作可以概括为三个部分路由管理、请求封装、页面组件开发。路由管理上面已经提到过核心是路由守卫。我要再说一个细节就是路由的懒加载。const routes [ { path: /, component: Layout, redirect: /home, children: [ { path: home, name: Home, component: () import(/views/Home.vue), meta: { title: 首页, icon: el-icon-house } }, { path: scenic/:id, name: ScenicDetail, component: () import(/views/ScenicDetail.vue), meta: { title: 景点详情 } } ] } ]用() import()而不是直接import Home from /views/Home.vue可以把页面拆成独立代码块项目首次加载只加载首页必需的代码访问到某个子页面时才加载对应文件。这个优化对项目体积的影响特别明显。刚开始我没用懒加载整个项目打包出来有4MB白屏时间长改用懒加载之后首页首包只有1MB出头加载速度体验完全不同。毕设里能讲出这个优化点老师会觉得很实用。请求封装这块我在api/request.js里创建了一个统一的axios实例。import axios from axios const service axios.create({ baseURL: /api, timeout: 10000 }) service.interceptors.request.use(config { const token localStorage.getItem(token) if (token) { config.headers.Authorization token } return config }) service.interceptors.response.use( response { const res response.data if (res.code 401) { localStorage.removeItem(token) window.location.href /login return Promise.reject(new Error(登录状态已过期)) } if (res.code ! 200) { ElementUI.Message.error(res.message || 请求失败) return Promise.reject(new Error(res.message)) } return res }, error { ElementUI.Message.error(网络异常请稍后重试) return Promise.reject(error) } ) export default service有了这个封装之后业务页面里调用接口就非常简洁了比如// api/order.js import request from /api/request export function createOrder(data) { return request({ url: /order/create, method: post, data: data }) }页面里只需要关心成功后的数据async handleSubmit() { this.loading true try { const res await createOrder({ lineId: this.line.id, count: this.ticketCount, contactName: this.contactName, contactPhone: this.contactPhone }) this.loading false this.$message.success(下单成功) this.$router.push(/my-orders) } catch (e) { this.loading false } }3.3 登录鉴权与权限控制登录鉴权这块我推荐用JWT的方案它比传统的Session更符合前后端分离架构。说一下我的实现思路。用户登录后后端用用户名、用户ID、角色这些信息生成一个token这个token经过签名不能被伪造。后端把token返回给前端前端存在localStorage里。之后每次请求前端在axios拦截器里自动把token放到请求头Authorization中。后端写了一个Spring MVC拦截器在所有不以/auth/login开头的接口上做拦截解析token如果解析成功就把当前用户ID存到ThreadLocal里方便后续业务代码直接取用。用户角色控制我用的是一个自定义注解RequireRole加拦截器的方式。在管理员接口上标注RequireRole(0)拦截器里判断当前用户角色如果不是管理员就返回403。这个方案比引入Spring Security轻量很多代码量少逻辑也容易讲清楚。我承认Spring Security是更专业的方案但毕设场景下手写一个轻量鉴权链路的理解深度往往比照着网上的配置搭一个Spring Security更真实。你要用Spring Security也可以前提是你真能把过滤器链讲明白。有一点必须强调密码必须加密存储。我当时用的是BCrypt加密登录时把用户输入的密码用BCrypt的check方法比对。有些同学图省事直接把明文密码存数据库答辩时老师看到数据库里的密码是明文印象分一下就下来了。BCrypt加密码并不复杂引入一个依赖调用两行代码的事但效果是本质性的不同。4. 环境搭建与部署全流程4.1 环境版本清单千万别乱装我见过太多人项目跑不起来根本原因就一个环境版本对不上。有同学一上来就装最新版JDK 17然后发现SpringBoot 2.x项目启动直接报错有同学装Node 18跑Vue 2的老项目构建报内存溢出。这个教训真的太常见了。下面这套版本组合是我实测下来最稳的毫不夸张地说按这个来运行阶段至少少踩一半坑组件推荐版本说明JDK1.8Java 8SpringBoot 2.x最佳搭档Maven3.6.3稳定依赖下载正常Node.js14.x 或 16.xVue CLI和依赖兼容性最好Vue CLI4.5.x默认创建Vue 2项目MySQL5.7 或 8.0两者皆可注意驱动不同IDEA2020.3及以上提前装好Lombok插件MySQL 8.0和5.7在连接串上有个坑8.0的驱动类名是com.mysql.cj.jdbc.Driver5.7是com.mysql.jdbc.Driver。如果你用的是SpringBoot 2.x它内置的数据库驱动版本一般已经适配了8.0直接连8.0是没问题的。真正容易出问题的反而是SSL连接和时区设置所以连接串里一定要写serverTimezoneAsia/Shanghai不然数据库连接会报时区错误。4.2 本地跑通项目的完整步骤假设你现在拿到的是一个正常的SpringBootVue项目包含数据库脚本。按下面的顺序来我保证你能跑起来。第一步把项目解压确认目录结构。后端和前端是两个独立的文件夹比如backend/和frontend/。数据库脚本通常叫travel.sql或者init.sql。第二步启动MySQL用命令行或者MySQL Workbench执行数据库脚本。我用的是Workbench操作起来比较直观。执行完成后在数据库列表里能看到travel_db数据库里面已经建好了表。第三步改后端配置文件。找到application.yml或application.properties把数据库账号密码改成你自己的spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/travel_db?serverTimezoneAsia/ShanghaiuseUnicodetruecharacterEncodingutf-8 username: root password: 你自己的密码第四步用IDEA打开后端项目。IDEA会自动识别Maven项目并开始下载依赖。如果你挂了镜像仓库设置下载速度会快很多。依赖下载完成后找到主启动类是一个带SpringBootApplication注解的类右键运行。看到类似Tomcat started on port(s): 8081的日志就说明后端启动成功了。第五步用VS Code或IDEA打开前端项目。在终端里执行npm install等待依赖安装完成。这里要提醒一句npm install如果很慢大概率是网络问题可以配置淘宝镜像npm config set registry https://registry.npmmirror.com。安装完成后执行npm run serve。终端会打印出访问地址一般是http://localhost:8080。第六步浏览器打开http://localhost:8080看到一个能登录、能导航的页面就说明整个前后端已经连通了。4.3 从本地到服务器部署实操毕设验收虽然不一定要求部署上线但如果你能现场打开一个线上地址让评审老师直接访问效果一定好过在一个localhost窗口里现场启动项目。另外有些学校会检查系统的部署文档所以这一节我也想讲透。部署的核心思路是前端打包成静态文件由Nginx托管后端打包成可执行jar包用java命令启动。前端打包cd frontend npm run build执行完frontend目录下会生成一个dist文件夹。把这个文件夹里的内容静态文件上传到服务器上假设放在/opt/travel/frontend。后端打包cd backend mvn clean package -DskipTests执行完backend/target目录下会生成一个travel-system-0.0.1-SNAPSHOT.jar。把这个jar包上传到服务器假设放在/opt/travel/backend。然后在服务器上安装Nginx配置一个站点。Nginx配置核心内容如下server { listen 80; server_name your_domain_or_ip; location / { root /opt/travel/frontend; index index.html; try_files $uri $uri/ /index.html; } location /api/ { proxy_pass http://127.0.0.1:8081; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }try_files $uri $uri/ /index.html;这一行必须写。Vue的history路由模式在访问非首页地址时会请求服务器上的真实路径比如访问/my-ordersNginx先去找根目录下是否存在my-orders这个文件找不到就回退到index.html由Vue路由接管页面渲染。如果漏掉这行刷新页面就会出现经典的404。后端启动命令cd /opt/travel/backend nohup java -jar travel-system-0.0.1-SNAPSHOT.jar --spring.profiles.activeprod app.log 21 nohup和是为了让进程在后台持续运行。日志输出到app.log方便排查问题。线上环境的话我建议把数据库密码改成独立的强密码不要用本地数据库的弱口令。5. 论文撰写与文档打包5.1 论文框架与各章侧重毕设论文是很多同学最容易忽视的部分总觉得代码跑通了就万事大吉结果中期检查被老师批“论文水分太多”。实际上论文就是把你的项目按学术表达习惯重新讲一遍的过程它的结构几乎固定关键在于每一章你放什么内容。一份标准的毕业设计论文包含六到七章第一章 绪论研究背景与意义、国内外研究现状、研究内容与论文结构第二章 相关技术介绍SpringBoot、Vue、MySQL、MyBatis-Plus、JWT第三章 系统分析可行性分析、需求分析、用例建模第四章 系统设计总体架构、功能模块设计、数据库设计第五章 系统实现页面展示与核心代码讲解第六章 系统测试测试环境、测试用例、测试结果第七章 总结与展望项目完成情况、收获、不足与改进方向每一章的侧重点可以这样把握。绪论不要写太多两三页足够重点把研究背景写得贴近实际就行。相关技术介绍不要照抄百度百科老师一眼就能看出来要结合你的系统来讲比如“SpringBoot的自动配置机制在本系统中主要用于简化数据库连接和Web配置”。系统分析里面最核心的是需求分析要把功能性需求和非功能性需求分清楚能画出用例图就加分。系统设计是论文的正文数据库表和ER图要放在这一章接口的设计思路也要在这里讲。系统实现要放截图但不要光放截图每张截图旁边要有两到三段文字说明讲清楚你在这个页面里实现了哪些功能、遇到了什么难点、怎么解决的。系统测试需要有测试用例表格包括测试项、测试步骤、预期结果、实际结果最后结论是“测试通过”。5.2 截图、图表与查重的几个细节论文里的截图质量会直接影响评审老师的印象。我见过有人直接手机拍屏幕放进论文画面里还有背光条纹这种视觉好感度直接清零。我建议你截图时用WinShiftS区域截图并且在浏览器里按F12把视口宽度调成1440px按桌面版视图来截这样截出来的图片比例均匀、信息完整。另外系统里的数据一定要填充真实数据至少要有几十个景点、十几条线路、几十条订单记录。别拿一张空白的管理表格去截图老师会觉得你的系统没什么实际内容只是搭了个壳。ER图、流程图、用例图这类图表建议用ProcessOn或者draw.io画画完导出PNG高清图。不要用其他工具自动生成密密麻麻的图Word里根本看不清。图表的样式要统一线条粗细一致图例标注齐全图下方加“图4-3 用户下单时序图”这种编号和标题这是学术论文的基本排版规范。查重这一块最有效的方法就是“用自己的话写”。特别是相关技术介绍很多人直接抄官方文档整段重复率极高。我的办法是先理解一个技术点是干什么的然后在项目里找到了对应的使用场景用自己的语言把两者结合起来描述。比如写MyBatis-Plus时我写的是“MyBatis-Plus在系统中承担了数据持久化层的工作通过继承BaseMapper接口简化了景点、线路等实体的基础增删改查操作使代码量减少约40%”。这段话既介绍了技术又结合了项目重复率自然低。好的我已经把部署和论文的方法都讲清楚了。最后这部分是真正从坑里爬出来的经验总结。6. 常见问题与避坑指南6.1 环境配置一大半的坑都在这我从做毕设到帮别人调项目环境配置的问题见得太多了。下面这个表格是我根据经验整理的基本覆盖了90%的情况问题原因分析解决方案SpringBoot启动即报错提示Unsupported class file major versionJDK版本太高项目是JDK8编译安装JDK8并在IDEA里切换Project SDK为1.8Maven依赖下载慢或失败默认中央仓库不稳定在Maven的settings.xml里配置阿里云镜像Tomcat started后页面无法访问端口被占用或端口被防火墙拦截检查8081端口是否被占用杀进程释放端口MySQL连接超时或报错时区连接串缺少serverTimezone参数在jdbc连接串里加serverTimezoneAsia/Shanghainpm install报错提示ERESOLVENode版本和依赖锁定版本冲突切换Node到14或16删除node_modules后重装前端能启动但接口
返回列表