
房 租 赁 管 理 系 统 这 个 项 目 名 字 在 毕 设 题 目 里 属 于 经 典 得 不 能 再 经 典 的 存 在 。 SpringBoot Vue 的 组 合 加 上 完 整 的 S Q L 脚 本 和 接 口 文 档 基 本 上 覆 盖 了 一 个 J a v a W e b 全 栈 毕 设 需 要 的 所 有 要 素 。 这 篇 文 章 我 就 从 实 战 角 度 把 这 套 房 屋 租 赁 管 理 系 统 的 设 计 思 路 、 核 心 实 现 、 数 据 库 脚 本 细 节 、 前 后 端 联 调 过 程 和 部 署 排 查 经 验 从 头 到 尾 捋 一 遍 。 分 享 给 正 在 做 类似 毕 设 的 同 学 、 想 借 这 个 项 目 入 门 J a v a W e b 全 栈 的 开 发 者 也 给 那 些 拿 到 源 码 但 不 知 道 从 哪 入 手 的 朋 友 一 条 清 晰 的 路 线 。我 接 触 过 不 少 毕 设 项 目 很 多 人 拿 到 源 码 后 第 一 反 应 是 双 击 打 开 然 后 被 一 堆 环 境 问 题 搞 到 崩 溃 。 真 正 有 价 值 的 不 是 那 串 代 码 本 身 而 是 代 码 背 后 的 设 计 逻 辑 为 什 么 表 要 这 么 建 、 接 口 为 什 么 这 么 分 、 权 限 为 什 么 这 么 控 制 。 这 套 房 屋 租 赁 系 统 表 面 看 是 “ 房 源 租 约 用 户 ” 三 件 套 实 际 上 涉 及 了 角 色 权 限 、 状 态 机 流 转 、 条 件 检 索 、 文 件 上 传 等 一 大 堆 J a v a W e b 的 高 频 考 点 把 它 吃 透 比 刷 一 百 道 面 试 题 都 管 用 。1. 项目整体设计与技术选型思路1.1 为什么是这个技术组合先 说 技 术 选 型 的 问 题 。 很 多 人 做 毕 设 喜 欢 追 新 非 要 用 SpringCloud Alibaba、微 服 务 网 关 、 分 布 式 事 务 什 么 的 结 果 架 子 搭 了 一个 月 业 务 一 行 没 写 。 我 的 建 议 是 毕 设 阶 段 一 定 要 选 自 己 能 够 驾 驭 的 技 术 栈 而 SpringBoot Vue 正 好 是 这 个 范 围 内 最 合 适 的 组 合 。SpringBoot 的 核 心 价 值 在 于 “ 约 定 大 于 配 置 ” 它 帮 你 把 Spring 那 一 大 堆 XML 配 置 文 件 全 省 了 内 嵌 Tomcat 又 免 去 了 单 独 部 署 容 器 的 麻 烦 。 而 Vue 这 边 单 页 应 用 的 开 发 体 验 比 传 统 的 JSP 或 者 Thymeleaf 好 太 多 前 后 端 通 过 JSON 交 互 边 界 清 晰 调 试 方 便 。 前 后 端 分 离 这 套 模 式 在 企 业 里 已 经 是 绝 对 主 流 拿 它 做 毕 设 不 仅 是 完 成 任 务 更 是 提 前 适 应 企 业 开 发 流 程 。比 如 说 这 套 房 屋 租 赁 系 统 后 端 负 责 房 源 数 据 的 管 理 和 租 赁 业 务 逻 辑 的 处 理 前 端 负 责 页 面 渲 染 和 用 户 交 互 二 者 只 通 过 接 口 约 定 来 对 话 。 这 种 分 离 让 开 发 效 率 提 升 很 明 显 一 个 人 写 后 端 的 时 候 不 用 去 管 页 面 长 什 么 样 写 前 端 的 时 候 也 不 用 担 心 SQL 怎 么 写 。1.2 系统角色与功能模块拆分一 个 合 格 的 房 屋 租 赁 管 理 系 统 至 少 要 有 三 个 核 心 角 色 管 理 员 、 房 东 、 租 客 。 功 能 模 块 的 划 分 也 是 围 绕 角 色 来 定 的 。 管 理 员 负 责 整 体 运 营 审 核 房 源 信 息 、 管 理 用 户 账 号 、 查 看 所 有 租 赁 订 单 房 东 负 责 发 布 房 源 、 更 新 房 源 状 态 、 处 理 租 客 的 租 赁 申 请 租 客 则 是 浏 览 房 源 、 收 藏 房 源 、 发 起 租 赁 申 请 、 签 署 订 单 。除 了 这 三 个 角 色 的 核 心 业 务 还 需 要 一 些 辅 助 功 能 来 撑 起 完 整 性 比 如 公 告 信 息 发 布 、 租 约 合 同 的 生 成 与 查 看 、 数 据 统 计 看 板 。 这 些 也 是 答 辩 时 老 师 比 较 容 易 发 问 的 点 。 有 段 时 间 我 帮 一 个 学 弟 调 试 类 似 项 目 他 的 系 统 里 只 有 简 单 的 增 删 改 查 房 源 一 但 被 租 出 去 就 直 接 删 掉 后 来 做 了 一 个 “ 租 赁 订 单 ” 的 概 念 加 进 去 整 个 系 统 的 业 务 闭 环 才 算 成 立 。 房 源 是 商 品 租 赁 订 单 是 交 易 记 录 二 者 必 须 分 开 。功 能 概 览 建 议 按 这 样 的 表 格 来 梳 理 一 目 了 然 模 块功 能 点涉 及 角 色用 户 管 理注 册 、 登 录 、 个 人 信 息 修 改所 有 角 色房 源 管 理发 布 、 编 辑 、 下 架 、 条 件 检 索房 东 、 管 理 员收 藏 管 理添 加 收 藏 、 取 消 收 藏 、 收 藏 列 表租 客租 赁 订 单申 请 租 房 、 审 核 、 签 约 、 退 租租 客 、 房 东 、 管 理 员公 告 管 理发 布 、 编 辑 、 删 除 、 查 看管 理 员数 据 统 计房 源 数 量 、 订 单 数 量 、 用 户 增 长管 理 员等 项 目 做 完 你 会 发 现 这 些 模 块 之 间 的 关 系 网 才 是 真 正 的 难 点 前 端 页 面 和 后 端 接 口 都 是 为 了 服 务 这 张 关 系 网 。2. 数据库设计与核心SQL脚本分析2.1 数据表结构的设计思路拿 到 源 码 的 时 候 第 一 件 事 不 是 跑 起 来 而 是 打 开 S Q L 脚 本 看 表 结 构 。 数 据 库 设 计 直 接 决 定 了 后 端 接 口 的 写 法 表 建 得 不 合 理 后 面 的 代 码 只 能 一 层 一 层 地 堆 查 询 条 件 来 打 补 丁 。一 套 标 准 的 房 屋 租 赁 系 统 数 据 库 起 码 包 含 这 些 表 用 户 表 ( t _ u s e r ) i d 、 u s e r n a m e 、 p a s s w o r d 、 r e a l _ n a m e 、 p h o n e 、 g e n d e r 、 i d _ c a r d 、 r o l e ( 0 管 理 员 / 1 房 东 / 2 租 客 ) 、 a v a t a r 、 c r e a t e _ t i m e 。 这 里 的 r o l e 字 段 是 整 个 系 统 权 限 的 基 石 后 端 接 口 的 拦 截 器 判 断 权 限 就 是 靠 它 。房 源 表 ( t _ h o u s e ) i d 、 l a n d l o r d _ i d ( 房 东 用 户 i d ) 、 t i t l e 、 d e s c r i p t i o n 、 c o v e r _ i m a g e 、 i m a g e s 、 a d d r e s s 、 c o m m u n i t y _ n a m e 、 r o o m _ n u m 、 h a l l _ n u m 、 a r e a 、 p r i c e 、 d e p o s i t 、 s t a t u s ( 0 待 审 核 / 1 出 租 中 / 2 已 租 出 / 3 已 下 架 ) 。 s t a t u s 字 段 值 得 好 好 琢 磨 很 多 人 用 一 个 简 单 的 0 和 1 表 示 “ 在 售 / 不 在 售 ” 但 在 租 赁 场 景 里 “ 待 审 核 ” 和 “ 已 下 架 ” 是 完 全 不 同 的 状 态 前 者 是 管 理 员 还 没 处 理 后 者 是 房 东 主 动 操 作 。 我 建 议 用 0 - 3 四 个 数 字 把 状 态 分 清 楚 前 端 根 据 状 态 决 定 显 示 什 么 按 钮 后 端 根 据 状 态 决 定 允 许 什 么 操 作 。租 赁 订 单 表 ( t _ l e a s e ) i d 、 h o u s e _ i d 、 t e n a n t _ i d ( 租 客 用 户 i d ) 、 l a n d l o r d _ i d 、 l e a s e _ s t a t u s ( 0 申 请 中 / 1 已 签 约 / 2 已 退 租 / 3 已 拒 绝 ) 、 m o n t h l y _ r e n t 、 d e p o s i t 、 s t a r t _ d a t e 、 e n d _ d a t e 、 c o n t r a c t _ p a t h 、 c r e a t e _ t i m e 。 这 张 表 是 整 个 系 统 的 业 务 枢 纽 前 后 端 联 调 时 大 部 分 调 的 就 是 这 个 表 的 接 口 。其 次 还 有 收 藏 表 ( t _ f a v o r i t e ) 、 公 告 表 ( t _ n o t i c e ) 、 合 同 附 件 表 ( 可 以 打 包 进 t _ l e a s e 的 c o n t r a c t _ p a t h ) 、 管 理 员 操 作 日 志 表 等 。 外 键 的 使 用 要 拿 捏 分 寸 数 据 库 层 面 用 逻 辑 外 键 就 够 了 不 要 在 表 上 加 太 多 物 理 F O R E I G N K E Y 约 束 不 然 删 数 据 的 时 候 会 被 外 键 限 制 折 磨 得 很 难 受 M y B a t i s P l u s 里 的 查 询 也 会 变 得 很 别 扭 。 实 际 开 发 中 我 习 惯 在 S Q L 脚 本 里 加 好 注 释 说 明 这 个 i d 对 应 哪 张 表 但 不 建 物 理 约 束 。2.2 初始化脚本与关键 SQL 写法S Q L 脚 本 的 质 量 直 接 影 响 答 辩 时 的 印 象 分 。 很 多 同 学 的 脚 本 就 是 简 单 的 C R E A T E T A B L E 加 几 条 I N S E R T 老 师 一 问 “ 你 数 据 量 多 大 、 索 引 怎 么 建 的 ” 就 卡 壳 。 建 议 在 脚 本 里 至 少 体 现 三 类 东 西 一 是 明 确 的 字 符 集 设 置 。建 库 的 时 候 指 定 U T F 8 M B 4 防 止 中 文 乱 码 和 E M O J I 报 错 数 据 库 连 接 字 符 集 和 表 字 符 集 要 一 致 。 很 多 本 地 跑 起 来 没 问 题 一 上 服 务 器 就 乱 码 的 情 况 九 成 是 字 符 集 不 统 一 造 成 的 。二 是 合 理 的 索 引 。对 于 经 常 查 询 的 字 段 比 如 h o u s e 表 的 s t a t u s 、 p r i c e 、 a d d r e s s 要 加 索 引 。 房 源 列 表 页 的 核 心 查 询 是 “ 按 地 址 模 糊 搜 索 按 价 格 排 序 按 状 态 过 滤 ” 这 三 个 条 件 加 进 去 之 后 索 引 的 配 置 是 影 响 查 询 速 度 的 关 键 。 当 然 毕 设 阶 段 数 据 量 不 大 索 引 的 效 果 感 受 不 明 显 但 脚 本 里 有 索 引 语 句 和 没 有 索 引 语 句 老 师 看 到 的 是 两 个 层 次 的 东 西 。三 是 几 条 典 型 的 复 杂 查 询 语 句 示 例 。比 如 查 询 “ 某 个 房 东 名 下 所 有 在 租 房 源 的 订 单 数 量 ” 就 需 要 用 到 J O I N 和 G R O U P B Y 。 房 源 列 表 页 的 多 条 件 查 询 则 要 写 好 动 态 S Q L 前 端 传 什 么 条 件 就 拼 什 么 条 件 用 M y B a t i s 的 i f 标 签 或 者 M y B a t i s P l u s 的P a g e 对 象 L a m b d a 查 询都 可 以 。这 里 给 一 个 实 战 中 很 常 用 的 多 条 件 分 页 查 询 示 例 前 端 搜 房 源 的 时 候 可 能 同 时 传 地 址 、 价 格 区 间 、 房 型 几 个 条 件 后 端 需 要 灵 活 拼 接 select idselectHousePage resultTypecom.example.entity.House SELECT h.*, u.real_name AS landlord_name FROM t_house h LEFT JOIN t_user u ON h.landlord_id u.id where if testaddress ! null and address ! AND h.address LIKE CONCAT(%, #{address}, %) /if if testminPrice ! null AND h.price gt; #{minPrice} /if if testmaxPrice ! null AND h.price lt; #{maxPrice} /if if teststatus ! null AND h.status #{status} /if /where ORDER BY h.create_time DESC /select看 到 没 这 种 写 法 的 好 处 是 前 端 有 传 参 数 就 加 条 件 没 传 就 直 接 忽 略 完 全 不 需 要 写 超 级 多 的 i f - e l s e 判 断 。 联 调 的 时 候 前 端 传 参 名 和 这 里 的p a r a m一 一 对 应 就 行 。2.3 数据初始化与演示数据的设计这 个 点 容 易 被 忽 视 但 对 于 完 成 一 个 可 演 示 的 系 统 来 说 至 关 重 要 。 你 的 S Q L 脚 本 里 要 预 置 好 管 理 员 账 号 、 几 个 房 东 账 号 、 几 个 租 客 账 号 然 后 每 个 房 东 名 下 有 3 - 5 套 房 源 每 个 房 源 对 应 不 同 的 价 格 和 状 态 。 再 加 几 条 处 于 不 同 状 态 的 租 赁 订 单 覆 盖 “ 申 请 中 、 已 签 约 、 已 退 租 ” 三 种 情 况 。这 样 做 的 目 的 是 答 辩 演 示 的 时 候 不 需 要 临 场 注 册 账 号 、 逐 条 录 入 数 据 打 开 页 面 就 有 数 据 可 看 。 而 且 不 同 状 态 的 订 单 能 直 接 展 示 你 的 业 务 流 程 是 闭 环 的 。 我 还 习 惯 在 脚 本 末 尾 加 一 段 注 释 写 明 预 置 账 号 的 用 户 名 和 密 码 加 密 后 的 方 便 上 手 就 能 登 录 测 试 。密 码 存 储 一 定 要 用 M D 5 或 者 B C r y p t 加 密 千 万 不 要 明 文 保 存 。 有 个 朋 友 的 毕 设 项 目 里 密 码 全 是 明 文 答 辩 老 师 当 场 就 指 出 了 安 全 问 题 。 其 实 M D 5 加 盐 就 够 用 了 代 码 也 不 复 杂 但 这 个 细 节 很 能 体 现 你 的 工 程 素 养 。3. 后端 SpringBoot 核心实现解析3.1 项目结构与分层设计解 压 源 码 之 后 先 看 项 目 结 构 是 否 符 合 标 准 的 分 层 设 计 。 标 准 的 S p r i n g B o o t 项 目 结 构 应 该 是 c o n t r o l l e r层 接 收 前 端 请 求 s e r v i c e层 处 理 业 务 逻 辑 m a p p e r层 负 责 数 据 库 交 互 e n t i t y层 定 义 实 体 类 另 外 加 一 个c o n f i g包 放 配 置 类 、c o m m o n包 放 统 一 返 回 结 果 和 异 常 处 理 。很 多 同 学 写 代 码 的 时 候 喜 欢 把 业 务 全 塞 在 C o n t r o l l e r 里 几 百 行 的 方 法 一 个 接 一 个 这 样 做 看 起 来 快 但 后 期 维 护 的 时 候 会 痛 不 欲 生 。 我 的 经 验 是 C o n t r o l l e r 里 只 做 三 件 事 收 参 数 、 调 S e r v i c e 、 返 回 统 一 结 果 对 象 。 一 切 业 务 判 断 放 在 S e r v i c e 里 这 样 测 试 的 时 候 可 以 直 接 测 S e r v i c e 层 不 用 经 过 H T T P 请 求 。统 一 返 回 结 果 对 象R e s u l t是 这 类 项 目 的 标 配 一 般 包 含c o d e 、 m s g 、 d a t a三 个 字 段 。 前 端 a x i o s 拦 截 器 里 判 断c o d e是 否 为 200 不 是 的 话 直 接 弹 错 误 提 示 。 这 样 的 统 一 封 装 能 让 前 后 端 对 接 的 时 候 少 掉 很 多 脑 细 胞 不 会 出 现 “ 这 个 接 口 返 回 的 是 数 组 、 那 个 接 口 返 回 的 是 对 象 ” 的 糟 糕 情 况 。3.2 登录认证与会话管理租 赁 系 统 涉 及 三 种 角 色 后 端 接 口 必 须 有 权 限 校 验 。 目 前 主 流 的 做 法 是 J W T 拦 截 器 。 用 户 登 录 成 功 后 后 端 根 据 用 户 i d 和 角色 生 成 一 个 T o k e n 返 回 给 前 端 前 端 存 在 本 地 存 储 里 每 次 请 求 时 放 在A u t h o r i z a t i o n请 求 头 里 。 后 端 拦 截 器 在 请 求 进 入 C o n t r o l l e r 之 前 校 验 T o k e n 通 过 了 才 放 行 。J W T 的 好 处 是 无 状 态 服 务 器 不 用 存 会 话 水 平 扩 展 的 时 候 不 用 考 虑 会 话 同 步 问 题 。 毕 设 项 目 里 用 它 可 以 说 是 又 简 单 又 有 面 子 。 但 要 注 意 一 个 坑 J W T 的 密 钥 千 万 不 要 写 死 在 代 码 里 要 放 在a p p l i c a t i o n . y m l配 置 文 件 中 方 便 不 同 环 境 切 换 。 有 一 次 我 看 到 有 人 把 密 钥 写 在 了C o n s t a n t类 里 结 果 一 打 包 部 署 别 人 通 过 反 编 译 就 能 拿 到 安 全 性 直 接 到 谷 底 。拦 截 器 的 配 置 也 有 讲 究 。 不 能 拦 截 登 录 接 口 本 身 否 则 没 法 登 录 了 。 我 习 惯 把 需 要 放 行 的 路 径 单 独 列 出 来 比 如/ u s e r / l o g i n、/ u s e r / r e g i s t e r、/ h o u s e / p u b l i c / **这 些 是 不 需 要 登 录 就 能 访 问 的 其 他 的 全 部 拦 截 。 还 有 一 个 细 节 是 C O R S 跨 域 处 理 前 端 项 目 运 行 在 8080 端 口 后 端 运 行 在 9090 端 口 之 间 必 须 配 置 C O R S 不 然 浏 览 器 会 直 接 拦 截 请 求 报 错 信 息 还 特 别 迷 糊 稍 不 注 意 就 会 在 这 里 卡 半 天 。3.3 核心业务接口与状态流转后 端 接 口 的 设 计 是 整 个 项 目 的 重 中 之 重 。 我 们 从 房 源 和 租 赁 订 单 两 条 主 线 来 分 析 。房 源 主 线 上 核 心 接 口 有 发 布 房 源 、 修 改 房 源 、 下 架 房 源 、 审 核 房 源 管 理 员 、 分 页 查 询 房 源 。 这 里 有 个 经 典 的 权 限 坑 房 东 只 能 修 改 自 己 名 下 的 房 源 不 能 动 别 人 的 。 后 端 在 S e r v i c e 层 要 先 比 对 当 前 登 录 用 户 的 i d 和 房 源 的 l a n d l o r d _ i d 是 否 一 致 不 一 致 直 接 抛 异 常 。 很 多 人 在 前 端 把 编 辑 按 钮 隐 藏 掉 就 以 为 万 事 大 吉 了 但 前 端 隐 藏 只 是 体 验 问 题 后 端 必 须 做 真 校 验 这 是 安 全 意 识 的 问 题 。 想 想 看 如 果 别 人 在 浏 览 器 控 制 台 手 动 发 一 个 请 求 你 的 后 端 接 口 没 有 权 限 判 断 人 家 就 能 随 便 改 你 的 数 据 。租 赁 订 单 主 线 上 状 态 流 转 是 最 容 易 出 问 题 的 地 方 。 租 客 发 起 申 请 时 订 单 状 态 是 0 申 请 中 房 东 点 击 “ 同 意 签 约 ” 后 变 成 1 已 签 约 同 时 房 源 状 态 要 改 成 2 已 租 出 。 这 两 个 操 作 必 须 放 在 同 一 个 事 务 里 不 然 订 单 改 了 房 源 没 改 数 据 就 不 一 致 了 。 类 似 这 种 “ 一 个 操 作 影 响 多 张 表 ” 的 逻 辑 建 议 在 S e r v i c e 层 方 法 上 加 T r a n s a c t i o n a l注 解 。 我 还 见 过 一 个 更 极 端 的 案 例 退 租 的 时 候 只 改 了 订 单 状 态 忘 了 把 房 源 状 态 恢 复 成 “ 出 租 中 ” 结 果 这 套 房 源 永 远 没 办 法 再 被 搜 索 到 了 。接 口 文 档 是 这 个 项 目 包 里 的 一 大 亮 点 。 我 建 议 除 了 P O S T M A N 导 出 的 文 档 再 写 一 份 简 单 的 M a r k d o w n 版 本 的 接 口 列 表 包 含 每 个 接 口 的 请 求 方 式 、 U R L 、 参 数 说 明 、 返 回 示 例 。 不 要 觉 得 这 是 多 余 工 作 答 辩 的 时 候 老 师 翻 你 的 文 档 一 眼 就 能 看 出 你 对 整 个 系 统 的 掌 握 程 度 。 文 档 清 晰 项 目 直 接 加 分 。3.4 文件上传与资源访问房 源 图 片 的 上 传 是 这 类 项 目 逃 不 掉 的 功 能 。 S p r i n g B o o t 处 理 文 件 上 传 其 实 很 简 单 M u l t i p a r t F i l e接 收 文 件 然 后 把 文 件 写 到 本 地 指 定 目 录 把 访 问 路 径 存 入 数 据 库 。 但 有 个 容 易 踩 的 坑 文 件 上 传 到 本 地 磁 盘 后 如 果 不 做 静 态 资 源 映 射 前 端 用i m g s r c / u p l o a d / x x x . j p g 是 访 问 不 到 的 。 S p r i n g B o o t 默 认 只 映 射c l a s s p a t h : / s t a t i c / 你 需 要 在 配 置 类 里 加 一 个W e b M v c C o n f i g u r e r 把 本 地 文 件 路 径 映 射 成 U R L 路 径 Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler(/upload/**) .addResourceLocations(file: uploadDir); }注 意u p l o a d D i r最 好 配 置 在a p p l i c a t i o n . y m l里 不 要 写 死 。 不 同 环 境 下 路 径 可 能 完 全 不 一 样 写 死 了 换 台 电 脑 就 得 改 代 码 重 打 包 太 痛 了 。再 提 醒 一 个 细 节 文 件 上 传 之 前 一 定 要 校 验 后 缀 名 和 文 件 大 小 。 很 多 人 不 校 验 直 接f i l e . g e t O r i g i n a l F i l e n a m e ( )拿 到 名 字 就 存 这 样 会 有 两 个 问 题 一 是 恶 意 上 传 . j s p 文 件 可 能 造 成 服 务 器 被 植 入 网 页 木 马 二 是 大 文 件 会 把 内 存 打 爆 。 合 理 的 做 法 是 限 制 后 缀 名 为 图 片 格 式 大 小 限 制 在 5 M B 左 右 然 后 用U U I D 原 始 文 件 名的 方 式 重 新 命 名 存 储 文 件 避 免 文 件 名 冲 突 。4. 前端 Vue 页面实现与前后端联调4.1 前端项目结构与路由设计前 端 V u e 项 目 的 结 构 直 接 决 定 了 后 面 维 护 的 心 情 。 我 建 议 按 照 “ 页 面 组 件 工 具 接 口 ” 四 层 来 组 织 v i e w s放 页 面 级 组 件 c o m p o n e n t s放 可 复 用 的 子 组 件 a p i放 所 有 请 求 后 端 的 接 口 函 数 u t i l s放 工 具 函 数 和 a x i o s 封 装 。路 由 设 计 上 要 分 清 “ 门 户 页 面 ” 和 “ 管 理 后 台 ” 。 门 户 页 面 包 括 首 页 、 房 源 列 表 、 房 源 详 情 、 登 录 注 册 这 些 是 所 有 人 都 能 看 的 。 管 理 后 台 则 要 根 据 角 色 做 动 态 路 由 比 如 房 东 后 台 有 “ 我 的 房 源 、 订 单 管 理 ” 管 理 员 后 台 有 “ 用 户 审 核 、 公 告 管 理 、 数 据 统 计 ” 。 这 里 有 个 经 典 做 法 在 前 端 路 由 配 置 里 加m e t a . r o l e s字 段 标 明 这 个 路 由 可 以 被 哪 些 角 色 访 问 路 由 守 卫 里 做 判 断 没 有 权 限 的 跳 转 到 404 页 面 或 者 重 新 定 向 到 首 页 。V u e R o u t e r 的 路 由 守 卫 是 前 端 权 限 控 制 的 第 一 道 关 它 不 是 后 端 权 限 校 验 的 替 代 而 是 为 了 良 好 的 用 户 体 验 用 户 没 登 录 就 访 问 后 台 页 面 直 接 弹 到 登 录 页 而 不 是 等 后 端 返 回 401 才 处 理 。 我 在 项 目 里 常 常 这 么 写 router.beforeEach((to, from, next) { const token localStorage.getItem(token) if (to.meta.requiresAuth !token) { next(/login) } else { next() } })表 单 校 验 也 是 前 端 的 基 本 功 。 注 册 页 面 的 手 机 号 格 式 、 密 码 长 度 、 二 次 密 码 一 致 性 这 些 校 验 用 V u e 的 表 单 校 验 规 则 就 能 搞 定 但 要 记 住 前 端 校 验 是 为 了 用 户 体 验 后 端 校 验 才 是 安 全 底 线 。 前 端 可 以 拦 住 九 成 的 误 操 作 剩 下 一 成 恶 意 请 求 只 能 靠 后 端 兜 底 。4.2 核心页面拆解从首页到订单管理接 下 来 把 几 个 核 心 页 面 过 一 遍 这 也 是 答 辩 演 示 的 主 要 场 景 。首 页 / 房 源 列 表 页 这 是 整 个 系 统 的 门 面 。 有 两 个 要 点 搜 索 条 件 的 设 计 和 分 页 的 实 现 。 我 们 的 搜 索 条 件 是 地 址 关 键 词 、 价 格 区 间 、 房 型 几 室 几 厅 每 个 条 件 变 化 都 触 发 重 新 查 询 这 里 要 防 止 的 是 “ 条 件 竞 态 ” — — 用 户 快 速 切 换 条 件 时 最 后 发 出 的 请 求 不 一 定 是 最 先 返 回 的 如 果 不 加 处 理 页 面 可 能 显 示 的 是 旧 条 件 的 结 果 。 简 单 的 做 法 是 在 请 求 前 记 录 一 个 序 号 返 回 后 判 断 是 不 是 最 新 的 序 号 不 是 就 丢 弃 。房 源 详 情 页 展 示 图 片 轮 播 、 基 本 信 息 、 房 东 信 息 、 租 赁 申 请 按 钮 。 这 个 页 面 的 难 点 在 于 按 钮 的 显 隐 逻 辑 已 登 录 且 是 租 客 角 色 才 显 示 “ 申 请 租 房 ” 房 东 看 到 的 是 “ 编 辑 / 下 架 ” 未 登 录 的 人 看 到 的 是 “ 登 录 后 申 请 ” 。 这 种 多 状 态 的 页 面 很 容 易 写 乱 我 的 习 惯 是 在 页 面 里 定 义 一 个computed属 性actionableList 集 中 管 理 按 钮 的 操 作 权 限 判 断 。管 理 后 台 页 这 里 用 到 了 E l e m e n t U I 的el-table和el-dialog组 件 。 列 表 页 面 的 标 配 是 搜 索 栏 表 格 分 页 器 三 件 套 。 编 辑 操 作 要 么 跳 转 到 新 页 面 要 么 弹 出 对 话 框 我 建 议 用 对 话 框 形 式 减 少 页 面 跳 转 次 数 。 但 对 话 框 里 的 表 单 一 定 要 记 得 在 关 闭 时 清 空 校 验 状 态 不 然 第 二 次 打 开 的 时 候 会 出 现 “ 第 一 次 的 校 验 红 色 提 示 还 留 着 ” 的 尴 尬 场 面 。订 单 管 理 页 租 客 视 角 看 申 请 记 录 和 签 约 状 态 房 东 视 角 看 待 审 核 的 申 请 。 这 里 有 一 个 很 经 典 的 前 端 页 面 联 动 场 景 房 东 点 击 “ 同 意 ” 按 钮 后 订 单 状 态 变 成 “ 已 签 约 ” 同 时 房 源 状 态 也 变 了 。 前 端 要 在 房 东 操 作 成 功 后 刷 新 当 前 页 面 数 据 同 时 如 果 页 面 上 有 房 源 信 息 的 概 览 卡 片 也 要 一 起 刷 新 。 用 E l e m e n t U I 的M e s s a g e B o x做 二 次 确 认 是 标 准 操 作 防 止 房 东 手 滑 误 点 。4.3 axios 封装与请求响应拦截前 端 调 接 口 最 头 疼 的 不 是 写 请 求 而 是 每 个 请 求 都 要 处 理 T o k e n 、 错 误 提 示 、 加 载 状 态 重 复 代 码 越 来 越 多 。 解 决 方 案 是 把 a x i o s 做 一 个 统 一 封 装 通 过 请 求 拦 截 器 加 上 T o k e n 通 过 响 应 拦 截 器 统 一 处 理 错 误 状 态 码 。const service axios.create({ baseURL: /api, timeout: 10000 }) service.interceptors.request.use(config { const token localStorage.getItem(token) if (token) { config.headers[Authorization] token } return config }) service.interceptors.response.use( response { const res response.data if (res.code ! 200) { Message.error(res.msg || 请求失败) return Promise.reject(new Error(res.msg)) } return res }, error { if (error.response error.response.status 401) { localStorage.removeItem(token) router.push(/login) } Message.error(error.message || 网络异常) return Promise.reject(error) } )这 个 封 装 有 一 个 好 处 所 有 的 页 面 里 调 用 接 口 时 只 需 要 关 心r e s u l t . d a t a 不 用 反 复 判 断c o d e和 弹 错 误 提 示 。 另 外 b a s e U R L的 配 置 建 议 用 相 对 路 径/ a p i 然 后 通 过 V u e 的p r o x y配 置 转 发 到 真 实 后 端 端 口 这 样 就 能 躲 开 前 端l o c a l h o s t : 8 0 8 0请 求l o c a l h o s t : 9 0 9 0的 跨 域 问 题 — — 从 浏 览 器 的 视 角 看 请 求 的 是 同 一 个 源 。v u e . c o n f i g . j s里 的 代 理 配 置 很 简 单 却 极 常 用 devServer: { proxy: { /api: { target: http://localhost:9090, changeOrigin: true } } }有 个 细 节 需 要 留 意 后 端 接 口 的 路 径 前 缀 统 一 加/ a p i 前 端 代 理 也 用/ a p i 这 样 办 公 室 联 调 的 时 候 直 接 通 过 代 理 访 问 上 线 部 署 时 又 可 以 用 N g i n x 做 同 样 的 转 发 整 个 过 程 不 需 要 改 代 码 只 需 要 调 配 置 这 就 是 “ 环 境 与 代 码 分 离 ” 的 思 路 。5. 项目运行部署与常见问题排查5.1 环境准备与初始化运行步骤正 式 开 始 跑 项 目 之 前 把 环 境 列 表 理 清 楚 J D K 1 . 8 、 M y S Q L 5 . 7 、 M a v e n 3 . 6 、 N o d e . j s 1 4 。 版 本 匹 配 是 第 一 个 坑 比 如 S p r i n g B o o t 2 . x 对 应 J D K 8 没 问 题 但 有 的 同 学 本 机 装 了 J D K 17 又 去 跑 老 版 本 的 S p r i n g B o o t 2 . 3 启 动 会 报 一 堆 看 不 懂 的 错 误 。 如 果 你 的 项 目 用 的 是 S p r i n g B o o t 2 . 7 系 列 建 议 老 老 实 实 用 J D K 8 稳 定 压 倒 一 切 。数 据 库 那 边 的 操 作 顺 序 是 先 用s o u r c e xxx.sql或 者 N a v i c a t 运 行 S Q L 脚 本 建 好 数 据 库 和 表 。 这 个 时 候 有 个 细 节 要 注 意 运 行 脚 本 前 先 看 一 下 开 头 有 没 有C R E A T E D A T A B A S E和U S E语 句 如 果 有 直 接 运 行 就 会 自 动 建 库 切 库 没 有 的 话 需 要 手 动 新 建 一 个 数 据 库 再 选 中 它 运 行 脚 本 。 很 多 人 在 这 里 栽 跟 头 运 行 完 脚 本 后 后 台 报 “ 表 不 存 在 ” 原 因 就 是 脚 本 里 没 有 U S E 语 句 表 建 到 默 认 的 数 据 库 里 去 了 。后 端 配 置 文 件a p p l i c a t i o n . y m l里 需 要 改 三 个 东 西 数 据 库 连 接 的 u r l 、 用 户 名 、 密 码 。 有 些 项 目 还 配 了 R e d i s 或 者 其 他 中 间 件 没 有 的 话 直 接 忽 略 就 行 不 要 手 贱 去 加 加 了 反 而 启 动 失 败 。 配 好 后 在 I D E A 里 点 击A p p l i c a t i o n主 类 运 行 看 到 “ T o m c a t s t a r t e d” 字 样 就 说 明 后 端 起 来 了 。前 端 部 分 进 入 前 端 项 目 目 录 先n p m i n s t a l l装 依 赖 再n p m r u n d e v启 动 开 发 服 务 。 这 里 有 个 常 见 问 题 n p m i n s t a l l很 慢 或 者 直 接 挂 掉 。 解 决 办 法 是 换 国 内 镜 像 n p m c o n f i g s e t r e g i s t r y h t t p s : / / r e g i s t r y . n p m t a o b a o . o r g 装 完 之 后 再 配 置 回 来 也 行 。 前 端 启 动 成 功 后 浏 览 器 访 问l o c a l h o s t : 8 0 8 0 如 果 后 端 也 在 跑 首 页 的 数 据 应 该 能 正 常 加 载 。整 个 流 程 看 下 来 其 实 就 是 建 库 → 配 后 端 → 启 动 后 端 → 启 动 前 端 。 每 一 步 有 问 题 都 有 明 确 的 报 错 信 息 只 要 不 着 急 一 步 一 步 排 查 就 能 解 决 。5.2 高频报错的排查思路把 我 调 试 这 类 项 目 时 遇 到 的 高 频 问 题 整 理 成 了 一 张 表 基 本 上 覆 盖 了 九 成 的 踩 坑 场 景 现 象可 能 原 因排 查 方 向后 端 启 动 报 数 据 库 连 接 失 败密 码 错 、 端 口 错 、 驱 动 未 加检 查 y m l 配 置 用 N a v i c a t 本 地 连 一 下 试 试前 端np m run dev报 缺 少 依 赖n o d e _ m o d u l e s 不 完 整删 掉 重 新 n p m i n s t a l l页 面 能 开 但 数 据 加 载 不 出 来跨 域 / 代 理 配 置 错 / 后 端 接 口 路 径 对 不 上打 开 浏 览 器 F12 看 N e t w o r k 的 请 求 状 态登 录 成 功 但 访 问 后 台 跳 回 登 录 页T o k e n 存 储 / 拦 截 器 校 验 逻 辑 不 匹 配看 请 求 头 里 有 没 有 A u t h o r i z a t i o n 字 段图 片 上 传 成 功 但 显 示 不 出 来静 态 资 源 映 射 未 配后 端 加 资 源 映 射 直 接 用 完 整 U R L 访 问 图 片 试 试数 据 库 中 文 乱 码字 符 集 不 统 一数 据 库 / 表 / 连 接 参 数 全 部 改 成 U T F 8 M B 4第 一 个 坑 太 经 典 了 多 说 两 句 。 数 据 库 连 接 失 败 的 时 候 很 多 人 第 一 反 应 是 检 查 密 码 。 密 码 确 实 是 最 常 见 的 原 因 但 其 次 容 易 被 忽 视 的 是s e r v e r T i m e z o n e M y S Q L 8 . x 连 接 串 里 必 须 加? s e r v e r T i m e z o n e A s i a / S h a n g h a i u s e S S L f a l s e c h a r a c t e r E n c o d i n g u t f 8 不 然 启 动 的 时 候 报 时 区 错 误 。 这 个 问 题 在 我 接 触 的 项 目 里 至 少 出 现 过 十 次 。还 有 一 个 经 典 问 题 是 前 端 版 本 不 匹 配 。 有 些 源 码 是 用 V u e 2 写 的 有 的 是 V u e 3 。 如 果 你 在 V u e 3 项 目 里 用t h i s . $ r o u t e r . p u s h去 跳 转 它 其 实 是 会 报 错 的 因 为 C o m p o s i t i o n A P I 里 没 有t h i s。 拿 到 源 码 先 看p a c k a g e . j s o n 确 认 一 下 V u e 的 版 本 和 E l e m e n t U I 的 版 本 再 决 定 用 哪 种 写 法 。 很 多 人 在 V u e 3 项 目 里 硬 套 V u e 2 的 写 法 排 错 排 到 怀 疑 人 生 。5.3 打包部署从开发环境到生产环境开 发 完 成 之 后 面 临 的 一 个 问 题 是 部 署 。 很 多 人 的 毕 设 答 辩 只 需 要 本 地 演 示 但 我 建 议 把 “ 前 端 打 包 放 进 S p r i n g B o o t ” 这 条 路 走 一 遍 因 为 这 是 企 业 里 常 见 的 简 化 部 署 方 式 老 师 问 到 部 署 方 案 时 也 能 答 上 来 。前 端 打 包 的 命 令 是np m r u n b u i l d 打 包 完 之 后 会 生 成 一 个d i s t目 录 。 后 端 的src/main/resources/static目 录 下 放 入 这 个d i s t的 内 容 重 新 打 包 S p r i n g B o o t 应 用 访 问l o c a l h o s t : 9 0 9 0就 能 直 接 看 到 前 端 页 面 不 再 需 要 单 独 启 动 V u e 开 发 服 务 。不 过 这 里 有 两 个 坑 。 第 一 前 端 里 的b a s e U R L如 果 是/ a p i 那 么 打 包 后 页 面 里 请 求/ a p i / h o u s e / l i s t 会 直 接 请 求 到 后 端 的/ a p i / h o u s e / l i s t 这 时 候 后 端 接 口 路 径 前 缀 必 须 和 它 对 应 。 如 果 后 端 接 口 没 有/ a p i前 缀 就 需 要 在 C o n t r o l l e r 的 R e q u e s t M a p p i n g里 加 上/ a p i 或 者 配 置 一 个s e r v l e t C o n t e x t P a t h。 第 二 V u e R o u t e r 默 认 用 的 是h i s t o r y模 式 这 种 模 式 在 静 态 资 源 部 署 时 会 出 问 题 — — 直 接 访 问/ l o g i n会 404 。 解 决 办 法 有 两 个 要 么 把 路 由 模 式 改 成hash模 式 要 么 在 后 端 配 置 一 个 转 发 规 则 把 所 有 非 静 态 资 源 的 请 求 转 发 到 i n d