简介:本资源是一套完整的高分本科毕业设计项目——乐乐农产品销售系统,面向计算机、软件工程等专业学生,解决电商类课程设计、期末大作业及毕设选题落地难的问题。压缩包含871个文件,总大小27.67MB,涵盖137个Java后端源码、69个Vue前端组件、161个JS交互逻辑、57个HTML页面、52个CSS样式及162个SVG图标,辅以MySQL 8.0数据库脚本(SQL)、Maven构建配置(XML/YML)、批处理部署脚本(BAT)及论文文档(DOCX),结构清晰、模块完整。已有296人学习下载,所有代码经导师指导与多轮调试,确保在IDEA+Navicat+Tomcat环境下开箱即用。读者可直接部署运行,掌握Spring Boot+Vue前后端分离开发全流程,深入理解农产品电商系统的商品管理、订单处理、用户中心等核心模块实现,并获得配套论文用于答辩与技术复盘。
1. 项目概述与核心价值
最近几年,我身边不少学弟学妹在做毕业设计时,都倾向于选择“农产品销售系统”这个方向。这确实是个好选题,它紧贴乡村振兴和电商下沉的热点,技术栈又涵盖了Java后端、Vue前端和MySQL数据库,非常能体现一个计算机专业学生的综合能力。但我也发现,很多人拿到类似“乐乐农产品销售系统”这样的源码包后,往往一头雾水,不知道从何下手去理解、修改和运行,更别提基于它做出自己的创新了。今天,我就以一个过来人和面试官的双重身份,来深度拆解一下这类项目的里里外外,不仅告诉你它是什么,更要讲清楚为什么这么设计,以及如何把它变成一个真正能为你加分的作品。
简单来说,一个典型的“Java+SpringBoot+Vue+MySQL农产品销售系统”,其核心就是一个B2C的电商平台。它模拟了从农户或供应商上架商品,到消费者浏览、下单、支付,再到后台管理员处理订单、管理用户的完整业务流程。这个项目的价值在于,它麻雀虽小,五脏俱全:用SpringBoot快速搭建了稳健的后端服务,用Vue构建了交互流畅的前端界面,用MySQL持久化存储所有业务数据。对于毕业生而言,吃透这个项目,意味着你不仅掌握了CRUD(增删改查),更理解了用户认证、权限控制、商品库存管理、订单状态流转等电商核心模块的设计思想,这在面试中是非常扎实的筹码。
2. 系统整体架构与设计思路拆解
2.1 技术选型背后的逻辑
为什么是Java + SpringBoot + Vue + MySQL这个“黄金组合”?这绝不是随意拼凑,而是经过市场检验的、最适合快速开发中小型Web应用的技术栈。
首先看后端。Java的稳定性和强大的生态是工业级应用的首选。而SpringBoot则是Spring框架的“一键启动”版,它通过自动配置和起步依赖,极大地简化了Spring应用的初始搭建和开发过程。对于毕业设计这种需要快速产出、且要保证一定代码质量的项目来说,SpringBoot能帮你省去大量繁琐的XML配置,让你更专注于业务逻辑。比如,内嵌的Tomcat服务器让你不用单独部署,一个main方法就能启动整个后端服务。
前端选择Vue.js,主要是看中了它的渐进式特性和上手速度。相比于React和Angular,Vue的学习曲线更平缓,其声明式渲染和组件化开发的思想,能让你高效地构建出用户友好的单页面应用(SPA)。对于农产品销售系统这种需要频繁进行商品列表渲染、表单提交、状态切换的前端场景,Vue的数据驱动视图模式非常合适。
数据库选用MySQL几乎是毋庸置疑的。作为最流行的开源关系型数据库,它免费、稳定、社区活跃,对于交易型系统(涉及订单、支付)来说,其ACID事务特性保证了数据的一致性。农产品销售系统中的库存扣减、订单创建必须是原子操作,MySQL的事务支持能很好地满足这一点。
这个技术栈的分层是清晰的:Vue负责用户看到和交互的视图层;SpringBoot构建的业务逻辑层(Service)和处理HTTP请求的控制器层(Controller)是核心;MySQL作为数据持久层。它们之间通过RESTful API(前后端分离)或模板引擎(如Thymeleaf,但本项目更可能是前后端分离)进行通信。
2.2 核心业务模块设计
一个完整的农产品销售系统,其业务模块可以抽象为以下几个核心部分,理解这些模块的关联是读懂源码的关键:
- 用户模块:这是系统的基石。通常分为普通用户(买家)、农户/供应商(卖家)、系统管理员三种角色。设计上会有一张
user表,通过一个role字段或关联的角色表来区分权限。Spring Security或Shiro这类安全框架常被用来管理登录、授权和会话。 - 商品模块:对应农产品。核心表是
product,字段至少包括ID、名称、分类ID、价格、库存、图片、详情描述、上架状态、创建时间等。这里的关键是分类管理(多级分类)和库存管理(防止超卖)。 - 购物车与订单模块:这是电商系统的核心流程。
cart表临时存储用户的选购意向,order表记录一笔完整的交易,order_item表则记录订单中的具体商品项(与order是一对多关系)。订单的状态机设计(如:待付款、待发货、已发货、已完成、已取消)是重点和难点。 - 支付模块:毕业设计中为了简化,常模拟支付流程,即用户点击“支付”后,订单状态直接变为“已付款”。但在更完整的项目中,会集成支付宝、微信支付的沙箱接口进行演示。
- 后台管理模块:这是给管理员使用的界面,通常独立于用户前端。需要实现对所有模块(用户、商品、订单)的增删改查(CRUD)操作,以及数据统计仪表盘。
注意:在阅读源码时,不要只看单个模块的代码。要顺着“用户浏览商品 -> 加入购物车 -> 创建订单 -> 支付 -> 后台发货”这条主链路去跟踪代码,理解数据是如何在各个模块间流转和变化的。这是理解业务系统的最佳方式。
3. 核心细节解析与实操要点
3.1 数据库表结构深度解析
数据库设计是系统的骨架。下面我以一个高度简化的核心表结构为例,说明设计时的思考要点:
用户表 (user)
| 字段名 | 类型 | 说明 | 设计思考 |
|---|---|---|---|
id | bigint | 主键,自增 | 使用bigint而非int为长远考虑。自增ID简单高效。 |
username | varchar(50) | 用户名,唯一 | 用于登录,必须唯一且建立索引以加速查找。 |
password | varchar(255) | 加密后的密码 | 绝对不要明文存储!使用Spring Security的BCryptPasswordEncoder进行哈希加密。 |
phone | varchar(20) | 手机号 | 可选,用于找回密码或通知。 |
avatar | varchar(500) | 头像URL | 存储图片在服务器或OSS上的路径,而非图片本身。 |
role | varchar(20) | 角色(user/admin/seller) | 简单的系统可用字段区分,复杂的需用user_role关联表。 |
create_time | datetime | 创建时间 | 记录数据产生时间,便于审计和排查问题。 |
商品表 (product)
| 字段名 | 类型 | 说明 | 设计思考 |
|---|---|---|---|
id | bigint | 主键 | 同上。 |
category_id | bigint | 分类ID | 外键,关联分类表。便于按分类筛选商品。 |
name | varchar(100) | 商品名称 | 建立全文索引或普通索引以支持商品搜索。 |
price | decimal(10,2) | 价格 | 使用decimal精确存储金额,避免浮点数精度问题。 |
stock | int | 库存 | 核心字段,所有涉及库存的操作(下单、取消)都必须在此字段上做原子性更新(如update ... set stock = stock - 1 where id=? and stock > 0),防止超卖。 |
status | tinyint | 状态(0下架/1上架) | 用于控制前端是否展示。 |
image_url | varchar(500) | 主图URL | 通常只存一张主图,详情图用另一张表关联。 |
订单表 (order) 与订单项表 (order_item)这是典型的一对多关系。order表记录订单概要(订单号、总金额、用户ID、状态、收货地址),order_item表记录订单详情(商品ID、购买时单价、数量)。这样设计避免了数据冗余(如商品名、价格变动不影响历史订单),也符合数据库第三范式。
实操心得:
- 索引策略:在
user.username,product.name,order.user_id,order_item.order_id等经常用于查询条件的字段上创建索引,能极大提升查询性能。但索引不是越多越好,会影响写入速度。 - 字段选择:像
description(商品详情)这种可能很长的文本,应使用text类型。status这类状态值,使用tinyint或enum比varchar更节省空间和高效。 - 外键约束:在毕业设计或小型项目中,为了简化,有时会在逻辑上保持关联,而不在数据库层面建立外键约束。但在严谨的业务系统中,外键能保证数据的一致性和完整性。
3.2 后端核心:SpringBoot业务逻辑与API设计
后端代码通常遵循MVC(Model-View-Controller)模式,但在前后端分离架构中,View层由Vue替代,SpringBoot主要承担Controller和Service层。
1. 实体类(Model/Entity): 这是与数据库表一一对应的Java类。使用JPA(Java Persistence API)注解(如@Entity,@Table,@Id,@GeneratedValue)进行对象-关系映射(ORM)。Lombok库的@Data注解可以自动生成getter、setter等方法,让代码更简洁。
@Entity @Table(name = "product") @Data public class Product { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; private BigDecimal price; private Integer stock; // ... 其他字段及关联注解(如 @ManyToOne) }2. 数据访问层(Repository): Spring Data JPA提供了现成的JpaRepository接口,只需继承它,就自动拥有了基本的CRUD方法,无需编写实现类。这是SpringBoot开发中“约定优于配置”的典型体现。
public interface ProductRepository extends JpaRepository<Product, Long> { // 可以根据方法名自动推导查询,如查找上架商品 List<Product> findByStatusOrderByCreateTimeDesc(Integer status); // 或使用@Query注解编写自定义JPQL/SQL @Query("SELECT p FROM Product p WHERE p.name LIKE %:keyword%") List<Product> searchByName(@Param("keyword") String keyword); }3. 业务逻辑层(Service): 这里是业务规则的核心。Service类调用Repository进行数据操作,并处理复杂的业务逻辑。事务管理(@Transactional)通常加在这一层,确保一系列数据库操作要么全部成功,要么全部回滚。
@Service public class OrderService { @Autowired private OrderRepository orderRepository; @Autowired private ProductRepository productRepository; @Transactional // 关键注解,保证下单操作的原子性 public Order createOrder(CreateOrderRequest request, Long userId) { // 1. 校验库存(悲观锁或乐观锁) Product product = productRepository.findById(request.getProductId()).orElseThrow(...); if (product.getStock() < request.getQuantity()) { throw new RuntimeException("库存不足"); } // 2. 扣减库存(原子操作) int updatedRows = productRepository.deductStock(product.getId(), request.getQuantity()); if (updatedRows == 0) { // 扣减失败,可能已被其他请求修改,抛出异常触发事务回滚 throw new RuntimeException("并发修改,请重试"); } // 3. 创建订单 Order order = new Order(); // ... 设置订单属性 return orderRepository.save(order); // 如果上面任何一步失败,Spring会回滚整个事务,库存不会被错误扣减。 } }4. 控制层(Controller): 负责接收HTTP请求,调用相应的Service处理,并返回响应(通常是JSON)。使用@RestController注解。这里要做好参数校验(使用@Valid注解)和统一的异常处理(使用@ControllerAdvice),保证API的健壮性。
@RestController @RequestMapping("/api/order") public class OrderController { @Autowired private OrderService orderService; @PostMapping("/create") public ApiResponse<OrderVO> createOrder(@Valid @RequestBody CreateOrderRequest request, HttpSession session) { Long userId = (Long) session.getAttribute("userId"); // 实际项目中,用户ID更应从Token或Spring Security上下文获取 Order order = orderService.createOrder(request, userId); return ApiResponse.success(convertToVO(order)); } }API设计原则:
- RESTful风格:使用合适的HTTP方法(GET-查询,POST-创建,PUT-更新,DELETE-删除)和URL路径(如
/api/products,/api/products/{id})。 - 统一响应格式:所有API返回一个固定的包装类,如
{“code”: 200, “msg”: “success”, “data”: {...}},便于前端统一处理。 - 分页查询:商品列表、订单列表必须支持分页,使用Spring Data的
Pageable对象非常方便。
3.3 前端核心:Vue组件化开发与状态管理
前端项目通常使用Vue CLI创建,结构清晰。核心在于组件化和状态管理。
1. 组件化: 将页面拆分成一个个可复用的组件。例如,一个ProductList.vue组件负责展示商品列表,一个ProductItem.vue组件负责渲染单个商品卡片,ProductList中循环使用ProductItem。
<!-- ProductItem.vue --> <template> <div class="product-card"> <img :src="product.imageUrl" :alt="product.name"> <h3>{{ product.name }}</h3> <p class="price">¥{{ product.price }}</p> <button @click="addToCart">加入购物车</button> </div> </template> <script> export default { props: { // 接收父组件传递的数据 product: { type: Object, required: true } }, methods: { addToCart() { // 触发事件,通知父组件 this.$emit('add-to-cart', this.product.id); } } } </script>2. 状态管理(Vuex): 对于购物车数据、用户登录状态这种需要在多个组件间共享的状态,强烈建议使用Vuex。它将共享状态抽离出来,以可预测的方式发生变化。
// store/index.js import Vue from 'vue'; import Vuex from 'vuex'; Vue.use(Vuex); export default new Vuex.Store({ state: { cartItems: [], // 购物车商品列表 userInfo: null // 用户信息 }, mutations: { // 同步修改状态 ADD_TO_CART(state, product) { const item = state.cartItems.find(i => i.id === product.id); if (item) { item.quantity++; } else { state.cartItems.push({ ...product, quantity: 1 }); } }, SET_USER_INFO(state, info) { state.userInfo = info; } }, actions: { // 异步操作,如调用API,然后提交mutation async login({ commit }, credentials) { const res = await axios.post('/api/user/login', credentials); commit('SET_USER_INFO', res.data); localStorage.setItem('token', res.data.token); // 存储token } }, getters: { cartTotalCount(state) { return state.cartItems.reduce((sum, item) => sum + item.quantity, 0); } } });3. 路由(Vue Router): 管理前端页面跳转。需要配置路由表,并设置路由守卫(如检查登录状态,未登录则跳转到登录页)。
4. 与后端交互(Axios): 使用Axios库发起HTTP请求。关键是要配置请求拦截器(自动添加Token到请求头)和响应拦截器(统一处理错误),这是写出健壮前端代码的必备技巧。
// utils/request.js import axios from 'axios'; const service = axios.create({ baseURL: process.env.VUE_APP_BASE_API, // 从环境变量读取后端地址 timeout: 5000 }); // 请求拦截器 service.interceptors.request.use( config => { const token = localStorage.getItem('token'); if (token) { config.headers['Authorization'] = 'Bearer ' + token; } return config; }, error => { return Promise.reject(error); } ); // 响应拦截器 service.interceptors.response.use( response => { const res = response.data; if (res.code !== 200) { // 假设后端返回code不为200是业务错误 Message.error(res.msg || 'Error'); return Promise.reject(new Error(res.msg || 'Error')); } else { return res.data; // 直接返回后端响应的data字段 } }, error => { Message.error(error.message || '网络请求失败'); return Promise.reject(error); } ); export default service;4. 项目搭建与核心环节实现
4.1 从零开始的环境搭建与项目初始化
拿到一个完整的源码包(如乐乐农产品销售系统.zip),正确的打开方式不是直接导入IDE就跑,而是先理清结构。
后端(SpringBoot)初始化步骤:
- 解压与导入:解压后,找到后端项目文件夹(通常包含
pom.xml或build.gradle)。使用IntelliJ IDEA或Eclipse导入为一个Maven或Gradle项目。 - 配置数据库:在
src/main/resources/application.properties或application.yml文件中,修改数据库连接信息(URL、用户名、密码),确保与你本地安装的MySQL匹配。 - 运行SQL脚本:在项目资源文件夹(如
/src/main/resources/sql)中通常会有数据库初始化脚本(schema.sql,data.sql)。在你的MySQL客户端中执行它,创建表并导入初始数据(如管理员账号、测试商品)。 - 启动应用:找到主启动类(带有
@SpringBootApplication注解的类),直接运行它的main方法。观察控制台日志,没有报错且看到“Started ... in ... seconds”字样,说明后端启动成功。
前端(Vue)初始化步骤:
- 安装Node.js:确保本地已安装Node.js(包含npm)。在命令行输入
node -v和npm -v检查版本。 - 安装依赖:进入前端项目文件夹(通常包含
package.json和src目录),运行npm install或yarn install。这个过程会下载所有依赖包,网络慢的话可能需要耐心等待或配置镜像源。 - 配置代理:为了在开发时解决跨域问题,需要配置Vue的代理。在
vue.config.js文件中(如没有则创建)添加:module.exports = { devServer: { proxy: { '/api': { target: 'http://localhost:8080', // 你的SpringBoot后端地址 changeOrigin: true } } } } - 启动前端:运行
npm run serve。访问命令行输出的地址(通常是http://localhost:8081),看到页面即成功。
踩坑记录:
- 端口冲突:SpringBoot默认端口8080,Vue开发服务器默认8081。如果被占用,需要在各自的配置文件中修改。
- 依赖版本问题:这是最大的坑。如果项目是几年前写的,其依赖的SpringBoot、Vue或组件库版本可能较老,与新版本的Node.js或JDK不兼容。解决办法是:先尝试用源码包中
package.json和pom.xml指定的版本。如果不行,再谨慎地尝试升级主要依赖到较新的稳定版,并注意查看版本升级的迁移指南。
4.2 核心功能流程代码走读
以“用户下单”这个最核心的流程为例,我们串联起前后端代码:
前端(Vue组件):
- 用户在商品详情页点击“立即购买”或“加入购物车”。
- 前端组件的方法被触发,通过配置好的Axios实例,向
/api/order/create发送一个POST请求,请求体中包含商品ID、数量等信息,并在请求头自动带上登录Token。 - 发送请求后,显示“加载中”状态,提升用户体验。
后端(SpringBoot Controller -> Service -> Repository):
OrderController的createOrder方法接收到请求。- 通过拦截器或Spring Security从Token中解析出当前用户ID。
- 调用
OrderService.createOrder()方法,传入请求参数和用户ID。 OrderService方法被@Transactional注解标记,开启事务。- 在方法内部:
- 校验商品是否存在、库存是否充足。
- 执行扣减库存的SQL(使用乐观锁或悲观锁机制,见下文详解)。
- 创建订单和订单项数据,并保存到数据库。
- 如果所有步骤成功,事务提交,返回成功的订单信息给前端。
- 如果任何一步失败(如库存不足、扣减库存行数为0),抛出异常,事务回滚,数据库状态回到操作前,前端收到错误提示。
前端收到响应后:
- 如果成功,跳转到订单详情页或支付页。
- 如果失败,显示后端返回的错误信息。
库存扣减的并发控制详解: 这是电商系统必须面对的经典问题。假设库存只剩1件,两个用户同时下单。
- 悲观锁:在查询商品时就用
SELECT ... FOR UPDATE锁定这行数据,直到当前事务结束才释放。这样第二个请求会被阻塞。这种方式简单粗暴,但在高并发下性能较差。// 在Repository中使用@Query和原生SQL @Query(value = "SELECT * FROM product WHERE id = ?1 FOR UPDATE", nativeQuery = true) Product findByIdForUpdate(Long id); - 乐观锁:更常用的方式。在商品表中增加一个
version字段(版本号)。更新时,不仅匹配ID,还要匹配查询时得到的版本号。
执行后,检查受影响的行数(UPDATE product SET stock = stock - 1, version = version + 1 WHERE id = ? AND version = ? AND stock > 0;updatedRows)。如果为0,说明数据已被其他请求修改过(版本号变了或库存不足),本次更新失败,抛出异常让用户重试。这种方式并发性能更好。
在毕业设计项目中,实现乐观锁是加分项,能体现出你对并发问题的思考。
5. 常见问题与排查技巧实录
在实际运行和二次开发这类项目时,你会遇到各种各样的问题。下面是我总结的一些高频问题及排查思路。
5.1 环境与启动类问题
| 问题现象 | 可能原因 | 排查步骤与解决方案 |
|---|---|---|
后端启动失败,报Failed to configure a DataSource | 数据库连接配置错误或数据库服务未启动。 | 1. 检查application.properties中的spring.datasource.url, username, password。2. 确认MySQL服务已启动( net start mysql)。3. 确认数据库名、表是否存在(执行提供的SQL脚本)。 |
前端npm install报错,大量ERR! | 网络问题或Node.js/npm版本与项目不兼容。 | 1. 切换npm镜像源:npm config set registry https://registry.npmmirror.com。2. 删除 node_modules文件夹和package-lock.json,重新npm install。3. 核对 package.json中要求的Node.js版本,使用nvm切换版本。 |
| 前端运行后,页面空白,控制台报跨域错误 | 前端请求的API地址与后端服务地址不同源,且未配置代理。 | 1. 确认Vue开发服务器和后端服务已分别启动。 2. 检查 vue.config.js中的proxy配置,确保target指向正确的后端地址和端口。3. 在前端代码中,检查Axios实例的 baseURL是否配置正确(开发环境通常设为/api,由代理转发)。 |
| 页面能打开,但所有API请求返回404 | 后端API路径错误,或前端请求路径拼接错误。 | 1. 打开浏览器开发者工具的“网络(Network)”标签,查看请求的完整URL是否正确。 2. 在后端IDE中,使用“运行(Run) Dashboard”或端点映射检查,确认 @RequestMapping定义的路径是否存在。3. 检查是否有过滤器或安全配置拦截了请求。 |
5.2 业务逻辑与数据问题
| 问题现象 | 可能原因 | 排查步骤与解决方案 |
|---|---|---|
| 登录成功,但后续操作提示“未授权”或“未登录” | Token未正确传递或后端会话失效。 | 1. 检查前端请求拦截器,是否成功将Token放入Authorization请求头。2. 检查后端安全配置(如Spring Security的过滤器链),是否放行了登录接口但拦截了其他接口。 3. 确认Token的生成、验证逻辑一致(如使用相同的密钥)。 4. 如果是Session方式,检查Session是否超时。 |
| 下单时提示“库存不足”,但管理后台显示有库存 | 1. 库存校验逻辑有bug。 2. 发生了超卖(并发问题)。 | 1. 在OrderService.createOrder方法中打日志,打印校验时的库存值和商品ID。2.重点检查库存扣减SQL:是否使用了 stock > 0的条件?是否采用了乐观锁机制?在高并发场景下,简单的update product set stock=stock-1 where id=1会导致超卖。3. 使用Jmeter或Postman进行并发测试,验证扣减逻辑的正确性。 |
| 图片上传失败或无法显示 | 文件上传路径配置错误,或前端未正确传递文件数据。 | 1. 后端:检查接收文件的方法是否使用@RequestParam("file") MultipartFile file,以及是否配置了文件保存路径(如spring.servlet.multipart.max-file-size)。2. 前端:检查上传组件(如 el-upload)的action地址是否正确,name属性是否与后端@RequestParam值匹配,是否设置了enctype="multipart/form-data"。3. 访问图片的静态资源路径是否被SpringBoot正确映射(检查 WebMvcConfigurer配置)。 |
| 分页查询结果不对 | 前后端分页参数未对齐,或SQL分页语句有误。 | 1. 前端:检查传给后端的参数名,通常是pageNum(页码)和pageSize(每页条数)。2. 后端:Controller使用 @RequestParam(defaultValue="1") int pageNum, @RequestParam(defaultValue="10") int pageSize接收。Service层使用PageRequest.of(pageNum-1, pageSize)创建Pageable对象(注意JPA页码从0开始)。3. Repository层方法返回 Page<Product>类型。 |
5.3 性能与部署问题
- 首次访问页面很慢:可能是Vue打包后的文件过大。解决方案:配置路由懒加载,使用
import()语法动态导入组件;使用npm run build --report分析包体积,优化较大的依赖。 - 列表页滚动卡顿:商品列表数据量过大,一次性渲染DOM元素过多。解决方案:实现虚拟滚动或分页加载更多。虚拟滚动只渲染可视区域内的DOM,性能极佳。
- 数据库查询慢:随着数据量增加,复杂查询(如多表关联、模糊搜索)会变慢。解决方案:为常用查询条件字段添加索引;考虑对商品名称等字段使用Elasticsearch等搜索引擎;将热点数据(如商品信息)放入Redis缓存。
部署上线简易步骤:
- 后端:使用
mvn clean package打包,生成一个可执行的jar文件。在服务器上安装Java运行环境(JRE),使用java -jar your-project.jar命令运行。可以使用nohup命令或配置为系统服务(如systemd)保持后台运行。 - 前端:运行
npm run build,生成静态文件在dist目录。将这些文件(index.html, css, js等)放到Nginx或Apache的静态资源目录下。 - 数据库:在服务器上安装MySQL,导入数据。
- 配置:修改后端
application.properties中的数据库连接信息为服务器地址;修改前端生产环境API地址(通常通过环境变量VUE_APP_BASE_API设置),并重新构建。
最后,如果你想把这个毕业设计项目提升一个档次,可以考虑加入一些进阶特性:集成Redis缓存商品分类和热点商品、使用WebSocket实现后台订单状态变化时前台实时通知、使用ECharts在管理后台绘制销售数据图表、编写单元测试(JUnit)和接口测试(Postman集合)。这些都能让你的项目在答辩和面试中脱颖而出。记住,理解原理、能解决问题、有自己思考的项目,才是好项目。
本文还有配套的精品资源,点击获取