☰
基于Spring Boot与MyBatis的农村住宅信息管理系统设计与实现
2026/10/13 5:55:20 网站建设 项目流程

1. 项目整体拆解与需求分析

每年到了这个节点,总有朋友在前端后台两头折腾,熬夜赶工一个Java毕设系统。我这些年陆续接触过不少类似项目,看得最多的就是“管理系统”这三个字——班级管理、图书管理、仓库管理,换汤不换药。但“农村住宅房屋信息管理”这个题目,却值得单独拿出来拆一拆。它表面是一个常规的增删改查系统,实际上藏了三个层面的东西:一是房屋档案的登记与归档,二是宅基地使用状态的动态跟踪,三是乡镇到村一级的分级管理需求。把这些想清楚了,系统才不会沦为花架子,答辩的时候也才有东西可讲。

说白了,这个项目的目标是做一个基于Java技术栈的农村住宅信息管理应用系统,核心是“管房”,但服务的其实是“人”——包括村里的管理员、乡镇的审核人员、系统运维人员,以及之后可能要对接的上级平台。刚才说的这些角色,决定了系统不能只做一个单机版的信息录入工具,而是需要有多角色、多权限、多状态流转的完整业务流程。

我理解这个题目的核心价值在于:它把“房屋”这个物理实体,抽象成了可管理的数据对象。你可以通过户主姓名、房屋编号、建造年份、结构类型、是否危房、是否空置等维度进行查询统计,还能把照片、产权证编号、宅基地面积这些附件一并管起来。对毕设来说,这正好能覆盖到Java Web开发中的大部分核心考点——面向对象建模、Spring Boot自动配置、MyBatis动态SQL、MySQL表关系设计、以及前端框架的数据绑定。

再说说适合谁来参考。如果你是计算机相关专业的学生,需要完成一个能用、能演示、能讲清楚的毕设,这个题目非常合适。它不像商城秒杀那样卷并发,也不像推荐系统那样拼算法,但它考察的是你“把需求落地成工程”的能力。尤其是论文里可以写的技术点非常多:Spring Boot的依赖注入与自动装配、JWT登录鉴权、拦截器/切面日志、动态SQL查询优化、数据字典与枚举状态流转,每一块都能展开写清楚,论文方向也容易确定。

  1. 这个系统能解决的实际问题也很直观。过去村里的房屋档案可能是一摞纸质表格,排查危房要翻半天;现在你把它变成系统里的结构化记录,按条件一筛就出来了。房屋状态从“正常居住”变更为“危房鉴定待复核”,也只需要在系统里完成一次状态流转,留痕清晰。这正好呼应了农村住宅信息化管理中的真实痛点:档案数字化、状态可追踪、权限有分级。

1.1 项目功能全景图

我习惯在动手写代码之前,把功能模块列成一张清单,越细越好。这个项目我建议划分为九大模块,每个模块对应一套完整的接口和页面:

  • 系统登录与账号管理:支持账号密码登录,登录后根据角色动态显示菜单,管理端可以创建不同角色的账号并重置密码。
  • 房屋档案管理:房屋基本信息的新增、修改、删除、详情查看,支持批量导入和照片上传,字段包含户主信息、宅基地信息、房屋结构、建筑年代等。
  • 户主与家庭成员管理:维护户主身份证号、联系方式、家庭成员人数,户主可作为独立实体,与房屋建立一对多关系。
  • 房屋状态管理:状态字典包含正常居住、闲置空置、危房待鉴定、坍塌拆除等,状态变更需要记录操作人和变更时间。
  • 综合查询与统计报表:按乡镇、村、建筑年代、结构类型等维度组合筛选,同时生成统计图表,用于反映某区域房屋安全情况。
  • 宅基地与产权信息管理:记录宅基地批准面积、实际建筑面积、产权证编号,判断是否存在超占面积。
  • 附件管理:房屋照片、扫描件等文件统一存储,支持在线预览和下载。
  • 操作日志与审计:关键操作记录日志,谁在什么时间改了什么信息,原始值和新值对照保存。
  • 系统设置:数据字典维护、菜单管理、系统参数配置。

这份功能清单基本可以支撑一篇合格的毕业设计论文的第三章,同时也是项目答辩时功能演示的索引。功能划分要特别注意“状态管理”和“日志审计”这两个点,它们是区分普通CRUD项目和完整管理系统的重要分界线。

1.2 技术选型思路解析

技术选型不能拍脑袋,要站在“答辩稳、开发快、演示顺”三个角度综合考虑。Java生态里,Spring Boot是当前主流中的主流,它简化了配置,也让项目结构更加清晰。持久层我建议搭配MyBatis,因为查询条件多、组合逻辑复杂,MyBatis的动态SQL处理起来非常顺手;如果更习惯Spring Data JPA,也不是不行,但对复杂统计查询的把控会稍微麻烦一些。

前端层面,如果追求快速开发和稳定演示,直接用Thymeleaf模板渲染服务端页面是最稳的方案;如果希望界面更现代一点,前后端分离,Vue + Element Plus也是常见选择。考虑到毕设答辩现场的网络环境和服务稳定性,我建议后端接口 + 本地打包的前端静态资源部署方式,不要在生产环境上依赖前端开发服务器。数据库选MySQL 8.x,原因很简单——它在高校里普及率最高,出问题容易找到解决办法,而且支持JSON字段,对扩展灵活度有帮助。

做个小对比,方便你答辩时讲选型理由:

对比项Spring Boot + MyBatis + MySQL可选替代方案
开发上手速度高,社区资料多,模板方案常见JSP + Servlet,老旧且繁琐
动态查询支持很强,<if>、<where>标签灵活拼SQLJPA规范性强但复杂查询要拼Specification
统计报表支持SQL group by + 简单聚合即可NoSQL方案反而复杂
答辩讲解难度易,Spring Boot自动配置本身就是亮点框架太新或太旧都不好讲

除了框架,还要注意统一样式。管理后台的表单、表格、按钮风格建议直接采用一个开源Admin主题,比如Simple Admin或Pear Admin这类模板,把时间花在业务功能上,而不是反复调CSS。界面是不是华丽不太重要,整洁清晰、操作流程完整才关键。

2. 核心细节解析与数据模型设计

2.1 角色权限体系怎么设计才稳

在“农村住宅信息管理”这个业务场景里,角色权限不能只做一套简单的登录鉴权,而是要根据“县—乡镇—村”的实际层级来设计。我建议设置四种角色:系统管理员(超管)、乡镇管理员、村级信息员、普通访客(比如上级检查时用的只读账号)。

权限策略使用RBAC模型,即用户—角色—权限三级关联。后端实现时,不需要引入过于庞大的权限框架,用Spring Security或者拦截器判断当前用户拥有的权限码就行。控制粒度建议到按钮级别,也就是前端根据用户权限码渲染“新增”“删除”“审核”等按钮,后端在Controller上加对应权限校验接口。前后端各拦一道,不能只靠前端隐藏按钮来防越权。

这里有一个细节容易忽略:村级信息员通常只能管理和查看本村数据,不能看到乡镇其他村的记录。很多毕设项目不做数据权限,全都混在一起查,这恰恰是评委容易提问的地方。实现方式可以在用户表里加一个belong_village_id字段,查询时强制拼接本村ID条件,并在后端统一处理。这样做演示的时候也更有说服力——两个不同村的信息员看到的列表内容完全不一样。

2.2 核心数据表与字段取舍

表设计是这个项目的灵魂。我在建模的时候一般会把所有实体先列出来,然后考虑它们之间的关系:户主和房屋是一对多(其实严格来说一户可能有多处房屋,但这里为了简化模型,按“户主—房屋”一对多处理),房屋和附件是一对多,房屋和状态变更是1对N(每次变更留一条记录)。

建议核心表如下:

  • sys_user:用户表,字段包括id、角色id、用户名、密码、真实姓名、联系电话、所属村id、状态、创建时间。
  • sys_role/sys_user_role:角色表和用户角色关联表。
  • sys_menu:菜单权限表,用于构建动态菜单,也可以直接存权限标识符。
  • house_info:房屋主表,字段包括房屋编号、户主id、所属乡镇、所属村、宅基地面积、建筑面积、建筑年份、结构类型、房屋状态、层数、是否危房、产权证编号、位置描述、经度纬度、备注。
  • house_owner:户主信息表,字段包括姓名、身份证号、手机号、家庭成员数、户籍地址、与户主关系。
  • house_attachment:附件表,字段包括关联房屋id、文件类型、文件路径、原文件名、上传人、上传时间。
  • house_status_log:状态变更日志表,字段包括房屋id、变更前状态、变更后状态、变更原因、操作人id、变更时间。
  • oper_log:操作日志表,记录关键业务操作。

建表时有两个细节值得注意。第一,状态字段不要再定义成VARCHAR存中文“正常”/“危房”,最好用INT存字典编码,比如0表示正常,1表示闲置空置,2表示危房待鉴定,3表示已拆除,同时在前端用字典翻译展示。这样后续统计和扩展都会轻松。第二,金额和面积字段用DECIMAL,不要用DOUBLE。很多同学会忽略浮点数精度问题,但面积算总额或者利用率时,小数点后精度差别可能导致统计结果不准确。

关于核心字段,我给一个参考建表SQL:

CREATE TABLE `house_info` ( `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键', `house_code` VARCHAR(50) NOT NULL COMMENT '房屋编号', `owner_id` BIGINT DEFAULT NULL COMMENT '户主ID', `village_id` BIGINT NOT NULL COMMENT '所属村ID', `town_id` BIGINT NOT NULL COMMENT '所属乡镇ID', `structure_type` TINYINT DEFAULT 0 COMMENT '结构类型:0砖混,1砖木,2土木,3框架', `build_year` INT DEFAULT NULL COMMENT '建造年份', `floor_count` TINYINT DEFAULT 1 COMMENT '层数', `base_area` DECIMAL(10,2) DEFAULT 0.00 COMMENT '宅基地面积(㎡)', `build_area` DECIMAL(10,2) DEFAULT 0.00 COMMENT '建筑面积(㎡)', `house_status` TINYINT DEFAULT 0 COMMENT '房屋状态:0正常,1闲置,2危房待鉴定,3已拆除', `cert_no` VARCHAR(100) DEFAULT NULL COMMENT '产权证编号', `location_desc` VARCHAR(255) DEFAULT NULL COMMENT '位置描述', `longitude` DECIMAL(10,6) DEFAULT NULL COMMENT '经度', `latitude` DECIMAL(10,6) DEFAULT NULL COMMENT '纬度', `remark` VARCHAR(500) DEFAULT NULL COMMENT '备注', `create_by` VARCHAR(50) DEFAULT NULL COMMENT '创建人', `create_time` DATETIME DEFAULT NULL COMMENT '创建时间', `update_by` VARCHAR(50) DEFAULT NULL COMMENT '更新人', `update_time` DATETIME DEFAULT NULL COMMENT '更新时间', PRIMARY KEY (`id`), UNIQUE KEY `uk_house_code` (`house_code`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='农村住宅房屋信息表';

2.3 数据库设计里的坑与取舍

在设计表时,很多人会陷入“字段越多越好”的误区,恨不得把所有能想到的属性都塞到一张表里。但字段过多会让页面表单非常长,录入负担大,统计查询也容易混乱。我的建议是:主表控制在二十个字段以内,一些不常用或扩展性强的信息(比如房屋照片、历史维修记录)单独放在子表里。

还有一个隐蔽问题——房屋编号的唯一性。农村房屋不像商品房有非常规范的门牌编号,所以需要在系统里生成唯一编号,例如“乡镇编码+村编码+年份+四位顺序号”的组合方式。这个编号一旦生成就不允许修改,在后续的统计分析、附件关联、状态查询中都是主键之外的第二关联唯一性。

关于逻辑删除与物理删除,要特别提醒。房屋档案一旦删除,可能导致历史统计报表对不上,所以在业务上推荐逻辑删除,增加del_flag字段,删除时置为1,查询时默认过滤。但有些同学还喜欢把状态改来改去,然后发现“删除”操作丢了,演示时尴尬。因此,建议在项目里直接把“删除”拆成两种概念:批量归档和彻底清除,前者平时用,后者只给管理员在特定页面用。

3. 核心功能实现与实操要点

3.1 系统登录与安全控制的落地写法

登录模块看似简单,但很多毕设项目只做了“读表比对密码”,完全没有安全意识。光凭这一点,答辩时被问到“你的系统安全怎么保障”就会露怯。

建议的处理流程是:用户输入账号密码,后端将其封装成登录请求,先校验账号是否存在且状态是否正常,再校验密码。密码存储不要用明文,必须用BCrypt加密。Spring Security自带BCryptPasswordEncoder,也可以单独引入jBCrypt。校验通过后,生成JWT令牌,令牌里只放用户ID和角色编码,不存放敏感信息。前端拿到token后每次请求都放在Header的Authorization字段中,后端在拦截器里解析token并关联当前用户。

一个要点是:token不要设置太长的过期时间,建议会话保持1到2小时,密码修改后强制重新登录。为了避免演示中途登录过期,可以在前端检测到401时弹窗提示,不影响整体流程。

@Component public class JwtInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { if ("OPTIONS".equalsIgnoreCase(request.getMethod())) { return true; } String token = request.getHeader("Authorization"); if (StringUtils.isBlank(token)) { throw new BusinessException("未登录或登录已过期"); } // 解析token并设置当前登录用户到ThreadLocal LoginUser loginUser = JwtUtil.parseToken(token); UserContext.set(loginUser); return true; } }

这里我还建议做一个权限注解,比如@RequiresPermission("house:add"),在Controller方法上标注,配合拦截器校验,同时实现对接口的细粒度权限控制。这一套写下来,无论是论文还是答辩素材都够用。

3.2 房屋档案的增删改查怎么实现才完整

房屋新增和编辑是整个项目的核心功能,需要处理的细节最多。先说表单字段,大致分成四大块:户主信息、宅基地信息、房屋本体信息、附加上传。新增时户主信息可以独立填写,同时支持“按身份证号自动带出已有户主”——这个细节非常加分。

保存房屋信息时,部分字段要做校验:房屋编号必填且不能重复;建造年份不能填未来年份;宅基地面积和建筑面积必须大于0;建筑面积建议不能超过宅基地面积的合理倍数。这些校验不用全放在前端,后端也要加一遍,防止有人绕过前端直接调接口。

查询列表页建议包含多条件组合筛选:房屋编号、户主姓名、所属乡镇、所属村、结构类型、建造年份区间、房屋状态。后端使用MyBatis动态SQL来拼接条件。这里要特别注意MyBatis的<where>标签会自动去掉多余的AND/OR,但如果你用<if>拼接时要格外小心,尤其是日期区间的边界条件容易多加一个空格或丢掉一个括号。

分页上建议用PageHelper插件,虽然简单,但需要注意设置合理的pageSize默认值,比如每页10条或20条。很多同学直接把所有数据一次性返回给前端,结果演示时数据稍微多一点页面就卡顿,体验很差。最佳实践是:后端分页 + 返回总记录数,前端分页组件展示页码,也能体现出你知道“大数据量场景怎么处理的”。

3.3 统计报表与状态流转的实现思路

统计报表模块是这个系统区别于普通CRUD的亮点。建议实现这样几个统计维度:

  • 按乡镇统计房屋数量,展示柱状图。
  • 按结构类型统计,展示饼图。
  • 按年份区间统计建造数量,展示折线图。
  • 按状态统计,展示当前危房或空置房屋数量。

后端接口可以直接用聚合SQL,比如SELECT town_id, COUNT(*) FROM house_info GROUP BY town_id,前端拿到数据后用ECharts渲染。这里有一个实用技巧:如果直接按town_id统计,图上显示的是数字,答辩时观感不好。最好关联乡镇表查出名称,再拼成“乡镇名—数量”的数据结构。

状态流转要注意留痕。假设一个房屋状态从“正常”变更为“危房待鉴定”,需要记录变更原因和操作人,不能只把状态改一下了事。我是这样设计状态变更接口的:

  1. 请求参数包含房屋ID、目标状态、变更原因。
  2. 后端先行校验房屋是否存在且当前状态合理(比如已拆除的房屋不应再改为正常)。
  3. 更新house_info表的状态字段。
  4. 插入house_status_log表,记录变更前状态、变更后状态、原因、操作人。
  5. 事务提交,保证状态更新和日志记录要么一起成功,要么一起失败。

状态机校验这一点,很多项目根本不做,状态想改成什么就改什么。一个合格的业务系统应该只允许“正常→闲置→危房待鉴定→已拆除”这样的顺序流转,中间跳过状态需要给出理由。这样设计,答辩时讲起来也显得你有业务流程思维。

3.4 附件上传与预览的实用处理

房屋照片是证件类档案的必备内容,建议用本机磁盘存储,而不是把图片转成Base64存进数据库。磁盘存储配一个独立的上传目录,按“房屋编号/文件类型/时间戳”组织文件路径,数据库只存相对路径。这样数据库体积可控,图片预览也方便。

上传时注意三个细节:第一,限制文件类型,只允许jpg、png、pdf,防止恶意脚本文件上传;第二,限制文件大小,单张建议不超过5MB;第三,文件名不要使用中文原名直接存储,容易产生乱码和路径问题,统一用UUID重命名后保存原始文件名映射。

图片预览可以用后端接口映射磁盘目录,前端<img>标签直接引用接口地址。这里又一个小经验:如果前端静态页面和后端接口部署在同一个域名下,直接返回可访问的相对路径即可;如果前后端分离跨域了,记得在后端配置跨域规则,或者通过Nginx代理避免浏览器拦截。

4. 项目搭建与核心环节实现

4.1 初始化环境与工程结构

开发之前先把环境准备好,JDK建议直接上8或11,Spring Boot用2.7.x,MySQL用5.7或8.0都可以。遇到不会配置的同学,我一般建议分三步走:

第一步,在官网或镜像站下载JDK并配置JAVA_HOME,验证命令是java -version。第二步,安装IDEA,社区版完全够用,安装时勾选Spring插件和数据库插件。第三步,本地安装MySQL和Navicat或者DBeaver。数据库字符集统一设置为utf8mb4,避免中文乱码。

工程结构方面,我强烈建议分包清晰,一般分为controller、service、mapper、entity、common、config、utils这些包。很多同学喜欢把所有代码堆在一起,或者直接使用代码生成器生成大量重复代码包,这会造成后面维护起来很痛苦。分层清晰不仅是为了好看,更是答辩时展示工程素养的重要一环。

src/main/java/com/example/housing/ ├── common // 通用返回结果、异常处理、常量 ├── config // 配置类、拦截器注册 ├── controller // 接口层 ├── entity // 数据库实体 ├── mapper // MyBatis Mapper接口 ├── service // 业务逻辑层 │ └── impl ├── utils // JWT、文件上传等工具类 └── HousingApplication.java

4.2 核心接口的完整流程演示

下面以“新增房屋信息”为例,完整走一遍接口链路。前端表单提交到/api/house/add,后端Controller接收HouseInfoDTO,经过三个环节后返回成功提示。

第一步,参数校验。DTO上加JSR-303注解,比如@NotBlank(message = "房屋编号不能为空"),@DecimalMin(value = "0.0", message = "宅基地面积不能小于0")。Controller入口加@Validated,校验不通过时全局异常处理器统一返回带错误信息的响应。这样Controller方法本身就非常干净,职责单一。

第二步,业务校验与数据补全。检查房屋编号是否重复;根据户主身份证号查户主信息,如果不存在则给出提示“请先维护户主档案”;自动生成房屋状态为“正常”。同时记录创建时间和创建人。

第三步,落库。这一步必须用事务,因为有可能需要同时更新户主表和房屋主表。如果新增户主和新增房屋不是同步的,容易出现户主已建但房屋插入失败导致的脏数据。在service方法上标注@Transactional(rollbackFor = Exception.class),保证一荣俱荣、一损俱损。

最后返回统一响应体。我习惯把响应对象设计成Result< T >,包含code、msg、data三个字段。不要直接用HashMap去返回,显得不专业。如下:

@PostMapping("/house/add") public Result<String> addHouse(@Validated @RequestBody HouseInfoDTO dto) { houseService.addHouse(dto); return Result.success("新增房屋档案成功"); }

整个接口从入口到返回,逻辑链路非常清晰。写代码的时候,每个Service方法一定要控制好职责范围,不要把几千行的业务逻辑都堆在一个方法里面。一个方法超过30行,就可以考虑拆分私有方法了。

4.3 演示数据怎么准备才有效果

很多同学系统开发完了,本地测试数据随便录几条,演示时数据太少,页面空空荡荡,评委想看的筛选、统计根本无法展示。所以演示数据不能随便造,要“有层次”。

建议准备至少5个村、3个乡镇、30户以上的房屋记录。房屋状态要覆盖正常、闲置、危房待鉴定、已拆除这几种。建造年份要拉开梯度,从八十年代到近几年都有。结构类型也要尽力覆盖砖混、砖木、土木。这样统计报表的图表才会好看,筛选功能也有意义。

造数据可以用数据库脚本批量插入,写SQL时注意保持房屋状态、结构类型等字段的枚举值一致。也可以写一个临时测试接口,循环生成假数据。但演示完成后要记得把测试数据清理或者保留一部分有代表性的数据,毕竟答辩时视频录制或者现场演示的数据洗干净比什么都重要。

另外,建议特意留一条“经查已倒塌”或“鉴定危房”的数据,这样操作人可以通过状态流转功能,把这条数据从待鉴定更新为已纳入改造计划,正好可以演示状态变更与日志记录,很加分。

5. 常见问题与排查技巧实录

5.1 刚启动就报错的排查清单

这类系统最常见的启动问题,前几名非数据库配置莫属。application.yml里的数据库地址、账号、密码任何一个不对,项目一启动就报连接失败。排查思路很简单,把spring.datasource.url改成jdbc:mysql://localhost:3306/housing_db?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai,再把账号密码核对一遍,基本能解决。注意MySQL 8.x要把驱动改成com.mysql.cj.jdbc.Driver。

第二个高频问题是端口冲突。Spring Boot默认8080,如果没有关闭其他占用进程,启动时会报Port already in use。这时候要么改server.port,要么把占用进程关掉。我试过最常见的场景是之前项目残留的Spring Boot进程没有停止,直接再启动一次就冲突了。

第三个问题是IDEA不识别Spring Boot工程。多发生在导入已有项目时,Maven依赖一直下载不下来。解决办法是检查IDEA的Maven配置是不是用了默认的本地仓库,确认pom.xml没有版本号错误。实在不行就删除本地~/.m2/repository下对应目录重新下载。

5.2 查询慢、分页异常怎么办

分页异常最常见的表现是:使用PageHelper后,返回的total数不对,或者某次查询没有生效。原因通常是PageHelper的调用方式不对。它必须紧跟着第一次执行的Mapper查询前调用,中间不能有其他数据库操作,比如:

PageHelper.startPage(pageNum, pageSize); List<HouseInfo> list = houseInfoMapper.selectHouseList(condition); PageInfo<HouseInfo> pageInfo = new PageInfo<>(list);

如果查询语句使用了JOIN关联多表,PageHelper的count语句有时候会生成得不正确。替代方案是写一个独立的count查询方法,单独统计总条数。我建议干脆别过度依赖插件,复杂的统计查询自己手写count和分页SQL,更可控。

还有一个隐蔽坑:LIMIT分页数据量大时性能不好。但毕设数据量通常到不了这个级别,不必过度优化。只要在house_code、owner_id、village_id上建好索引,查询效率完全够用。

5.3 文件上传失败与跨域问题

文件上传遇到的第一个问题是MaxUploadSizeExceededException,也就是超出大小限制。需要在配置里调整两个参数:spring.servlet.multipart.max-file-size和spring.servlet.multipart.max-request-size,默认是1MB和10MB,我通常会调大到10MB和20MB。

第二个问题是Linux服务器上图片路径无法访问。本地Windows开发时路径分隔符是\,到了Linux是/,如果写死了绝对路径或者用File.separator不当,就会出问题。我建议保存相对路径,然后统一通过配置类映射虚拟路径访问,避免服务器发布时还要改代码。

跨域问题在前后端分离部署时特别常见。后端添加CORS配置类:

@Configuration public class CorsConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOriginPatterns("*") .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") .allowedHeaders("*") .allowCredentials(true) .maxAge(3600); } }

但也要注意,如果使用了JWT拦截器,跨域预检请求OPTIONS需要先放行。很多接口在浏览器直接访问没问题,前端一调就报跨域,排查思路首先要看这条路通没通。

5.4 答辩演示时的隐藏坑

答辩现场的网络往往不稳定,甚至没网。所以本地部署的系统和本地数据库就是保命方案。演示前务必确保浏览器访问的是localhost,而不是云服务器或者局域网IP,否则一旦网络出问题,系统就瘫痪在评委面前。

另外,浏览器要提前安装和配置好,清理缓存,确保登录状态是缓缓新新登录进去的。不要演示中途弹出一个“登录过期”之类的页面,当场很尴尬。实际操作我通常会把演示流程反复走三遍:登录、新增房屋、上传照片、查询筛选、修改状态、查看日志、统计报表。每一步都提前截图,万一现场翻车也有截图兜底。

再分享一个让我记忆犹新的教训——有一次演示前,数据库突然断电重启了,系统里所有数据还在,但房屋编号唯一索引在插入时暴露出重复数据错误。后来发现是代码生成编号时,并发场景下没有做唯一性兜底。虽然答辩现场没有特别追问,但这个事情让我意识到:写代码不能只看正常路径,还要想到异常路径。最好在Service层捕获唯一键冲突,再重试一次生成编号,可以在很大程度上避免类似尴尬。

写在最后的小建议

做了这么多类似项目后,我最大的体会是:这类管理系统题目的技术门槛其实没那么高,难点在于把业务逻辑理清楚,并且用工程化的方式落地。很多同学容易陷入“框架学太多、业务没做透”的误区,结果代码里全是炫技,核心流程却漏洞百出。其实,负责地把每个功能模块做完做稳、数据模型设计合理、答辩时能讲清楚每一步的取舍,就已经是高质量毕设了。

我建议你在完成基础功能之后,可以选一到两个点做深入:比如在报表模块中引入ECharts做可视化大屏,或者在状态日志中增加“操作前数据快照”功能。这些延伸点不需要很多工作量,但会让系统看起来更有血有肉,也方便论文里挑选章节做亮点展开。

如果按这个思路去开发和准备,相信无论是系统演示还是论文撰写,你都能从容许多。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询