SpringBoot+Vue前后端分离家政服务平台开发实战指南 最近在辅导学生毕业设计和指导团队开发时发现很多同学在构建一个完整的、可落地的“前后端分离”项目时常常感到无从下手。特别是像家政服务平台这类涉及多角色、多流程的业务系统如何从零开始清晰地划分前后端职责并实现高效的数据交互是大家普遍遇到的难题。本文将围绕一个基于 SpringBoot 和 Vue 的家政服务平台为你拆解从环境搭建、技术选型到核心功能实现的完整闭环。无论你是正在寻找毕业设计课题的计算机专业学生还是希望巩固前后端分离开发经验的初级开发者都能从这篇实战指南中获得可直接复用的代码和清晰的架构思路。1. 项目背景与核心概念1.1 什么是家政服务平台家政服务平台是一个连接家政服务人员如保洁师、保姆、月嫂与雇主的在线中介系统。它本质上是一个B2C或C2C的电子商务平台但交易标的物是“服务”而非实体商品。核心业务流程包括雇主发布需求、服务人员接单、双方沟通确认、服务执行、在线支付、服务评价等。1.2 为什么选择 SpringBoot Vue 前后端分离架构对于毕业设计或中小型实战项目SpringBoot Vue 的组合是目前非常主流且高效的技术选型。SpringBoot作为后端框架它极大地简化了基于 Spring 的应用初始搭建和开发过程。通过自动配置和起步依赖开发者可以快速构建出独立运行、生产级别的微服务或单体应用无需繁琐的 XML 配置。它天然适合构建 RESTful API为前端 Vue 应用提供清晰的数据接口。Vue.js作为前端渐进式框架Vue 的核心库只关注视图层易于上手且能与现代工具链如 Vue CLI、Vite以及各种支持类库结合轻松构建复杂的单页面应用SPA。其响应式数据绑定和组件化开发模式能极大地提升前端开发效率和用户体验。前后端分离这种架构模式将前端展示逻辑与后端业务逻辑、数据访问彻底解耦。后端专注于提供 API 接口前端负责渲染和用户交互。这样做的好处是职责清晰前后端开发可以并行进行通过接口文档进行协作。技术栈灵活后端可以替换为其他语言框架前端亦然只要接口协议不变。易于维护和扩展前后端可以独立部署、升级和伸缩。更适合现代前端开发可以利用 Vue Router、Vuex/Pinia 等生态构建复杂的交互应用。1.3 本系统核心功能模块设计一个完整的家政服务平台通常包含以下核心模块用户管理区分雇主、家政人员、系统管理员三种角色实现注册、登录、个人信息管理。服务项目管理管理员或服务人员可以发布、上架、下架各类家政服务如日常保洁、深度清洁、家电清洗并设置价格、时长、描述等。订单管理雇主浏览服务并下单服务人员接单形成订单的生命周期管理待接单、已接单、服务中、待支付、已完成、已评价、已取消。支付模块集成第三方支付如支付宝、微信支付沙箱环境实现订单的在线支付。评价系统服务完成后雇主可以对服务人员进行评分和文字评价。后台管理管理员拥有最高权限可以管理所有用户、服务项目、订单查看统计数据等。2. 环境准备与版本说明在开始编码之前请确保你的开发环境已就绪。以下版本为本文示例所使用你可以根据实际情况进行调整。2.1 后端开发环境操作系统Windows 10/11 macOS 或 Linux 均可。JDKJava Development Kit 17LTS长期支持版本。Spring Boot 3.x 要求最低 JDK 17。IDEIntelliJ IDEA Ultimate 或 Community Edition推荐或 Eclipse with STS。构建工具Apache Maven 3.6.3 或 Gradle。数据库MySQL 8.0。我们将使用 MySQL 作为持久化存储。项目管理使用 Spring Initializr 快速生成项目骨架。2.2 前端开发环境Node.js版本 16.x 或 18.xLTS。这是运行 npm 和 Vue CLI 的基础。包管理器npm 或 yarn。本文使用 npm。IDEVisual Studio Code推荐或 WebStorm。Vue 脚手架Vue CLI 或 Vite。本文使用 Vue CLI 创建项目。2.3 关键依赖版本后端通过 Spring Initializr 生成项目时选择以下依赖Spring Boot3.1.x 或 3.2.x稳定版依赖项Spring Web用于构建 RESTful APISpring Data JPA简化数据库操作MySQL DriverMySQL 数据库连接驱动Lombok简化实体类代码Spring Boot DevTools开发热部署Spring Security可选用于权限控制毕业设计可简化2.4 关键依赖版本前端使用 Vue CLI 创建项目时选择 Vue 3 生态Vue3.xVue Router4.x用于前端路由状态管理PiniaVue 官方推荐的状态管理库替代 VuexUI 组件库Element Plus基于 Vue 3 的桌面端组件库或 Vant移动端组件库根据项目定位选择。本文示例使用 Element Plus。HTTP 客户端Axios用于发起 HTTP 请求3. 后端核心实现SpringBoot 项目搭建与 API 开发3.1 创建 SpringBoot 项目访问 start.spring.io 。选择项目信息Project: Maven ProjectLanguage: JavaSpring Boot: 3.2.5 (SNAPSHOT)Project Metadata:Group:com.homemakingArtifact:serverPackaging: JarJava: 17添加依赖Spring Web,Spring Data JPA,MySQL Driver,Lombok。点击“GENERATE”下载项目压缩包解压后用 IDEA 打开。3.2 数据库设计与实体类映射我们首先设计核心表结构并使用 JPA 实体类进行映射。1. 用户表 (sys_user)CREATE TABLE sys_user ( id bigint NOT NULL AUTO_INCREMENT COMMENT 主键, username varchar(50) NOT NULL COMMENT 用户名, password varchar(100) NOT NULL COMMENT 密码, nickname varchar(50) DEFAULT NULL COMMENT 昵称, phone varchar(20) DEFAULT NULL COMMENT 手机号, avatar varchar(255) DEFAULT NULL COMMENT 头像, role varchar(20) NOT NULL DEFAULT EMPLOYER COMMENT 角色EMPLOYER-雇主 WORKER-家政人员 ADMIN-管理员, status tinyint NOT NULL DEFAULT 1 COMMENT 状态0-禁用 1-正常, create_time datetime DEFAULT CURRENT_TIMESTAMP COMMENT 创建时间, update_time datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 更新时间, PRIMARY KEY (id), UNIQUE KEY uk_username (username) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COLLATEutf8mb4_0900_ai_ci COMMENT系统用户表;对应的 Java 实体类// 文件路径src/main/java/com/homemaking/entity/User.java package com.homemaking.entity; import jakarta.persistence.*; import lombok.Data; import java.time.LocalDateTime; Entity Table(name sys_user) Data // Lombok 注解自动生成 getter, setter, toString 等 public class User { Id GeneratedValue(strategy GenerationType.IDENTITY) private Long id; Column(nullable false, unique true, length 50) private String username; Column(nullable false, length 100) private String password; Column(length 50) private String nickname; Column(length 20) private String phone; Column(length 255) private String avatar; Column(nullable false, length 20) private String role EMPLOYER; // 默认角色为雇主 Column(nullable false) private Integer status 1; // 1-正常 0-禁用 Column(updatable false) private LocalDateTime createTime; private LocalDateTime updateTime; // JPA 生命周期回调在持久化前设置创建时间 PrePersist protected void onCreate() { createTime LocalDateTime.now(); updateTime LocalDateTime.now(); } // JPA 生命周期回调在更新前设置更新时间 PreUpdate protected void onUpdate() { updateTime LocalDateTime.now(); } }2. 服务项目表 (service_item)CREATE TABLE service_item ( id bigint NOT NULL AUTO_INCREMENT, name varchar(100) NOT NULL COMMENT 服务名称, description text COMMENT 服务描述, price decimal(10,2) NOT NULL COMMENT 服务价格元, duration int DEFAULT NULL COMMENT 预计时长分钟, category varchar(50) DEFAULT NULL COMMENT 服务分类如日常保洁、深度清洁, worker_id bigint DEFAULT NULL COMMENT 关联的服务人员ID可为空表示平台通用服务, status tinyint NOT NULL DEFAULT 1 COMMENT 状态0-下架 1-上架, create_time datetime DEFAULT CURRENT_TIMESTAMP, update_time datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (id), KEY idx_worker_id (worker_id), CONSTRAINT fk_service_worker FOREIGN KEY (worker_id) REFERENCES sys_user (id) ON DELETE SET NULL ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COLLATEutf8mb4_0900_ai_ci COMMENT服务项目表;对应的ServiceItem实体类请参照User实体自行创建注意使用ManyToOne关联User实体。3.3 数据访问层Repository 接口Spring Data JPA 的强大之处在于只需定义接口无需实现。// 文件路径src/main/java/com/homemaking/repository/UserRepository.java package com.homemaking.repository; import com.homemaking.entity.User; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; import java.util.Optional; Repository public interface UserRepository extends JpaRepositoryUser, Long { // 根据用户名查找用户 OptionalUser findByUsername(String username); // 判断用户名是否存在 boolean existsByUsername(String username); // 根据角色查找用户列表 ListUser findByRole(String role); }ServiceItemRepository接口可以定义类似的方法如findByCategory、findByStatus等。3.4 业务逻辑层Service 实现Service 层负责处理核心业务逻辑。这里以用户注册和登录为例。首先定义一个通用的响应结果类// 文件路径src/main/java/com/homemaking/common/Result.java package com.homemaking.common; import lombok.Data; Data public class ResultT { private Integer code; // 状态码如 200成功 500失败 private String msg; // 提示信息 private T data; // 返回的数据 public static T ResultT success(T data) { ResultT result new Result(); result.setCode(200); result.setMsg(操作成功); result.setData(data); return result; } public static T ResultT success(String msg, T data) { ResultT result new Result(); result.setCode(200); result.setMsg(msg); result.setData(data); return result; } public static T ResultT error(String msg) { ResultT result new Result(); result.setCode(500); result.setMsg(msg); return result; } }用户服务接口和实现// 文件路径src/main/java/com/homemaking/service/UserService.java package com.homemaking.service; import com.homemaking.common.Result; import com.homemaking.entity.User; public interface UserService { ResultUser register(User user); ResultString login(String username, String password); // ... 其他方法 }// 文件路径src/main/java/com/homemaking/service/impl/UserServiceImpl.java package com.homemaking.service.impl; import com.homemaking.common.Result; import com.homemaking.entity.User; import com.homemaking.repository.UserRepository; import com.homemaking.service.UserService; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.util.DigestUtils; import java.nio.charset.StandardCharsets; import java.util.Optional; Service RequiredArgsConstructor // Lombok 注解为 final 字段生成构造函数 public class UserServiceImpl implements UserService { private final UserRepository userRepository; Override public ResultUser register(User user) { // 1. 校验用户名是否已存在 if (userRepository.existsByUsername(user.getUsername())) { return Result.error(用户名已存在); } // 2. 对密码进行 MD5 加密生产环境应使用更安全的 BCrypt String encryptedPassword DigestUtils.md5DigestAsHex( user.getPassword().getBytes(StandardCharsets.UTF_8) ); user.setPassword(encryptedPassword); // 3. 设置默认角色如果未设置 if (user.getRole() null) { user.setRole(EMPLOYER); } // 4. 保存用户 User savedUser userRepository.save(user); // 5. 返回时清空密码 savedUser.setPassword(null); return Result.success(注册成功, savedUser); } Override public ResultString login(String username, String password) { // 1. 根据用户名查找用户 OptionalUser userOpt userRepository.findByUsername(username); if (userOpt.isEmpty()) { return Result.error(用户名或密码错误); } User user userOpt.get(); // 2. 校验密码 String encryptedInputPassword DigestUtils.md5DigestAsHex( password.getBytes(StandardCharsets.UTF_8) ); if (!user.getPassword().equals(encryptedInputPassword)) { return Result.error(用户名或密码错误); } // 3. 校验用户状态 if (user.getStatus() 0) { return Result.error(账号已被禁用); } // 4. 登录成功这里简单返回一个成功信息。实际项目应生成 JWT Token 返回。 return Result.success(登录成功, 用户ID: user.getId()); } }3.5 控制层RESTful API 控制器Controller 层接收前端请求调用 Service并返回 JSON 数据。// 文件路径src/main/java/com/homemaking/controller/UserController.java package com.homemaking.controller; import com.homemaking.common.Result; import com.homemaking.entity.User; import com.homemaking.service.UserService; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.*; RestController RequestMapping(/api/user) RequiredArgsConstructor public class UserController { private final UserService userService; PostMapping(/register) public ResultUser register(RequestBody User user) { return userService.register(user); } PostMapping(/login) public ResultString login(RequestParam String username, RequestParam String password) { return userService.login(username, password); } // 其他接口获取用户信息、修改信息等 GetMapping(/{id}) public ResultUser getUserById(PathVariable Long id) { // 此处省略 Service 层方法实现应返回用户信息密码置空 return Result.success(查询成功, null); // 示例 } }3.6 应用配置文件配置数据库连接和 JPA 属性。# 文件路径src/main/resources/application.yml spring: datasource: url: jdbc:mysql://localhost:3306/homemaking_db?useUnicodetruecharacterEncodingutf-8serverTimezoneAsia/Shanghai username: root password: your_password # 替换为你的数据库密码 driver-class-name: com.mysql.cj.jdbc.Driver jpa: hibernate: ddl-auto: update # 开发环境可用 update生产环境应设为 validate 或 none并使用 Flyway/Liquibase show-sql: true # 控制台打印 SQL便于调试 properties: hibernate: format_sql: true # 格式化 SQL 输出 dialect: org.hibernate.dialect.MySQL8Dialect server: port: 8080 # 后端服务端口 # 自定义配置示例 app: jwt: secret: your-jwt-secret-key # 用于 JWT 签名的密钥 expiration: 86400000 # token 过期时间毫秒24小时3.7 启动与测试在 MySQL 中创建数据库homemaking_db。修改application.yml中的数据库密码。找到主启动类HomemakingApplication位于src/main/java/com/homemaking运行它。使用 Postman 或浏览器测试 APIPOST http://localhost:8080/api/user/registerBody (JSON):{username:test,password:123456,nickname:测试用户}POST http://localhost:8080/api/user/login?usernametestpassword1234564. 前端核心实现Vue 3 Element Plus 项目搭建4.1 创建 Vue 项目并安装依赖# 1. 安装 Vue CLI如果未安装 npm install -g vue/cli # 2. 创建项目 vue create homemaking-frontend # 选择 Manually select features # 勾选Babel, Router, Vuex (或 Pinia), CSS Pre-processors (如 Sass) # Vue 版本选择 3.x # Router 使用 history 模式 Yes # CSS 预处理器选择 Sass/SCSS # 其他配置按需选择或默认 # 3. 进入项目目录并安装 Element Plus 和 Axios cd homemaking-frontend npm install element-plus axios # 或者使用按需导入推荐减小打包体积 # npm install element-plus element-plus/icons-vue # npm install -D unplugin-vue-components unplugin-auto-import4.2 配置 Element Plus 和 Axios1. 全局引入 Element Plus (main.js 或 main.ts)// 文件路径src/main.js import { createApp } from vue import App from ./App.vue import router from ./router import store from ./store // 如果使用 Vuex // 引入 Element Plus 及其样式 import ElementPlus from element-plus import element-plus/dist/index.css // 引入 axios 并配置全局实例 import axios from axios axios.defaults.baseURL http://localhost:8080 // 后端 API 地址 const app createApp(App) app.use(store) app.use(router) app.use(ElementPlus) app.mount(#app)2. 创建统一的请求拦截器 (src/utils/request.js)import axios from axios import { ElMessage } from element-plus import router from ../router // 创建 axios 实例 const service axios.create({ baseURL: process.env.VUE_APP_BASE_API, // 可从 .env 文件读取 timeout: 10000 // 请求超时时间 }) // 请求拦截器 service.interceptors.request.use( config { // 在发送请求之前做些什么例如添加 token const token localStorage.getItem(token) if (token) { config.headers[Authorization] Bearer token } return config }, error { // 对请求错误做些什么 console.error(Request Error:, error) return Promise.reject(error) } ) // 响应拦截器 service.interceptors.response.use( response { // 对响应数据做点什么 const res response.data // 假设后端统一返回格式为 { code, msg, data } if (res.code ! 200) { ElMessage.error(res.msg || 请求失败) // 如果是 token 过期等特定错误码可以跳转到登录页 if (res.code 401) { router.push(/login) } return Promise.reject(new Error(res.msg || Error)) } else { return res.data // 直接返回后端定义的 data 字段 } }, error { // 对响应错误做点什么 console.error(Response Error:, error) ElMessage.error(error.message || 网络错误) return Promise.reject(error) } ) export default service4.3 实现用户登录页面!-- 文件路径src/views/Login.vue -- template div classlogin-container el-card classlogin-card h2 styletext-align: center; margin-bottom: 30px;家政服务平台/h2 el-form :modelloginForm :rulesloginRules refloginFormRef label-width80px el-form-item label用户名 propusername el-input v-modelloginForm.username placeholder请输入用户名/el-input /el-form-item el-form-item label密码 proppassword el-input v-modelloginForm.password typepassword placeholder请输入密码 keyup.enterhandleLogin/el-input /el-form-item el-form-item el-button typeprimary stylewidth: 100%; :loadingloading clickhandleLogin登录/el-button /el-form-item div styletext-align: center; font-size: 14px; 还没有账号el-link typeprimary click$router.push(/register)立即注册/el-link /div /el-form /el-card /div /template script setup import { ref, reactive } from vue import { useRouter } from vue-router import { ElMessage } from element-plus import request from /utils/request // 导入封装好的 axios 实例 const router useRouter() const loginFormRef ref() const loginForm reactive({ username: , password: }) const loginRules { username: [{ required: true, message: 请输入用户名, trigger: blur }], password: [{ required: true, message: 请输入密码, trigger: blur }] } const loading ref(false) const handleLogin () { loginFormRef.value.validate((valid) { if (valid) { loading.value true // 使用 FormData 或 URLSearchParams 发送表单数据 const params new URLSearchParams() params.append(username, loginForm.username) params.append(password, loginForm.password) request.post(/api/user/login, params) .then(res { ElMessage.success(登录成功) // 假设后端返回了 token存储到 localStorage // localStorage.setItem(token, res.token) // 存储用户信息到 Vuex/Pinia // store.commit(user/SET_USER_INFO, res.userInfo) // 跳转到首页 router.push(/) }) .catch(err { console.error(登录失败:, err) // 错误信息已在 request.js 的拦截器中统一提示 }) .finally(() { loading.value false }) } else { console.log(表单验证失败) return false } }) } /script style scoped .login-container { display: flex; justify-content: center; align-items: center; height: 100vh; background-color: #f5f7fa; } .login-card { width: 400px; } /style4.4 实现服务列表页面!-- 文件路径src/views/ServiceList.vue -- template div classservice-list el-row :gutter20 el-col :span6 v-foritem in serviceList :keyitem.id stylemargin-bottom: 20px; el-card :body-style{ padding: 0px } img :srcitem.image || https://via.placeholder.com/300x200 classservice-image / div stylepadding: 14px; h3{{ item.name }}/h3 p classdescription{{ item.description }}/p div classbottom span classprice¥{{ item.price }}/span span classduration{{ item.duration }}分钟/span el-button typeprimary sizesmall clickhandleOrder(item)立即预约/el-button /div /div /el-card /el-col /el-row !-- 分页组件 -- el-pagination size-changehandleSizeChange current-changehandleCurrentChange :current-pagequeryParams.pageNum :page-sizes[10, 20, 50, 100] :page-sizequeryParams.pageSize layouttotal, sizes, prev, pager, next, jumper :totaltotal /el-pagination /div /template script setup import { ref, reactive, onMounted } from vue import { ElMessage } from element-plus import request from /utils/request const serviceList ref([]) const total ref(0) const queryParams reactive({ pageNum: 1, pageSize: 10, category: , keyword: }) // 获取服务列表 const fetchServiceList () { request.get(/api/service/list, { params: queryParams }) .then(res { serviceList.value res.list || [] total.value res.total || 0 }) .catch(err { console.error(获取服务列表失败:, err) }) } const handleSizeChange (val) { queryParams.pageSize val fetchServiceList() } const handleCurrentChange (val) { queryParams.pageNum val fetchServiceList() } const handleOrder (item) { // 跳转到订单确认页面传递服务ID // this.$router.push({ path: /order/confirm, query: { serviceId: item.id } }) ElMessage.info(预约服务: ${item.name}) } onMounted(() { fetchServiceList() }) /script style scoped .service-image { width: 100%; height: 200px; object-fit: cover; } .description { color: #999; font-size: 14px; margin: 10px 0; overflow: hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; } .bottom { display: flex; justify-content: space-between; align-items: center; margin-top: 10px; } .price { color: #f56c6c; font-size: 18px; font-weight: bold; } .duration { color: #909399; font-size: 14px; } /style5. 前后端联调与跨域问题解决当前后端运行在不同端口如前端localhost:8081后端localhost:8080时浏览器会因为同源策略而阻止请求这就是跨域问题。5.1 后端解决跨域推荐在 SpringBoot 后端项目中添加一个全局跨域配置类。// 文件路径src/main/java/com/homemaking/config/CorsConfig.java package com.homemaking.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.UrlBasedCorsConfigurationSource; import org.springframework.web.filter.CorsFilter; Configuration public class CorsConfig { Bean public CorsFilter corsFilter() { CorsConfiguration config new CorsConfiguration(); // 允许的域不要写*否则cookie无法传递 config.addAllowedOrigin(http://localhost:8081); // 你的前端地址 // 允许的请求方式 config.addAllowedMethod(*); // 允许的头信息 config.addAllowedHeader(*); // 允许携带凭证如 cookie config.setAllowCredentials(true); UrlBasedCorsConfigurationSource source new UrlBasedCorsConfigurationSource(); // 对所有接口路径生效 source.registerCorsConfiguration(/**, config); return new CorsFilter(source); } }5.2 前端代理解决跨域开发环境在 Vue 项目的vue.config.js文件中配置代理。// 文件路径vue.config.js const { defineConfig } require(vue/cli-service) module.exports defineConfig({ transpileDependencies: true, devServer: { port: 8081, // 前端开发服务器端口 proxy: { /api: { // 匹配所有以 /api 开头的请求路径 target: http://localhost:8080, // 代理目标的基础路径 changeOrigin: true, // 支持跨域 pathRewrite: { ^/api: // 重写路径去掉 /api 前缀 } } } } })配置后前端请求/api/user/login会被代理到http://localhost:8080/user/login。6. 常见问题与排查思路在开发过程中你可能会遇到以下典型问题问题现象可能原因排查步骤与解决方案后端启动失败端口被占用8080 端口已被其他程序如另一个 SpringBoot 应用、Tomcat使用。1. 修改application.yml中的server.port。2. 命令行执行netstat -ano | findstr :8080(Windows) 或lsof -i :8080(Mac/Linux) 找到进程并结束。前端npm run serve报错Node.js 版本不兼容或依赖包安装不完整。1. 检查 Node.js 版本node -v确保是 16.x 或 18.x LTS。2. 删除node_modules和package-lock.json重新执行npm install。访问后端 API 返回 4041. 后端接口路径写错。2. 后端 Controller 未正确映射。3. 跨域配置未生效。1. 检查浏览器 Network 面板确认请求的 URL 是否正确。2. 在后端 Controller 类和方法上添加RestController和RequestMapping/PostMapping等注解。3. 检查后端CorsConfig是否生效允许了前端源。数据库连接失败1. MySQL 服务未启动。2.application.yml中数据库配置错误用户名、密码、URL。3. 数据库驱动版本不匹配。1. 确保 MySQL 服务已启动。2. 仔细核对application.yml中的spring.datasource配置。3. 检查pom.xml中mysql-connector-java版本SpringBoot 3.x 建议使用 8.x 驱动。前端页面空白控制台报错1. 路由配置错误。2. 组件引入错误。3. 浏览器缓存。1. 检查浏览器控制台 (Console) 的具体错误信息。2. 检查router/index.js中的路由配置是否正确。3. 尝试CtrlF5强制刷新浏览器或使用无痕模式。JPA 实体类映射表失败1. 实体类注解如Entity,Table缺失或错误。2. 数据库表不存在。3.ddl-auto配置问题。1. 检查实体类是否添加了Entity和Table(name“表名”)。2. 检查数据库中表是否创建或设置spring.jpa.hibernate.ddl-autoupdate让 Hibernate 自动建表仅限开发。3. 查看启动日志是否有表创建或映射的 SQL 输出。前端请求后端成功但收不到响应数据1. 后端 Controller 方法没有ResponseBody或类不是RestController。2. 后端返回的数据格式不是 JSON。3. 前端 axios 拦截器处理响应数据有误。1. 确保 Controller 类上有RestController注解。2. 使用 Postman 直接测试后端接口看返回的 JSON 格式是否正确。3. 检查src/utils/request.js中响应拦截器的逻辑是否正确地返回了res.data。7. 项目扩展与最佳实践完成基础功能后你可以从以下方向深化项目这会让你的毕业设计或项目经验更具竞争力。7.1 引入 JWT 实现无状态认证上述示例的登录只是简单验证生产环境需要使用 Token如 JWT来管理用户会话。添加依赖在pom.xml中加入jjwt相关依赖。创建 JWT 工具类用于生成和解析 Token。修改登录逻辑登录成功后生成 JWT 并返回给前端。添加拦截器/过滤器在后台验证请求头中的 Token 是否有效。前端存储 Token登录成功后将 Token 存入localStorage或Vuex/Pinia并在后续请求的Authorization头中携带。7.2 使用 Spring Security 进行权限控制对于管理员、雇主、家政人员等不同角色其可访问的 API 和页面应不同。引入依赖spring-boot-starter-security。配置 Security 配置类继承WebSecurityConfigurerAdapter(Spring Boot 2.x) 或使用SecurityFilterChainBean (Spring Boot 3.x)配置 URL 权限规则、密码加密方式BCrypt、登录成功/失败处理等。在 Controller 方法上使用注解如PreAuthorize(“hasRole(‘ADMIN’)”)来控制方法级别的访问。7.3 集成 MyBatis-Plus 增强数据操作如果你觉得 JPA 的 SQL 不够灵活或想使用更强大的条件构造器可以集成 MyBatis-Plus。添加依赖替换spring-boot-starter-data-jpa为mybatis-plus-boot-starter。配置 Mapper 扫描在启动类加MapperScan。创建 Mapper 接口继承BaseMapper即可获得丰富的 CRUD 方法。使用 QueryWrapper进行复杂的动态 SQL 查询。7.4 前端路由守卫与权限校验防止用户未登录就访问需要认证的页面。// 文件路径src/router/index.js import { createRouter, createWebHistory } from vue-router import store from ../store // 假设使用 Vuex 存储用户状态 const routes [ { path: /login, component: () import(/views/Login.vue) }, { path: /dashboard, component: () import(/views/Dashboard.vue), meta: { requiresAuth: true } // 需要认证的元信息 }, // ... 其他路由 ] const router createRouter({ history: createWebHistory(), routes }) // 全局前置守卫 router.beforeEach((to, from, next) { const isAuthenticated store.state.user.token // 检查是否有 token if (to.matched.some(record record.meta.requiresAuth) !isAuthenticated) { // 如果目标路由需要认证且用户未登录则跳转到登录页 next({ path: /login, query: { redirect: to.fullPath } }) } else { next() // 放行 } }) export default router7.5 项目部署建议后端使用mvn clean package打包成可执行的 JAR 文件在服务器上通过java -jar your-app.jar运行。建议配合nohup或 systemd 服务保持后台运行。对于生产环境务必配置好数据库连接池、日志、监控和 HTTPS。前端运行npm run build生成静态文件位于dist目录。可以将这些文件部署到 Nginx 或 Apache 等 Web 服务器上。记得配置 Nginx 的反向代理将/api路径的请求转发到后端服务。数据库做好定期备份。对于毕业设计可以使用云数据库如阿里云 RDS、腾讯云 CDB的免费试用套餐避免本地环境问题。通过以上步骤你已经完成了一个具备核心功能的 SpringBoot Vue 前后端分离家政服务平台。从环境搭建、数据库设计、API 开发到前端页面实现和联调覆盖了一个完整 Web 应用开发的主要环节。你可以在此基础上继续实现订单管理、支付集成如支付宝沙箱、评价系统、后台管理面板等更复杂的功能使其成为一个丰满的毕业设计或作品集项目。记住在开发过程中多查阅官方文档善用调试工具遇到问题优先看日志和错误信息祝你编码顺利

本月热点