news 2026/10/28 23:49:25

基于Spring Boot+Vue的校园勤工俭学平台设计与开发实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
基于Spring Boot+Vue的校园勤工俭学平台设计与开发实战

又到毕业设计开题季了。后台私信里问得最多的永远是同一个问题:想做个 Spring Boot 方向的管理系统题目,该选什么业务?该用哪些技术?论文怎么写才能过查重?我自己的毕业设计做的就是基于 Spring Boot + Vue 的校园勤工俭学平台,从开题报告、数据库设计、前后端编码、LW 文档撰写到最终答辩完整走了一遍,源码和论文都是自己一点点磨出来的。这篇就把整个项目的拆解思路、关键实现和踩过的坑全部写出来,给正在选题或者已经选了类似题目的同学一个能直接对着做的参照。

这类管理系统的套路是相通的,你今天能做完勤工俭学平台,明天给你换成二手交易、会议室预约、实验室管理,你也能在一个星期内搭出来。文章覆盖业务建模、技术选型、核心代码、论文写作、部署交付和答辩准备六个模块,内容偏实操,代码和配置都会给到,建议收藏后跟着思路捋一遍,别只看不练。

1. 选题逻辑与整体蓝图

1.1 为什么选"勤工俭学"这个业务方向

计算机毕业设计最忌讳的就是选题假大空。你做一个人脸识别考勤系统,听起来高级,可是摄像头硬件、深度学习环境、数据集标注这些环节每一项都能拖你两个星期。你做电商秒杀系统,高并发、分布式锁、消息队列写进论文倒是好看,可真答辩的时候老师问一句"你们学校有多少学生同时访问你的系统",场面就尴尬了。

勤工俭学平台这个题目的定位非常精准:它是典型的"校务管理 + 业务流程"综合系统,业务知识零门槛,任何评委老师都听得懂、挑不出业务逻辑毛病。学生要找工作、企业或校内部门要发布岗位、管理员要审核信息,这就是一个完整的双向选择流程,天然包含用户认证、角色权限、信息发布、状态流转、数据统计这些计算机系统必考的知识点。

更关键的是,这个选题有非常充分的调研基础。随便找个高校的资助管理中心问一问,勤工俭学岗位的分配基本都是靠 Excel 表加微信群,学生抢岗位靠手速,老师统计工时靠手动,工资结算要人工核算好几个晚上。也就是说,你的系统是在解决一个真实存在的痛点,这在论文"选题背景"和"需求分析"两章里能写出实打实的内容,而不是干套模板。

1.2 三类角色与一整套业务流程

整个系统的核心是三类角色:学生、企业/校内用工部门、系统管理员。这三类角色对应三种完全不同的操作视角和数据权限,从开发角度看,这就是三个天然的模块边界。

学生端的核心诉求是"找活干"。学生注册登录后可以浏览全部已审核的岗位列表,按薪资、工作地点、岗位类型筛选,查看岗位详情并提交申请。申请之后可以查看自己的申请状态是被录用还是被拒绝,被录用之后进入岗位工作,每天通过签到打卡功能记录工时,月底可以在个人中心看到工资结算明细,还能对用工部门发布的岗位进行评价。

用工部门端的核心诉求是"招到人"。部门负责人注册后要填写单位信息并提交管理员审核,审核通过后可以发布岗位、管理岗位状态,查看所有投递该岗位的学生申请列表,对申请进行录用或拒绝操作。录用学生后,每天审核学生的签到记录,月底根据工时计算工资并提交管理员复核。

管理员端是系统的最高权限节点。管理员负责审核用工部门的注册申请、审核所有新发布的岗位、管理所有用户状态、查看全站的工资结算数据、发布站内公告。管理后台还需要有一个基础数据看板,展示岗位总数、在岗学生数、本月结算金额这些统计指标。

这三类角色串起来的完整流程是:管理员审核部门入驻 → 部门发布岗位 → 管理员审核岗位 → 学生浏览并申请 → 部门录用学生 → 学生每日签到打卡 → 部门确认工时 → 管理员复核工资 → 学生确认收款。一个典型的"发布—审核—执行—结算"闭环,每一步都有状态流转,这也直接决定了数据库表怎么设计、后端接口怎么写。

1.3 技术选型的版本细节与理由

技术栈就选最主流、资料最多、答辩最好解释的那套:Spring Boot + MyBatis-Plus + MySQL + Vue + Element UI。这套组合在学校里是绝对的大众配置,出任何问题都能在网上找到现成答案。

我用的具体版本如下,建议你直接照抄,不要在这个阶段当版本控。

前端用 Vue 2.6 加 Element UI 2.15,Vue Router 3.x 做路由,Axios 做请求,不用上 TypeScript,毕业设计阶段用 JavaScript 足够。Vue 3 当然也可以,但配套的 Element Plus 在部分旧教程里兼容性问题更多,你查资料的时间成本会高不少。后端用 Spring Boot 2.7.x,搭配 MyBatis-Plus 3.5.x,内置分页插件和代码生成器能省下大量重复的 CRUD 代码。数据库用 MySQL 8.0,如果需要更低版本,5.7 也能跑,建表语句基本一致。

有一点要特别提醒:Spring Boot 2.7 和 3.x 在配置上有差异,尤其 javax 到 jakarta 的包名迁移,很多网上教程已经默认 Spring Boot 3。你如果选了 2.7,查资料时一定要留意文章里用的版本,否则照抄配置会直接报包名错误。我就见过同学把 Spring Boot 3 的配置抄到 2.7 工程里,结果整个项目起不来。

2. 数据库设计:一切业务的核心底座

2.1 九张核心表的结构与关联

勤工俭学平台我最终设计了 9 张核心表,这个数量对于一篇本科毕业设计论文来说非常合适,不算臃肿,每一张表在论文里都能被需求分析章节明确引用。

用户表(sys_user)保存所有登录账号,包含用户名、密码(MD5 加盐)、真实姓名、手机号、角色标识(1 学生、2 部门、3 管理员)、头像、状态字段。部门信息表(enterprise_info)只针对角色为部门的企业用户,包含单位名称、营业执照号、单位简介、负责人、审核状态字段。学院表(college)和岗位类别表(job_category)都是基础字典表,给学生信息提供数据来源、给岗位提供分类维度。

岗位表(job)是业务核心,字段包括岗位名称、类别、工作地点、工作时间、时薪、招聘人数、已招人数、详细描述、发布部门 ID、审核状态(0 待审、1 通过、2 拒绝)。这里有个容易忽略的设计:审核状态不能只在岗位表里做,也要在审核流程表里留痕,方便论文写"流程管理"章节时有据可依。

申请记录表(job_apply)记录学生投递岗位的动作,包含学生 ID、岗位 ID、申请时间、状态(待处理、已录用、已拒绝)。用工部门录用学生之后生成录用关系表(job_employment),这张表把岗位和学生进行绑定,包含学生 ID、岗位 ID、录用时间、工作状态(在岗、离职)。录用关系表是整个系统的枢纽,它承接了申请与工时两个环节。

工时记录表(work_record)记录学生每一天的签到信息,包含录用关系 ID、签到日期、开始时间、结束时间、工时数、确认状态(待确认、已确认、驳回)。工资结算表(salary_record)按月汇总每个学生的工时和应发工资,包含录用关系 ID、结算月份、总工时、总工资、确认状态,并且和最终工资表区分开。最后是公告表(notice)和评价表(job_comment),用于站内公告发布和学生完成工作后的双向评价。

2.2 表关系设计里的几个关键决策

表之间的关系多用外键逻辑关联,不强制物理外键,这是实践中很务实的做法。物理外键在删除和更新时容易被数据库约束卡住,比如你要删除一个已经产生工时记录的学生,外键约束会直接报错。逻辑外键在代码里通过业务校验控制,既保证数据一致,又不干扰日常操作。

录用关系表与岗位表、学生表各关联一次,通过状态字段判断当前是否在岗。工资记录之所以单独建表,而不是在录用关系表里加一个数字字段,是因为工资结算有固定的业务周期:每月初对上月所有在岗人员进行汇总计算。单独建表可以保留每个月的数据快照,即使后来工资被调整,历史记录也不会被覆盖,这个在论文答辩时经常被问到,回答上来会加分。

对于两张字典表(college 和 job_category),在管理端各做一个简单的数据维护页面即可。很多同学会忽略字典表的界面维护功能,觉得直接写死到代码里就行,但答辩的时候老师会问"如果学校新增了一个学院,你怎么维护?"——提前把维护界面做出来,这类问题就迎刃而解。

2.3 索引设计与分页查询的配合

岗位表按发布时间创建普通索引,申请记录表按学生 ID 和岗位 ID 创建联合索引,工时记录表按录用关系 ID 创建索引。索引不是越多越好,每张表保持一到两个核心查询索引就足够,太多索引会在插入数据时增加额外开销。

分页查询统一走 MyBatis-Plus 的 Page 对象,配合内置的分页插件,接口只需要接收 current 和 size 两个参数。具体查询时用 LambdaQueryWrapper 构建条件,例如查询已审核通过的岗位列表,核心代码是:

Page<Job> page = new Page<>(current, size); LambdaQueryWrapper<Job> wrapper = new LambdaQueryWrapper<>(); wrapper.eq(Job::getAuditStatus, 1) .eq(Job::getPublishStatus, 1) .like(StringUtils.hasText(keyword), Job::getJobName, keyword) .orderByDesc(Job::getCreateTime); Page<Job> result = jobMapper.selectPage(page, wrapper);

这段代码里有个细节值得注意:like前面的布尔条件是StringUtils.hasText(keyword),意思是只有用户实际输入了关键词才拼这个条件。这个写法比 if 判断更简洁,也避免了空字符串查询把全表数据捞出来的问题。分页查询出的记录总数直接由 MyBatis-Plus 的 Page 对象带出,前端只需要拿records和total渲染列表和分页组件即可。

3. 后端实现:Spring Boot 的三大核心模块

3.1 系统登录与 JWT 认证机制

登录认证是每个管理系统都绕不开的模块,也是论文里必须重点写的技术点。我用的是 JWT(JSON Web Token)模式,前端登录成功后拿到一个 token 字符串,后续每个请求都在请求头里带上这个 token,后端拦截器统一校验,校验通过才放行。

JWT 的核心优势是服务端无状态:用户信息被加密放进 token 里,服务器不需要在 Session 中保存登录状态。这对毕业设计来说非常合适,因为不用处理 Session 的并发问题,也不需要额外搭建 Redis 存会话,架构更简单、答辩也更好解释。

登录接口的逻辑是:接收用户名密码 → 按用户名查用户表 → 密码通过 MD5 加盐后比对 → 比对成功则生成 JWT 返回给前端。生成 JWT 用 jjwt 库,核心代码:

String token = Jwts.builder() .setSubject(user.getUsername()) .claim("userId", user.getUserId()) .claim("role", user.getRole()) .setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 12)) .signWith(SignatureAlgorithm.HS256, secretKey) .compact();

这里用signWith算法的 HS256 是对称加密,secretKey是写在配置文件里的密钥字符串。12 小时过期时间是我调过的比较舒服的配置,学生白天写作业、晚上再打开系统也不用重新登录,同时也不会像 7 天那么久导致安全风险扩大。

拦截器里校验 JWT 的逻辑放在 Spring 的 HandlerInterceptor 中实现,在 preHandle 方法里从请求头取 token、解析校验、把 userId 放进 request 的 attribute 中供后续 Controller 使用。放行的 URL 用白名单配置:登录接口、注册接口、获取岗位列表接口允许匿名访问,其余一律需要 token。这里踩过的一个坑是:跨域预检请求(OPTIONS 方法)会被拦截器拦截,必须提前放行 OPTIONS 请求,否则前端浏览器的跨域预检直接失败,所有请求都发不出去。

3.2 岗位申请与录用流程的状态机设计

岗位申请和录用是整个业务流转最复杂的部分,我用一个简单的状态机来管理。学生提交申请后,记录的状态从 0(待处理)开始,部门负责人审核后状态变为 1(已录用)或 2(已拒绝)。录用之后创建录用关系,录用关系同样有状态字段控制学生在岗、离职。

这个状态机在开发时有一个关键约束:学生不能对同一个岗位重复提交申请。实现上很简单,在插入申请记录前先查询一下是否存在相同学生 ID 和岗位 ID 的记录,存在就直接返回"你已经申请过这个岗位了"。还有一个细节是岗位已招满后自动关闭申请入口,需要在每次录用成功时对岗位的已招人数做自增并判断是否达到招聘人数上限。

这两个业务点建议都用精确到业务层的事先判断来实现,不要在数据库层做联合唯一约束。联合唯一约束虽然也能防重复申请,但它会直接抛数据库异常,前端友好提示不好做,答辩时解释"数据库层面限制"远不如解释"业务层经过两次校验"听起来自然。

部门端审核申请时,录用操作和创建录用关系是强关联的,需要在同一个事务里执行。Spring 的@Transactional注解放在 Service 方法上即可,默认遇到 RuntimeException 就会回滚。实际开发时,我把录用逻辑封装成了独立方法,在事务里先更新申请记录状态,再新增录用关系记录,再更新岗位已招人数。这三步任何一步失败,整体回滚,保证数据不出现"申请已录用但录用关系不存在"的脏数据。

3.3 工时打卡与工资结算的实现思路

工时打卡是一个偏物联网风格的功能,但实现起来比想象中简单。每个被录用的学生每天早上进入系统点击"签到",系统记录当前日期和开始时间;晚上点击"签退",系统自动计算当天的工时并写入工时记录表。

打卡接口需要做一道防重复逻辑:同一天内不能重复签到,签退前必须已经签到。用最简单的查询判断就能实现,不需要锁机制,因为毕业设计系统根本不会出现高并发场景。工时计算用后端处理,前端只传开始和结束时间,后端算出小时数并保留一位小数。

工资结算是一个定时任务,用 Spring 自带的@Scheduled注解就能实现。我配置在每个自然月的 1 日凌晨 1 点执行,任务会扫描上个月所有的工时记录,按录用关系分组,结合岗位时薪计算工资总额,批量写入工资结算表。

这个定时任务里要注意月份边界:不能直接在方法里取"上月 1 日到上月底",而是要用LocalDate.now().withDayOfMonth(1).minusDays(1)的方式计算。直接获取当前月份再减一,在 1 月执行时会算出 0 月,妥妥的 Bug。每个月执行完任务之后,我还额外做了一个手动触发接口,用来应对开发测试时调时间、补数据的需求,这个接口在论文的"系统测试"章节里也是很好的验证点。

4. Vue 前端构建与联调实战

4.1 脚手架初始化与工程结构规划

前端我用 Vue CLI 创建工程,命令是vue create,具体项目名、预设全选默认即可,不需要复杂配置。工程创建好之后,按照 src 下三层的习惯组织目录:views放页面级组件,components放可复用组件,api放所有后端接口请求方法,router放路由配置,utils放 axios 封装和工具函数。

一个实用的目录习惯是:每一个业务模块建一个 api 文件,比如api/user.js、api/job.js、api/workRecord.js。组件里绝不直接写this.$http.post(...),而是从 api 文件引入方法。这样做的好处是不只是代码整洁,更重要的是毕业论文里的"系统实现"章节,你可以贴上 api 文件里高度内聚的接口方法,页面组件里只调一次方法就能完成数据交互,代码贴出来非常好看。

页面级组件的划分直接对应后端角色:学生端有岗位浏览页、我的申请页、我的岗位页、工时打卡页;部门端有岗位管理页、申请处理页、工时确认页;管理员端有用户审核页、岗位审核页、数据看板页。公共的登录页和注册页单独放在views/login和views/register,所有角色共用。

4.2 路由守卫与请求拦截的落地写法

前端路由守卫是登录态的最后一层防线。我在router/index.js中给每一个需要登录的路由添加meta: { requiresAuth: true },然后在全局前置守卫里判断:

router.beforeEach((to, from, next) => { const token = localStorage.getItem('token'); if (to.meta.requiresAuth && !token) { next({ path: '/login', query: { redirect: to.fullPath } }); } else { next(); } });

这段代码解决了"用户未登录时直接输入 URL 访问内部页面"的问题。实际用的时候还可以扩展:根据角色判断路由可达性,比如管理员页面只允许 role 为 3 的用户访问,这个判断在守卫里加一个角色过滤即可,前端能过滤掉大部分越权操作,后端的角色校验仍然保留,双保险。

axios 的请求拦截器里统一加上 JWT 请求头,响应拦截器里做统一错误处理。后端返回的 JSON 统一采用{ code, message, data }结构,前端拦截器判断 code 是否为 200,如果不是直接弹错误消息。特别是后端返回 401 时,拦截器需要清空本地 token 并跳转登录页,这个逻辑如果不做统一封装,每个页面都要重复写一遍,极易漏漏改改。

4.3 常见联调问题:跨域、日期格式、端口冲突

跨域问题是联调阶段第一个要解决的事。开发环境下,前端跑在 8080 端口,后端跑在 8081 端口,浏览器默认禁止跨域请求。最省事的方案是在 vue.config.js 里配置 devServer 的 proxy,把/api前缀的请求代理到后端服务,前端代码里写的就是相对路径,上线后交给 Nginx 统一转发:

devServer: { port: 8080, proxy: { '/api': { target: 'http://localhost:8081', changeOrigin: true, pathRewrite: { '^/api': '' } } }

这样配置之后,前端发GET /api/job/list,实际被代理转发到http://localhost:8081/job/list,完美解决跨域,而且浏览器 network 面板里看到的请求都是相对路径,部署时也不用改前端代码。这个方案比在后端写 CORS 过滤器更推荐,因为上线后同一个端口服务,天然不存在跨域。

第二个高频坑是日期格式。后端默认返回的 LocalDateTime 序列化成的是 ISO 格式字符串,在 Java 里是2025-05-20T10:30:00,这个 T 字符前端用户绝对看不懂。解决方案是在后端配置文件中加spring.jackson.date-format相关的自定义格式化配置,也可以用@JsonFormat注解在实体类字段上指定pattern = "yyyy-MM-dd HH:mm:ss"。

第三个是端口冲突,尤其是 8080 被占用的情况非常多。优先在 config 里把前端端口改成 8081,后端改用 8082,两边错开,省得每次启动都要查占用。如果已经用了默认 8080,关不掉占用进程,也可以直接用vue-cli-service serve --port 8081临时指定端口,开发过程中别把精力浪费在这种小事上。

5. LW 文档写作与查重降重实战

5.1 文档章节结构与每章写作重点

LW 文档(也就是论文文档)是毕业设计的另一半边天。我见过太多代码写得不错、论文一塌糊涂、最后被答辩老师批得抬不起头的例子。论文的整体结构按老规矩:摘要、绪论、需求分析、系统设计、系统实现、系统测试、总结与展望。

摘要要写出三件事:选题背景、完成的工作、最终的结果。一字一句写,不要从网上复制,摘要页查重率是最容易超标的区域。绪论里的国内外研究现状不要只罗列文献,要有自己的评述:现有方案解决了什么问题、没解决什么问题、你的系统准备怎么补上。

需求分析章节要附上用例图和数据流图。用例图可以从三类角色的视角画,每个用例说明它的触发者、前置条件、基本流程、异常流程。数据流图从顶层数据流图开始,再细化到第二层,拆出登录流程、岗位发布审核流程、工时结算流程三张子图。

系统设计章节写总体架构图、功能模块图、数据库 E-R 图和数据表结构。系统实现章节配合核心代码截图,截图要清晰,不要截一整个屏幕,只截关键代码段。系统测试章节写功能测试用例表和测试结果,采用黑盒测试的等价类划分和边界值分析方法。这个测试用例表是答辩老师最爱翻的地方,用例设计得越细,老师觉得你越认真。

5.2 论文插图规范与降重技巧

论文里的图一定要注意规范。所有流程图用 Visio 或 draw.io 画,统一线条和字体大小,不要直接贴代码逻辑手绘图。E-R 图用 PowerDesigner 或者 MySQL Workbench 自带的逆向工程生成,保证实体和字段名与数据库完全一致。截图里的数据要尽量真实,不要出现"测试数据 123"这类一眼假的记录,评阅老师看到会质疑系统是否真的运行过。

降重方面我的一条核心心得是:需求分析和系统设计部分不要大段复制任何博客内容,用自己的话重新表述一遍业务流程,哪怕慢一点也没关系。代码截图和数据库建表语句一般不会进查重库,但"技术选型"这类理论章节极容易中招,尤其是 Spring Boot 和 Vue 的简介,十个有九个抄的是同一篇。解决办法是只写自己的理解和选择理由,不要写官方的技术特性介绍。

5.3 答辩演示的编排与高频追问预案

答辩演示不需要面面俱到,重点是展示三个能力:业务流程跑通、关键技术点能讲清楚、系统能实际操作演示。我的演示顺序是:登录不同角色 → 管理员审核部门 → 部门发布岗位 → 管理员审核岗位 → 学生申请岗位 → 部门录用 → 学生打卡签到 → 部门确认工时 → 管理员查看工资结算。整个过程一条线走下来,每一步页面变化明显,Connected without any跳跃。

演示过程有一个容易翻车的点:不要在答辩现场现敲命令或现场调试代码。提前录好一段 8 分钟内的操作视频作为后备,同时准备好现场演示环境。如果现场环境出了问题,直接播放视频,并表示"现场环境网络波动,这是完整演示录像",比手忙脚乱处理报错体面得多。

答辩高频追问目前遇到过这些:数据库为什么这么设计、MyBatis-Plus 和 MyBatis 有什么区别、JWT 和 Session 的区别、如何防止重复提交申请、定时任务没有执行怎么办、多角色权限怎么控制的、项目部署在什么环境上。这些问题的答案在写论文的时候就已经能整段覆盖,答辩前把论文里系统设计章和实现章的核心段落再读两遍,就能应对大部分提问。

6. 部署上线与完整启动流程

6.1 本地环境从零到跑通

本地跑通整个系统需要准备的软件:JDK 1.8 或 11、Maven 3.6 以上、MySQL 8.0、Node.js 14 以上、IDEA。数据库用 Navicat 执行项目内附的sql文件夹里的全量脚本,一键建库建表,并插入初始管理员账号。

后端启动步骤:在 IDEA 里打开后端工程,等待 Maven 依赖下载完成,创建本地数据库后修改application.yml里的数据库连接账号密码,修改 JWT 密钥(可选),启动主类。看到 Spring Boot 启动成功的日志后,测试访问http://localhost:8081/接口返回统一响应结构。

前端启动步骤:在终端进入前端目录,执行npm install安装依赖,npm run serve启动开发服务器。浏览器访问http://localhost:8081/api/...能拿到后端数据,说明代理配置正确。我建议把前端所有请求的根路径设置成环境变量,开发时用/api,生产时直接留空或启用 Nginx 代理,这样一套代码两个环境都不误。

6.2 服务器部署与 Nginx 配置要点

部署方式有多种,我只推荐最省心的组合:后端打 jar 包、前端构建后由 Nginx 托管、MySQL 用云数据库或服务器本地安装。后端打包命令是mvn clean package,打出的 jar 包用java -jar启动。生产环境建议用nohup或者直接配 systemd 服务,保证进程退出后能自动拉起。

Nginx 的核心配置是把前端静态文件和后端接口转发放在同一个 server 块里:

server { listen 80; server_name your-domain.com; root /usr/share/nginx/html; index index.html; location /api/ { proxy_pass http://127.0.0.1:8081/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } location / { try_files $uri $uri/ /index.html; } }

location /api/这一节的 proxy_pass 末尾带不带斜杠效果完全不同。带斜杠表示把/api前缀去掉再转发,不带斜杠则保留。这个配置要和前端请求路径保持一致,否则上线后接口全部 404。我把这个坑单独写出来,就是因为我自己被它坑了整整一天。

6.3 源码打包与作品交付的细节

毕业设计交付通常要求源码、LW 文档、演示视频三件套。源码交付前要做一次全量检查:把本地数据库里的测试数据清一下、把 application.yml 里的数据库密码改成通用账号、把前端控制台的无用日志代码删掉、确认不用到的依赖全部移除,保持工程干净。

LW 文档的同步更新也常被忽略。很多同学写完论文就不动了,答辩前一回头才发现论文里的数据库表结构和代码对不上,临时补图手忙脚乱。建议编码结束的第一时间就把论文的"数据库设计"和"系统实现"两章同步更新,因为这时候代码最新鲜,也是最完整的对照物。

演示视频录制的分辨率控制在 1080P、时长在 8-10 分钟即可。视频里要包含环境启动过程和核心功能操作,声音清晰,逻辑按业务流程走。录制视频的另一个作用是可以在论文的"系统测试"章节中标注"详见演示视频",让答辩专家知道你已经做了充分的验证。

7. 复盘与给后来人的大实话

7.1 我踩过的五个比较典型的坑

第一个坑是前期没有统一时间字段。早期工时记录用 String 存时间,岗位发布时间又用 LocalDateTime,前后端传参格式完全不一致,联调时字段解析报错频率极高,改起来费时费力。所以建表时时间字段要统一风格,能用 LocalDateTime 就用它,别混着用。

第二个坑是前端角色判断只做了路由守卫。刚开始我以为前端路由限制了访问,后端就不会有越权问题。后来测试发现,直接把后端返回的接口地址放到浏览器里访问,绕过前端照样能拿到数据。正确的做法是后端每一个接口都校验当前用户角色,而不是只依赖前端隐藏菜单。

第三个坑是 MyBatis-Plus 的逻辑删除配置。给表加了deleted字段做逻辑删除,结果所有查询都要额外带上deleted = 0条件,刚开始漏了很多地方,出现了大量已删除数据仍然被查询出来的问题。后来才知道 MyBatis-Plus 有@TableLogic注解,配置之后全局自动拼接条件,不用手写。

第四个坑是文件上传模块的预算。我之前加了图片上传功能,本地跑的好好的,部署到服务器上路径就走不通,因为服务器没有对应目录,也没给写权限。后来改成了上传到本地服务器自定义目录,并通过 Nginx 静态映射访问,问题才解决。这个模块如果时间预算紧,建议用最朴素的本地存储方案。

第五个坑是答辩前把论文里的截图全部换新。原来论文里放了很多早期开发阶段的截图,界面特别简陋,答辩时根本拿不出手。利用一周时间重新跑通所有流程,把每张截图统一换新版本,这个动作在最终盲评时救了我一命。

7.2 给准备做类似题目同学的时间规划建议

从开题算起,建议留出 6 到 8 周。第 1 周完成需求分析和数据库设计,把表结构写成 SQL 脚本;第 2 周完成后端基础 CRUD 和登录鉴权;第 3 周完成核心业务模块(申请、录用、打卡、结算);第 4 周完成前端所有页面和前后端联调;第 5 周集中写论文初稿;第 6 周进行系统测试和论文修改;第 7 周准备答辩 PPT 和演示视频;如果学校要求提前提交,第 8 周作为缓冲期。

按照这个节奏,关键的决策点集中在第 1 周,数据库设计做不好后面全是返工。我第一次的数据库设计把录用关系和申请记录合并成一张表,导致工时记录表无法关联,测试数据一插入业务就乱,最后花了 3 天重构。这个教训的总结是:表结构设计阶段多花一天,后面的开发能少走五天弯路。

7.3 最后说一句个人体会

整个项目做下来,最大的感受是少做不会、多做不乱。不要一开始就想把系统做得很大很强,毕业设计的核心是流程完整、逻辑清晰、代码规范、论文真实,而不是功能越多越好。你把这个勤工俭学平台的闭环吃透了,Spring Boot 加 Vue 的这套前后端分离体系就真正入门了,后续往里面加 Spring Security、Redis、消息队列都是水到渠成的事。

我自己后期复习校招面试时,这个项目是被问得最多的:从表设计到权限控制到定时任务,每一层都是能讲清楚的原生代码,这比网上抄来的大型项目香得多。做毕业设计这件事,能让你真正学到东西的,永远是自己一行行写出来的那个项目。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/25 21:33:24

Gitee实战指南:从SSH密钥配置到Pages部署与开源许可证选择

1. Gitee为什么能成为开发者生态的底层设施先说个实际现象。这几年不管是做外包、创业公司做项目&#xff0c;还是传统企业搞内部系统&#xff0c;很多团队第一步不是开会定方案&#xff0c;而是先建仓库。仓库建在哪&#xff1f;国内团队用Gitee的比例越来越高。我的经验是&am…

作者头像 李华
网站建设 2026/10/26 0:28:36

微信小程序+SSM健身项目源码实战:跑通与二次开发

手头这套交付包是典型的“微信小程序SSM&#xff08;SpringSpringMVCMyBatis&#xff09;”项目组合&#xff0c;文件名是“weixin159健身小程序ssm&#xff08;文档源码&#xff09;”。这类资源我接触过不少&#xff0c;健身房预约、食堂订餐、校园二手交易&#xff0c;业务五…

作者头像 李华
网站建设 2026/10/25 22:22:11

JDBC连接数据库全攻略:配置、排错与连接池实战

周一早上刚到工位&#xff0c;隔壁组的小王就抱着笔记本过来了&#xff1a;“哥&#xff0c;我连不上数据库了&#xff0c;报错是CommunicationsException&#xff0c;但昨天还好好的。”这种问题我一年少说碰十几次&#xff0c;每次排查到最后&#xff0c;绝大多数情况都回到同…

作者头像 李华
网站建设 2026/10/28 14:03:03

迈瑞病人数据共享协议开发指南:HL7接口对接与MLLP服务实现

简介&#xff1a;这份《迈瑞病人数据共享协议开发指南》中文电子档面向具备软件开发与网络基础的专业工程师&#xff0c;解决第三方产品与迈瑞监护仪、麻醉机、远望VI中心监护系统及病人数据共享网关之间的数据交换问题。文档围绕HL7底层协议与协议层展开&#xff0c;涵盖物理层…

作者头像 李华
网站建设 2026/10/21 12:26:26

Sickos1.1靶机实战:SQL注入绕过与Shellshock提权全记录

可以做渗透测试练习的时候&#xff0c;我有个习惯&#xff1a;每打完一台靶机&#xff0c;就把WriteUp里容易被一带而过的部分拿出来反复琢磨。Sickos1.1就是这样一台机器&#xff0c;它来自VulnHub&#xff0c;难度标签是Hard&#xff0c;但真正难的地方不是某个漏洞的利用代码…

作者头像 李华
网站建设 2026/10/26 7:43:45

Agent-Reach:量化Agent工具触达能力的评测与诊断框架

你猜一个Agent最容易翻车的地方在哪&#xff1f;不是模型推理能力不够&#xff0c;也不是prompt写得不好&#xff0c;而是它根本够不到该用的东西。我过去三个月一直在调一个企业内部AI助手&#xff0c;工具函数从20个膨胀到120个之后&#xff0c;模型开始频繁选错工具、填错参…

作者头像 李华