ARTICLE DETAIL

资讯详情

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

SpringBoot+Vue打造二手交易系统:从架构设计到毕设落地全解析

SpringBoot+Vue打造二手交易系统:从架构设计到毕设落地全解析 每年毕设季收到最多的咨询就是“学长我想做个二手物品交易网站当毕业论文用SpringBootVue行不行”。这个问题无外乎是因为市面上现成的管理系统选题太多老师看腻了而带交易流程、权限控制、状态流转的项目又刚好能覆盖比较完整的开发链路。这里直接说结论行而且这套组合已经是被无数毕业生验证过的稳妥路线前提是你把架构选型、数据库设计、权限认证、订单状态这几块核心想清楚而不是把代码凑出来就完事。这篇文章主要面向正在准备毕设、需要完成一个可答辩、可演示、可写进论文的二手物品交易系统的同学。我会把整个项目怎么拆、每个关键模块怎么做、哪些地方最容易翻车以及论文和答辩怎么跟代码衔接全部按实际项目推进的顺序捋一遍。看完之后你应该能直接照着落地一个属于自己的完整项目。1. 为什么二手交易系统敢选SpringBootVue这套组合1.1 选型逻辑不是因为它“高级”而是因为它“容错率高”很多同学在选题时纠结要不要上SpringCloud、要不要搞微服务、要不要用Redis做缓存。我的建议是毕设场景下先不要为了炫技而上分布式。二手物品交易系统本质上是“一个带商品、订单、用户的一种多角色信息管理系统”它的高并发、海量数据需求在毕设场景中是不存在的你真正要展示的是“完整闭环”和“合理设计”。SpringBootVue的前后端分离架构正好是当前企业项目的主流形态既能展示你掌握了主流技术栈也能把论文写成“系统设计与实现”的标准范式。SpringBoot的核心优势在于“约定优于配置”。你不需要像老Spring那样写一大堆XML配置文件一个application.yml就可以把数据源、端口、上传大小、日志级别全搞定。内嵌Tomcat也让部署变得简单后端打包成一个Jar直接跑。这对毕设来说非常关键答辩现场的环境千奇百怪依赖越少、启动越简单越不容易当场翻车。Vue这边我用的是Vue 2的成熟版本搭配Element UI而不是Vue 3Element Plus。原因很简单Vue 2的教程数量几乎是Vue 3的三倍以上网上你能搜到的组件用法、踩坑记录绝大多数都是针对Vue 2的。作为一个时间紧张的毕业生你不需要追求“最新”你需要的是“遇到问题能搜到答案”。如果你学有余力、时间充裕选Vue 3TypeScript也可以但如果是赶论文求稳才是第一原则。1.2 前后端分离后的职责边界前后端分离不是简单的“前端一个项目、后端一个项目”就完了难点在“约定接口”。前端是Vue工程负责页面渲染和交互后端是SpringBoot工程只负责提供JSON格式的RESTful接口。两者通过HTTP通信前端的axios发请求后端用RestController接收并返回统一数据结构。在这个项目里角色分工大概是这样的前端负责注册登录页、商品列表页、商品详情页、发布商品表单、个人中心、后台管理页面路由控制权限管理token。后端负责用户认证、商品CRUD、图片上传、订单状态流转、数据统计、权限拦截。比较典型的约定是一个接口规范所有接口路径以/api开头前台接口和后台管理接口用/api/admin和/api/user区分。返回格式统一为{ code: 200, message: success, data: {...} }这样前端拦截器拿到response后统一处理不用每个接口单独判断。1.3 这套组合的“性能天花板”其实没那么低有人觉得SpringBootVue只能做简单系统其实不然。即使后续论文里写“系统响应时间小于200ms”也完全能实现。本项目的核心表通常只有几千条数据量MySQL在加索引的情况下单次查询基本都在几十毫秒级别。压力测试你也只需要写到“用JMeter模拟50并发”这种程度JVM默认配置的Tomcat线程池200个线程处理这个绰绰有余。所以不要被“性能优化”三个字吓住你要做的是把接口层、持久层写得干净合理用上事务、索引、分页这本身就是答辩时可以说的优化点。2. 系统功能模块与数据库设计先想清楚再动手2.1 功能模块拆解别漏掉“卖家”和“管理员”这两个视角很多新手做二手交易系统写完商品列表和下单就以为完事了结果到论文“系统功能结构图”那一步卡壳因为功能太少画不出来。这里建议至少拆出三个角色视角模块就自然丰富了普通用户买家视角注册登录、浏览商品、搜索筛选、收藏商品、下单购买、确认收货、评价、个人资料维护。普通用户卖家视角发布商品、编辑下架商品、查看我的商品列表、处理订单发货、查看交易记录。管理员视角用户管理禁用/启用、商品审核上下架、分类管理、订单监控、统计数据商品数量、用户数量、交易金额。这样拆下来前台和后台管理端就都有了论文里的功能模块图、用例图也都能撑起来。更重要的是这些模块在后端都能对应到具体的Controller层接口写起来不虚。2.2 核心表设计与字段取舍数据库设计是论文里的重头戏评审老师一定会看E-R图和表结构设计。二手交易系统的核心表大概有六张用户表、商品表、商品分类表、订单表、收藏表、留言/评价表。我建议再把“用户地址表”加进去因为交易流程里需要收货地址。用户表t_userid、username、password、nickname、avatar、phone、status0禁用1启用、is_deleted逻辑删除标记、create_time、update_time商品表t_productid、title、description、category_id、priceDECIMAL(10,2)、images用逗号分隔多个图片URL、condition9成新、几乎全新等、seller_id、status0待审核 1在售 2已下架 3已售出、view_count、is_deleted、create_time订单表t_orderid、order_no唯一订单号方便统计和展示、product_id、buyer_id、seller_id、amount、status0待付款 1待发货 2待收货 3已完成 4已取消、address_id、create_time、pay_time、ship_time、confirm_time这里有几个容易偷懒但实际很重要的细节。商品价格字段一定要用DECIMAL不要用double或者float否则金额累计、比较时会出现精度问题这在答辩时被老师问到“为什么金额字段用DECIMAL不动它”会很加分。所有表都要带上逻辑删除标记is_deleted注意这不是硬性需求而是能体现你考虑到“用户误删数据恢复”和“历史订单查询完整性”的场景。2.3 订单状态机把“状态流转”变成答辩亮点订单状态是二手交易系统最容易被人忽视但又最值得展开讲的设计点。很多人的订单表只有一个status字段然后代码里直接用if判断各种情况久而久之逻辑就是一团乱麻。正确做法是先行定义好状态机明确哪些状态能从哪些状态转过来0待付款 - 1待发货买家付款 0待付款 - 4已取消买家取消/超时 1待发货 - 2待收货卖家发货 2待收货 - 3已完成买家确认收货 1待发货 / 2待收货 - 4已取消超时或双方协商取消前端的“订单状态”按钮也全部由这个状态机驱动待付款显示“去支付/取消订单”待发货显示“提醒发货”待收货显示“确认收货”已完成显示“删除订单/评价”。后端在同一处写一个状态流转校验方法凡是非法跳转直接抛业务异常返回“非法状态流转”。这样你在论文“系统设计”章节可以写清楚在答辩时也可以理直气壮地说“订单状态不是随意改的是受状态机约束的”。2.4 常见索引设计别等数据库卡了才想起来给搜索字段加上索引是性价比最高的优化。商品表的category_id、seller_id、status都要建普通索引订单表的buyer_id和seller_id要建索引order_no要建唯一索引。另外商品表的title字段在数据量大时可以建全文索引但毕设一般用LIKE %关键词%模糊查询就够了。注意LIKE %xxx%是走不了普通索引的这一点在论文里写“优化方案”的时候可以提一下然后说“由于毕设数据规模不大采用应用层模糊查询满足需求”这算是一个有思考、有取舍的论述。3. 项目环境准备与认证授权最花时间但回报最高的一环3.1 环境清单与Maven项目构建搞这个项目之前先把环境对齐能避免后面踩一堆版本坑。我的推荐组合是JDK 1.8不要用JDK 17除非你想折腾新语法兼容问题Maven 3.6.3以上MySQL 5.7或8.0Node.js 14.x以上Vue 2项目建议用14或16Node版本过高容易出node-sass编译问题IDE后端用IntelliJ IDEA前端用VS Code后端项目通过Spring Initializr生成即可pom.xml里需要加的核心依赖也就这几个dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-validation/artifactId /dependency dependency groupIdorg.mybatis.spring.boot/groupId artifactIdmybatis-spring-boot-starter/artifactId version2.2.0/version /dependency dependency groupIdcom.baomidou/groupId artifactIdmybatis-plus-boot-starter/artifactId version3.4.3.4/version /dependency dependency groupIdmysql/groupId artifactIdmysql-connector-java/artifactId scoperuntime/scope /dependency dependency groupIdcn.hutool/groupId artifactIdhutool-all/artifactId version5.7.22/version /dependency为什么我加了MyBatis-Plus而不是纯MyBatis很大原因是MyBatis-Plus的BaseMapper自带CRUD方法一张表的基础增删改查不需要写XML能省下大量时间。而且它自带分页插件实现在列表接口里只需要一行代码。毕设项目用MP完全够用不用纠结开发规范。3.2 Spring Security JWT理解Filter链是这章的核心登录认证这块是大部分人的痛点也是最容易在答辩时被追问到底的地方。我用的方案是Spring Security JWT。建议你动手前先把原理理清楚不要只会复制代码。Spring Security的工作机制是一串Filter链。当一个请求进来时它会经过一系列过滤器先做用户密码认证、再判断Session或Token、最后做权限校验。在前后端分离项目中Session天然不适用因为跨域、多端所以我们用JWT来无状态化。流程是这样用户提交用户名密码到/api/login接口。后端用UserDetailsService查数据库BCryptPasswordEncoder负责匹配密码。匹配成功后用jjwt库生成一个带用户ID和用户名信息的Token过期时间设成24小时。前端把Token存到localStorage里在axios的请求拦截器中加到Authorization请求头。后端写一个JwtAuthenticationFilter从请求头里取出Token并解析如果有效就把用户信息放到SecurityContext里放行如果无效就直接返回401。这里核心代码如下你可以直接抄进自己的项目然后逐步理解Component public class JwtAuthenticationFilter extends OncePerRequestFilter { Autowired private JwtUtils jwtUtils; Autowired private UserDetailsServiceImpl userDetailsService; Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { String authHeader request.getHeader(Authorization); if (StringUtils.hasText(authHeader) authHeader.startsWith(Bearer )) { String token authHeader.substring(7); try { String username jwtUtils.getUsernameFromToken(token); if (username ! null SecurityContextHolder.getContext().getAuthentication() null) { UserDetails userDetails userDetailsService.loadUserByUsername(username); UsernamePasswordAuthenticationToken authentication new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities()); authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); SecurityContextHolder.getContext().setAuthentication(authentication); } } catch (Exception e) { // token校验失败则不放行 } } filterChain.doFilter(request, response); } }同时在SecurityConfig里要放行登录接口、商品列表接口、图片访问路径其他都设置成“认证后才能访问”。需要注意很多同学在配置Spring Security拦截规则时把/api/product/detail也拦了导致前端拿不到商品详情这就是“全拦截”和“按需拦截”理解不到位。放行哪些接口取决于项目逻辑例如游客可以浏览商品但不login不能下单。3.3 Vue侧登录态管理与路由权限前端这边登录页提交表单到后端拿Token然后路由守卫生效。Vue Router中写一个beforeEach全局前置守卫判断当前访问的路由是否需要登录权限如果localStorage里没有Token就跳转到登录页。这个方法非常简单但却是整个前端项目里最能体现你“懂认证”的点router.beforeEach((to, from, next) { const token localStorage.getItem(token) if (to.meta.requiresAuth !token) { next({ path: /login, query: { redirect: to.fullPath } }) } else { next() } })axios这边写两个拦截器一个请求拦截器带Token一个响应拦截器统一处理code!200的情况比如Token过期时清空本地存储并跳回登录页。很多同学只做了请求拦截器遇到Token过期问题就只能手动刷新页面这是不完整的。另外发布商品、订单操作这些需要知道“当前登录的用户是谁”的接口最合理的做法不是前端传userId而是后端从Token里解析。前端只负责把Token放到请求头里后端从SecurityContextHolder拿出当前用户这样更安全也更能体现你理解无状态认证。4. 核心业务模块实现商品、订单、收藏的完整闭环4.1 商品发布与图片上传前端组件和后端存储的配合商品发布是二手交易系统最有“业务感”的功能前端需要一个富交互表单商品标题、描述、分类下拉、价格输入、成色选择、图片上传、联系方式。其中图片上传最容易出问题因为涉及跨域、静态资源映射、文件大小限制三件事。我采用的是相对简单的方案前端用el-upload组件把图片传到后端的/api/upload接口后端接收文件后保存到本地磁盘目录然后把访问路径返回给前端前端拿到路径后把它拼到商品images字段里多个图片用逗号分隔。在application.yml里配置静态资源映射让/upload/**路径映射到本地磁盘目录spring: servlet: multipart: max-file-size: 5MB max-request-size: 10MB mvc: static-path-pattern: /upload/** resources: static-locations: file:D:/project/upload/后端上传接口核心就是一个MultipartFile接收并转存PostMapping(/api/upload) public Result upload(RequestParam(file) MultipartFile file) { String originalFilename file.getOriginalFilename(); // 用UUID生成新的文件名防止重名和中文乱码 String newFileName UUID.randomUUID().toString().replace(-, ) originalFilename.substring(originalFilename.lastIndexOf(.)); File dest new File(D:/project/upload/ newFileName); try { file.transferTo(dest); return Result.success(/upload/ newFileName); } catch (IOException e) { return Result.error(文件上传失败); } }注意用UUID重命名文件这是必做的否则两个用户上传同名图片会互相覆盖。我见过不少项目因为不重命名图片一会儿有用一会儿404排查半天发现是文件被后来的上传覆盖了。这个坑具体会在下一章节详聊。4.2 商品列表页分页、搜索、筛选的接口设计商品列表是另一个关键接口。前端首页的搜索框对应后端接口的参数一般是keyword模糊搜索标题、categoryId分类筛选、priceMin和priceMax价格区间、sort排序方式、page和size分页参数。后端用MyBatis-Plus的条件构造器LambdaQueryWrapper来拼查询条件这样逻辑清楚且不容易产生SQL注入。这里有一个很小但很加分的点搜索时把“标题包含关键词”和“商品是否在售”这两个条件一起过滤。很多人会忘记在搜索列表里加status 1的条件导致下架商品还出现在首页。这个状态条件必须出现在所有商品查询上。前端展示时“在售状态”决定是否显示“立即购买”按钮状态为2则按钮变为“已下架”状态为3则显示“已卖出”UI体验完全不一样。4.3 订单状态流转的Controller实现订单模块是交易闭环的核心。代码层面下单动作应该是一个事务操作生成订单记录的同时需要把商品状态改成“待付款”并对同一件商品做并发校验。如果两个买家同时下单同一件商品谁也不希望出现“明明支付成功了商品却被别人买走”的情况。这里的兜底做法是在下单前更新商品状态时加一个条件判断使用MyBatis-Plus的UpdateWrapperboolean update productService.update(new LambdaUpdateWrapperProduct() .eq(Product::getId, productId) .eq(Product::getStatus, 1) .set(Product::getStatus, 0));这个eq(Product::getStatus, 1)是SQL级别的条件判断只有商品状态确实是1时才会更新成功。如果更新影响行数为0说明商品已经被别人下单了直接抛“商品已被拍下”的业务异常。光加if判断是挡不住并发的只有“比较并交换”语义的SQL才能做到。这个做法写进论文比你写十页页面截图都更有含金量。4.4 收藏与“我想要”功能重复数据的唯一索引约束收藏功能看起来简单实际上有一个隐藏难点同一用户不能重复收藏同一商品。前端可以控制按钮状态但后端必须做边界控制。实现方式是在t_favorite表中给user_id和product_id加联合唯一索引。后端先查是否存在记录存在就提示“已经收藏过了”不存在就插入。联合唯一索引的意义在于即使两个请求几乎同时到达数据库层面也会拦住第二条重复记录。类似的思路还可以扩展到防重复提交订单、防重复评价上。这也是答辩时老师喜欢听的细节——你不只是做了一个CRUD而是考虑到了数据一致性。5. 实测中最容易踩进去的几个坑完整排查链路5.1 跨域问题症状在浏览器根源在安全策略这个坑几乎是所有前后端分离项目新手必踩的。表现是前端登录请求发出去了后端日志没有任何打印前端控制台直接报一段CORS error。这很容易让人以为是后端接口写错了但实际是浏览器的同源策略拦住了跨域请求。排查的思路是这样的先打开浏览器的开发者工具Network面板看失败请求的响应头里有没有Access-Control-Allow-Origin这个字段。如果没有那基本可以确认是后端没有配置跨域。Spring Boot的解决方案一般是这样Configuration public class CorsConfig implements WebMvcConfigurer { Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping(/**) .allowedOriginPatterns(*) .allowedMethods(GET, POST, PUT, DELETE, OPTIONS) .allowedHeaders(*) .allowCredentials(true) .maxAge(3600); } }这里要特别注意一个配置组合问题allowCredentials(true)的同时allowedOrigins(*)会失效浏览器不允许在携带凭证模式下使用通配符来源。所以要用allowedOriginPatterns(*)而不是allowedOrigins(*)。这是我当年调试了整整一个晚上才发现的坑贴出来给大家省时间。另外如果你配置了Spring Security还要在SecurityConfig里放行OPTIONS请求因为跨域预检请求就是OPTIONS方法。不配置的话CORS配置写了也会被Security拦截掉浏览器一样报错。这属于“两处配置叠加”才能解决的问题只改其中一处都会无效。5.2 前端拿到的商品ID莫名变了Long精度丢失这个问题的现象是后端返回的商品ID是100001234567前端拿到手却变成100001234000之类的尾数不对。根源在于JavaScript的Number类型只能安全表示2^53-1以内的整数而后端主键一旦超过这个范围JSON序列化的时候就会丢失精度。排查时如果发现数据库里ID是正常的就打开接口的响应体看原始JSON。如果原始JSON里ID已经是错的那就说明是后端JSON序列化时用了默认的Long类型如果原始JSON没问题但前端取值变了那就要检查前端是否有隐式类型转换。后端解决方案是给Jackson配置不让Long转成数字而是转成字符串Bean public Jackson2ObjectMapperBuilderCustomizer jacksonCustomizer() { return builder - { builder.serializerByType(Long.class, ToStringSerializer.instance); builder.serializerByType(Long.TYPE, ToStringSerializer.instance); }; }配置完成后接口返回的ID会变成带引号的字符串前端业务上要传ID时直接把字符串传回去即可。Spring Boot不会强制要求所有ID都这样处理但在实习或真实项目中这属于必改项写在论文里也是标准实践。5.3 图片上传成功但页面无法访问路径映射没配对图片上传失败最常见的情形是上传接口返回200文件也确实保存在磁盘上了但你拿着返回的/upload/xxx.jpg去访问却得到404。这时多半是静态资源映射路径配置和请求路径不匹配。排查步骤第一步看application.yml里的static-locations确认它指向的目录和你代码里transferTo保存的目录是不是同一个。第二步看static-path-pattern如果你配置的是/upload/**那访问路径就必须以/upload/开头。第三步看保存文件时有没有创建目录很多新手直接把文件写到D:/project/upload/但目录根本不存在transferTo不会自动创建父目录直接抛异常。稳妥的写法是上传前先File dir new File(uploadPath); if(!dir.exists()) { dir.mkdirs(); }。还有一个容易被忽略的点是spring.resources.static-locations配置中的路径末尾要加/否则Spring会把它当文件而不是目录。这种问题日志里不会报什么明显错误纯靠细心才能定位。我第一次遇到时以为是无权限问题折腾了很久才在文档里发现这个细节。5.4 登录后接口仍然返回401Token放行路径和认证顺序的问题我自己在测试环境遇到过一次诡异的故障单独请求登录接口没问题单独请求商品列表也没问题但在网页上先后调用登录和商品列表接口商品列表却始终401。排查后发现了嵌套原因。第一步看后端日志发现JWT过滤器的日志根本没打印说明这个Filter压根没被Spring Security加载。为什么没加载因为我的SecurityConfig里只配置了一个addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class)但整个Security的FilterChain如果有任何一个环节直接拦截并返回401后续Filter就不会执行。第二步看Security的拦截规则发现我放行了/api/login和/api/product/**但是并没有对前端实际请求的Origin、Headers做处理。第三步回头检查CORS配置发现CORS和Security的Filter顺序有冲突最终需要在SecurityConfig里显式启用.cors()让CORS在Security认证之前执行。这是个“多个过滤器叠加导致行为不一致”的典型案例。最后的教训是凡是给项目加了Spring Security跨域和请求放行必须同时在SecurityConfig和CORS配置中处理两边缺一不可否则接口行为就不符合直觉。5.5 前端修改商品状态后列表刷新混乱状态与缓存的同步最后一个比较常见但不太容易直接联想到代码的问题商品发布成功后如果只push一条数据到列表前端而不重新查询后端的最新状态就会出现列表状态与后端不一致。比如你把一个商品下架了但前端列表还是显示“在售”。这个不是技术难点而是设计习惯。我的做法是所有修改商品状态的接口前端一律重新调用列表接口刷新数据不手动维护前端状态。尤其在订单流程里支付成功后还要重新拉取订单详情和商品详情这样才能确保页面展示和数据库一致。这些坑都不算深但每一个都真实地浪费过我大量时间。写成这章是为了让你在动手之前就有心理准备碰到对应现象时能少走弯路。6. 论文写作与答辩准备的衍生工作6.1 论文目录怎么搭让目录结构体现系统完整性有了代码以后论文结构其实有相对固定的模板可以参考但不要全抄网上模板要按自己代码的实际模块来填。这里给一个可以直接套的骨架绪论背景与意义、国内外研究现状、主要工作相关技术介绍SpringBoot、Vue、MySQL、JWT逐个介绍并说明为什么选它系统分析可行性分析、需求分析、用例分析、功能模块结构系统设计总体架构图、E-R图、数据库表结构、接口设计、状态机设计系统实现前端页面截图后端核心代码片段按前台和后台分开写系统测试测试环境、功能测试用例表、部分性能测试结果总结与展望6.2 论文里必须有哪几张图提前准备别临时画评审老师大概率会快速翻图所以图的质量直接影响观感。至少需要有这几张图系统总体架构图展示前端Vue、后端SpringBoot、数据库MySQL这三层关系。系统功能结构图按角色把功能模块画成树状图。用例图画出三种角色各自能做什么每个角色至少5-6个用例。E-R图展示核心实体之间的关系。用MySQL Workbench自带的反向工程生成实体关系图再手工调整一下就很专业。订单状态流转图这个最能体现设计感。部分关键接口调用时序图比如下单流程。画图工具推荐用ProcessOn或者draw.io前者在线方便后者免费且能导出高清图。别用Word里自带的形状硬拼排版极易错乱还没法后期统一调整。6.3 “创新点”别硬编把细节打磨成亮点很多同学在论文最后写创新点时只会写“界面友好、提高了效率”这类空话。其实你的项目里已经有好几个细节比“界面友好”更有价值基于JWT的无状态认证方案前后端分离下的安全控制。基于SQL级条件更新的并发控制防止一件商品被重复下单。订单状态机的设计与落地统一管理订单流转规则。图片文件上传的规范化处理包括UUID重命名与静态资源映射。这些虽然不是什么前沿技术但在本科生的项目范畴里已经是合格的设计。写创新点时不要写“我用了最新技术”而是写“我在什么场景下解决了一个什么实际问题采用了什么方案”。有具体场景、有具体方案老师一看就知道你确实做过这个项目。6.4 答辩常见提问与应对思路答辩前给自己准备一个“问题清单”把最容易被问的问题写下来背熟。比如系统有哪些角色各角色能做什么订单各状态之间的流转是怎样的如果两个人同时下单怎么办密码加密用什么算法JWT和Session有什么区别分页是怎么实现的为什么用MyBatis-Plus前端路由守卫是什么图片存到本地为什么不用OSS这些问题的答案在代码里都能找到你要做的就是用自己的话复述出来。还有一个小技巧演示环节尽量用自己电脑提前把所有服务启动好关掉弹窗提示。答辩现场最怕的不是答不上来而是“项目环境崩溃”。你可以提前准备一个兜底方案在手机热点下也测试过系统能正常访问以防现场WiFi依赖连不上数据库。总之论文和代码只是一部分答辩时的从容和逻辑清晰同样重要。7. 最后说点我自己的体会做类似的项目这几年下来最大的一个体会是不要等所有技术细节都懂了再动手要边做边学。你完全可以先搭一个能跑通“注册登录-发布商品-下单”的最小闭环然后再逐步把收藏、评价、统计功能往上加。很多问题尤其是跨域和Long精度丢失不是你看文档能提前预防的只有亲手踩一次才能对它留下深刻印象。如果你现在连项目骨架都还没有搭起来建议你先花一个下午把后端的基础CRUD和前端登录注册跑通哪怕UI简陋一点也没关系。系统一旦能跑起来之后每加一个功能都是正反馈你会越写越有底气。到后期可以考虑把前端打包后的dist目录放进SpringBoot的静态资源目录实现一个Jar包同时启动前后端这样部署时只需要一个Java进程演示也更方便。这也是一个可以写进论文“部署方案”的加分项。
返回列表