资讯动态

SpringBoot+Vue运动服装销售系统:前后端分离电商项目实战解析

发布时间:2026/10/13 6:01:32 来源:尧图企业网站定制
做电商类的毕设或者练手项目SpringBoot加Vue这套组合基本是绕不开的。今天要聊的这款运动服装销售系统正好是这个技术栈里比较典型的一个后端SpringBoot负责业务逻辑和数据处理前端Vue负责页面交互和界面渲染数据走MySQL整体是一套完整的前后端分离电商类项目。系统围绕运动服装这个品类把商品展示、分类检索、购物车、下单流程、后台商品管理、订单管理这些核心模块都做了既可以直接当毕业设计选题来用也可以拿来当作自己学习前后端分离开发流程的参考范本。如果你正在找一套结构清晰、资料齐全的JavaWeb项目来跟代码、理解思路或者需要一套能改改就用、能讲清楚设计亮点的选题这篇文章值得看完。1. 项目整体设计与技术选型思路1.1 为什么是SpringBootVue这对组合先说后端。SpringBoot这几年在Java后端项目里的统治力没什么好争议的它把Spring那一套繁琐的XML配置全部干掉用自动配置和内嵌容器把项目启动成本压到极低。对毕设或者个人练手来说最直接的好处是你不用花大量时间在处理Tomcat部署、Spring配置这些环境问题上打开IDE、写个启动类项目就能跑起来。而且SpringBoot生态里的starter机制非常成熟接MyBatis、接Redis、接文件上传都是引入一个依赖、加几行配置的事学习成本友好答辩的时候也容易讲清楚原理。前端选Vue的原因更简单它在国内中小型项目里的普及率太高了组件化开发、双向绑定、虚拟DOM上手曲线比React平滑很多配合Element UI或者Element Plus这类组件库两天时间就能把管理后台的界面搭得像个样子。对于销售系统这种页面类型固定、交互偏CRUD的项目Vue的模板语法和组件复用机制简直是为它量身定做的。再说回业务本身。运动服装销售系统本质上是一个垂直电商系统业务链路是用户浏览商品→加入购物车→生成订单→后台发货管理再加上后台的商品维护、分类管理、会员管理。这类业务用前后端分离架构非常合适前端专注页面展示和交互体验后端专注接口和数据处理两边通过JSON格式的RESTful接口通信。实际开发中也可以把前端页面拆成用户端商城和管理后台两个部分复用同一套后端接口这也是这类项目展示设计能力的一个加分项。1.2 功能模块与业务逻辑拆解这类销售系统的功能模块看起来多但归纳起来就是两条线用户购物线和后台管理线。用户购物线包括注册与登录账号密码注册登录登录后获取Token后续请求携带Token访问受限接口商品浏览首页推荐、分类筛选、商品详情查看购物车管理加入购物车、修改数量、删除、勾选结算订单流程确认订单、生成订单、在线支付模拟、查看订单状态个人中心我的订单、收货地址、个人信息修改后台管理线包括管理员登录与权限校验商品管理商品的增删改查、上下架、库存调整、图片上传分类管理商品分类的维护支持一级分类或两级分类订单管理订单列表筛选、发货操作、查看订单明细用户管理用户列表、禁用/启用账号数据统计简单的销售数据统计比如订单量、销售额曲线这个功能划分是标准的毕设级电商系统粒度。做的时候我的建议是不要一开始就想着把功能堆满先把主链路打通——从商品列表到下单成功这是一条完整闭环链路通了之后再往后台加管理功能最后有余力再补统计、补营销工具。很多同学喜欢先做登录、先做后台结果核心购物流程反倒赶工答辩时被问几个业务细节就露馅了。1.3 数据库设计要点数据库设计是这类项目里最值得花时间的地方因为面试和答辩都喜欢问表结构、表关系。核心表我列一下表名核心字段说明userid, username, password, nickname, phone, avatar, role, status用户表role区分普通用户和admincategoryid, name, parent_id, sort分类表parent_id为0表示一级分类productid, category_id, name, subtitle, main_image, detail_images, price, stock, sales, status商品表status控制上下架cartid, user_id, product_id, quantity, checked购物车表ordersid, order_no, user_id, total_price, status, receiver_name, receiver_phone, receiver_address, create_time, pay_time, ship_time订单主表order_itemid, order_id, product_id, product_name, product_image, price, quantity订单明细表冗余商品快照几个关键点一是订单表要拆成主表和明细表。一个订单包含多个商品如果不拆相同订单号要重复存多次收货信息数据库冗余严重。明细表里为什么要冗余商品名称和图片因为商品信息后续可能改名字、换图片但历史订单必须保持下单时的快照这是电商系统的常识。二是商品表的库存字段和销量字段。库存字段是必须的下单时要扣减库存销量字段可以没有但是加上之后做热卖排行非常方便只是需要在订单生成时做同步更新事务里一起处理。三是status字段的语义要统一。比如商品status1上架、0下架订单status0待付款、1待发货、2已发货、3已完成、4已取消。用数字还是用字符串我建议用数字因为前端做筛选和状态标签映射比较方便代码里用一个常量类或者枚举统一管理避免魔法数字满天飞。2. 核心功能模块的细节与实现关键2.1 登录鉴权方案JWT还是Session这是一个很值得展开的技术点也是答辩时老师大概率会问的问题。早期单体项目用Session比较普遍用户登录后后端把登录态存在Session里返回一个JSESSIONID给前端前端请求时带上这个Cookie。如果前端是服务端渲染的页面这套方案完全没有问题。但到了前后端分离场景问题就来了前端和后端可能不在同一个域名下跨域请求对Cookie的限制比较麻烦而且后端如果做成集群Session复制又是一个额外的工作量。所以现在前后端分离的毕设项目绝大多数用JWTJSON Web Token。JWT的思路是用户登录成功后后端生成一个包含用户ID、用户名、过期时间等信息的加密Token返回给前端前端把它存在localStorage或者vuex里每次请求在请求头里加上Authorization: Bearer xxx后端通过拦截器解析Token得到当前登录用户校验通过就放行。这套方案的好处是后端不需要存储Token天然支持多实例部署跨域也方便。代价是Token无法主动失效所以通常会设置一个过期时间比如2个小时前端在请求拦截器里发现Token过期就跳转登录页。实现上很简单后端引入jjwt依赖写一个JwtUtil工具类提供生成Token和解析Token的方法写一个拦截器拦截需要登录的接口路径从请求头取Token解析失败就返回401前端在axios请求拦截器里统一设置Token请求头在响应拦截器里统一处理401跳转登录页有几个细节需要提醒Token里不要放敏感信息。有的同学图方便把密码也放进Token里这是很不好的习惯Token虽然带签名但也只是Base64编码是可解开的。前端Token的存储位置localStorage刷新不丢但XSS攻击能读到用HttpOnly Cookie更安全但实现稍复杂。毕设场景用localStorage完全够但答辩时如果能主动说出这个取舍会显得你对安全问题有思考。2.2 商品与分类的数据设计商品和分类是销售系统最容易做糙的地方很多方案把分类做死商品字段也随意导致后期扩展困难。分类我这里推荐的两级结构一级分类比如上衣、裤装、运动鞋、配件二级分类比如上衣下面再分T恤、卫衣、外套。表结构上就是category表里加一个parent_id字段parent_id为0的就是顶级分类。查询某个分类下的商品时先查该分类及子分类的ID集合再做商品查询。这个设计既简单又能体现树形结构的思路比单级分类扩展性好比无限极分类实现成本低很适合这个项目。商品表里interaction比较大的是图片字段。一张主图、多张详情图怎么存储方案一是在product表里存一个主图URL字段再加一个product_image子表存详情图这是最规范的。方案二是偷懒一点主图字段存一个URL详情图片用逗号拼接存到一个字段里查询时用split拆开。毕设项目用方案二完全没问题因为详情图数量少、很少单独维护但需要在代码里写一个图片列表的转换方法别在页面里去处理逗号字符串。另外一个常见的坑是商品价格用浮点类型。Java后端用float或者double算金额比较时容易出现精度误差比如0.10.2不等于0.3。规范的方案是用BigDecimal尤其是涉及订单总价计算时。MySQL端对应字段用decimal(10,2)。这个细节如果能在设计说明里写一句金额使用BigDecimal避免精度丢失那专业度一下子就上来了。2.3 购物车与订单流程购物车模块看起来简单其实有几处容易掉坑的逻辑。一是购物车表要不要冗余商品信息。我的答案是不要存商品名称、图片、价格购物车表只存user_id、product_id、quantity、checked就够了。页面展示购物车列表时通过商品ID去查商品表拿商品的最新信息。因为购物车是临时的商品改价后用户看到的应该是当前价格所以冗余反而会造成数据不一致。二是商品加入购物车时的数量校验。很多方案没做库存校验用户添加100件也直接入库等到下单才报错体验很差。我的建议是加入购物车时就校验一次库存下单时再校验一次双重保障。订单流程建议做成一个严格的状态机0待付款 → 1待发货 → 2已发货 → 3已完成 → 4已取消用户提交订单时如果状态是待付款可以取消管理员发货后状态变为已发货不能再取消用户确认收货后变为已完成已完成的订单不能退款毕设可以不写退款逻辑但状态要占位。下单这个动作是整个系统里最需要事务的环节。一次下单涉及的数据库操作有插入订单主表、插入订单明细表、扣减商品库存、增加商品销量。任何一个操作失败都必须整体回滚不然就会出现订单建了但库存没减这种严重问题。后端实现时在Service方法上加Transactional注解默认遇到RuntimeException就会回滚这个必须会用。还有一个稍微进阶的操作防止重复提交订单。用户快速点两次提交订单可能生成两笔相同订单。简单的处理方式是前端按钮加loading禁用但严谨一点后端可以在订单表加一个用户ID和时间的幂等判断或者在下单前查询一下是否有相同用户、相同金额、相同商品且时间相近的未支付订单。这个算是加分项量力而行。2.4 文件上传与图片处理商品图片上传是管理后台必须的功能。SpringBoot里用MultipartFile接收前端上传的文件默认大小限制是1MB一般商品图片肯定超所以要在配置文件里调大spring.servlet.multipart.max-file-size10MB spring.servlet.multipart.max-request-size50MB存储路径有两个方向。一个是本地存储把上传的文件写到项目运行目录下的upload文件夹同时配置一个静态资源映射路径让图片可以通过URL直接访问。另一个是对象存储比如国内的七牛云、阿里云OSS把文件传到云上拿到一个CDN链接。毕设项目推荐本地存储简单可控不涉及第三方SDK和付费问题但如果你想让项目方案更完整可以在设计文档里对比一下两种方案说明企业级生产环境下应该使用对象存储本地存储仅用于开发环境这就是一个很好的答辩话术。本地存储的静态映射配置示例Configuration public class WebMvcConfig implements WebMvcConfigurer { Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler(/upload/**) .addResourceResolver(new PathResourceResolver()); } }写路径时要注意Windows下用D:/xxx/upload/Linux下用/usr/local/upload/开发时最好把路径配到配置文件里不要把绝对路径写死在代码中不然换一台电脑项目就崩了。另外上传的文件名一定要处理一下。用户上传的原始文件名可能是中文可能包含特殊字符直接拼接路径很容易出问题。常用的办法是用UUID或者时间戳生成新文件名保留原始后缀名比如String filename UUID.randomUUID().toString().replace(-, ) originalFilename.substring(originalFilename.lastIndexOf(.));这样处理后文件命名唯一还能保留图片格式。3. 从搭建到部署的完整实操记录3.1 环境准备清单先把环境捋一遍。我建议的版本组合是工具版本建议说明JDK1.8 或 11如果你是SpringBoot 2.x1.8完全够如果是SpringBoot 3.x必须JDK 17Maven3.6.3后端依赖管理IDEA内置也可以MySQL5.7 或 8.0数据库推荐8.0Node.js14.x 以上前端运行环境Vue CLI 5要求Node 12推荐14或16前端脚手架Vue CLI 4/5也可以直接用Vite创建Vue 3项目这里有个版本兼容性提醒很多同学项目跑不起来不是代码问题是版本错配。比如用了SpringBoot 2.7又配上MyBatis-Plus 3.5的旧版本或者用Node 18跑Vue CLI 4的依赖树容易出现奇奇怪怪的报错。我的建议是后端如果参照网上的教程用SpringBoot 2.x那就别去动MySQL 8以下的驱动版本前端如果用Vue 2配Element UI就不要混着装Element Plus的组件组件库版本错乱是前端报错的重灾区。3.2 后端项目的搭建流程后端环境准备好之后用IDEA的Spring Initializr创建项目或者直接去官网start点一下生成zip下载导入。核心依赖我列一份dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency dependency groupIdcom.baomidou/groupId artifactIdmybatis-plus-boot-starter/artifactId version3.5.3.1/version /dependency dependency groupIdmysql/groupId artifactIdmysql-connector-java/artifactId scoperuntime/scope /dependency dependency groupIdio.jsonwebtoken/groupId artifactIdjjwt/artifactId version0.9.1/version /dependencyMyBatis-Plus算是国内毕设项目的事实标准了好处是你不用写一大堆Mapper XMLBaseMapper提供单表CRUD方法分页用分页插件Demo里需求基本上靠条件构造器就够了。如果你对MyBatis原生写法更熟悉也可以不用MP手写XML代码量会多一些但对于学习价值来说更高。后端代码的分层结构要规范Controller-Service-Mapper三件套是底线再往上是entity、dto、vo、config、common、utils这几个包。我见过不少同学的代码所有类都堆在一个包下几百行一个Service类虽然功能能跑但答辩时老师问你分层分在哪了会很尴尬。一个标准的商品列表接口大概是这样的Controller层RestController RequestMapping(/api/product) public class ProductController { Autowired private ProductService productService; GetMapping(/list) public Result list(RequestParam(defaultValue 1) Integer pageNum, RequestParam(defaultValue 8) Integer pageSize, RequestParam(required false) Long categoryId) { return Result.success(productService.getProductPage(pageNum, pageSize, categoryId)); } }Service层public PageProduct getProductPage(Integer pageNum, Integer pageSize, Long categoryId) { LambdaQueryWrapperProduct wrapper new LambdaQueryWrapper(); wrapper.eq(Product::getStatus, 1); if (categoryId ! null) { wrapper.eq(Product::getCategoryId, categoryId); } wrapper.orderByDesc(Product::getSales); PageProduct page new Page(pageNum, pageSize); return productMapper.selectPage(page, wrapper); }这里有几个容易被忽略的点Result统一返回体。很多同学每个接口都返回不同的结构前端写得很痛苦。建议写一个泛型Result类所有接口都返回Result.success(data)或者Result.error(msg)里面有code、msg、data三个字段。前端只用判断code是不是200代码会清爽很多。分页参数和返回结构的规范。前端传pageNum和pageSize后端返回total、pages、records等内容这也是约定俗成的分页规范不要自己发明格式。商品列表查询时优惠的是只查上架商品。如果后台下架了一件商品用户端列表里就不应该再出现它所以查询条件里加status1这是一个非常容易漏掉的逻辑。3.3 前端项目的搭建流程前端用Vue CLI创建一个基础项目然后按需引入Element UIVue2或者Element PlusVue3。项目结构建议这样src/ ├── api/ # 接口封装 ├── assets/ # 静态资源 ├── components/ # 公共组件 ├── router/ # 路由配置 ├── store/ # vuex状态管理 ├── views/ # 页面 │ ├── admin/ # 后台管理页面 │ └── user/ # 用户端页面 ├── utils/ # 工具函数 └── App.vueaxios封装是前端工程质量的分水岭。很多同学在每个页面里直接写axios.get代码重复不说改一个baseURL要全局搜索替换。我的做法是先在utils/request.js里建一个实例import axios from axios const request axios.create({ baseURL: /api, timeout: 10000 }) // 请求拦截器添加token request.interceptors.request.use(config { const token localStorage.getItem(token) if (token) { config.headers.Authorization Bearer token } return config }) // 响应拦截器统一处理错误 request.interceptors.response.use( response response.data, error { if (error.response error.response.status 401) { localStorage.removeItem(token) window.location.href /login } return Promise.reject(error) } ) export default request然后每个接口模块一个文件比如src/api/product.jsimport request from /utils/request export function getProductList(params) { return request.get(/product/list, { params }) }页面里调用时就很清爽了getProductList({pageNum:1, pageSize:8}).then(...)。商品列表页面的核心逻辑无非是页面加载时调接口拿数据渲染列表点击分类时带分类ID重新请求分页组件切换时更新查询参数。这里面有个小技巧搜索关键词和分页参数要用响应式数据统一管理每次变化时调用同一个加载方法而不是在三个地方各写一遍请求代码。3.4 联调、打包与部署本地联调阶段最大的问题就是跨域。开发时最简单的处理方式前端在vue.config.js里配置代理把/api开头请求转发到后端地址module.exports { devServer: { proxy: { /api: { target: http://localhost:8080, changeOrigin: true } } } }这样前端请求/api/product/list实际转发到后端的/api/product/list开发环境下不存在跨域问题因为浏览器看到的是同源请求。后端也可以开启CORS配置两种方式都行。我的建议是只在开发环境开代理后端不要全局开启CORS因为生产环境下前端和后端通常是同域部署或者经过Nginx转发后端的CORS配置反而会有隐患。打包部署是比较容易出问题的一步这里给出一个亲测可用的方案后端打包mvn clean package得到target目录下的jar包用java -jar xxx.jar启动。注意内置Tomcat默认端口是8080如果被占用了可以加--server.port9090指定。前端打包npm run build产出dist目录里面是编译后的静态文件。生产环境的部署方式有两种方式一单体部署把Vue的dist目录放到后端项目的src/main/resources/static目录下重新打包这样一个jar里同时包含后端接口和前端页面直接java -jar启动后访问本机IP加端口就是完整系统。这种方式部署最简单适合交作业演示。方式二前后端分离部署。后端jar单独跑在8080前端dist目录交给Nginx托管Nginx监听80端口请求/api开头的路径转发到后端。这种方式更贴近生产配置也不复杂location /api/ { proxy_pass http://localhost:8080/; } location / { root /usr/share/nginx/html; index index.html; try_files $uri $uri/ /index.html; }最后一行try_files很关键它解决的是前端路由刷新404的问题后面会展开讲。4. 常见问题与排查技巧实录4.1 跨域问题跨域报错大概是你做前后端分离项目第一个遇到的拦路虎。浏览器控制台出现No Access-Control-Allow-Origin header is present不用慌张这就是前端页面在3000端口后端在8080端口两个端口不同就产生了跨域。解决方案前面提到了开发环境用前端代理生产环境用Nginx反代。但还有一个临时应急的办法就是后端加一个CORS配置类Configuration public class CorsConfig { Bean public CorsFilter corsFilter() { CorsConfiguration config new CorsConfiguration(); config.addAllowedOriginPattern(*); config.addAllowedMethod(*); config.addAllowedHeader(*); config.setAllowCredentials(true); UrlBasedCorsConfigurationSource source new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration(/**, config); return new CorsFilter(source); } }这段配置开发时很好使但生产环境我仍然建议关掉它原因前面已经说了。有一个隐蔽的坑如果后端用了拦截器跨域预检请求OPTIONS会被拦截器拦截掉导致CORS配置失效。遇到这种情况在拦截器里放行OPTIONS请求即可。4.2 前端路由刷新404这是Vue路由的一个经典坑。前端用了Vue Router的History模式URL看起来是http://localhost:8080/#/home这种刷新是按http://localhost:8080/product/1这种模式访问的。开发环境一般不会出问题因为webpack-dev-server默认支持history fallback。但部署到Nginx后就露馅了用户在首页点击跳转没问题因为这是前端路由所有页面切换都是前端控制的浏览器地址栏有反应但不发送真实请求可是用户按F5刷新浏览器就会向服务器发起一个对/product/1的请求Nginx发现没有这个文件直接返回404。解决办法就是在Nginx配置里加try_files指令把所有的路由请求都指向index.html由前端路由去解析location / { root /usr/share/nginx/html; index index.html; try_files $uri $uri/ /index.html; }如果是SpringBoot单体的部署方式则要在后端加一个ForwardController把所有非接口的请求转发到index.htmlController public class ForwardController { RequestMapping(value {path:[^\\.]*}) public String forward() { return forward:/index.html; } }4.3 数据库连接与中文乱码数据库连接串里最经典的两个参数是useSSL和serverTimezone。如果用MySQL 8.0连接串建议这样写jdbc:mysql://localhost:3306/sport_shop?useUnicodetruecharacterEncodingutf8useSSLfalseserverTimezoneAsia/ShanghaiserverTimezone这个参数不写通常报server time zone value错误因为MySQL 8.0默认时区设置和中国不一样。用useSSLfalse是因为本地开发用SSL加密连接没有意义反而会产生告警。中文乱码问题分三层排查第一层是数据库表的编码。建表时指定utf8mb4这是兜底。第二层是后端接口返回的中文乱码。SpringBoot默认就会把响应用UTF-8编码一般不会出问题。重点检查的是数据库驱动连接串有没有带characterEncodingutf8。第三层是前端页面显示乱码。检查HTML文件的meta标签确认charset是utf-8。从MySQL看拷贝一张表到项目里时最容易出现乱码因为原库可能用了latin1或gbk。解决方法是建库时显式指定字符集CREATE DATABASE sport_shop DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;4.4 图片上传成功了但页面看不到图片这个问题高发。图片传上去了数据库里也存了路径但浏览器访问图片路径是404。原因通常是后端没做静态资源映射。SpringBoot默认只映射classpath:/static/作为静态资源目录如果你把图片写到D:/upload/这种外部目录不配置映射是访问不到的。解决方案前面已经写过WebMvcConfig注册/addResourceHandler(/upload/)映射到本地磁盘路径。这里提醒一个细节映射路径不要写成/upload/而存储目录是upload/相对路径这样在打包成jar后运行会上很多坑因为jar内部结构不是普通文件系统。我建议统一使用本地磁盘的绝对路径比如D:/project/upload/映射到/upload/**这样开发、部署后都稳定。第二个常见原因是权限/跨域问题特别是前后端分离部署的时候后端接口返回的是类似http://localhost:8080/upload/xxx.jpg的地址前端页面在80端口图片请求8080端口又产生了跨域需要后端对图片接口也能处理跨域或者通过Nginx转发。4.5 登录状态丢失Token登录模式下最常见的登录状态丢失是这么发生的用户登录成功跳转页面刷新一下或者重新打开浏览器发现又回到登录页了。排查方向有一个确认Token存哪里。如果用了localStorage刷新不会丢如果用了vuex刷新就清空。很多同学把Token从接口返回后存到vuex里然后忘记同时写一份到localStorage结果页面一刷新vuex重新初始化Token就没了。另一个方向是时间问题。后端设置的Token过期时间太短比如30分钟模拟支付用户隔一会儿再操作就提示登录过期。毕设项目建议Token有效期设置成2小时或者更长省得演示到一半跳登录页这种尴尬情况。如果要做到关闭浏览器后仍保持登录可以把Token存到localStorage并在axios拦截器里每次请求都带上它。如果要更严谨一些后端做token续期前端拦截每个请求的响应如果token快过期就自动刷新不过这是加分项不是必修项。4.6 端口占用与Maven依赖下载慢启动项目报Port 8080 was already in use是最容易解决的Windows下用netstat -ano | findstr 8080查占用进程然后taskkill /PID 进程号 /F或者直接换端口启动。Maven依赖下载慢的根源是默认中央仓库在国外。解决方法是修改Maven的settings.xml加一个国内镜像源这一点对国内开发者来说几乎是必做操作。换完镜像之后新项目导入依赖的速度肉眼可见地提升。还有一个小坑MyBatis-Plus 3.5以上版本分页插件需要单独配置一个分页拦截器bean不配置的话分页查询不会真正生效返回的数据是全量而非当前页。这是很多人写完后发现明明分了页怎么数据不对的原因Configuration public class MybatisPlusConfig { Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); return interceptor; } }5. 写在最后的几点实操心得这个运动服装销售系统看着是一个典型的JavaWeb毕设项目但把每个细节做好、讲清楚其实能体现出不少工程素养。我自己的体会是做这类项目最忌讳的是重代码轻设计拿到一个Demo就开始抄界面抄完了数据库表和接口为什么这么设计完全说不上来。答辩时老师不太会去抠你某个页面布局更多会问你表为什么要拆成两张、下单时库存怎么扣、Token过期了怎么办、跨域怎么处理、分页怎么实现的。这些问题你一旦自己动手写过、踩过坑、修过Bug回答起来跟背出来的感觉是完全不一样的。另外一个很实际的建议整套项目除了源码配套的论文、部署文档和讲解视频最好自己通读一遍改动代码前先在文档里标出对应的模块因为答辩现场可能不允许完全照搬别人写的东西有时候问你一个这里为什么这么写如果你连文档里是怎么描述的都答不上来就非常难圆场。如果你打算拿这个项目做二次开发我建议优先把这几块做升级商品搜索模块目前很多基础版本只有分类筛选加上关键词模糊搜索就能覆盖不少场景、订单的物流跟踪用一个物流单号字段加状态即可、数据看板把统计报表做成可视化图表。这三个方向投入产出比高并且都能在答辩时讲出我做了什么、解决了什么问题。最后再分享一个小技巧开发时把数据库的表结构文档、接口文档、部署步骤三份文档整理好放一起每完成一个模块就把对应的SQL字段、接口调用数据、验证结果记录下来。等最后写论文和做演示的时候你会感谢自己当时的记录习惯。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑