ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

基于SpringBoot+Vue的摄影工作室管理系统开发实战

基于SpringBoot+Vue的摄影工作室管理系统开发实战 做网上摄影工作室管理系统这个项目起因是我帮一个做独立摄影工作室的朋友处理他那一摊子“手工运维”的破事。预约靠微信消息、排期靠Excel、交片靠网盘链接、收款靠记账本客片一多就乱漏掉预约、搞错档期是家常便饭。我索性用 SpringBoot Vue MyBatis MySQL 这套2025年依然很稳的技术组合帮他做了一套线上管理系统把作品展示、在线预约、排期管理、订单跟进全部串了起来。这篇文章就把从零开发的完整过程写出来从需求拆解、表结构设计、后端接口实现、前端页面开发到最后打包部署和踩坑实录一条线讲透。这套系统适合谁看如果你正在准备毕业设计、课程综合实训或者想给小型工作室搭一套内部管理系统这篇里的方案、代码思路、排错方法基本都能直接抄作业。哪怕你以前没接触过前后端分离项目按这个链路走一遍也能明白 SpringBoot 和 Vue 到底是怎么协同工作的以及 MyBatis 和 MySQL 在这条链路里各自扮演什么角色。1. 项目定位与技术方案选型1.1 摄影工作室的痛点到底在哪先别急着写代码我把这个项目真正要解决的问题摆出来。一个典型的中小型摄影工作室业务链条是这样的摄影师拍摄 → 选片修片 → 交付成品 → 客户评价转介绍。看起来简单但每个环节都有让人头大的细节。客户想看样片你得有一个在线作品集客户想约档期你得确认摄影师哪天有空订单拍完了客户还得知道后续修片进度到哪一步了。传统的人工管理模式下这些信息散落在微信聊天记录、手机相册、纸质登记表里根本不具备可追踪性。所以做这套系统时我没有一上来就堆功能而是先梳理清楚三个核心角色——普通用户想拍照的客户、摄影师接单和上传作品的人、管理员负责排期和订单审核的人——分别要解决什么问题。明确角色之后功能模块就自然浮出水面用户端需要作品浏览和在线预约摄影师端需要档期管理和作品图集上传管理员端需要订单分配和全流程状态管理。1.2 技术选型为什么还是这套经典组合很多人在2025年做技术选型时会纠结是不是该上微服务、上云原生但我的观点很明确项目复杂度决定技术架构不是技术越新就越适合。这套系统属于典型的中小型业务管理系统并发量不大业务逻辑中等偏复杂用 SpringBoot Vue MyBatis MySQL 这套组合开发和维护成本是最低的。具体来看SpringBoot 提供自动配置和起步依赖省去了大量 Spring XML 配置把精力集中在业务代码上MyBatis 则把 SQL 控制权留给开发人员方便针对摄影业务做复杂查询和动态条件拼接MySQL 作为成熟的关系型数据库处理用户、作品、预约、订单这类强关系数据非常顺手。前端用 Vue核心原因是它组件化开发体验好响应式数据绑定写起来自然加上 Element Plus 这类现成 UI 组件库后台管理页面开发效率很高。这套组合在2025年依然是国内 Java 后端开发的主流答案资料多、社区活跃、遇到问题能查到的解决方案也最多。一句话总结选型逻辑业务规模不大但逻辑关系复杂、查询需求多变选择灵活掌控 SQL 的 MyBatis搭配开发效率最高的 SpringBoot再配上前端生态最成熟的 Vue正好卡在“开发速度”和“系统易维护性”的最佳平衡点上。2. 开发环境搭建与数据库设计2.1 版本搭配2025年最省心的组合版本问题一定要提前说因为我见过太多初学者在环境配置上卡一周的。SpringBoot 版本不是越新越好要看你的 JDK 和依赖生态是否匹配。标题里写了“2025最新”但“最新”不等于“最稳”这里给出我个人实测比较稳妥的版本搭配表组件推荐版本说明JDK1.8 或 17SpringBoot 2.x 用 JDK83.x 必须 JDK17Spring Boot2.7.18 或 3.2.x毕设和中小项目选 2.7 最稳新项目可选 3.2MyBatis3.5.x mybatis-spring-boot-starter2.7 对应 starter 2.3.x3.2 对应 3.0.xMySQL8.0.x8.0 以上性能更好注意驱动配置变化VueVue 3.4.x Vite 5.x课程要求 Vue2 的话就用 Vue2.7Node.js18 LTS 或 20 LTSVite 5 需要 Node 18 以上如果你是跟着教程做毕设建议优先选 SpringBoot 2.7 JDK8因为这个版本的资料最多第三方开源项目里几乎所有 Java 管理系统都是基于这个版本写的出现问题排查最快。我在开发时踩过“SpringBoot 版本太高导致 mybatis starter 不兼容”的坑后来降级到 2.7.x 就一切都顺了。2.2 MySQL安装与初始配置MySQL 的安装在 Windows 和 Mac 上差别不大重点是安装完之后的几个必做动作。去 MySQL 官网下载对应系统的安装包安装时选择 Server only端口默认 3306编码选 utf8mb4因为摄影作品评论里可能出现各种字符utf8mb4 才能完整支持。安装完成后一定要设置 root 用户密码并且打开 MySQL 命令行验证一下能不能正常登录。如果你用的是免安装版那配置路径就不同了。下载解压后需要手动创建一个 my.ini 配置文件写入 basedir 和 datadir 两个路径然后以管理员身份打开 CMD执行mysqld --initialize-insecure初始化再执行net start mysql启动服务。这里有个细节初始化成功后 root 默认是没有密码的你需要在命令行里执行ALTER USER rootlocalhost IDENTIFIED BY 你的密码;重新设置密码。这些步骤我在实际配置过程中踩过好几回坑免安装版最大的问题就是服务起不来十有八九是初始化没执行或者 my.ini 里的路径写错了。2.3 数据库表设计从业务出发而不是从代码出发摄影工作室系统需要哪几张表我按业务链路梳理出这些核心表users用户表统一存管理员、摄影师、普通客户三类账号通过 role 字段区分works作品表保存摄影作品包含标题、封面图、原图地址、所属摄影师、作品分类categories作品分类表比如婚纱、写真、儿童、商业等appointments预约表客户发起的拍摄预约含预约时间、拍摄地点、状态orders订单表预约确认后生成订单跟踪支付、拍摄、修片、交付进度comments评论表客户对拍摄服务的评价banners轮播图表首页轮播图配置这里分享一下 works 表的设计CREATE TABLE works ( id INT AUTO_INCREMENT PRIMARY KEY, title VARCHAR(200) NOT NULL COMMENT 作品标题, cover_url VARCHAR(500) COMMENT 封面图URL, img_urls JSON COMMENT 作品图片列表, video_url VARCHAR(500) COMMENT 视频作品地址, category_id INT COMMENT 分类ID, photographer_id INT COMMENT 摄影师用户ID, description TEXT COMMENT 作品描述, view_count INT DEFAULT 0 COMMENT 浏览量, status TINYINT DEFAULT 1 COMMENT 0下架 1上架, create_time DATETIME DEFAULT CURRENT_TIMESTAMP ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT摄影作品表;注意 img_urls 字段我用了 JSON 类型这样一组作品可以放多张图既不需要单独建作品图片表查询时又能直接用 SQL 函数处理MySQL 8.0 支持得很好。如果团队工作流严格一点也可以拆成 works_img 表但考虑到这个项目的规模用 JSON 字段完全够用还能少写一套增删改查代码。3. 后端核心功能实现从登录鉴权到业务闭环3.1 登录鉴权JWT方案怎么落地管理系统的登录鉴权我的方案是 JWT 拦截器不额外引入 Spring Security。原因是这个系统只有三种角色、页面级权限控制用 Spring Security 会引入大量复杂配置开发速度反而变慢。JWT 方案只需在用户登录成功后生成一个带角色信息的 token前端存本地发请求时放请求头后端用拦截器统一解析校验。核心代码分三块。第一块是登录接口查询用户表、校验密码密码用 MD5 加盐处理后存储第二块是 TokenUtil 工具类用 JJWT 库生成和解析 token第三块是自定义拦截器在 preHandle 方法里读取请求头中的 token解析用户 ID 和角色后放入 ThreadLocal方便 controller 直接获取当前登录用户。Configuration public class WebConfig implements WebMvcConfigurer { Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new AuthInterceptor()) .addPathPatterns(/**) .excludePathPatterns(/api/auth/login, /api/works/**, /api/register); } }注意拦截器要放行哪些路径这个一定要想清楚。作品浏览、登录注册是免登录接口其他像预约、订单、后台管理的接口都需要校验。我一开始把全部接口都拦截了结果前端页面一片 401排查半天才发现是放行路径没配好。而这里 JWT 生成的 token 本身是可以携带角色信息前端拿到之后也能根据角色去渲染不同的菜单和按钮前后端各管一层的权限控制是我在这个项目里比较满意的设计。3.2 作品管理与图片上传作品管理是这个系统最有“摄影感”的模块。摄影师登录后台后可以上传作品图集。这里涉及两个关键技术点一是图片上传到服务器的哪些目录二是上传后前端如何展示。图片存储方案我用的是本地磁盘存储加静态资源映射。在 application.yml 里配置spring: servlet: multipart: max-file-size: 20MB web: resources: static-locations: file:E:/photo_works/,classpath:/static/这样上传的图片统一存在 E 盘 photo_works 文件夹下SpringBoot 会自动把该路径映射为静态资源前端直接用http://localhost:8080/uploads/xxx.jpg就能访问。这里踩过一个坑上传失败原因多半是磁盘路径不存在一定要先手动把目录建好程序没有自动创建目录的逻辑的话就会报 FileNotFoundException。如果你打算用对象存储比如阿里云 OSS 或腾讯云 COS那就是另一套方案了。上传成功后返回一个公网 URL优点是不占服务器磁盘、访问速度快缺点是要配置额外依赖和密钥。中小型项目先用本地存储就够了等以后量大了再切换 OSS 也不迟因为上传接口可以统一抽象成 FileService 接口两种实现互不影响。视频作品也一样MP4 文件较大我建议有时间的话用 ffmpeg 转成 m3u8 切片再播放后面单独说。3.3 预约到订单的完整业务流转预约和订单是这个系统的业务主链路也是最能体现“管理系统”价值的地方。业务流程是客户在线上选好摄影套餐或摄影师提交预约申请填写期望拍摄时间和地点管理员在后台看到待审核预约确认摄影师档期后排期然后生成订单记录拍摄状态摄影师拍摄完成后上传成片客户下载并评价。这样的状态流转我设计为两个关联的状态机。预约表的状态有 pending待审核、approved已同意、rejected已拒绝、canceled已取消订单表的状态有 wait_pay待支付、wait_shoot待拍摄、shoot_done已拍摄、reviewing修片中、delivered已交付、finished已完成。每个状态变更都写清楚触发条件和操作人角色避免两个后台管理员同时操作时出现订单状态错乱。实现时用一个常量类定义状态枚举Service 层方法里做好状态合法性校验非法跳转直接抛出业务异常。预约接口的核心逻辑可以这样理解前端提交预约请求的时候传过来 worksId 和预约时间后端先判断该摄影师在这个时间段是否已有 approved 状态的预约有就返回“该时间段已被约满”没有就插入预约记录。排期冲突检测是这块的关键我建议用数据库查询来实现查询条件精确到摄影师 ID 预约日期 状态避免并行请求造成重复预约。真要说更稳妥的做法可以在 appointment 表加一个唯一索引字段是 photographer_id appointment_time数据库层面兜底防重这是比代码判断更可靠的一层保障。3.4 MyBatis层的几个关键实操细节MyBatis 在这个项目里的作用是把复杂的 SQL 从代码中剥离出来集中在 XML 文件里管理。我用 MyBatis Generator 生成基础的 Mapper然后针对业务需求手写 XML 里的自定义 SQL。第一个细节动态 SQL。作品列表页需要按分类、关键词、状态三个条件筛选这是典型的动态拼接场景。在 XML 里这样写select idsearchWorks resultTypemap SELECT w.*, u.nickname AS photographer_name, c.name AS category_name FROM works w LEFT JOIN users u ON w.photographer_id u.id LEFT JOIN categories c ON w.category_id c.id where if testcategoryId ! null AND w.category_id #{categoryId} /if if testkeyword ! null and keyword ! AND (w.title LIKE CONCAT(%, #{keyword}, %) OR w.description LIKE CONCAT(%, #{keyword}, %)) /if if teststatus ! null AND w.status #{status} /if /where ORDER BY w.create_time DESC /selectwhere标签会帮我们自动处理掉多余的 AND这个语法一定要熟练几乎每个带筛选条件的业务查询都离不开它。第二个细节批量写操作。摄影师可能会一次性上传几十张作品图片最高效的方式是用 foreach 标签做批量插入一次 insert 多条记录性能远高于循环单条插入。批量操作在这个项目里最典型的就是批量上传作品图片、批量更新订单状态用 foreach 拼 values 就能实现。第三个细节MyBatis 缓存。一级缓存是 SqlSession 级别的默认开启二级缓存是 namespace 级别的默认关闭。如果开了二级缓存要注意缓存刷新问题尤其是像订单状态更新这种高频变更的数据缓存可能导致读到旧状态。经验是查询多、更新少的只读数据比如作品分类可以开二级缓存更新频繁的业务数据不要开直接用数据库实时查。还有一个我踩了很多次坑的细节XML 里判断单个数字字符时写法很容易出错。比如你想判断作品状态等于 1写成if teststatus 1在参数类型是字符串时可能报 NumberFormatException。稳妥的做法是统一用 Integer 类型接收状态参数或者在 XML 里用status 1的写法时确保两边类型一致。这个细节面试的时候也经常被问到能说清楚会加分。3.5 业务层与接口层前后端联调的数据契约接口返回格式统一是前后端联调顺畅的关键。我的做法是封装一个 Result 类所有接口都返回{code, message, data}这个结构code 为 200 表示成功其他为业务错误码。前端 Axios 根据 code 统一处理成功和失败分支不用每个接口单独写异常逻辑。public class ResultT { private Integer code; private String message; private T data; public static T ResultT success(T data) { ... } public static T ResultT error(String message) { ... } }Controller 层保持薄只做参数接收和结果封装业务逻辑全部下沉到 Service 层。Service 层注入 Mapper处理事务时加 Transactional 注解。比如预约审核通过并生成订单这个动作涉及两张表的更新如果不加事务就可能出现预约状态改了但订单没生成的脏数据。Transactional 放在方法级别任何一个环节报错都会整体回滚这是保证数据一致性的基础。4. 前端Vue实现要点与部署实战4.1 Vue工程初始化与路由设计前端工程我用 Vue3 Vite 初始化执行npm create vuelatest创建项目然后安装 vue-router、pinia、axios、element-plus 这几个核心依赖。Vite 比 Webpack 快很多开发模式下热更新几乎是即时的写页面效率高不少。如果你在安装依赖时遇到网络慢的问题可以把 npm 源切到国内镜像这一步能帮你省下大量等待时间。路由设计的核心是按角色区分布局。系统分前台客户页面和后台管理页面两块前台有首页、作品列表、作品详情、我的预约、个人中心后台有仪表盘、预约管理、订单管理、作品管理、用户管理。我用嵌套路由实现两套独立布局后台页面套 AdminLayout 组件前台页面套 FrontLayout 组件。路由守卫是重点在 router.beforeEach 里检查用户 tokentoken 为空或角色不匹配就跳到登录页实现页面级权限控制。4.2 组件拆分与页面开发Vue 的组件化思路在这个项目里体现得很明显。拿作品列表页举例它拆成作品卡片组件WorkCard、分页组件Pagination、筛选栏组件FilterBar三个子组件父组件只负责数据请求和状态管理。这样做的最大好处是摄影师用户上传的新作品会自动复用 WorkCard 组件展示一处改动处处生效不用在多个页面里复制粘贴代码。前后端联调时我用 Axios 做了统一封装import axios from axios import { ElMessage } from element-plus const request axios.create({ baseURL: /api, timeout: 10000 }) request.interceptors.request.use(config { const token localStorage.getItem(token) if (token) { config.headers.Authorization token } return config }) request.interceptors.response.use( response { const res response.data if (res.code 200) { return res.data } ElMessage.error(res.message) return Promise.reject(new Error(res.message)) }, error { ElMessage.error(error.message || 请求失败) return Promise.reject(error) } )这里请求 baseURL 配的是 /api实际生产环境要靠 nginx 转发到后端服务开发环境则通过 Vite 的 proxy 代理解决跨域。前后端分离项目里接口封装是特别值得花时间做好的基础工程一旦封装不规范后续每个页面都要写一堆重复的报错处理。4.3 视频作品展示与m3u8播放的实现摄影工作室除了图片作品还经常有宣传视频、婚纱摄影的旅拍视频。这类视频如果用 MP4 直出文件大、加载慢体验很一般。常见方案是转成 HLS 流媒体格式生成 m3u8 索引文件和一个个 ts 切片。前端播放 m3u8我用的是 hls.js 库。在 Vue 组件里这样集成import Hls from hls.js const video videoRef.value if (Hls.isSupported()) { const hls new Hls() hls.loadSource(http://localhost:8080/uploads/videos/demo.m3u8) hls.attachMedia(video) hls.on(Hls.Events.MANIFEST_PARSED, () { video.play() }) }m3u8 播放最大的优势是支持码率自适应用户网络不好的时候自动切低清晰度播放体验比 MP4 好很多。后端生成 m3u8 文件用 ffmpeg 命令把 MP4 转成 HLS 格式即可一条命令就能搞定ffmpeg -i demo.mp4 -codec copy -hls_time 10 -hls_list_size 0 demo.m3u8如果你在项目里碰到“vue播放m3u8”这个需求用 hls.js 基本是标准答案。需要注意的点是Vite 打包时 hls.js 体积不小可以用动态 import 的方式按需加载避免首屏白屏时间变长。4.4 打包构建与nginx部署前端开发完成后执行npm run build生成 dist 静态文件。这里最容易踩的坑是打包后的页面布局异常比如刷新页面 404、样式错乱。原因基本都是两个一是路由模式用了 historynginx 没配置 try_files 对前端路由的 fallback二是资源路径 base 没配置正确部署到子目录时找不到 JS 和 CSS。我的生产环境 nginx 配置server { listen 80; server_name photo.example.com; root /var/www/photo/dist; index index.html; location / { try_files $uri $uri/ /index.html; } location /api/ { proxy_pass http://127.0.0.1:8080/api/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }location / 用来处理 history 路由的前端页面请求location /api/ 把接口请求转发给 SpringBoot 后端。这样一个 nginx 就能同时托管前端静态资源和后端接口部署在单台服务器上时是最简洁的方案。如果一台服务器要部署多个 web 项目只要复制这份 server 配置改 server_name、root、proxy_pass 就能实现这也是面试里经常被问到的“nginx部署多个web项目”的实际做法。4.5 跨域问题的统一处理前后端分离开发时跨域是躲不开的问题。开发阶段我在 Vite 的 vite.config.js 里配置了代理解决跨域server: { proxy: { /api: { target: http://localhost:8080, changeOrigin: true } } }生产环境通过 nginx 转发同样不需要后端开跨域。如果有的接口是给外部系统调用的确实需要跨域那我建议在 SpringBoot 里加个 CorsConfig 类配置允许的来源和请求头而不是用 CrossOrigin 注解散落在各个 Controller 上。统一配置的好处是改动最小、可维护性最好。跨域问题看着吓人其实原理就一句话浏览器限制了不同源页面之间的资源访问解决办法要么让后端允许跨域要么让前端走代理绕开限制。5. 开发与部署中常见问题排查实录5.1 环境类问题速查表下面这张表是我在开发这套系统过程中实际遇到的典型问题整理成速查表方便你排查问题现象可能原因解决方案IDEA 创建 SpringBoot 项目一直失败SpringBoot 版本太高或网络无法下载 start 模板用阿里云镜像地址创建项目或 start.spring.io 下载后导入版本选 2.7.x 最稳MySQL 8.0 连接报 Public Key Retrieval 错误驱动版本和连接参数问题JDBC URL 加上 allowPublicKeyRetrievaltrueuseSSLfalseVue 打包后刷新页面 404history 路由模式未配置 fallbacknginx 的 location / 里加 try_files $uri $uri/ /index.htmlVue 打包后布局异常、图片丢失base 路径未配置或静态资源路径写死vite.config.js 配置 base: ./资源用相对路径或统一前缀网页提示 could not register service workerPWA 插件注册失败或 HTTPS 环境要求开发环境忽略该提示正式部署确保 HTTPS 和 sw.js 路径正确接口请求一直Pending请求超时、接口响应过慢、跨域被拦用浏览器 Network 看请求状态F12 控制台看 CORS 报错MyBatis 二级缓存导致更新后查询旧数据缓存未清理更新类操作后调用缓存清理或直接关闭业务表二级缓存免安装版 MySQL 服务无法启动未初始化数据目录my.ini 路径错误管理员 CMD 执行 mysqld --initialize-insecure确认 basedir、datadir 路径正确上传图片后前端访问 404静态资源映射未生效检查 application.yml 配置确认路径末尾斜杠重启后端服务环境类问题的排查思路都差不多先看项目日志再看浏览器控制台最后检查配置文件。很多看似玄学的问题其实都是版本不匹配或路径配置错这种低级原因。5.2 业务类问题与调试技巧除了环境问题业务代码里也有几个高频踩坑点值得单独说。第一个是时间字段的时区问题。MySQL 8.0 默认时区是 UTC如果后端连接串没指定 serverTimezoneAsia/Shanghai查询出来的预约时间会比实际时间早 8 小时。这个坑非常隐蔽我在测试预约模块时发现时间全对不上查了半天数据库才发现是时区问题。顺便提醒一句如果你电脑上装了多个 MySQL 版本最好用SHOW VARIABLES LIKE %time_zone%;查看当前实例的时区配置。第二个是文件删除失败问题。摄影师删除作品时数据库记录删掉了但服务器磁盘上的图片文件没删时间一长磁盘空间会被占满。解决方法是删除作品时同时调用 FileUtil 删除对应的物理文件但这里要注意路径的安全性必须防止用户通过参数注入删掉服务器上的其他文件。文件操作类的代码建议统一走一个封装好的 FileService不要在 Controller 里写裸的 File.delete 调用。第三个是登录 token 过期的问题。JWT 默认有效期我设置为 7 天但如果用户密码被修改旧的 token 在 7 天内依然有效。要解决这个可以在 JWT 的 claim 里放一个版本号或最后修改时间密码修改后重新校验这个版本号实现强制下线效果。这类问题不遇到确实想不到但一旦用户反馈“我改完密码旧 token 还能用”就说明你是真的经历过真实业务的拷打了。5.3 性能慢查询优化注意这个系统数据量不大正常不会有性能问题但作品列表首页如果一次性查全表图片又都是外链大图页面加载就会明显变慢。我做的优化点有两个一是查询列表时用 LIMIT 分页后端接口返回当前页码和总条数前端配合 Element Plus 的分页组件交互二是给作品表加了一个联合索引(category_id, create_time)让按分类展示作品时的排序查询走索引而不是全表扫描。另外多个页面复用同一个查询接口时可以利用 MyBatis 的二级缓存或者手动写一个本地缓存 Map但要注意缓存只放在作品分类这类几乎不变的数据上。摄影作品列表我反而每页都实时查因为作品浏览量要实时更新保证数据的准确性比缓存性能更优先。面试时如果被问到“MyBatis缓存适合什么场景”你就拿这个项目里的例子回答只读数据开缓存频繁更新数据别碰缓存。6. 这套系统的复盘与扩展思路做完这个项目之后回头看我最满意的是业务流程闭环。从客户浏览作品、预约、生成订单、拍摄、交付到评价系统的状态流转是完整的真实落地后可运营。同时也要承认这套项目在以下几个维度还能继续升级。第一权限控制目前是基于拦截器和角色判断如果系统继续扩大比如增加财务、店长、兼职摄影师等更多角色建议引入 Spring Security 资源服务器方案让权限模型从“角色判断”升级为“权限点判断”。第二图片和视频存储从本地磁盘切换到阿里云 OSS 或者 MinIO 自建存储配合 CDN 加速可以支撑更大的访问量。到时候 FileService 接口就显得尤为重要切换实现类不影响上层业务代码。第三预约排期目前是人工审核模式如果想让系统更“聪明”一点可以引入自动化排期和档期日历在预约提交时实时查询摄影师忙闲状态像选座那样可视化选择可预约时间段。这个方向做出来项目的高级感会明显提升。第四做一套移动端适配方案。因为客户大多数用手机浏览作品和预约服务目前 PC 端优先的布局在手机上能用但不完美后续可以考虑做一套 H5 的移动端布局或者用 uni-app 封装成小程序。如果面试被人问到这个项目我建议抓住几个亮点讲完整业务闭环的状态机设计、MyBatis 动态 SQL 和批量操作的细节、JWT 拦截器的快速鉴权方案、nginx 解决前后端分离部署和路由 fallback 的实践。这些点都能体现你不是单纯“照着教程敲了一遍”而是真的理解了整套系统怎么运转。最后分享一个我自己真实的开发习惯项目里始终保留一份“问题记录文档”每次踩坑就把现象、原因、解决过程写下来。这套系统的很多排错经验比如 MySQL 时区、Vue 打包后 404、MyBatis 数字比较的坑都是当时记下来后反复受用的。做项目最大的收获不只是代码跑通了而是你积累了一套能迁移到下一个项目的排错能力和工程思维。开发这件事踩坑不可怕可怕的是同一个坑踩三遍。
返回列表