1. 项目背景与核心需求
房屋租赁市场近年来呈现爆发式增长态势,据行业数据显示,2022年全国住房租赁市场规模已突破2.5万亿元。在这种背景下,传统纸质合同管理和Excel表格记录的方式已经无法满足现代化房产中介、长租公寓运营商和物业管理公司的业务需求。一个典型的房产中介门店每月需要处理的合同数量在50-200份不等,涉及租客信息、付款记录、维修申请等多维度数据管理。
这个毕业设计项目正是针对这一市场需求,采用SSM(Spring+SpringMVC+MyBatis)框架构建的B/S架构管理系统。系统主要解决四大核心痛点:
- 合同电子化存档难题:纸质合同易丢失、难检索的问题,通过电子归档和全文检索功能解决
- 租金催缴效率低下:系统自动计算应收日期,提前3天推送短信/邮件提醒
- 维修响应不及时:租户可通过系统提交维修工单,自动分配最近维修人员
- 数据统计缺失:自动生成出租率、空置期、租金收缴率等关键业务指标报表
提示:在实际商业环境中,此类系统通常需要对接电子签名CA认证和在线支付接口,但毕业设计版本可适当简化这些复杂功能。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 技术选型与架构设计
2.1 SSM框架组合优势分析
选择SSM框架组合而非Spring Boot主要基于以下考虑:
- 教学示范价值:更清晰地展示各层之间的调用关系(如Controller→Service→Dao)
- 配置透明性:XML配置方式让初学者更易理解Bean生命周期
- 轻量化:对毕业设计而言,避免Spring Boot的自动配置"黑箱"
技术栈明细:
- 前端:Bootstrap 4 + jQuery + ECharts
- 后端:Spring 5.2.8(IoC容器和AOP支持)
- Web层:SpringMVC(RESTful接口设计)
- 持久层:MyBatis 3.5.6 + PageHelper分页插件
- 数据库:MySQL 8.0(采用InnoDB引擎)
- 构建工具:Maven 3.6.3
2.2 系统架构示意图
code复制用户层
↓
表示层(JSP/Bootstrap)
↓
控制层(SpringMVC)
↓
业务层(Spring)
↓
持久层(MyBatis)
↓
数据层(MySQL)
关键设计决策:
- 采用RESTful风格API设计,前后端分离但保留JSP渲染能力
- 实现MyBatis二级缓存提升高频查询性能(如房源列表)
- 使用Spring声明式事务管理合同修改操作
- 引入Hibernate Validator进行参数校验
3. 核心功能模块实现
3.1 合同生命周期管理
合同状态机设计:
code复制草稿 → 待签署 → 已生效 → 即将到期 → 已终止
↑ │
└── 续约 ───┘
关键代码片段(MyBatis映射文件):
xml复制<update id="updateContractStatus">
UPDATE housing_contract
SET status = #{status},
version = version + 1
WHERE id = #{id} AND version = #{version}
</update>
注意:这里使用乐观锁机制防止并发修改冲突,version字段在每次更新时自动递增。
3.2 租金自动提醒功能
采用Spring Task实现定时任务:
java复制@Scheduled(cron = "0 0 9 * * ?") // 每天上午9点执行
public void checkRentPayment() {
List<Contract> expiringContracts = contractMapper.selectExpiringContracts(3);
expiringContracts.forEach(contract -> {
smsService.sendReminder(contract.getTenantPhone(),
"尊敬的租户,您的房租将于3天后到期,请及时缴纳");
});
}
提醒规则配置:
| 提前天数 | 提醒方式 | 提醒内容模板 |
|---|---|---|
| 3天 | SMS | 【XX公寓】租金提醒... |
| 1天 | SMS+邮件 | 紧急提醒:您的... |
| 过期 | 系统标记 | 自动生成催缴记录 |
3.3 维修工单流转设计
状态流转逻辑:
- 租户提交工单(带照片上传功能)
- 系统根据维修类型和位置自动分配维修工
- 维修工接单后状态变更为"处理中"
- 完成后上传维修结果照片
- 租户确认后关闭工单
数据库表关系:
sql复制CREATE TABLE repair_order (
id BIGINT PRIMARY KEY,
contract_id BIGINT NOT NULL,
repair_type ENUM('PLUMBING','ELECTRICAL','FURNITURE'),
status ENUM('PENDING','ASSIGNED','PROCESSING','COMPLETED'),
assignee_id BIGINT,
created_at DATETIME,
FOREIGN KEY (contract_id) REFERENCES housing_contract(id)
);
4. 关键问题解决方案
4.1 合同版本控制实现
采用双重方案保证合同修改可追溯:
- 数据库层面:使用history表存储每次修改快照
java复制public void updateContract(Contract newVersion) {
Contract old = contractMapper.selectById(newVersion.getId());
contractHistoryMapper.insert(old); // 存档旧版本
contractMapper.update(newVersion); // 更新当前版本
}
- 文件层面:PDF合同上传OSS时自动添加时间戳后缀
4.2 大数据量查询优化
针对房源列表查询的优化措施:
- 建立复合索引:
sql复制ALTER TABLE house_info ADD INDEX idx_area_price (area_id, monthly_price);
- 使用MyBatis二级缓存配置:
xml复制<cache eviction="LRU" flushInterval="60000" size="512"/>
- 分页查询使用PageHelper:
java复制PageHelper.startPage(pageNum, 10);
List<House> houses = houseMapper.selectByCondition(condition);
return new PageInfo<>(houses);
4.3 日期冲突校验算法
检查新合同时间段是否与已有合同冲突:
java复制public boolean checkDateConflict(Long houseId, LocalDate start, LocalDate end) {
return contractMapper.countOverlappingContracts(houseId,
start.atStartOfDay(),
end.atTime(23, 59, 59)) > 0;
}
对应的SQL查询:
sql复制SELECT COUNT(*) FROM housing_contract
WHERE house_id = #{houseId}
AND status = 'ACTIVE'
AND (
(start_date BETWEEN #{start} AND #{end})
OR (end_date BETWEEN #{start} AND #{end})
OR (start_date <= #{start} AND end_date >= #{end})
)
5. 系统部署与测试方案
5.1 环境搭建步骤
- 开发环境:
bash复制# 初始化数据库
mysql -u root -p < schema.sql
# 导入测试数据
mysql -u root -p housing_db < sample_data.sql
- Tomcat配置:
xml复制<!-- conf/context.xml -->
<Context>
<Resource name="jdbc/housingDB"
auth="Container"
type="javax.sql.DataSource"
maxTotal="20"
maxIdle="5"
username="housing_user"
password="Housing@1234"
driverClassName="com.mysql.cj.jdbc.Driver"
url="jdbc:mysql://localhost:3306/housing_db?useSSL=false"/>
</Context>
5.2 压力测试结果
使用JMeter模拟100并发用户:
| 接口路径 | 平均响应时间 | 错误率 | TPS |
|---|---|---|---|
| /contract/list | 128ms | 0% | 78 |
| /contract/search | 253ms | 0.2% | 42 |
| /payment/record | 87ms | 0% | 115 |
优化建议:
- 对复杂查询结果引入Redis缓存
- 将静态资源迁移至CDN
- 启用Gzip压缩传输
5.3 毕业设计答辩要点
-
技术亮点展示:
- 合同状态机的设计模式应用(State Pattern)
- 使用AOP实现操作日志记录
- 基于Spring Security的权限控制
java复制@PreAuthorize("hasRole('ADMIN') or #contract.ownerId == principal.id") public void updateContract(Contract contract) { // ... } -
常见问题准备:
- 如何保证合同电子签名的法律效力?
- 系统是否考虑过 GDPR 数据合规要求?
- 如果日订单量达到10万级,架构需要如何调整?
6. 源码结构与使用指南
6.1 项目目录说明
code复制src/
├── main/
│ ├── java/
│ │ └── com/
│ │ └── housing/
│ │ ├── config/ # Spring配置类
│ │ ├── controller/ # MVC控制器
│ │ ├── dao/ # MyBatis接口
│ │ ├── entity/ # 实体类
│ │ ├── service/ # 业务逻辑
│ │ └── util/ # 工具类
│ ├── resources/
│ │ ├── mapper/ # MyBatis映射文件
│ │ ├── spring/ # Spring配置文件
│ │ └── application.properties
│ └── webapp/
│ ├── resources/ # 静态资源
│ └── WEB-INF/
│ └── views/ # JSP页面
└── test/ # 单元测试
6.2 快速启动步骤
- 数据库初始化:
sql复制CREATE DATABASE housing_db CHARACTER SET utf8mb4;
CREATE USER 'housing_user'@'%' IDENTIFIED BY 'Housing@1234';
GRANT ALL ON housing_db.* TO 'housing_user'@'%';
- 修改数据源配置:
properties复制# application.properties
jdbc.url=jdbc:mysql://localhost:3306/housing_db
jdbc.username=housing_user
jdbc.password=Housing@1234
- 启动项目:
bash复制mvn tomcat7:run
6.3 扩展建议
-
商业版可扩展功能:
- 对接微信小程序端
- 集成电子签名服务(如e签宝)
- 增加智能门锁对接模块
- 开发业主自助门户
-
性能优化方向:
- 引入Elasticsearch实现全文检索
- 使用Quartz替代Spring Task实现分布式定时任务
- 采用Sharding-JDBC进行分库分表
-
安全增强措施:
- 敏感数据加密存储(如租户身份证号)
- 增加操作二次验证
- 实现审计日志归档
实际开发中遇到的一个典型问题:日期处理时区不一致导致合同到期日计算错误。解决方案是在所有日期字段存储时统一转换为UTC时间,前端展示时再按用户时区转换。
