ARTICLE DETAIL

资讯详情

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

SpringBoot+Vue小区物业系统:毕设高分工程实践指南

SpringBoot+Vue小区物业系统:毕设高分工程实践指南 简介这是一套面向计算机专业本科生的高分毕业设计实战资源基于SpringBoot后端与Vue前端构建的小区物业管理系统适用于毕设开发、课程大作业及Java全栈项目练手。资源包含完整可运行源码、配套MySQL数据库脚本及详细部署说明所有代码均经本地编译调试通过评审得分98分内容由导师指导并助教审定难度适中、结构规范、功能完备。压缩包共1066个文件涵盖45个核心Java类、202个JavaScript交互逻辑、342个CSS样式文件、242个PNG图标资源及45个HTML页面另有SQL建表语句、YML配置与XML配置文件等整体大小16.86MB目录层次清晰前后端分离明确便于学习模块划分与二次开发。目前已有105人下载学习适合零基础入门SpringBootVue全栈开发、理解物业业务流程如住户管理、报修工单、费用收缴、公告发布并掌握真实项目工程化实践。1. 为什么一个“小区物业管理系统”能成为高分毕设——它不是 CRUD 堆砌而是 SpringBoot Vue 协同落地的完整工程闭环你手头这个标题“基于 SpringBoot Vue 的小区物业管理系统 数据库高分毕设”不是在找一个能跑起来的 demo而是在验证你能否把真实业务场景、分层架构设计、前后端协作边界、数据库建模合理性、以及工程化交付细节这五根骨头一根不漏地炖进同一个 jar 包和 dist 文件夹里。我带过三届毕设答辩翻过 200 份代码仓库高分项目从来不是功能最多那个而是登录页没报错、业主报修单能存进 MySQL、物业工单状态变更实时推到 Vue 页面、导出 Excel 表头对得上字段、部署到学生自己买的 1C2G 阿里云轻量服务器上不 OOM —— 这些看似琐碎的“不翻车”才是答辩老师盯着看的硬指标。它不涉及 AI 大模型或高并发秒杀但恰恰因为业务清晰、流程可溯、数据可验反而最能暴露你对 SpringBoot 生命周期管理、Vue 路由守卫与状态同步、MySQL 索引设计、以及前后端联调中跨域/401/500 错误归因的真实掌控力。适合正在写毕设、卡在“功能都写了但总被说‘像练习题’”的同学也适合想用真实项目练手 SpringBoot Vue 全栈开发的转行者。2. 从零搭起骨架SpringBoot 后端服务初始化与核心模块划分一个高分毕设的后端绝不是spring-boot-starter-web加个RestController就完事。它必须体现分层意识、可测试性、以及对业务边界的尊重。我们按实际开发节奏来先初始化工程再拆解模块职责最后落定关键配置。2.1 初始化 SpringBoot 工程选版本、加依赖、避坑 JDK 版本我强烈建议用SpringBoot 2.7.18LTS 最后一个稳定版而非 3.x。原因很现实毕设答辩环境多为 JDK 8 或 11SpringBoot 3.x 强制要求 JDK 17很多学校机房、答辩电脑装不了spring-boot-starter-thymeleaf、mybatis-spring-boot-starter在 2.7.x 下生态成熟文档齐全出问题搜 StackOverflow 有现成答案Vue 打包后的静态资源放src/main/resources/static目录SpringBoot 2.7 默认静态资源路径兼容性更好不会出现index.html404。用 Spring Initializr 创建时勾选以下最小依赖集!-- pom.xml 关键依赖 -- dependencies dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-data-jpa/artifactId /dependency dependency groupIdmysql/groupId artifactIdmysql-connector-java/artifactId scoperuntime/scope /dependency dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-validation/artifactId /dependency dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-configuration-processor/artifactId optionaltrue/optional /dependency /dependencies提示spring-boot-starter-data-jpa比mybatis更适合毕设——它自动生成 CRUD SQL、支持Query写复杂查询、实体类即映射、无需 XML 映射文件极大降低出错概率。答辩时老师问“你怎么查维修工单按楼栋统计”你直接贴Query(SELECT b.name, COUNT(*) FROM RepairOrder r JOIN Building b ON r.buildingId b.id GROUP BY b.name)比解释 MyBatis 的foreach标签更直观。2.2 模块化分包拒绝com.example.demo一包到底高分项目的包结构是答辩老师打开 IDEA 第一眼就扫的“简历”。按业务域垂直切分而不是按技术层水平切分com.example.propertymgmt ├── config // WebMvcConfigurer、Swagger 配置 ├── controller // RestController只做参数接收、DTO 转换、调 service ├── dto // Data Transfer Object如 RepairOrderCreateDTO ├── entity // JPA Entity对应数据库表含 Entity、Table ├── repository // JpaRepository 接口如 RepairOrderRepository ├── service // 接口 实现含事务控制、业务逻辑如派单规则 │ └── impl ├── exception // 自定义异常如 OrderStatusException、全局异常处理器 └── util // 工具类如 Excel 导出工具、日期格式化关键点controller层绝不写 SQL、不操作数据库、不处理业务规则service实现类方法上必须加Transactional且只标注在 public 方法上JPA 代理机制限制entity中所有字段加Column(nullable false)或NotNull让 Hibernate 在 persist 前就校验而不是等 MySQL 报NULL not allowed。2.3 数据库建模从业务语义出发不是 ER 图搬运工小区物业的核心实体不是“用户”“订单”这种泛化词而是Building楼栋含code如“A栋”、unitCount单元数、floorCount层数House房屋含buildingId、unitNo单元号、floorNo楼层、roomNo房号、ownerName、phoneRepairOrder报修单含houseId、category水电/门窗/网络、status待受理/处理中/已完成、assigneeId指派员工 ID、createTime、finishTimeStaff物业员工含name、position维修工/客服/保安、phone、available是否在职重点避坑RepairOrder.status不用VARCHAR(20)存“待受理”而用TINYINT存枚举值0待受理,1处理中,2已完成Java 层用Enumerated(EnumType.ORDINAL)映射既节省空间又防前端传非法字符串House表加唯一索引UNIQUE KEY uk_building_unit_floor_room (building_id, unit_no, floor_no, room_no)避免同一楼栋重复录入 101 房所有时间字段用LocalDateTimeCreatedDate/LastModifiedDate不要用Date或字符串。3. Vue 前端工程搭建与关键页面实现不只是npm run serveVue 不是炫技舞台而是把后端 API 变成可交互界面的翻译器。高分毕设的前端要体现“能用、不崩、看得懂”。3.1 Vue CLI 初始化与目录规范告别src/views/Home.vue万能页用 Vue CLI 4.5.19兼容 Vue 2.7避免 Composition API 学习成本创建项目禁止把所有页面塞进views目录。按模块组织src/ ├── api/ // 所有 axios 请求封装如 repairApi.js、staffApi.js ├── assets/ // 静态资源图片、字体 ├── components/ // 可复用组件如 TablePagination、StatusBadge ├── router/ // 路由配置含路由守卫 ├── store/ // Vuex简单项目可用复杂状态才上 Pinia ├── utils/ // 工具函数如 formatTime、downloadExcel └── views/ // 页面级组件按业务域分repair/、house/、staff/router/index.js必须加路由守卫防止未登录访问// src/router/index.js import Vue from vue import VueRouter from vue-router import Login from /views/Login.vue Vue.use(VueRouter) const routes [ { path: /login, name: Login, component: Login }, { path: /, component: () import(/layouts/MainLayout.vue), children: [ { path: , redirect: /repair/list }, { path: repair/list, name: RepairList, component: () import(/views/repair/List.vue) }, { path: house/manage, name: HouseManage, component: () import(/views/house/Manage.vue) } ] } ] const router new VueRouter({ routes }) // 全局前置守卫 router.beforeEach((to, from, next) { const token localStorage.getItem(token) if (!token to.path ! /login) { next(/login) } else if (token to.path /login) { next(/) } else { next() } }) export default router注意localStorage.getItem(token)是最简方案毕设不需 JWT 解析或刷新逻辑。答辩时老师问“怎么保证安全”答“生产环境会加 HTTPS 和后端 Session 校验毕设聚焦功能闭环”。3.2 关键页面实现以报修单列表页为例展示真实数据流RepairList.vue不是写死的表格而是体现“请求 → 渲染 → 交互 → 刷新”的完整链路!-- src/views/repair/List.vue -- template div classrepair-list h2报修单管理/h2 el-button typeprimary clickshowCreateDialog true新增报修/el-button el-table :datalist stylewidth: 100%; margin-top: 20px el-table-column propid label编号 width100/el-table-column el-table-column prophouseInfo label房屋 width180/el-table-column el-table-column propcategory label类型 width120 template #defaultscope span :class{text-danger: scope.row.category 水电}{{ scope.row.category }}/span /template /el-table-column el-table-column propstatus label状态 width120 template #defaultscope el-tag :typestatusTagType(scope.row.status){{ statusText(scope.row.status) }}/el-tag /template /el-table-column el-table-column label操作 width180 template #defaultscope el-button sizemini clickhandleEdit(scope.row)编辑/el-button el-button sizemini typedanger clickhandleDelete(scope.row.id)删除/el-button /template /el-table-column /el-table !-- 新增弹窗 -- el-dialog title新增报修单 :visible.syncshowCreateDialog el-form :modelform :rulesrules refformRef el-form-item label房屋 prophouseId el-select v-modelform.houseId placeholder请选择房屋 clearable el-option v-forh in houseOptions :keyh.id :labelh.fullAddress :valueh.id/el-option /el-select /el-form-item el-form-item label类型 propcategory el-select v-modelform.category placeholder请选择类型 el-option label水电 value水电/el-option el-option label门窗 value门窗/el-option el-option label网络 value网络/el-option /el-select /el-form-item el-form-item label描述 propdescription el-input typetextarea v-modelform.description :rows3/el-input /el-form-item /el-form div slotfooter el-button clickshowCreateDialog false取消/el-button el-button typeprimary clicksubmitForm确认/el-button /div /el-dialog /div /template script import { listRepairOrders, createRepairOrder, deleteRepairOrder } from /api/repairApi export default { name: RepairList, data() { return { list: [], showCreateDialog: false, form: { houseId: null, category: , description: }, rules: { houseId: [{ required: true, message: 请选择房屋, trigger: change }], category: [{ required: true, message: 请选择类型, trigger: change }], description: [{ required: true, message: 请填写描述, trigger: blur }] }, houseOptions: [] // 房屋下拉选项需从 API 获取 } }, async mounted() { await this.loadList() await this.loadHouseOptions() // 提前加载房屋列表避免弹窗打开时空白 }, methods: { async loadList() { try { const res await listRepairOrders() this.list res.data.map(item ({ ...item, houseInfo: ${item.buildingCode}-${item.unitNo}-${item.floorNo}-${item.roomNo} })) } catch (err) { this.$message.error(加载报修单失败 err.message) } }, async loadHouseOptions() { // 此处应调用 houseApi 获取为简化示例省略 this.houseOptions [ { id: 1, fullAddress: A栋-1单元-1层-101 }, { id: 2, fullAddress: A栋-1单元-1层-102 } ] }, statusText(status) { const map { 0: 待受理, 1: 处理中, 2: 已完成 } return map[status] || 未知 }, statusTagType(status) { return status 0 ? warning : status 1 ? primary : success }, async submitForm() { this.$refs.formRef.validate(async valid { if (valid) { try { await createRepairOrder(this.form) this.$message.success(新增成功) this.showCreateDialog false this.form { houseId: null, category: , description: } await this.loadList() // 刷新列表 } catch (err) { this.$message.error(提交失败 err.message) } } }) }, handleDelete(id) { this.$confirm(确认删除该报修单, 提示, { confirmButtonText: 确定, cancelButtonText: 取消, type: warning }).then(async () { try { await deleteRepairOrder(id) this.$message.success(删除成功) await this.loadList() } catch (err) { this.$message.error(删除失败 err.message) } }) } } } /script逻辑说明listRepairOrders()返回的是后端 JSON前端不做任何字段改名而是用map生成houseInfo字符串保持数据源纯净statusText()和statusTagType()是纯函数不依赖this方便单元测试submitForm中this.$refs.formRef.validate()是 Element UI 表单校验入口比手动if (!this.form.houseId)更健壮删除用this.$confirm而非直接alert符合企业级交互习惯。3.3 API 封装axios 实例 统一错误拦截不是裸写axios.getsrc/api/repairApi.jsimport axios from axios // 创建独立 axios 实例避免污染全局 const repairApi axios.create({ baseURL: /api/repair, // 与后端 Controller RequestMapping 一致 timeout: 10000 }) // 请求拦截自动带 token repairApi.interceptors.request.use( config { const token localStorage.getItem(token) if (token) { config.headers.Authorization Bearer ${token} } return config }, error Promise.reject(error) ) // 响应拦截统一错误处理 repairApi.interceptors.response.use( response { // 后端约定{ code: 200, data: xxx, msg: ok } if (response.data.code 200) { return response.data } else { return Promise.reject(new Error(response.data.msg || 请求失败)) } }, error { if (error.response?.status 401) { localStorage.removeItem(token) window.location.href /login } return Promise.reject(error) } ) export function listRepairOrders() { return repairApi.get(/list) } export function createRepairOrder(data) { return repairApi.post(/create, data) } export function deleteRepairOrder(id) { return repairApi.delete(/delete/${id}) }参数说明baseURL: /api/repair对应 SpringBoot Controller 的RequestMapping(/api/repair)前后端路径严格对齐interceptors.response中判断response.data.code这是与后端约定的响应体结构不是默认的 HTTP 状态码401拦截后跳转/login比在每个页面catch里写重定向更干净。4. 前后端联调与数据库落地让数据真正流动起来光有前后端代码不等于系统跑通。这一章解决“为什么我点了按钮没反应”“为什么数据库里没数据”“为什么页面显示 null”。4.1 SpringBoot Controller 设计RESTful 规范 DTO 分离 全局异常捕获RepairOrderController.java示例RestController RequestMapping(/api/repair) RequiredArgsConstructor public class RepairOrderController { private final RepairOrderService repairOrderService; /** * 查询报修单列表支持分页 * GET /api/repair/list?page1size10 */ GetMapping(/list) public ResultPageRepairOrderVO list( RequestParam(defaultValue 1) int page, RequestParam(defaultValue 10) int size) { Pageable pageable PageRequest.of(page - 1, size); PageRepairOrderVO result repairOrderService.list(pageable); return Result.success(result); } /** * 新增报修单 * POST /api/repair/create * Body: { houseId: 1, category: 水电, description: 漏水 } */ PostMapping(/create) public ResultString create(Valid RequestBody RepairOrderCreateDTO dto) { repairOrderService.create(dto); return Result.success(创建成功); } /** * 删除报修单 * DELETE /api/repair/delete/123 */ DeleteMapping(/delete/{id}) public ResultString delete(PathVariable Long id) { repairOrderService.delete(id); return Result.success(删除成功); } }关键点Valid RequestBody RepairOrderCreateDTODTO 类上加NotNull等校验注解SpringBoot 自动拦截非法请求并返回 400Pageable pageable PageRequest.of(page - 1, size)JPA 分页从 0 开始前端传page1后端转成0Result...是自定义响应包装类强制所有接口返回统一结构避免前端res.data有时是数组、有时是对象。Result.javaData AllArgsConstructor NoArgsConstructor public class ResultT { private int code; private String msg; private T data; public static T ResultT success(T data) { return new Result(200, ok, data); } public static ResultString success(String msg) { return new Result(200, msg, null); } public static T ResultT fail(String msg) { return new Result(500, msg, null); } }4.2 数据库初始化schema.sql data.sql 双文件不是靠 Hibernate 自动生成Hibernatehibernate.hbm2ddl.autocreate只用于开发初期毕设必须提供可执行的 SQL 脚本这是答辩硬性材料。在src/main/resources下建schema.sql建表语句含注释、索引、外键-- schema.sql CREATE TABLE building ( id bigint NOT NULL AUTO_INCREMENT COMMENT 主键, code varchar(20) NOT NULL COMMENT 楼栋编码如A栋, unit_count int NOT NULL DEFAULT 0 COMMENT 单元数, floor_count int NOT NULL DEFAULT 0 COMMENT 层数, PRIMARY KEY (id), UNIQUE KEY uk_code (code) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT楼栋信息; CREATE TABLE house ( id bigint NOT NULL AUTO_INCREMENT, building_id bigint NOT NULL COMMENT 所属楼栋ID, unit_no varchar(10) NOT NULL COMMENT 单元号, floor_no int NOT NULL COMMENT 楼层, room_no varchar(10) NOT NULL COMMENT 房号, owner_name varchar(50) DEFAULT NULL COMMENT 业主姓名, phone varchar(20) DEFAULT NULL COMMENT 联系电话, PRIMARY KEY (id), UNIQUE KEY uk_building_unit_floor_room (building_id, unit_no, floor_no, room_no), KEY idx_building_id (building_id), CONSTRAINT fk_house_building_id FOREIGN KEY (building_id) REFERENCES building (id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;data.sql插入基础数据3 条楼栋、10 条房屋、5 条报修单-- data.sql INSERT INTO building (code, unit_count, floor_count) VALUES (A栋, 2, 18), (B栋, 2, 18), (C栋, 2, 18); INSERT INTO house (building_id, unit_no, floor_no, room_no, owner_name, phone) VALUES (1, 1单元, 1, 101, 张三, 13800138000), (1, 1单元, 1, 102, 李四, 13800138001), -- ... 其他房屋 ; INSERT INTO repair_order (house_id, category, status, description, create_time) VALUES (1, 水电, 0, 厨房水龙头漏水, 2024-05-01 08:30:00), (2, 门窗, 1, 阳台门关不严, 2024-05-02 14:20:00);提示SQL 文件必须用 UTF-8 编码保存MySQL 客户端执行时加--default-character-setutf8mb4否则中文注释变乱码。4.3 联调排错三板斧curl、浏览器 Network、后端日志当 Vue 页面点击“新增”没反应按顺序排查用 curl 直接调后端接口绕过前端curl -X POST http://localhost:8080/api/repair/create \ -H Content-Type: application/json \ -d {houseId:1,category:水电,description:测试}如果返回{code:200,msg:ok,data:null}→ 后端 OK问题在前端如果返回400 Bad Request→ 检查 DTO 校验失败原因看控制台日志如果返回500→ 看 SpringBoot 控制台堆栈。浏览器 F12 → Network → 查看请求详情看 Request URL 是否为http://localhost:8080/api/repair/create不是/api/repair/create/多了个斜杠看 Request Payload 是否为合法 JSON无 trailing comma看 Response Headers 是否有Content-Type: application/json;charsetUTF-8。后端日志定位在application.yml加日志级别logging: level: com.example.propertymgmt: debug org.springframework.web.servlet.DispatcherServlet: debug启动后看控制台是否有Mapped {[/api/repair/create],methods[POST]}确认 Controller 被扫描到。5. 高分毕设必踩的 5 个坑血泪经验总结别等答辩被问住才后悔高分和及格的分水岭往往就在这些“小地方”。我见过太多同学功能全有却因一个坑被老师当场质疑“这真是你写的吗”。5.1 坑Vue 打包后静态资源 404页面白屏现象npm run build生成dist文件夹把dist整个拷贝到 SpringBoot 的src/main/resources/static下启动项目访问http://localhost:8080显示空白F12 看 Network 里js/app.xxx.js404。原因Vue CLI 默认public/index.html中 script 路径是/js/app.xxx.js但 SpringBoot 静态资源根路径是/所以它去请求http://localhost:8080/js/app.xxx.js而实际文件在static/js/下。解决修改vue.config.js设publicPath为相对路径// vue.config.js module.exports { publicPath: ./, // 关键不是 /也不是 outputDir: dist, assetsDir: static }重新npm run build此时index.html中 script 路径变成static/js/app.xxx.jsSpringBoot 能正确映射。5.2 坑MySQL 中文乱码日志打印 ????现象数据库表字段设了COMMENT 楼栋信息但 Navicat 里显示????SpringBoot 日志打印 SQL 也显示INSERT INTO building (code) VALUES (A??)。原因MySQL 服务端、数据库、表、连接四层编码不一致。常见是服务端character_set_serverutf8但新建数据库没指定CHARSETutf8mb4。解决MySQL 命令行执行ALTER DATABASE propertymgmt CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; ALTER TABLE building CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;application.yml中 JDBC URL 加参数spring: datasource: url: jdbc:mysql://localhost:3306/propertymgmt?useUnicodetruecharacterEncodingutf8mb4serverTimezoneAsia/Shanghai5.3 坑JPA save() 后 getId() 返回 null现象RepairOrder order new RepairOrder(); order.setHouseId(1L); repairOrderRepository.save(order); System.out.println(order.getId());打印null。原因实体类Id字段没配GeneratedValue(strategy GenerationType.IDENTITY)或 MySQL 表id字段没设AUTO_INCREMENT。解决实体类Id GeneratedValue(strategy GenerationType.IDENTITY) private Long id;MySQL 表ALTER TABLE repair_order MODIFY id BIGINT AUTO_INCREMENT;5.4 坑Element UI 表单校验不触发this.$refs.formRef.validate()一直返回 false现象表单有el-form-item但validate()总是false控制台无报错。原因el-form-item的prop值与v-model绑定的 data 字段名不一致。例如prophouseId但 data 里是form.house_id。解决确保prop值完全匹配 data 字段路径且el-form必须有refformRefel-form-item必须有propv-model必须绑定到form.xxx。5.5 坑Vue 路由嵌套路由不显示子组件现象访问/repair/list页面空白但/login能正常显示。原因MainLayout.vue中没写router-view插槽。解决MainLayout.vue必须包含template div classmain-layout Header / Sidebar / div classcontent router-view / !-- 关键没有这行子路由永远不渲染 -- /div /div /template6. 让毕设脱颖而出的 3 个实战技巧从“能跑”到“值得给高分”答辩老师看毕设前 3 分钟决定印象分。下面这三件事花 2 小时做完能让你的项目在一堆“能用就行”的作品里立刻被记住。6.1 技巧一用 Swagger 自动生成 API 文档答辩时现场演示别再手写 Word 文档列接口。SpringBoot 集成 Swagger让接口自描述、可调试、可导出。添加依赖dependency groupIdio.springfox/groupId artifactIdspringfox-swagger2/artifactId version2.9.2/version /dependency dependency groupIdio.springfox/groupId artifactIdspringfox-swagger-ui/artifactId version2.9.2/version /dependency配置类SwaggerConfig.javaConfiguration EnableSwagger2 public class SwaggerConfig { Bean public Docket api() { return new Docket(DocumentationType.SWAGGER_2) .select() .apis(RequestHandlerSelectors.basePackage(com.example.propertymgmt.controller)) .paths(PathSelectors.any()) .build() .apiInfo(apiInfo()); } private ApiInfo apiInfo() { return new ApiInfoBuilder() .title(小区物业管理系统 API 文档) .description(毕设项目后端接口说明) .version(1.0) .build(); } }启动项目后访问http://localhost:8080/swagger-ui.html所有RestController接口自动列出支持在线调试。答辩时打开这个页面点 “Try it out”输入参数点 Execute当场返回 JSON 结果——老师会点头“嗯工程规范。”6.2 技巧二给关键操作加 Excel 导出且表头中文可读毕设常被问“数据怎么导出” 如果只答“用 Navicat”显得业余。加一个导出按钮导出当前列表为 Excel表头是“报修编号”“房屋地址”“报修类型”不是idhouseIdcategory。后端RepairOrderController加接口GetMapping(/export) public void export(HttpServletResponse response) throws IOException { ListRepairOrderVO list repairOrderService.listAll(); // 获取全部 // 使用 Apache POI 或更轻量的 easyexcel EasyExcel.write(response.getOutputStream(), RepairOrderExportDTO.class) .sheet(报修单列表) .doWrite(list.stream().map(this::convertToExportDTO).collect(Collectors.toList())); }RepairOrderExportDTO.java专为导出设计的 DTOData public class RepairOrderExportDTO { ExcelProperty(报修编号) private Long id; ExcelProperty(房屋地址) private String houseAddress; // 拼接好的字符串 ExcelProperty(报修类型) private String category; ExcelProperty(状态) private String statusText; // 0→待受理 ExcelProperty(创建时间) DateTimeFormat(pattern yyyy-MM-dd HH:mm:ss) private LocalDateTime createTime; }前端调用handleExport() { window.open(/api/repair/export, _blank) }注意window.open绕过 axios 拦截器所以不用带 token后端export方法不校验权限毕设简化但加了ResponseBody注解会导致返回 JSON必须用HttpServletResponse直接写流。6.3 技巧三用 Actuator 暴露健康检查端点证明你懂运维SpringBoot Actuator 是生产级监控入口。加一个/actuator/health返回{ status: UP }说明你的应用是活的。加依赖dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-actuator/artifactId /dependencyapplication.yml开放端点management: endpoints: web: exposure: p a hrefhttps://download.csdn.net/download/weixin_55305220/90520684 stylecolor:#ec7500;font-size:14px; 本文还有配套的精品资源点击获取 /a img altmenu-r.4af5f7ec.gif srchttps://csdnimg.cn/release/wenkucmsfe/public/img/menu-r.4af5f7ec.gif stylewidth:16px;margin-left:4px;vertical-align:text-bottom;cursor:text; /p
返回列表