
简介在当今数字化浪潮中Web应用开发已成为连接用户与服务的重要桥梁。其核心原理在于通过前后端分离的架构实现数据与界面的高效交互。SpringBoot作为Java领域主流的后端框架以其“约定大于配置”的理念极大地简化了企业级应用的开发与部署流程技术价值在于能够帮助开发者快速构建稳健、可扩展的RESTful API服务。微信小程序则凭借其无需安装、即用即走的特性成为连接海量用户的轻量级前端解决方案尤其适合政务服务、电商、工具类等应用场景。本文聚焦于一个典型的综合性实践——乡村政务服务系统深入剖析如何将SpringBoot后端与微信小程序前端进行技术整合并重点探讨了JWT用户认证、审批流程的事务控制以及数据库查询优化等工程实践中的关键问题为开发者构建类似系统提供了一套完整、可落地的技术方案。1. 项目概述与核心价值最近几年无论是学校里的课程设计还是企业里的实际项目基于SpringBoot和微信小程序的组合开发模式越来越常见。我带的几个应届生还有不少来找我咨询的学弟学妹他们的毕业设计选题也大多集中在这个方向。今天要聊的这个“乡村政务服务系统”就是一个非常典型且具有现实意义的毕业设计选题。它不是一个简单的增删改查练习而是将后端Java技术栈、前端小程序生态和具体的民生服务场景紧密结合的综合性项目。这个系统的核心目标是为乡村居民提供一个便捷、高效的线上办事窗口。想象一下村民不用再为了开个证明、咨询个政策跑几里路去村委会或乡镇府而是通过手机上的微信小程序就能完成信息查询、业务申请、进度跟踪等一系列操作。对于管理者村委、乡镇工作人员而言则可以通过一个功能完善的后台管理系统高效处理这些线上申请实现政务服务的数字化、流程化。从技术角度看它涵盖了SpringBoot后端API开发、微信小程序前端交互、数据库设计与优化、前后端数据通信、文件上传处理、权限控制等多个核心技能点完全能够支撑起一个优秀的本科甚至硕士毕业设计。选择这个题目高分几乎是必然的。因为它不仅技术栈主流、完整更重要的是它“有用”。评委老师看到的不再是冷冰冰的学生信息管理系统而是一个能解决实际社会问题、有明确应用场景的方案。接下来我会把这个项目从设计思路到关键实现再到那些容易踩坑的细节掰开揉碎了讲清楚希望能给正在或即将着手类似项目的同学一些实实在在的参考。2. 系统整体架构与设计思路拆解做一个项目最怕一开始思路不清写到一半推倒重来。对于这个乡村政务服务系统我们首先得在脑子里搭好它的骨架。2.1 业务模型与核心模块划分系统的用户主要分为两类村民小程序端用户和政务管理员Web后台管理端用户。他们的核心诉求截然不同这直接决定了我们的功能模块设计。对于村民来说核心诉求是“方便办事”。因此小程序端需要围绕“服务”展开信息服务政策法规、村务公开、通知公告的浏览与查询。这是最基础的信息获取功能。办事服务在线申请各类证明如居住证明、贫困证明、预约办理业务、提交各类申报材料。这是系统的核心交互功能。互动服务问题咨询、投诉建议、满意度评价。这能形成服务的闭环提升体验。个人中心我的申请、办理进度跟踪、个人信息维护。对于政务管理员来说核心诉求是“高效管理”。因此后台管理系统需要围绕“审批”和“管理”展开内容管理对前端展示的政策、通知等信息进行发布、编辑、下架。业务审批处理村民提交的各类申请进行审核、驳回、办结等操作并能更新进度。用户管理管理村民账号信息通常由村民自行注册管理员可进行审核或信息维护。数据统计统计各类业务的申请量、办结率、用户活跃度等为决策提供支持。系统管理角色权限管理、操作日志查看等。基于以上分析我们的后端SpringBoot项目可以按功能模块进行分包例如controller控制层、service业务逻辑层、dao/mapper数据访问层是基础分层。此外可以按业务域建立不同的包如module下包含user用户、policy政策、application办事申请、approval审批流程等这样结构清晰便于协作和维护。2.2 技术栈选型与考量为什么是SpringBoot 微信小程序这个组合几乎是当前轻量级、快速开发类项目的“黄金搭档”。后端SpringBoot 2.x (建议 2.7.x稳定版)理由它极大地简化了Spring应用的初始搭建和开发过程。“约定大于配置”的理念让我们能快速构建出独立运行、生产级别的基于Spring框架的应用程序。内嵌Tomcat打包成Jar直接运行部署极其方便。对于毕业设计而言它能让你把精力集中在业务逻辑上而不是繁琐的XML配置。关键依赖spring-boot-starter-web: 提供Web MVC支持用于开发RESTful API。mybatis-spring-boot-starter或spring-boot-starter-data-jpa: 数据库持久层框架。MyBatis更灵活SQL可控性强JPA更面向对象开发速度快。根据个人熟悉程度选择我倾向于MyBatis因为毕业设计常需要展示复杂的查询SQL。spring-boot-starter-security或shiro: 安全与权限控制。Spring Security功能强大但稍重Shiro轻量简单。对于这个系统Shiro可能更易上手。druid-spring-boot-starter: 阿里巴巴的数据库连接池提供强大的监控功能。spring-boot-starter-validation: 参数校验。knife4j-spring-boot-starter: 集成Swagger自动生成API文档前后端联调和答辩演示时非常有用。hutool-all: 国产工具类库能极大提升开发效率。前端小程序微信小程序原生框架 Vant Weapp理由微信小程序无需安装、触手可及、开发成本低完美契合乡村居民使用习惯微信普及率高。使用原生框架能保证最佳性能和兼容性。UI库选择微信官方组件基础但样式可能不够丰富。推荐引入Vant Weapp这是一个轻量、可靠的移动端组件库提供了按钮、表单、弹窗、导航栏等大量现成组件能极大提升开发效率和界面美观度。数据库MySQL 8.0理由开源、流行、资料丰富是学习关系型数据库的首选。8.0版本在性能、JSON支持、窗口函数等方面有增强。对于这个系统完全够用且是主流选择。其他工具项目管理Maven 或 Gradle。SpringBoot默认支持Maven学习资源多。IDEIntelliJ IDEA (后端) 微信开发者工具 (前端)。API测试Postman 或 Apifox。版本控制Git代码托管到Gitee或GitHub注意敏感信息。注意技术选型不是越新越好。毕业设计追求的是稳定、完整、可演示。避免使用过于前沿或尚未广泛验证的版本比如SpringBoot 3.x初期版本以免遇到难以解决的兼容性问题耽误进度。2.3 数据库设计核心要点数据库设计是项目的基石设计不好后期编码会处处掣肘。这里强调几个关键点用户表 (sys_user)需要区分用户类型user_type: 0-村民1-管理员。村民的注册信息可能包括身份证号、所属村组等。密码存储必须加密使用BCrypt或更安全的算法绝对不要明文存储。权限相关表如果权限设计稍复杂可以采用经典的用户-角色-权限模型建立sys_role,sys_menu,sys_user_role,sys_role_menu等表。如果简单可以在用户表加一个role字段标识。核心业务表如biz_policy政策表、biz_notice通知表。重点是办事申请流程表例如biz_application。这个表的设计至关重要。它需要包含申请人ID、申请业务类型、申请内容、提交材料可以是文件路径或JSON、申请状态如待审核、审核中、已通过、已驳回、已办结、当前处理人、审批意见、各环节时间戳提交时间、审核时间、办结时间等。状态流转是核心逻辑要在设计时考虑清楚所有可能的状态和触发状态变更的操作。文件存储村民上传的身份证照片、证明文件等如何处理方案一简单在服务器本地创建目录存储数据库中保存相对路径如/upload/202405/xxx.jpg。但需注意备份和分布式部署时的文件同步问题。方案二推荐使用对象存储服务如阿里云OSS、腾讯云COS。它们提供高可靠、高可用的存储自带CDN加速并且有现成的SDK易于集成。毕业设计可以申请免费额度这会是项目的一个亮点。索引优化在经常用于查询条件的字段上建立索引如用户表的username、phone申请表的applicant_id、status、create_time。但不宜过多影响写入性能。3. 后端SpringBoot核心实现详解后端是整个系统的大脑负责数据处理、业务逻辑和API提供。我们聚焦几个最核心、最容易出问题的环节。3.1 项目初始化与基础配置使用 Spring Initializr 或 IDEA 内置的 Spring Initializer 快速生成项目骨架。选好依赖Web, MyBatis, MySQL Driver等。关键配置application.ymlserver: port: 8080 servlet: context-path: /api # 统一API前缀 spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/village_gov?useUnicodetruecharacterEncodingUTF-8serverTimezoneAsia/Shanghai username: root password: yourpassword type: com.alibaba.druid.pool.DruidDataSource # 使用Druid连接池 druid: initial-size: 5 min-idle: 5 max-active: 20 test-on-borrow: true mybatis: mapper-locations: classpath:mapper/*.xml # MyBatis映射文件位置 configuration: map-underscore-to-camel-case: true # 自动驼峰命名转换非常重要 # 文件上传配置 spring: servlet: multipart: max-file-size: 10MB max-request-size: 20MB # 自定义配置例如文件存储路径 village: file: upload-path: /opt/upload/village/ # Linux路径示例Windows可设为 D:/upload/village/实操心得serverTimezoneAsia/Shanghai这个参数一定要加否则插入时间数据时可能会遇到时区问题。map-underscore-to-camel-case: true能省去你大量在实体类字段和数据库列名之间手动映射的麻烦。3.2 用户认证与权限控制实现小程序端用户和管理员都需要登录。这里我们采用JWT (JSON Web Token)拦截器的方案它无状态、适合前后端分离。引入JWT依赖在pom.xml中添加jjwt相关依赖。编写JWT工具类包含生成Token、解析Token、校验Token有效性的方法。登录接口 (/auth/login)接收用户名/密码或微信小程序传来的code需调用微信接口换openid这里简化。校验用户信息。校验成功后生成一个JWT TokenPayload中可包含用户ID、用户名、角色等信息返回给前端。前端小程序需要将此Token存储在本地如wx.setStorageSync(token, res.token)并在后续所有请求的Header中携带Authorization: Bearer token。创建认证拦截器拦截除了登录、注册等公开接口外的所有请求。从Header中取出Token利用JWT工具类进行校验。校验通过将用户信息存入ThreadLocal或SecurityContext方便后续业务层使用校验失败返回401状态码。权限注解可以自定义一个如RequiresRoles(admin)的注解结合AOP或拦截器在方法执行前判断当前用户是否拥有所需角色。// 示例简单的登录Controller方法 PostMapping(/login) public Result login(RequestBody LoginForm form) { // 1. 校验验证码如果有 // 2. 根据用户名查询用户 SysUser user userService.getByUsername(form.getUsername()); // 3. 判断用户是否存在、密码是否匹配使用BCrypt加密校验 if(user null || !passwordEncoder.matches(form.getPassword(), user.getPassword())) { return Result.fail(用户名或密码错误); } // 4. 生成JWT Token String token JwtUtil.generateToken(user.getId(), user.getUsername(), user.getRole()); // 5. 返回Token和用户基本信息避免返回密码 MapString, Object data new HashMap(); data.put(token, token); data.put(userInfo, new UserVo(user)); // 转换为视图对象 return Result.success(data); }3.3 业务逻辑层办事申请与审批流程这是系统的业务核心。我们以“开具居住证明”申请为例。实体类设计 (BizApplication)Data TableName(biz_application) // 假设使用MyBatis-Plus public class BizApplication { private Long id; private String applicationNo; // 申请编号可生成唯一流水号 private Long applicantId; // 申请人ID private Integer type; // 申请类型1-居住证明2-贫困证明... private String content; // 申请事由/内容 private String attachmentPaths; // 附件路径多个可用JSON数组或逗号分隔 private Integer status; // 状态0-草稿1-已提交待审核2-审核中3-已通过4-已驳回5-已办结 private Long currentHandlerId; // 当前处理人ID private String approvalComment; // 审批意见 private Date submitTime; private Date approvalTime; private Date finishTime; // ... 其他字段 }Service层核心方法submitApplication(ApplicationDTO dto): 提交申请。校验参数生成申请单号设置状态为“待审核”保存到数据库。这里可能涉及文件上传。getMyApplications(Long userId, Integer status): 查询我的申请列表支持按状态筛选。getApplicationDetail(Long id): 获取申请详情包括关联的审批记录。approveApplication(ApproveDTO dto): 审批申请。这是最复杂的方法。Transactional(rollbackFor Exception.class) // 事务管理 public void approve(ApproveDTO dto) { BizApplication application getById(dto.getApplicationId()); if (application null) throw new BusinessException(申请不存在); if (!application.getStatus().equals(StatusEnum.PENDING.getCode())) { throw new BusinessException(当前申请状态不允许审批); } // 权限校验当前登录用户是否有权处理此申请 if (!application.getCurrentHandlerId().equals(getCurrentUserId())) { throw new BusinessException(无权处理此申请); } // 更新申请单状态和意见 application.setStatus(dto.getApproved() ? StatusEnum.APPROVED.getCode() : StatusEnum.REJECTED.getCode()); application.setApprovalComment(dto.getComment()); application.setApprovalTime(new Date()); application.setCurrentHandlerId(null); // 处理完成清空当前处理人 updateById(application); // 记录审批日志 ApprovalLog log new ApprovalLog(); log.setApplicationId(application.getId()); log.setHandlerId(getCurrentUserId()); log.setAction(dto.getApproved() ? 通过 : 驳回); log.setComment(dto.getComment()); approvalLogService.save(log); // TODO: 如果通过可能触发后续流程如通知申请人、转交下一环节 // TODO: 发送微信模板消息通知申请人审批结果 }注意事项审批操作必须加事务注解Transactional确保申请状态更新和审批日志记录要么同时成功要么同时失败保证数据一致性。同时并发控制需要考虑比如使用乐观锁版本号防止同一申请被多人同时处理。3.4 文件上传与对象存储集成如前所述使用对象存储是更优解。以阿里云OSS为例引入OSS SDK依赖。配置OSS客户端Bean。编写文件上传工具类Component public class OssUtil { Value(${aliyun.oss.endpoint}) private String endpoint; Value(${aliyun.oss.bucket-name}) private String bucketName; Autowired private OSS ossClient; public String upload(MultipartFile file, String filePath) { try { // 生成唯一文件名防止覆盖 String originalFilename file.getOriginalFilename(); String suffix originalFilename.substring(originalFilename.lastIndexOf(.)); String fileName filePath / UUID.randomUUID() suffix; // 上传 ossClient.putObject(bucketName, fileName, file.getInputStream()); // 返回文件的访问URL可能需要拼接或设置Bucket为公共读 return https:// bucketName . endpoint / fileName; } catch (IOException e) { throw new RuntimeException(文件上传失败, e); } } }在Controller中调用PostMapping(/upload) public Result uploadFile(RequestParam(file) MultipartFile file) { if (file.isEmpty()) return Result.fail(文件为空); // 可按业务/日期分目录存储如 application/20240517/ String filePath application/ LocalDate.now().format(DateTimeFormatter.ofPattern(yyyyMMdd)); String url ossUtil.upload(file, filePath); return Result.success(url); // 将URL返回给前端保存 }踩坑记录前端小程序上传文件时需要将得到的临时文件路径res.tempFilePaths通过wx.uploadFileAPI 上传到你的后端接口。后端接口接收的参数名 (RequestParam(file)) 必须和小程序上传时的name字段一致。4. 微信小程序前端开发关键点小程序端是直接面向村民的窗口体验至关重要。4.1 项目结构与配置小程序目录结构清晰pages页面、components组件、utils工具、app.js/json/wxss全局。在app.json中注册页面和配置全局样式尤其是导航栏和tabBar如果底部有菜单。网络请求封装这是第一个要做的统一处理请求、Token、加载状态和错误。// utils/request.js const baseURL https://your-domain.com/api; // 你的后端API地址 const request (options) { return new Promise((resolve, reject) { wx.request({ url: baseURL options.url, method: options.method || GET, data: options.data, header: { Content-Type: application/json, Authorization: wx.getStorageSync(token) ? Bearer wx.getStorageSync(token) : // 携带Token }, success: (res) { if (res.statusCode 200) { if (res.data.code 200) { // 假设你的后端统一返回格式 {code, msg, data} resolve(res.data.data); } else if (res.data.code 401) { // Token过期或无效跳转到登录页 wx.removeStorageSync(token); wx.showToast({ title: 登录已过期, icon: none }); wx.reLaunch({ url: /pages/login/login }); reject(res.data); } else { wx.showToast({ title: res.data.msg || 请求失败, icon: none }); reject(res.data); } } else { reject(res); } }, fail: (err) { wx.showToast({ title: 网络错误, icon: none }); reject(err); } }); }); }; // 导出get, post等方法 module.exports { get, post };4.2 核心页面开发办事申请与进度查询以“我要办事”页面为例通常是一个列表页展示可办理的业务类型点击进入申请表单页。申请表单页 (pages/apply/form)表单组件使用Vant Weapp的Field输入框、Uploader上传组件、Picker选择器等构建表单。数据绑定在Page的data中定义表单数据对象通过wx:model或手动绑定bindinput事件实现双向绑定。文件上传// 选择文件 chooseFile() { wx.chooseImage({ count: 3, success: (res) { const tempFilePaths res.tempFilePaths; this.setData({ tempFilePaths }); // 临时预览 // 实际上传在后端保存时进行 } }); }, // 提交表单 async submitForm() { const { formData, tempFilePaths } this.data; // 1. 前端校验 if (!formData.content) { wx.showToast({ title: 请填写申请事由, icon: none }); return; } // 2. 上传文件如果有 let uploadedUrls []; if (tempFilePaths tempFilePaths.length 0) { wx.showLoading({ title: 上传文件中... }); for (let path of tempFilePaths) { const url await this.uploadFile(path); // 调用封装的upload方法 uploadedUrls.push(url); } wx.hideLoading(); } // 3. 组装数据调用提交API const applyData { ...formData, attachmentPaths: uploadedUrls.join(,) }; const result await request.post(/application/submit, applyData); wx.showToast({ title: 提交成功 }); setTimeout(() wx.navigateBack(), 1500); }状态管理申请提交后跳转到“我的申请”列表页。列表页需要展示申请单号、类型、状态、提交时间。状态最好用标签形式展示不同状态不同颜色更直观。4.3 用户体验优化与注意事项登录态维护在app.js的onLaunch中检查本地是否有Token并尝试静默登录或跳转登录页。Token快过期时可以在请求拦截中尝试刷新Token。本地缓存对于不常变的数据如政策分类、村组列表可以在首次加载后存入wx.setStorageSync并设置过期时间减少不必要的网络请求。下拉刷新与上拉加载列表页务必实现。使用页面的onPullDownRefresh和onReachBottom生命周期函数。表单防重复提交在提交按钮点击后立即将其设为disabled状态直到请求返回。适配与样式使用rpx单位并在不同尺寸手机上测试。Vant Weapp组件默认使用px可以通过配置转换。5. 数据库设计与优化实战光有表结构设计还不够如何写出高效的SQL如何应对数据增长是区分普通项目和优秀项目的关键。5.1 核心表结构DDL示例-- 用户表 CREATE TABLE sys_user ( id bigint(20) NOT NULL AUTO_INCREMENT COMMENT 主键, username varchar(50) NOT NULL COMMENT 用户名/登录账号, password varchar(255) NOT NULL COMMENT 加密后的密码, nickname varchar(50) DEFAULT NULL COMMENT 用户昵称, phone varchar(20) DEFAULT NULL COMMENT 手机号, user_type tinyint(4) NOT NULL DEFAULT 0 COMMENT 用户类型0-村民1-管理员, village_group varchar(100) DEFAULT NULL COMMENT 所属村组, id_card varchar(20) DEFAULT NULL COMMENT 身份证号, avatar varchar(500) DEFAULT NULL COMMENT 头像, status tinyint(4) NOT NULL DEFAULT 1 COMMENT 状态0-禁用1-正常, create_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 创建时间, update_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 更新时间, PRIMARY KEY (id), UNIQUE KEY uk_username (username), KEY idx_phone (phone), KEY idx_user_type (user_type) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT系统用户表; -- 办事申请表 CREATE TABLE biz_application ( id bigint(20) NOT NULL AUTO_INCREMENT, application_no varchar(30) NOT NULL COMMENT 申请编号规则APP年月日序列号, applicant_id bigint(20) NOT NULL COMMENT 申请人ID, type tinyint(4) NOT NULL COMMENT 申请类型, title varchar(200) NOT NULL COMMENT 申请标题, content text COMMENT 申请详情, attachment_paths json DEFAULT NULL COMMENT 附件路径JSON数组, status tinyint(4) NOT NULL DEFAULT 1 COMMENT 状态1-待审核2-审核中3-已通过4-已驳回5-已办结, current_handler_id bigint(20) DEFAULT NULL COMMENT 当前处理人ID, approval_comment varchar(500) DEFAULT NULL COMMENT 审批意见, submit_time datetime DEFAULT NULL COMMENT 提交时间, approval_time datetime DEFAULT NULL COMMENT 审批时间, finish_time datetime DEFAULT NULL COMMENT 办结时间, create_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, update_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (id), UNIQUE KEY uk_application_no (application_no), KEY idx_applicant_id (applicant_id), KEY idx_status (status), KEY idx_create_time (create_time), KEY idx_handler_id (current_handler_id), CONSTRAINT fk_applicant FOREIGN KEY (applicant_id) REFERENCES sys_user (id) ON DELETE CASCADE ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT办事申请表;设计要点application_no设计为唯一键便于查询和展示。attachment_paths使用JSON类型MySQL 5.7支持比用逗号分隔的字符串更规范便于解析。外键约束 (FOREIGN KEY) 能保证数据完整性但在高并发写入场景下可能影响性能可根据实际情况决定是否使用。5.2 复杂查询与性能优化后台管理端经常需要复杂的多条件分页查询例如“查询某个村组、某段时间内、状态为‘已通过’的贫困证明申请”。MyBatis XML映射文件示例select idselectApplicationPage resultTypecom.example.vo.ApplicationVO SELECT a.*, u.nickname as applicant_name, u.phone as applicant_phone, h.nickname as handler_name FROM biz_application a LEFT JOIN sys_user u ON a.applicant_id u.id LEFT JOIN sys_user h ON a.current_handler_id h.id where if testquery.type ! null AND a.type #{query.type} /if if testquery.status ! null AND a.status #{query.status} /if if testquery.applicantName ! null and query.applicantName ! AND u.nickname LIKE CONCAT(%, #{query.applicantName}, %) /if if testquery.villageGroup ! null and query.villageGroup ! AND u.village_group #{query.villageGroup} /if if testquery.startTime ! null AND a.create_time #{query.startTime} /if if testquery.endTime ! null AND a.create_time #{query.endTime} /if /where ORDER BY a.create_time DESC /select性能陷阱LIKE %xxx%这种前置模糊查询会导致索引失效。如果applicantName查询频繁且数据量大需要考虑使用搜索引擎如Elasticsearch或对查询模式进行优化如改为后缀匹配LIKE xxx%这能利用索引。分页优化当数据量很大时比如超过100万条传统的LIMIT offset, size在offset很大时非常慢。方案一推荐使用基于主键ID的分页。查询时记录上一页最后一条记录的ID下一页查询条件为WHERE id lastId LIMIT size。这要求排序字段是主键或唯一索引。方案二使用MyBatis-Plus等框架提供的分页插件并确保ORDER BY的字段有索引。5.3 数据一致性保障事务如前所述涉及多表更新的操作如审批必须使用Transactional。乐观锁在高并发场景下更新操作可以使用版本号字段 (version)在更新时带上版本条件UPDATE table SET ... WHERE id#{id} AND version#{version}防止更新丢失。定时任务有些业务需要定时处理比如自动将超过3天未处理的申请标记为“超时”。可以使用Spring的Scheduled注解或更强大的分布式任务框架如XXL-JOB可作为扩展亮点。6. 项目部署、演示与答辩准备一个能跑起来的系统才是好系统。部署和演示是毕业设计的临门一脚。6.1 后端项目打包与部署打包在项目根目录执行mvn clean package -DskipTests会在target目录生成一个*.jar文件。服务器准备购买一台云服务器学生常有优惠安装好JDK版本与开发环境一致、MySQL。上传与运行将Jar包和配置文件如application-prod.yml上传到服务器。使用nohup命令在后台运行nohup java -jar village-gov-system.jar --spring.profiles.activeprod app.log 21 使用Nginx反向代理让后端API可以通过80/443端口访问并解决跨域问题。server { listen 80; server_name your-domain.com; # 你的域名或服务器IP location /api/ { proxy_pass http://127.0.0.1:8080; # 转发到SpringBoot应用 proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } # 可以配置静态资源目录存放上传的文件如果没用OSS location /upload/ { alias /opt/upload/village/; } }配置域名与HTTPS为你的服务器域名申请SSL证书很多云平台提供免费证书在Nginx中配置HTTPS提升安全性。6.2 微信小程序上线前准备配置服务器域名在小程序管理后台的“开发管理”-“开发设置”中将你的后端API域名如https://your-domain.com添加到request合法域名列表中。必须使用HTTPS。体验版测试上传代码为体验版邀请同学老师扫码测试充分进行功能、兼容性、性能测试。审核与发布提交审核前确保小程序符合平台规范无违规内容。审核通过后即可发布。6.3 答辩PPT与文档撰写要点答辩不仅仅是演示功能更是展示你系统性思考、解决问题能力的过程。PPT结构建议项目背景与意义1-2页讲清楚为什么做这个系统解决了什么痛点。系统设计与架构2-3页展示整体架构图技术栈、功能模块图、核心数据库ER图。核心功能演示3-4页录屏将小程序端村民申请、后台管理员审批的完整流程录制成高清视频嵌入PPT。现场网络不稳定录屏最保险。同时可准备现场演示。关键技术实现与难点2-3页挑1-2个亮点讲深比如JWT认证流程、审批事务控制、文件上传OSS集成、复杂查询优化。展示关键代码片段不要大段贴。项目总结与展望1页总结收获客观说明当前不足如未做压力测试、UI可进一步美化并提出可行的优化方向如引入消息队列异步处理、增加数据可视化大屏。使用文档编写简洁清晰的README.md放在项目根目录。内容应包括项目简介、技术栈、快速启动指南如何导入、配置、运行、主要功能说明、接口文档地址Swagger链接等。数据库设计文档导出数据库表结构的SQL文件并附上简要说明。最后也是最重要的建议从项目启动第一天起就用Git做好版本管理。每一次大的功能提交都写清晰的commit信息。这不仅能防止代码丢失在答辩时展示你的Git提交历史图也是你项目管理能力和严谨态度的有力证明。这个项目做下来只要你真正理解了上述每个环节并动手实现它绝对能成为你简历上浓墨重彩的一笔也是你迈向职业开发者的坚实一步。本文还有配套的精品资源点击获取