1. 项目概述
房屋租赁系统是典型的B/S架构企业级应用,我最近用Java技术栈完整实现了一套。这个系统包含房东端、租客端和管理员端三个角色模块,采用SpringBoot+MyBatisPlus+Vue的前后端分离架构。相比市面上的教学Demo,我们这套系统在合同电子签章、维修工单流转、智能账单计算等业务场景都做了深度实现。
提示:本教程默认读者已掌握Java基础语法和SpringBoot基本使用,数据库选用MySQL 8.0版本,前端使用Vue3+Element Plus。
2. 核心模块设计
2.1 权限控制系统
采用RBAC(基于角色的访问控制)模型设计权限体系,通过Spring Security实现。核心数据表包括:
- sys_user(用户表)
- sys_role(角色表)
- sys_menu(菜单表)
- sys_user_role(用户角色关联表)
- sys_role_menu(角色菜单关联表)
权限验证流程:
- 用户登录获取JWT令牌
- 每次请求携带令牌在过滤器中校验
- 查询用户拥有的菜单权限
- 校验请求路径是否在权限范围内
// 权限校验核心代码示例 @PreAuthorize("@ss.hasPermi('house:contract:add')") @PostMapping("/contract") public Result addContract(@Validated @RequestBody Contract contract) { return contractService.insertContract(contract); }2.2 房源管理模块
采用Elasticsearch实现房源搜索功能,包含以下核心字段:
- 地理位置(GeoPoint类型)
- 价格区间
- 户型标签
- 配套设施(数组类型)
房源状态机设计:
stateDiagram [*] --> 待审核 待审核 --> 已上架: 审核通过 已上架 --> 已出租: 签订合同 已出租 --> 已上架: 合同到期 待审核 --> 已驳回: 审核不通过2.3 合同管理模块
合同模块采用阿里云电子签章服务实现线上签约,关键流程:
- 房东发起合同草稿
- 租客在线预览条款
- 双方进行实名认证
- 添加手写签名/企业公章
- 合同归档并生成PDF
合同状态变更触发事件:
- 生成租金账单
- 更新房源状态
- 发送短信提醒
- 记录操作日志
3. 数据库设计
3.1 主要数据表结构
表名:house_info(房源信息表)
CREATE TABLE `house_info` ( `id` bigint NOT NULL AUTO_INCREMENT, `title` varchar(100) NOT NULL COMMENT '房源标题', `address` json NOT NULL COMMENT '详细地址JSON', `price` decimal(10,2) NOT NULL COMMENT '月租金', `room_config` json NOT NULL COMMENT '户型配置', `facilities` json DEFAULT NULL COMMENT '设施列表', `status` tinyint NOT NULL DEFAULT '0' COMMENT '状态(0待审1上架2出租)', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), SPATIAL KEY `idx_location` (`location`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;3.2 分库分表策略
账单表按租客ID进行分片,采用ShardingSphere实现:
spring: shardingsphere: datasource: names: ds0,ds1 sharding: tables: payment_bill: actual-data-nodes: ds$->{0..1}.payment_bill_$->{0..15} table-strategy: inline: sharding-column: tenant_id algorithm-expression: payment_bill_$->{tenant_id % 16}4. 典型业务实现
4.1 租金计算引擎
采用策略模式实现多种计费方式:
public interface RentCalculator { BigDecimal calculate(BillContext context); } @Component public class MonthlyCalculator implements RentCalculator { @Override public BigDecimal calculate(BillContext context) { return context.getBasePrice() .add(context.getManagementFee()) .subtract(context.getDiscount()); } }4.2 维修工单流转
基于Activiti工作流引擎实现:
- 租客提交工单(带图片附件)
- 系统自动分派给对应区域维修工
- 维修工接单处理
- 房东确认完成
- 自动结算维修费用
状态转换监听器示例:
@EventListener public void handleWorkOrderEvent(WorkOrderEvent event) { if(event.getStatus() == WorkOrderStatus.COMPLETED) { smsService.sendNotify(event.getOrderId(), "工单已完成,请评价"); } }5. 部署方案
5.1 容器化部署
Docker Compose编排文件:
version: '3' services: mysql: image: mysql:8.0 environment: MYSQL_ROOT_PASSWORD: ${DB_PASSWORD} volumes: - ./mysql/data:/var/lib/mysql redis: image: redis:6 ports: - "6379:6379" backend: build: ./house-rental ports: - "8080:8080" depends_on: - mysql - redis5.2 性能优化方案
- 接口缓存设计:
@Cacheable(value = "houseCache", key = "#id") public HouseInfo getById(Long id) { return baseMapper.selectById(id); }- 慢SQL监控配置:
# MyBatis-Plus配置 mybatis-plus.mapper-locations=classpath*:mapper/**/*.xml mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl6. 常见问题排查
6.1 电子签章失败处理
典型错误场景:
- 实名认证不通过
- 检查身份证照片清晰度
- 确认姓名与身份证完全匹配
- 签名位置偏移
- 调整前端签名板尺寸
- 校验坐标转换算法
6.2 并发订房冲突
解决方案:
@Transactional public Result bookHouse(Long houseId) { // 使用SELECT FOR UPDATE加锁 HouseInfo house = houseMapper.selectForUpdate(houseId); if(house.getStatus() != HouseStatus.AVAILABLE) { throw new BusinessException("房源已预订"); } // 更新状态 houseMapper.updateStatus(houseId, HouseStatus.RESERVED); }重要:生产环境建议使用分布式锁替代数据库锁,推荐Redisson实现方案。
7. 扩展功能建议
智能推荐系统
- 基于用户浏览历史推荐相似房源
- 使用协同过滤算法实现
虚拟看房功能
- 集成3D全景展示技术
- 支持VR设备接入
信用评估体系
- 对接第三方信用数据
- 建立租客信用评分模型
这套系统我在实际部署时发现,Elasticsearch的地理位置查询需要特别注意坐标系转换问题。建议使用GCJ-02坐标系存储数据,前端展示时再做转换,可以避免地图偏移问题。另外,合同模块的存证功能最好对接区块链服务,增强法律效力。