楼主: 八卦之坤
299 0

[经济学教育] 毕业设计实战:基于Spring Boot的民宿管理平台全栈开发 [推广有奖]

  • 0关注
  • 0粉丝

等待验证会员

小学生

71%

还不是VIP/贵宾

-

威望
0
论坛币
0 个
通用积分
0
学术水平
0 点
热心指数
0 点
信用等级
0 点
经验
60 点
帖子
5
精华
0
在线时间
0 小时
注册时间
2018-1-31
最后登录
2018-1-31

楼主
八卦之坤 发表于 2025-11-22 07:00:38 |AI写论文

+2 论坛币
k人 参与回答

经管之家送您一份

应届毕业生专属福利!

求职就业群
赵安豆老师微信:zhaoandou666

经管之家联合CDA

送您一个全额奖学金名额~ !

感谢您参与论坛问题回答

经管之家送您两个论坛币!

+2 论坛币

一、项目全流程:6步完成民宿管理平台开发

3.1 第一步:需求分析——明确平台核心价值

面对传统民宿管理模式中存在的“信息割裂、流程混乱、协作效率低下”等问题,本系统聚焦于实现“三端协同运作、业务闭环管理、数据集中可控”的目标。需求划分为功能性与非功能性两大类:

3.1.1 功能性需求

三角色权限体系:

  • 管理员:具备首页数据概览、个人中心(支持密码修改)、用户信息维护(增删改查)、商家资质审核与信息更新、民宿分类管理、房间类型配置、订单状态审批(含预订与退订)、投诉处理以及系统级设置(如轮播图调整、在线客服参数设定)等权限;
  • 商家:可进行店铺资料编辑、发布或修改民宿详情并上传图片、新增或管理房间类型(包括定价及设施说明)、查看自身订单记录、响应用户的退订请求、回复用户投诉;
  • 用户:能够维护个人信息、重置登录密码、按名称或地址筛选民宿信息、预订房间、提交退订申请、发起服务投诉,并收藏感兴趣的房源。

核心业务功能:

  • 民宿展示服务:提供分类浏览的民宿列表,包含名称、地理位置、实景图片和简要介绍,支持查看详情页及收藏操作;
  • 房间预订流程:用户选定房型后填写入住时间与人数→提交订单→由商家确认→进入支付环节;
  • 退订处理机制:用户发起退订并注明原因→商家审核通过与否→系统自动更新订单状态并向用户推送通知;
  • 投诉反馈功能:用户提交对服务的不满意见→管理员或对应商家查看并作出回应→用户可在个人中心查阅处理进展。

3.1.2 非功能性需求

  • 系统安全性:采用MD5加密存储用户密码,严格校验角色权限,防止非法访问与越权操作,确保交易数据不被篡改;
  • 响应及时性:页面加载控制在2秒以内,关键操作如订单提交、退订申请需实时响应,避免明显延迟;
  • 数据稳定性:对重要数据(如预订记录、支付信息)实施定期备份策略,支持灾难恢复,防止意外丢失;
  • 兼容性要求:适配Chrome、Firefox、Edge等主流浏览器,保证界面布局正常、功能完整可用。

3.2 第二步:系统设计——构建整体架构

为实现模块解耦与高效协作,系统采用经典的三层架构模式(表现层/业务逻辑层/数据访问层),同时设计合理的数据库模型以支撑三端数据流转。

3.2.1 系统总体架构

表现层(Web层)

  • 界面展示:使用JSP结合Bootstrap框架开发三套独立前端界面——管理员后台、商家管理中心和用户前台,涵盖表单输入、信息列表、详情展示等多种UI组件;
  • 交互控制:利用JavaScript实现前端校验(如手机号格式、日期选择限制)、异步加载(例如动态获取民宿列表)、页面跳转控制等功能。

业务逻辑层(Service层)

  • 封装核心服务模块,包括但不限于:用户服务(注册与登录逻辑)、商家服务(店铺运营相关操作)、民宿服务(信息录入与审核流程)、订单服务(处理预订与退订业务)、投诉服务(接收与响应反馈)。

二、技术架构:民宿管理平台的全栈技术选型

项目围绕“稳定性、易用性、可扩展性”三大原则,选用成熟稳定的Java Web技术栈,保障系统在多角色并发操作、高频数据交换场景下的可靠运行。具体技术组合如下:

技术模块 具体工具/技术 核心作用
后端框架 Spring Boot 2.x 简化项目初始化与配置流程,快速搭建分层结构(Controller/Service/DAO),支持事务管理和依赖注入,显著提升开发效率
数据库 MySQL 8.0 用于持久化存储用户账户、商家资料、民宿详情、房间库存及订单流水等核心业务数据,支持复杂关联查询,保障数据一致性与完整性
前端技术 JSP + Bootstrap + JavaScript 构建响应式网页界面,适配PC与平板设备,实现表单验证、局部刷新、图表展示等交互体验
架构模式 B/S结构 无需安装专用客户端,用户仅需通过浏览器即可访问系统,降低使用门槛,支持跨终端同步操作
开发工具 Eclipse + Navicat Eclipse作为主要编码与调试环境,Navicat用于数据库可视化操作(建表、查询、导出备份等)
服务器 Tomcat 9.0 承载Web应用部署,处理HTTP请求,具备良好的并发处理能力,保障平台高可用性
安全机制 密码MD5加密 + 角色权限控制 对敏感信息如登录密码进行不可逆加密存储,依据角色划分功能权限,杜绝未授权访问行为

一、项目背景:数字化时代的民宿管理革新

随着文化和旅游产业的复苏以及消费者需求的不断升级,民宿作为个性化住宿的重要形式,其市场规模持续扩大。截至2024年,我国民宿市场总规模已突破500亿元,线上预订用户数量超过3亿人。然而,传统的管理方式仍存在诸多瓶颈,如信息分散、操作繁琐、多方协作效率低等问题——许多商家仍依赖Excel表格记录房源信息,客户预订需通过电话或线下沟通完成,管理人员难以统一协调各角色的数据流,严重影响了服务质量和用户体验。

在此背景下,“基于Spring Boot的民宿管理平台”应运而生,致力于打造一个连接“管理员—商家—用户”三方的数字化中枢系统。平台采用B/S架构,借助信息化手段实现民宿信息发布、在线预订、退订审批、投诉处理等全流程线上化管理,建立起“管理员统一监管、商家自主经营、用户便捷消费”的协同机制。该方案为中小型民宿企业提供了一种轻量级、低成本的数字化转型路径,推动行业从“人工驱动”向“智能运营”迈进。

3.3 第三步:后端核心功能实现——Spring Boot架构

基于Spring Boot框架,系统实现了面向用户、商家和管理端的三端业务逻辑,重点解决“订单状态流转”、“民宿与房间管理”以及“权限控制”三大核心问题。通过分层设计与模块化开发,保障系统的可维护性与扩展性。关键代码如下:

3.3.1 房间预订与退订功能实现

@RestController
@RequestMapping("/api/order")
public class OrderController {
    @Autowired
    private OrderService orderService;

    @Autowired
    private RoomService roomService;

    /**
     * 用户提交房间预订请求
     */
    @PostMapping("/book")
    public ResponseEntity<?> submitBooking(@RequestBody BookingDTO bookingDTO) {
        try {
            // 1. 校验指定民宿及房间类型是否存在
            Room room = roomService.getRoomByType(bookingDTO.getMinsumingcheng(), bookingDTO.getFangjianleixing());
            if (room == null) {
                return ResponseEntity.badRequest().body("民宿或房间类型不存在");
            }

            // 2. (简化处理)默认房间可预订,实际场景中应校验库存或可用日期

            // 3. 生成唯一预订编号
            String bookingNo = generateBookingNo();

            // 4. 封装订单信息对象
            BookingOrder order = new BookingOrder();
            order.setYudingbianhao(bookingNo);
            order.setShangjiabianhao(bookingDTO.getShangjiabianhao());
            order.setMinsumingcheng(bookingDTO.getMinsumingcheng());

数据访问层(DAO层)设计

DAO层负责与数据库进行交互,采用MyBatis作为持久层框架,完成对数据表的增删改查操作,并确保关键事务的一致性。

数据操作

通过MyBatis将SQL语句封装在Mapper接口中,实现对数据库的CRUD操作。例如:查询用户的预订历史、更新订单当前状态、插入新的退订记录等,均通过XML或注解方式执行SQL。

事务管理

针对涉及资金与状态变更的核心流程(如订单支付、退订退款),使用Spring的声明式事务管理机制(@Transactional),保证多个数据库操作的原子性,防止出现部分成功、部分失败导致的数据不一致问题。

3.2.2 核心数据库设计

为支撑完整业务闭环,系统共设计7张核心数据表,覆盖用户、商家、订单、投诉等多维度数据需求,各表结构如下所示:

表名 核心字段 作用说明
yonghu(用户表) id、zhanghao(账号)、mima(密码)、xingming(姓名)、shouji(手机)、zhaopian(头像) 存储注册用户的基本资料,支持登录认证与个人信息展示
shangjia(商家表) id、shangjiabianhao(商家编号)、mima(密码)、shangjiamingcheng(商家名称)、lianxidianhua(联系电话)、touxiang(头像) 保存商家账户信息,用于店铺身份识别与订单归属关联
minsuxinxi(民宿信息表) id、shangjiabianhao(关联商家)、minsumingcheng(民宿名称)、minsudizhi(地址)、minsutupian(图片)、minsujianjie(简介) 记录民宿详细信息,供前端页面展示和搜索筛选使用
fangjianxinxi(房间信息表) id、shangjiabianhao(关联商家)、minsumingcheng(关联民宿)、fangjianleixing(房间类型)、fangjiansheshi(设施)、fangjianjiage(价格) 描述每个房间的具体配置与定价策略,支撑预订选择逻辑
fangjianyuding(房间预订表) id、yudingbianhao(预订编号)、shangjiabianhao(关联商家)、minsumingcheng(关联民宿)、zhanghao(关联用户)、tianshu(预订天数)、yishoujine(已收金额)、yudingshijian(预订时间) 保存所有预订记录,跟踪订单从创建到完成或取消的全过程
fangjiantuiding(房间退订表) id、tuidingbianhao(退订编号)、yudingbianhao(关联预订)、zhanghao(关联用户)、tuidingshijian(退订时间)、beizhu(退订原因) 记录用户的退订申请,配合审核流程进行状态更新与退款处理
tousufankui(投诉反馈表) id、zhanghao(关联用户)、shangjiabianhao(关联商家)、minsumingcheng(关联民宿)、fankuineirong(反馈内容)、shhf(审核回复)、sfsh(审核状态) 存储用户提交的投诉内容,支持后台处理进度追踪与结果反馈

业务规则控制机制

系统通过服务层逻辑严格管控以下核心流程:

  • 订单状态流转:实现订单生命周期管理,状态按序变更:待确认 → 已支付 → 已完成 / 已取消,禁止逆向跳转或非法状态修改。
  • 退订申请审核逻辑:用户发起退订后,进入人工或自动审核流程,根据政策判断是否允许退款并更新相关订单与财务状态。
  • 投诉处理时效管控:设定投诉响应与处理的时间阈值,确保用户反馈在规定时间内得到回应与解决,提升服务质量。
// 设置订单信息
order.setFangjianleixing(bookingDTO.getFangjianleixing());
order.setFangjianjiage(room.getFangjianjiage());
order.setTianshu(bookingDTO.getTianshu());
order.setYishoujine(calculateTotal(room.getFangjianjiage(), bookingDTO.getTianshu()));
order.setYudingshijian(new Date());
order.setZhanghao(bookingDTO.getZhanghao());
order.setXingming(bookingDTO.getXingming());
order.setShouji(bookingDTO.getShouji());
order.setIsPay("未支付");
order.setStatus("待确认");

// 保存订单数据
orderService.saveBooking(order);

return ResponseEntity.ok("预订提交成功,等待商家确认,预订编号:" + bookingNo);
} catch (Exception e) {
    e.printStackTrace();
    return ResponseEntity.internalServerError().body("预订失败:" + e.getMessage());
}
/**
 * 处理用户发起的退订请求
 */
@PostMapping("/cancel")
public ResponseEntity<?> submitCancel(@RequestBody CancelDTO cancelDTO) {
    try {
        // 查询对应预订单
        BookingOrder order = orderService.getBookingByNo(cancelDTO.getYudingbianhao());
        if (order == null) {
            return ResponseEntity.badRequest().body("预订订单不存在");
        }

        // 校验操作权限:仅允许订单所属账户申请退订
        if (!order.getZhanghao().equals(cancelDTO.getZhanghao())) {
            return ResponseEntity.status(HttpStatus.FORBIDDEN).body("无退订权限");
        }

        // 判断当前状态是否支持退订操作
        String status = order.getStatus();
        if (!"待确认".equals(status) && !"已支付".equals(status)) {
            return ResponseEntity.badRequest().body("当前订单状态不支持退订");
        }

        // 构建退订申请记录
        CancelOrder cancelOrder = new CancelOrder();
        cancelOrder.setTuidingbianhao(generateCancelNo());
        cancelOrder.setYudingbianhao(cancelDTO.getYudingbianhao());
        cancelOrder.setShangjiabianhao(order.getShangjiabianhao());
        cancelOrder.setMinsumingcheng(order.getMinsumingcheng());
        cancelOrder.setFangjianleixing(order.getFangjianleixing());
        cancelOrder.setTianshu(order.getTianshu());
        cancelOrder.setYishoujine(order.getYishoujine());
        cancelOrder.setTuidingshijian(new Date());
        cancelOrder.setBeizhu(cancelDTO.getBeizhu());
        cancelOrder.setZhanghao(cancelDTO.getZhanghao());
        cancelOrder.setStatus("待审核");

        // 持久化退订申请,并更新原订单状态
        orderService.saveCancel(cancelOrder);
        order.setStatus("退订申请中");
        orderService.updateBooking(order);
    } catch (Exception e) {
        e.printStackTrace();
        return ResponseEntity.internalServerError().body("退订申请提交失败:" + e.getMessage());
    }
    return ResponseEntity.ok("退订申请已提交,正在等待审核");
}
/**
 * 商家发布民宿信息
 */
public MinSu publishMinSu(MinSuPublishDTO publishDTO) {
    // 1. 校验商家注册状态
    Merchant merchant = merchantMapper.selectByNo(publishDTO.getShangjiabianhao());
    if (merchant == null) {
        throw new IllegalArgumentException("商家未注册,无法发布民宿信息");
    }

    // 2. 构建民宿实体对象
    MinSu minSu = new MinSu();
    minSu.setMingsuBianhao("MS" + System.currentTimeMillis()); // 生成民宿编号
    minSu.setShangjiaBianhao(publishDTO.getShangjiabianhao());
    minSu.setMingcheng(publishDTO.getMingcheng());
    minSu.setDizhi(publishDTO.getDizhi());
    minSu.setJingdu(publishDTO.getJingdu());
    minSu.setWeidu(publishDTO.getWeidu());
    minSu.setRongliang(publishDTO.getRongliang());
    minSu.setDanjia(publishDTO.getDanjia());
    minSu.setChuangxing(publishDTO.getChuangxing());
    minSu.setChuangshu(publishDTO.getChuangshu());
    minSu.setZhushiShebei(publishDTO.getZhushiShebei());
    minSu.setQitaPeitao(publishDTO.getQitaPeitao());
    minSu.setTupianUrls(fileService.uploadFiles(publishDTO.getTupianFiles())); // 图片上传处理
    minSu.setStatus("待审核");
    minSu.setCreateTime(new Date());

    // 3. 保存至数据库
    minSuMapper.insert(minSu);
    
    return minSu;
}

/**
 * 计算订单总金额(单价 × 天数)
 */
private String calculateTotal(String price, String days) {
    BigDecimal unitPrice = new BigDecimal(price);
    BigDecimal dayCount = new BigDecimal(days);
    return unitPrice.multiply(dayCount).toString();
}

/**
 * 生成预订编号:格式为 BK + 当前时间戳 + 随机四位数
 */
private String generateBookingNo() {
    SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
    String dateStr = sdf.format(new Date());
    String random = String.valueOf(new Random().nextInt(9000) + 1000);
    return "BK" + dateStr + random;
}

/**
 * 商家审核退订申请
 */
@PostMapping("/auditCancel")
public ResponseEntity<?> auditCancel(@RequestBody AuditCancelDTO auditDTO) {
    try {
        // 1. 权限校验:确认当前商家是否有权操作该退订请求
        if (!orderService.checkMerchantPermission(auditDTO.getShangjiabianhao())) {
            return ResponseEntity.status(HttpStatus.FORBIDDEN).body("无权限执行审核操作");
        }

        // 2. 查询退订记录是否存在
        CancelOrder cancelOrder = orderService.getCancelByNo(auditDTO.getTuidingbianhao());
        if (cancelOrder == null) {
            return ResponseEntity.badRequest().body("指定的退订申请记录不存在");
        }

        // 3. 更新退订状态及审核反馈
        cancelOrder.setStatus(auditDTO.getAuditResult()); // 设置审核结果:通过或驳回
        cancelOrder.setShhf(auditDTO.getAuditReply());   // 填写商家回复内容
        orderService.updateCancel(cancelOrder);

        // 4. 同步更新原订单状态
        BookingOrder order = orderService.getBookingByNo(cancelOrder.getYudingbianhao());
        order.setStatus(auditDTO.getAuditResult().equals("通过") ? "已取消" : "待支付");
        orderService.updateBooking(order);

        return ResponseEntity.ok("退订审核已完成,最终状态为:" + auditDTO.getAuditResult());
    } catch (Exception e) {
        e.printStackTrace();
        return ResponseEntity.internalServerError().body("审核过程中发生错误:" + e.getMessage());
    }
}

/**
 * 提交退订申请接口
 */
@PostMapping("/applyCancel")
public ResponseEntity<String> applyCancel(@RequestBody CancelApplyDTO applyDTO) {
    try {
        // 1. 检查订单是否可退
        BookingOrder order = orderService.getBookingByNo(applyDTO.getYudingbianhao());
        if (order == null) {
            return ResponseEntity.badRequest().body("订单不存在");
        }
        if (!"待入住".equals(order.getStatus())) {
            return ResponseEntity.badRequest().body("该订单当前状态不允许退订");
        }

        // 2. 创建退订申请记录
        CancelOrder cancelOrder = new CancelOrder();
        cancelOrder.setTuidingbianhao("TK" + System.nanoTime()); // 生成退订编号
        cancelOrder.setYudingbianhao(applyDTO.getYudingbianhao());
        cancelOrder.setShangjiabianhao(order.getShangjiabianhao());
        cancelOrder.setShenqingyuanyin(applyDTO.getReason());
        cancelOrder.setStatus("待审核");
        cancelOrder.setCreateTime(new Date());

        orderService.saveCancelOrder(cancelOrder);
        
        return ResponseEntity.ok("退订申请已成功提交,请等待商家审核");
    } catch (Exception e) {
        e.printStackTrace();
        return ResponseEntity.internalServerError().body("提交退订申请失败:" + e.getMessage());
    }
}
/**
 * 获取商家名下所有民宿
 */
public List<MinSu> getMinSuByMerchant(String shangjiabianhao) {
    return minSuMapper.selectByShangJiaBianHao(shangjiabianhao);
}

/**
 * 商家发布新民宿
 */
public MinSu publishMinSu(MinSuPublishDTO publishDTO) {
    // 1. 校验商家账号是否存在
    String shangjiabianhao = publishDTO.getShangjiabianhao();
    Merchant merchant = merchantMapper.selectByBianHao(shangjiabianhao);
    if (merchant == null) {
        throw new RuntimeException("商家账号不存在,请先注册");
    }

    // 2. 民宿图片上传处理(封面图 + 多张详情图)
    String coverUrl = fileService.uploadFile(publishDTO.getCoverFile(), "minsu/cover");
    List<String> detailUrls = new ArrayList<>();
    for (MultipartFile detailFile : publishDTO.getDetailFiles()) {
        if (!detailFile.isEmpty()) {
            detailUrls.add(fileService.uploadFile(detailFile, "minsu/detail"));
        }
    }

    // 3. 构建民宿信息实体对象
    MinSu minSu = new MinSu();
    minSu.setShangjiabianhao(publishDTO.getShangjiabianhao());
    minSu.setMinsubianhao(generateMinSuNo()); // 自动生成唯一民宿编号
    minSu.setMinsumingcheng(publishDTO.getMinsumingcheng());
    minSu.setMinsudizhi(publishDTO.getMinsudizhi());
    minSu.setMinsutupian(coverUrl); // 封面图URL
    minSu.setMinsujianjie(publishDTO.getMinsujianjie());
    minSu.setDetailImages(JSON.toJSONString(detailUrls)); // 详情图片列表转为JSON字符串存储
    minSu.setStatus("待审核"); // 初始状态设为待管理员审核
    minSu.setAddtime(new Date()); // 记录创建时间

    // 4. 插入数据库并返回结果
    minSuMapper.insertMinSu(minSu);
    
    return minSu;
}

/**
 * 商家修改已有民宿信息
 */
public MinSu updateMinSu(MinSuUpdateDTO updateDTO) {
    // 1. 查询目标民宿是否存在,并确认归属权
    MinSu minSu = minSuMapper.selectByNo(updateDTO.getMinsubianhao());
    if (minSu == null) {
        throw new RuntimeException("民宿不存在");
    }
    if (!minSu.getShangjiabianhao().equals(updateDTO.getShangjiabianhao())) {
        throw new RuntimeException("无权限编辑该民宿");
    }

    // 2. 更新可变字段,仅对非空内容进行覆盖
    if (StringUtils.hasText(updateDTO.getMinsumingcheng())) {
        minSu.setMinsumingcheng(updateDTO.getMinsumingcheng());
    }
    if (StringUtils.hasText(updateDTO.getMinsudizhi())) {
        minSu.setMinsudizhi(updateDTO.getMinsudizhi());
    }
    if (updateDTO.getCoverFile() != null && !updateDTO.getCoverFile().isEmpty()) {
        String newCoverUrl = fileService.uploadFile(updateDTO.getCoverFile(), "minsu/cover");
        minSu.setMinsutupian(newCoverUrl);
    }
    if (StringUtils.hasText(updateDTO.getMinsujianjie())) {
        minSu.setMinsujianjie(updateDTO.getMinsujianjie());
    }

    // 图片或信息变更后需重新进入审核流程
    minSu.setStatus("待审核");

    // 3. 执行数据更新操作
    minSuMapper.updateMinSu(minSu);
    
    return minSu;
}
@Service
public class AuthService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private MerchantMapper merchantMapper;

    @Autowired
    private AdminMapper adminMapper;

    /**
     * 实现三角色统一登录认证,根据传入的角色类型进行差异化验证
     * @param account  登录账号(支持用户账号、商家编号或管理员账户)
     * @param password 登录密码(明文输入)
     * @param role     用户角色标识(user/merchant/admin)
     * @return 返回封装后的登录结果对象,包含状态与基本信息
     */
    public LoginResult login(String account, String password, String role) {
        // 对原始密码执行MD5加密处理
        String encryptedPwd = DigestUtils.md5DigestAsHex(password.getBytes());

        switch (role) {
            case "user":
                User user = userMapper.selectByAccountAndPwd(account, encryptedPwd);
                if (user != null) {
                    return new LoginResult(true, "user", user.getZhanghao(), user.getXingming());
                }
                break;

            case "merchant":
                Merchant merchant = merchantMapper.selectByNoAndPwd(account, encryptedPwd);
                if (merchant != null) {
                    return new LoginResult(true, "merchant", merchant.getShangjiabianhao(), merchant.getShangjiamingcheng());
                }
                break;

            case "admin":
                Admin admin = adminMapper.selectByAccountAndPwd(account, encryptedPwd);
                if (admin != null) {
                    return new LoginResult(true, "admin", admin.getUsername(), "管理员");
                }
                break;

            default:
                return new LoginResult(false, null, null, null);
        }

        // 所有验证未通过则返回失败结果
        return new LoginResult(false, null, null, null);
    }

    /**
     * 权限校验方法:判断指定账号是否具备对应角色的合法身份
     * @param account 待校验的账号
     * @param role    目标角色类型
     * @return 若存在匹配记录则返回true,否则为false
     */
    public boolean checkRole(String account, String role) {
        switch (role) {
            case "user":
                return userMapper.selectByAccount(account) != null;
            case "merchant":
                return merchantMapper.selectByNo(account) != null;
            case "admin":
                return adminMapper.selectByAccount(account) != null;
            default:
                return false;
        }
    }

    /**
     * 处理新用户或商家注册请求
     */
    public void register(RegisterDTO registerDTO) {
        if ("user".equals(registerDTO.getRole())) {
            // 注册普通用户时,需确保账号在系统中唯一
        }
    }

    // 辅助功能:自动生成民宿编号,规则为“MS”+商家编号后四位+三位随机数
    private String generateMinSuNo() {
        String merchantSuffix = shangjiabianhao.substring(shangjiabianhao.length() - 4);
        String random = String.valueOf(new Random().nextInt(900) + 100);
        return "MS" + merchantSuffix + random;
    }

    // 数据访问层调用示例:根据商家编号查询关联的民宿信息
    public MinSu selectMinSuByMerchantNo(String shangjiabianhao) {
        return minSuMapper.selectByMerchantNo(shangjiabianhao);
    }
}

在注册逻辑处理中,若角色为普通用户,则首先校验账号是否已被使用:

if (userMapper.selectByAccount(registerDTO.getAccount()) != null) {
    throw new RuntimeException("用户名已被占用");
}

随后创建用户对象,并将注册信息进行封装。其中密码通过MD5加密存储,头像设置为默认路径,注册时间自动记录:

User user = new User();
user.setZhanghao(registerDTO.getAccount());
user.setMima(DigestUtils.md5DigestAsHex(registerDTO.getPassword().getBytes()));
user.setXingming(registerDTO.getName());
user.setShouji(registerDTO.getPhone());
user.setZhaopian("/static/default-avatar.png");
user.setAddtime(new Date());
userMapper.insertUser(user);

若注册角色为商家,则进入商家注册流程。系统将调用辅助方法生成唯一的商家编号,并初始化商家信息:

} else if ("merchant".equals(registerDTO.getRole())) {
    String merchantNo = generateMerchantNo();
    Merchant merchant = new Merchant();
    merchant.setShangjiabianhao(merchantNo);
    merchant.setMima(DigestUtils.md5DigestAsHex(registerDTO.getPassword().getBytes()));
    merchant.setShangjiamingcheng(registerDTO.getName());
    merchant.setLianxidianhua(registerDTO.getPhone());
    merchant.setTouxiang("/static/default-merchant.png");
    merchant.setStatus("待审核");
    merchant.setAddtime(new Date());
    merchantMapper.insertMerchant(merchant);

对于不支持的角色类型,系统抛出异常提示:

} else {
    throw new RuntimeException("不支持的注册角色");
}

商家编号的生成规则由独立方法实现,格式为“MER”前缀加当前日期与四位随机数:

private String generateMerchantNo() {
    SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
    String dateStr = sdf.format(new Date());
    String random = String.valueOf(new Random().nextInt(9000) + 1000);
    return "MER" + dateStr + random;
}

3.4 前端界面设计——三角色界面适配

采用JSP结合Bootstrap技术栈构建系统前端,分别面向管理员、商家和普通用户设计功能清晰、风格统一的操作界面。

3.4.1 管理员操作界面

管理首页:展示关键数据统计,包括用户总量、商家数量、民宿总数及待处理订单数;提供系统公告编辑功能和快捷入口,如商家审核与投诉处理模块。

商家管理页:列出所有商家信息(编号、名称、电话、状态),支持审核操作(通过或驳回),并可对商家信息进行编辑或删除,允许按状态筛选查看。

民宿审核页:展示待审民宿列表(名称、地址、所属商家、当前状态),支持查看详情(含图片与简介),并执行通过或驳回操作。

订单管理页:集中管理预订与退订订单,显示订单编号、关联用户、民宿及状态,支持审核确认(确认入住或同意退款),并可查看详细信息。

3.4.2 商家操作界面

店铺中心:展示商家基本信息(名称、联系方式、头像),提供编辑功能以更新店铺资料,并支持上传新头像。

民宿管理页:列出已发布的民宿(名称、地址、状态),支持新增民宿(填写详情并上传图片),以及对已有民宿进行编辑或删除操作。

房间管理页:展示各房间信息(类型、价格、配备设施),支持新增房间(选择对应民宿并配置价格与设施),也可对现有房间进行修改或移除。

订单处理页:分别列出待确认的预订请求和待审核的退订申请,商家可进行确认或驳回操作,并填写相应回复内容。

3.4.3 用户操作界面

前台首页:包含轮播图展示热门推荐民宿,提供搜索框支持按名称或地址筛选,下方以卡片形式呈现民宿列表,包含图片、名称与价格等信息。

民宿详情页:支持图片轮播展示,显示民宿具体位置、详细介绍,并列出可选房间类型(含价格与设施说明),页面提供预订与收藏功能按钮。

个人中心:用户可查看和管理个人信息(姓名、手机号、头像),浏览我的订单(含预订与退订记录及状态)、管理收藏的民宿(支持取消收藏),以及提交投诉反馈并查看处理回复。

3.5 系统测试——保障平台稳定运行

为验证系统的功能完整性与运行稳定性,实施了多维度的系统测试,重点覆盖管理端、商家端和用户端的核心业务流程,并包含各类异常场景的处理能力。

3.5.1 功能性测试

针对管理员、商家及用户的典型操作设计测试用例,确保各功能模块按预期执行。主要测试内容如下:

测试场景 预期结果 实际结果 是否通过
商家注册与审核 提交后状态为“待审核”,管理员审核通过后可登录 流程正常,状态更新准确
民宿发布与展示 发布需审核,审核后在首页展示 信息完整显示,审核机制有效
房间预订流程 用户预订→商家确认→支付完成→订单状态变更为“已支付” 状态流转正确,数据同步及时
退订申请处理 用户发起退订→商家审批→订单状态更新为“已取消” 逻辑清晰,状态变更无误
投诉反馈处理 用户提交投诉→商家回复→用户可查看回复内容 消息传递正常,数据实时同步

3.5.2 非功能性测试

从兼容性、性能、安全性和数据一致性四个方面进行深入验证,确保系统在真实环境中的可靠表现。

兼容性测试:在Chrome 120、Firefox 119、Edge 120等主流浏览器中对三端界面进行测试,页面布局未出现错乱,核心功能均可正常使用。

性能测试:模拟50个用户同时浏览民宿列表时,页面平均加载时间控制在1.8秒以内;10名用户并发提交预订请求时,系统平均响应时间不超过1.2秒,满足基本性能要求。

安全测试:普通用户尝试访问管理员后台路径(如/admin)时被成功拦截并跳转至登录页;在登录框输入SQL注入语句(如‘ or 1=1 #’),系统能有效过滤并提示“非法输入”,具备基础防护能力。

数据一致性测试:当商家删除某民宿时,其关联的房间信息及未完成订单均被标记为“无效”;用户注销账号后,相关预订记录保留但敏感信息脱敏处理,收藏数据则被清除,符合隐私与业务规范。

3.6 问题排查与优化——提升用户体验的关键措施

在开发过程中识别出若干典型问题,并采取针对性方案进行优化,显著改善系统稳定性与交互体验。

  • 民宿图片上传后返回404错误

    问题描述:图片虽成功上传至服务器本地目录,但通过URL访问时报404。

    解决方案:在Tomcat配置文件中设置虚拟路径映射(例如/upload/minsu/cover/指向实际存储路径),前端请求时拼接完整虚拟地址(如http://localhost:8080/upload/minsu/cover/xxx.jpg),实现资源正常访问。

  • 高并发下存在“超售”风险

    问题描述:多个用户同时预订同一间房(库存仅1间),可能出现重复下单成功的情况。

    解决方案:在房间表中引入“库存”字段,预订操作采用数据库事务结合行级锁(SELECT ... FOR UPDATE)机制,确保库存检查与扣减过程原子化,避免并发冲突。

  • 商家无法实时获知审核结果

    问题描述:管理员完成民宿审核后,商家必须手动刷新页面才能看到状态变化,影响使用体验。

    解决方案:集成WebSocket实现实时通信功能,审核完成后系统主动向前端推送通知(如弹窗提示“您的民宿已通过审核”),无需刷新即可获取最新状态。

  • 前台民宿列表加载缓慢

    问题描述:当民宿数量较多时,首页一次性加载全部数据导致页面卡顿。

    解决方案:引入分页机制(默认每页展示10条),图片启用懒加载技术(滚动至可视区域再加载),并对热门民宿列表使用Redis缓存(有效期1小时),大幅减少数据库查询压力,提升响应速度。

四、毕业设计复盘:经验总结与实践建议

4.1 开发过程中的技术收获

  • 分层架构的应用:基于Spring Boot实现Controller-Service-DAO三层结构,深入理解“高内聚、低耦合”的设计理念,增强了代码的可读性与维护性。
  • 多角色权限控制:采用RBAC模型,通过拦截器校验用户角色权限,有效防止越权访问,保障系统安全性。
  • 数据库设计能力提升:从初期单表存储逐步过渡到多表关联设计,掌握外键引用(如订单关联用户与民宿)、索引优化(如为“预订编号”添加唯一索引)等实用技能。
  • 问题解决能力增强:面对图片访问异常、并发冲突、实时通知缺失等问题,学会借助日志分析、调试工具和官方文档定位并解决问题,积累了宝贵的实战经验。

4.2 对后续开发者的建议

  • 以需求为导向:开发前应绘制用例图明确三端用户的核心流程(如预订-支付-退订闭环),厘清功能边界,减少后期返工。
  • 重视数据一致性:在涉及订单、支付等关键环节,务必使用数据库事务(如Spring的@Transactional注解),防止部分操作成功引发的数据不一致问题。
  • 优化用户体验:减少冗余跳转(如支持分步填写预订表单)、提供明确反馈(如提交后显示loading提示)、适配移动端显示(未来可考虑引入Vue.js开发H5版本)。
  • 预留扩展空间:在设计阶段考虑后续功能拓展(如接入第三方支付、增加会员积分体系),数据库表中提前预留扩展字段(如用户表添加“会员等级”字段)。
  • 完善测试覆盖:不仅测试正常流程,还需涵盖异常情况(如密码错误、重复提交订单、库存不足等),全面提升系统健壮性。

五、项目资源与发展展望

5.1 项目核心资源

本项目提供完整的开发与部署资料,便于学习者理解系统结构并开展二次开发:

  • 后端Spring Boot工程源码,包含管理端、商家端、用户端的完整接口实现;
  • 前端JSP页面源码,配套CSS样式与JavaScript脚本资源;
数据库资源:包括完整的MySQL建表语句,内含测试数据样本,便于快速初始化环境;同时提供清晰的数据库ER图,直观展示各数据表之间的关联关系。 部署文档涵盖本地开发与线上服务器两大部分。本地开发环境搭建指南详细说明JDK、MySQL及Tomcat的安装与配置步骤,帮助开发者快速构建运行环境;服务器部署部分则聚焦Linux系统下Nginx与Tomcat的协同配置流程,确保系统可稳定上线运行。 接口文档全面描述了三端(管理端、用户端、移动端)所使用的RESTful API,包含每个接口的请求方式、参数说明、响应格式以及常见错误码定义,便于前后端协作与第三方集成。

5.2 系统扩展方向

功能扩展

- 支付集成:支持接入微信支付和支付宝,实现订单的在线支付功能,提升交易效率与用户体验。 - 会员体系:设计多级会员制度(如普通会员、银卡、金卡),赋予不同等级用户相应的折扣权益与积分奖励机制。 - 智能推荐:根据用户的浏览历史与收藏偏好,利用协同过滤或内容推荐算法,推送个性化的民宿推荐列表。 - 评价系统:允许用户在入住完成后对民宿进行评分与评论,评价结果将纳入商家信誉评估体系,增强平台透明度。

技术升级

- 前端重构:采用Vue.js配合Element UI组件库替代传统JSP页面,构建单页应用(SPA),显著提升页面交互流畅性与响应速度。 - 后端优化:引入Spring Cloud微服务架构,将系统拆分为独立的服务模块,如民宿服务、订单服务和用户服务,提高系统的可维护性与并发处理能力。 - 数据存储优化:通过Redis缓存热门民宿信息以减轻数据库压力,同时使用MongoDB存储非结构化数据,例如用户评论、民宿详情描述等内容,提升读写灵活性。

场景延伸

- 移动端支持:开发微信小程序版本,支持用户随时随地完成预订操作,并实现扫码自助入住功能,提升便捷性。 - 多语言支持:增加中英文界面切换功能,拓展海外用户市场,提升国际化服务能力。 - 供应链整合:与本地旅游服务、特色产品供应商对接,推出“民宿+特产+景点”一体化套餐服务,丰富产品形态。 本项目作为本科阶段的毕业设计成果,不仅完整实现了民宿管理平台在管理端、用户端和移动端的核心业务功能,还系统性地贯穿了“需求分析—系统设计—编码实现—测试优化”的软件工程全过程。通过实际开发实践,有效巩固了Java Web开发、数据库设计等相关理论知识,锻炼了跨角色协作能力和复杂问题解决能力,为未来从事企业级应用开发积累了宝贵经验。
二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

关键词:Spring Pring 毕业设计 boot RING

您需要登录后才可以回帖 登录 | 我要注册

本版微信群
jg-xs1
拉您进交流群
GMT+8, 2025-12-25 06:03