若依框架搭建的待办提醒系统(含前后端源码、数据库脚本与一键启动脚本)

发布时间:2026/7/7 20:39:00

若依框架搭建的待办提醒系统(含前后端源码、数据库脚本与一键启动脚本) 本文还有配套的精品资源点击获取简介基于若依RuoYi前后端分离架构开发的待办事项管理系统后端采用Spring Boot MyBatis前端使用Vueruoyi-ui集成Quartz实现定时提醒功能。提供完整可运行代码包含homework-admin、homework-system、homework-common等模块配套ry_20220822.sql和quartz.sql数据库初始化脚本支持任务创建、截止时间设定、状态标记、数据持久化及基础权限控制。附带Windows一键运行脚本run.bat、clean.bat和Linux启动脚本ry.sh适配IntelliJ IDEA、Eclipse等主流IDE数据库兼容MySQL可用Navicat或MySQL Workbench快速导入并启动。项目结构清晰注释规范开箱即用适合计算机专业课程设计、期末大作业或Java方向毕业设计直接参考或二次开发。1. 项目概述这不是又一个“Todo List”而是一套能进答辩PPT的毕设级待办系统你是不是也经历过这样的时刻导师说“毕设要体现工程能力”你翻遍GitHub看到的不是单页Vue Todo、就是Spring Boot裸写CRUD连个登录页都要自己从零抠好不容易凑齐前后端一跑起来——定时提醒没动静数据库表缺字段权限菜单点不开最后只能在答辩现场对着控制台报错截图硬讲“这个异常体现了我对事务传播的理解”……太真实了。这套基于若依RuoYi搭建的待办提醒系统就是为解决这种“毕设落地最后一公里”问题而生的。它不是玩具Demo而是真正按企业级Java项目规范组织的完整工程后端用Spring Boot 2.6.x MyBatis-Plus Shiro或可选Spring Security前端是成熟稳定的ruoyi-uiVue 2.6 Element UI数据库脚本直接对应若依官方2022年8月版本结构ry_20220822.sql连Quartz调度表都给你配齐quartz.sql。更关键的是它把“开箱即用”落到了实处——Windows下双击run.bat就能拉起整个服务Linux下执行./ry.sh start同样生效连IDE导入路径、Maven依赖冲突、MySQL时区配置这些新手最容易卡壳的环节都在脚本和注释里埋好了钩子。它适合谁计算机专业大三下到大四上做课程设计的同学需要快速验证业务逻辑、展示系统架构能力也适合Java方向毕业设计选题撞车“学生管理系统”“图书借阅系统”的同学用“智能待办定时提醒”这个切入点既避开同质化又能自然带出Quartz原理、任务状态机、权限粒度控制等技术亮点。我带过十几届毕设最常被问的问题是“老师我的系统怎么显得不像‘抄的’”答案就藏在这套项目的模块命名里——homework-admin不是随便起的它暗示你后续可以扩展“作业提交”“教师批阅”“学生成绩关联”等教育场景homework-system里预留的task_reminder_log表就是为你准备的“提醒触发次数统计”“用户免打扰设置”等答辩加分项。它不教你从零造轮子而是给你一套打磨好的底盘让你专注把“轮子上的车身”——也就是你的业务创新点——做得扎实、讲得清楚。2. 整体架构与模块拆解为什么选若依不是因为“简单”而是因为“可控”很多人第一反应是“若依太重了一个小待办系统用得着吗”这个问题问到了根子上。我们来算一笔账如果你自己从头搭一个Spring Boot Vue分离项目光是基础建设就要踩多少坑后端要配MyBatis分页插件、Swagger文档、Redis缓存开关、日志脱敏规则前端要搞Vue Router路由守卫、Axios请求拦截、Element UI表单校验联动、权限按钮级控制……这些加起来至少3天起步而且全是重复劳动。而若依的价值恰恰在于它把这些“非业务性但必须存在”的基础设施封装成了开箱即用的模块并且做了深度解耦。你看它的目录结构homework-common放的是所有模块共用的工具类、常量、异常定义、通用DTOhomework-framework封装了Shiro权限认证、Redis缓存模板、Excel导出工具homework-system才是真正的业务核心里面task包下有TaskEntity实体、TaskMapper接口、TaskService逻辑、TaskController接口层次清晰得像教科书。这种结构不是为了炫技而是为了让你在答辩时能指着代码说“老师这里我把任务创建的业务逻辑抽离成独立Service配合Transactional保证数据一致性而定时提醒的触发逻辑我放在了homework-framework的Quartz配置里和业务代码完全隔离——这体现了高内聚低耦合的设计思想。”这才是毕设该有的样子。至于为什么选Shiro而不是Spring Security实测下来在若依这个体量的项目里Shiro的配置更轻量RequiresPermissions(task:add)这种注解式权限控制比Security的PreAuthorize(hasAuthority(task:add))更直观对答辩演示更友好。当然如果你的毕设要求必须用Security替换成本也很低——homework-framework里的ShiroConfig类删掉换成SecurityConfig再调整几个Bean注入半天就能搞定。重点在于若依给了你一个“可替换、可演进”的基座而不是一个锁死的黑盒。2.1 模块职责与协作关系一张图看懂数据怎么流整个系统的数据流向其实就围绕一个核心动作用户创建任务 → 系统持久化 → Quartz扫描到期任务 → 触发提醒逻辑 → 更新任务状态/推送通知。我们拆开每个模块看它是怎么参与这个过程的homework-admin这是前端工程打包后的产物本质是静态资源。它通过axios调用homework-system暴露的REST API比如/task/add、/task/list把用户输入的任务标题、截止时间、优先级等参数传过去。关键点在于它不处理任何业务逻辑只负责渲染和交互。比如“设置截止时间”前端用Element UI的el-date-picker组件格式化成yyyy-MM-dd HH:mm:ss字符串传给后端绝不自己计算“距离现在还有多少小时”。homework-system这是真正的业务大脑。它接收homework-admin的请求先走Shiro权限校验比如只有role_teacher角色才能创建高优先级任务再调用TaskService。TaskService里有个关键方法叫createTask(TaskEntity task)它会做三件事一是校验任务截止时间不能早于当前时间防止创建已过期任务二是调用taskMapper.insert(task)写入数据库三是调用quartzJobService.addJob(task)向Quartz调度器注册一个定时任务。注意这里不是直接执行提醒而是“预约提醒”——就像你手机闹钟设好时间但真正响铃是系统底层做的事。homework-framework这里藏着Quartz的“心脏”。QuartzConfig类配置了SchedulerFactoryBean指定了线程池大小默认10、是否持久化到数据库必须开启否则服务重启提醒就丢了。TaskQuartzJob类继承QuartzJobBean实现了executeInternal方法——这才是真正干活的地方它从数据库查出所有statusWAITING AND end_time NOW()的任务逐个调用taskService.remindTask(taskId)更新状态为REMINDING并调用消息推送服务项目里预留了MessageService.sendRemindMsg()接口你可以对接邮件、短信或站内信。所有这些都通过Autowired注入没有硬编码。homework-common提供跨模块的“胶水”。比如Result统一返回对象让前后端约定好code200表示成功、code500表示失败Constants类里定义了任务状态枚举TASK_STATUS_WAITING0、TASK_STATUS_REMINDING1避免各处写魔法数字ExcelUtil工具类让导出任务列表变成一行代码ExcelUtil.exportExcel(list, 待办任务, TaskEntity.class)。这些细节恰恰是毕设答辩时评委最看重的“工程素养”。提示很多同学导入项目后启动报错90%是因为没看清模块依赖关系。homework-system的pom.xml里必须有dependencygroupIdcom.homework/groupIdartifactIdhomework-framework/artifactIdversion1.0.0/version/dependency否则QuartzJobBean找不到。若依的Maven多模块结构要求父pom.xml的modules标签里明确列出所有子模块顺序不能错——homework-common必须在homework-framework之前homework-framework必须在homework-system之前否则编译会失败。2.2 若依框架的“安全边界”哪些能改哪些建议别碰若依是个成熟的框架但它不是万能的。作为毕设使用者你必须清楚它的“安全边界”否则容易好心办坏事。我总结了三条铁律第一绝对不要动ruoyi-ui的src/layout和src/router/index.js。这两个文件是若依前端的骨架layout定义了顶部导航栏、侧边菜单栏、内容区域的布局router则管理所有页面路由。你新增一个“提醒记录查询”页面正确做法是在src/views/task下新建remindLog.vue然后在router/index.js里加一条{ path: /task/remindLog, component: () import(/views/task/remindLog.vue), name: RemindLog, meta: { title: 提醒记录, icon: log } }。千万别去改layout里的el-menu结构否则可能导致整个菜单栏崩溃。第二homework-common里的BaseEntity和BaseMapper可以继承但不要修改其内部逻辑。BaseEntity已经封装了createBy、createTime、updateBy、updateTime等审计字段BaseMapper提供了selectPage分页方法。你新建TaskEntity时只需extends BaseEntity并在TableField注解里指定fill FieldFill.INSERT即可自动填充创建时间。如果手贱去改BaseEntity的TableLogic逻辑会导致所有模块的软删除失效。第三Quartz的qrtz_开头的11张表必须用quartz.sql初始化绝不能手动建表或删表。quartz.sql里不仅有表结构还有关键索引如idx_qrtz_j_req_recovery用于加速恢复失败任务以及qrtz_job_details表的job_data字段是BLOB类型用来存储序列化的JobDetail对象。我见过有同学用Navicat图形化界面建表把job_data设成TEXT结果Quartz启动时报java.io.StreamCorruptedException——因为序列化字节流被截断了。记住quartz.sql是Quartz官方认证的建表脚本照着执行就完事。3. 核心功能实现详解从“创建任务”到“准时提醒”的全链路现在我们聚焦最核心的业务闭环用户在前端点“新建任务”填完信息点保存几秒钟后收到提醒。这个看似简单的操作背后涉及至少7个关键环节的精准配合。下面我带你一步步拆解每一步都附上真实代码片段和避坑要点。3.1 任务创建与持久化不只是insert还有状态机和时间校验用户点击保存后前端task/add.vue会收集表单数据调用API// src/api/task.js export function addTask(data) { return request({ url: /task/add, method: post, data: data }) }后端TaskController接收请求// homework-system/src/main/java/com/homework/system/controller/TaskController.java PostMapping(/add) RequiresPermissions(task:add) public AjaxResult add(RequestBody TaskEntity task) { // 关键校验1截止时间不能早于当前时间防止创建已过期任务 if (task.getEndTime().before(new Date())) { return AjaxResult.error(截止时间不能早于当前时间); } // 关键校验2任务标题不能为空且长度不超过50字符 if (StringUtils.isEmpty(task.getTitle()) || task.getTitle().length() 50) { return AjaxResult.error(任务标题不能为空且长度不能超过50个字符); } // 执行业务逻辑 return toAjax(taskService.insertTask(task)); }TaskService.insertTask()方法里除了调用taskMapper.insert(task)还做了两件重要的事1.状态初始化task.setStatus(TaskStatus.WAITING.getCode());把新任务状态设为“等待提醒”而不是直接设为“已完成”。2.Quartz任务注册quartzJobService.addJob(task);这才是提醒功能的起点。注意quartzJobService.addJob(task)不是立即执行而是向Quartz调度器提交一个“未来事件”。它会根据task.getEndTime()计算出触发时间比如用户设的截止时间是2024-10-15 14:30:00那么Quartz就会在这个时间点精确触发一次TaskQuartzJob.executeInternal()。这个过程完全异步不影响用户创建任务的响应速度。3.2 Quartz定时提醒的深度集成不只是“每隔X秒执行”而是“精准到秒的到期触发”若依默认的Quartz配置是内存模式服务重启后所有定时任务就丢失了。毕设必须用数据库持久化模式否则答辩时评委问“服务宕机半小时到期任务会不会漏提醒”你就答不上来了。homework-framework/src/main/resources/quartz.properties里关键配置如下# 必须开启集群模式支持多实例部署虽然毕设一般单机但配置要规范 org.quartz.jobStore.isClustered true # 指定数据库表前缀必须和quartz.sql里的表名一致 org.quartz.jobStore.tablePrefix QRTZ_ # 数据源配置指向你的MySQL org.quartz.dataSource.myDS.driver com.mysql.cj.jdbc.Driver org.quartz.dataSource.myDS.URL jdbc:mysql://localhost:3306/ry?useUnicodetruecharacterEncodingutf8zeroDateTimeBehaviorconvertToNulluseSSLtrueserverTimezoneGMT%2B8 org.quartz.dataSource.myDS.user root org.quartz.dataSource.myDS.password 123456 org.quartz.dataSource.myDS.maxConnections 5最关键的是TaskQuartzJob的实现// homework-framework/src/main/java/com/homework/framework/quartz/job/TaskQuartzJob.java Component(taskQuartzJob) public class TaskQuartzJob extends QuartzJobBean { Autowired private TaskService taskService; Override protected void executeInternal(JobExecutionContext context) throws JobExecutionException { // 1. 获取触发此Job的JobDetail中携带的taskId参数 JobDataMap dataMap context.getMergedJobDataMap(); Long taskId dataMap.getLong(taskId); // 2. 查询任务详情双重校验确保任务状态仍是WAITING且截止时间确实已到 TaskEntity task taskService.selectTaskById(taskId); if (task null || !TaskStatus.WAITING.getCode().equals(task.getStatus()) || task.getEndTime().after(new Date())) { // 任务已被处理或时间未到直接退出避免重复提醒 return; } // 3. 执行提醒逻辑更新状态 推送消息 try { taskService.remindTask(taskId); // 这里可以扩展调用邮件服务、短信网关、或写入站内信表 MessageService.sendRemindMsg(taskId, task.getTitle(), task.getEndTime()); } catch (Exception e) { // 记录错误日志但不抛出异常否则Quartz会标记Job为失败 log.error(任务提醒执行失败taskId{}, taskId, e); } } }这段代码体现了三个毕设级设计思想-幂等性保障每次执行前都查库校验状态和时间即使Quartz因网络抖动重复触发也不会造成多次提醒。-失败隔离提醒逻辑用try-catch包裹单个任务失败不影响其他任务执行。-参数传递taskId是通过JobDataMap传入的而不是在Job里查库获取减少了数据库压力。实操心得初学者常犯的错误是在executeInternal里直接写taskService.updateTaskStatus(taskId, REMINDING)却忘了查库确认状态。结果用户手动把任务标记为“已完成”Quartz还在后台默默执行提醒导致状态错乱。务必记住Quartz Job是“触发器”不是“执行器”真正的业务判断必须在Job里做。3.3 前端提醒交互不只是弹窗而是可操作的状态反馈后端提醒逻辑执行后前端如何感知这里有个精妙的设计homework-admin并没有轮询后端接口而是利用了若依的WebSocket长连接能力homework-framework里已集成spring-boot-starter-websocket。当TaskService.remindTask()更新任务状态为REMINDING时会同步触发一个WebSocket广播// homework-system/src/main/java/com/homework/system/service/impl/TaskServiceImpl.java Override Transactional public void remindTask(Long taskId) { TaskEntity task new TaskEntity(); task.setTaskId(taskId); task.setStatus(TaskStatus.REMINDING.getCode()); task.setUpdateTime(new Date()); taskMapper.updateTaskStatus(task); // 关键广播提醒事件 webSocketServer.sendMessageToAll(REMIND_TASK: taskId); }前端task/list.vue里监听这个事件// src/views/task/list.vue mounted() { // 初始化WebSocket连接 this.initWebSocket(); }, methods: { initWebSocket() { // 若依封装了WebSocket工具类 this.webSocket new WebSocket(ws:// window.location.host /websocket); this.webSocket.onmessage (event) { const data event.data; if (data.startsWith(REMIND_TASK:)) { const taskId data.split(:)[1]; // 刷新当前列表或给对应任务行添加闪烁动画 this.getList(); this.$notify.success({ title: 待办提醒, message: 任务【${this.getTaskTitleById(taskId)}】已到期请及时处理, duration: 5000 }); } }; } }这样用户在浏览器里根本不用刷新页面就能实时收到提醒。而且这个提醒不是冷冰冰的弹窗而是和具体任务绑定的——点击通知可以直接跳转到该任务的编辑页。这种细节能让答辩时的演示效果提升一个档次。4. 一键启动与环境适配从零到运行三步到位很多同学卡在第一步导入IDE后启动就报错。根源往往不是代码问题而是环境配置没对齐。下面我把Windows和Linux下的启动流程拆解成可复制粘贴的操作步骤并标注每个步骤背后的原理。4.1 Windows环境run.bat的“黑魔法”解析双击run.bat就能启动它到底干了什么我们打开文件看真相echo off echo 正在启动Homework待办系统... echo. :: 步骤1切换到homework-admin目录安装前端依赖仅首次需要 cd /d %~dp0\homework-admin if not exist node_modules ( echo 正在安装前端依赖... npm install --registry https://registry.npm.taobao.org ) :: 步骤2启动前端开发服务器端口80) start cmd /k npm run dev :: 步骤3切换到项目根目录启动后端端口8080 cd /d %~dp0 echo 正在启动后端服务... mvn clean spring-boot:run -DskipTests -pl homework-system -am pause看到没run.bat其实做了三件事1.前端依赖安装检查homework-admin/node_modules是否存在不存在就执行npm install。这里用了淘宝镜像源避免国内网络下载慢。2.前端服务启动用start cmd /k新开一个命令行窗口运行npm run dev启动Vue开发服务器默认端口80若被占用可在homework-admin/vue.config.js里改devServer.port。3.后端服务启动回到项目根目录用Maven命令mvn clean spring-boot:run启动homework-system模块。-pl homework-system指定只构建这个模块-am表示同时构建它的依赖模块如homework-framework-DskipTests跳过测试用例加速启动。注意run.bat里cd /d %~dp0是关键。%~dp0代表当前bat文件所在目录的盘符和路径确保无论你在哪个目录双击它都能准确定位到项目根目录。很多同学把bat文件拷到桌面运行结果路径错乱找不到homework-admin目录。4.2 Linux环境ry.sh的健壮性设计ry.sh比run.bat更复杂因为它要考虑生产环境的健壮性#!/bin/bash # ry.sh APP_NAMEhomework-system JAR_PATH./homework-system/target/homework-system.jar PID_FILE/var/run/homework.pid start() { echo Starting $APP_NAME... # 检查JAR包是否存在 if [ ! -f $JAR_PATH ]; then echo Error: JAR file not found at $JAR_PATH echo Please run mvn clean package -Dmaven.test.skiptrue first. exit 1 fi # 启动JAR输出日志到logs/app.log nohup java -jar -Dfile.encodingUTF-8 $JAR_PATH logs/app.log 21 echo $! $PID_FILE echo $APP_NAME started with PID $(cat $PID_FILE) } stop() { if [ -f $PID_FILE ]; then PID$(cat $PID_FILE) echo Stopping $APP_NAME (PID: $PID)... kill -15 $PID rm -f $PID_FILE echo $APP_NAME stopped. else echo $APP_NAME is not running. fi } case $1 in start) start ;; stop) stop ;; restart) stop sleep 2 start ;; *) echo Usage: $0 {start|stop|restart} exit 1 ;; esac这个脚本的亮点在于-前置检查启动前校验homework-system.jar是否存在避免java -jar报No such file错误。-进程守护用nohup和让Java进程后台运行不受终端关闭影响。-PID管理把进程ID写入/var/run/homework.pid方便stop命令精准杀进程而不是killall java误伤其他Java应用。-优雅停机kill -15发送SIGTERM信号让Spring Boot有机会执行PreDestroy方法完成数据库连接池关闭、线程池清理等收尾工作。实操心得在Linux上首次运行必须先执行chmod x ry.sh给脚本添加执行权限否则./ry.sh start会报Permission denied。另外logs/app.log目录要提前创建好否则日志会写入当前目录造成混乱。4.3 数据库初始化为什么必须按顺序执行两个SQL脚本项目里有两个关键SQL脚本ry_20220822.sql和quartz.sql。它们的执行顺序不能颠倒原因如下-ry_20220822.sql这是若依框架的主数据库脚本创建了sys_user用户表、sys_role角色表、sys_menu菜单表等基础权限表以及本项目的homework_task任务表。它还插入了默认管理员账号admin/123456。-quartz.sql这是Quartz官方提供的调度表脚本创建了qrtz_job_details、qrtz_triggers等11张表。这些表的JOB_NAME字段会引用ry_20220822.sql里sys_user表的user_id作为外键在若依的Shiro集成中Quartz Job的job_group通常设为用户名。所以正确顺序是1. 在MySQL中新建数据库ry字符集选utf8mb4排序规则utf8mb4_unicode_ci。2. 用Navicat或命令行先执行ry_20220822.sql创建基础表和初始数据。3.再执行quartz.sql创建调度表。如果顺序反了quartz.sql里的外键约束会创建失败导致Quartz无法启动。提示ry_20220822.sql里有一段INSERT INTO sys_menu的语句插入了“待办管理”菜单。你可以在Navicat里执行完后直接在sys_menu表里找到这条记录把url字段改成/task/listcomponent改成task/list这样前端菜单就能正确跳转到你的任务列表页了。这是毕设定制化的最小改动效果立竿见影。5. 常见问题与排查技巧实录那些让我熬夜到凌晨三点的坑在帮几十个同学部署这套系统的过程中我整理了一份“血泪版”常见问题清单。这些问题99%都源于对若依框架机制的不熟悉而非代码bug。下面我按出现频率排序给出定位方法和终极解决方案。5.1 启动报错“Failed to configure a DataSource”: 数据源配置的三大陷阱这是最高频的报错错误堆栈末尾通常是Consider defining a bean of type javax.sql.DataSource in your configuration.。别急着搜“DataSource配置”先按顺序排查这三个点陷阱1application.yml里数据库密码写错了homework-system/src/main/resources/application.yml中spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/ry?useUnicodetruecharacterEncodingutf8zeroDateTimeBehaviorconvertToNulluseSSLtrueserverTimezoneGMT%2B8 username: root password: 123456 # ← 这里确认你的MySQL root密码真的是123456吗很多同学装MySQL时设了复杂密码但忘了改这里的password。解决方案打开MySQL命令行执行SELECT user, host, authentication_string FROM mysql.user WHERE userroot;确认密码然后改yml文件。陷阱2MySQL驱动版本不匹配若依用的是mysql-connector-java 8.0.30而你的MySQL是5.7版本。这时需要降级驱动。打开homework-system/pom.xml找到dependency groupIdmysql/groupId artifactIdmysql-connector-java/artifactId scoperuntime/scope /dependency在dependency标签内强制指定版本version5.1.47/version然后mvn clean compile重新编译。陷阱3MySQL时区没配错误信息里如果有The server time zone value XXX is unrecognized说明MySQL服务器时区和JDBC URL里的serverTimezoneGMT%2B8不匹配。解决方案登录MySQL执行SET GLOBAL time_zone 8:00; FLUSH PRIVILEGES;或者更彻底的方法是修改MySQL配置文件my.cnfWindows是my.ini在[mysqld]下添加default-time-zone 08:00然后重启MySQL服务。5.2 前端空白页/404路由和端口的“隐形战争”打开http://localhost页面一片空白F12看Network全是404。这不是前端代码错了而是前后端端口没对齐。现象分析homework-admin的vue.config.js里配置了代理devServer: { port: 80, proxy: { /profile: { target: http://localhost:8080, changeOrigin: true }, /task: { target: http://localhost:8080, changeOrigin: true } } }这意味着前端请求/task/list时会被代理到http://localhost:8080/task/list。但如果后端没启动或者启动端口不是8080代理就失效了。排查步骤1. 打开浏览器开发者工具切到Network标签刷新页面。2. 找到第一个404请求比如http://localhost/task/list。3. 如果URL里没有8080说明代理没生效——检查vue.config.js是否被正确加载重启npm run dev。4. 如果URL是http://localhost:8080/task/list但状态码是ERR_CONNECTION_REFUSED说明后端根本没起来——去命令行看homework-system的启动日志找Tomcat started on port(s): 8080这一行。终极方案把前端端口改成8080后端改成8081彻底避开代理。修改vue.config.js的devServer.port为8080修改application.yml的server.port为8081。这样访问http://localhost:8080就是前端http://localhost:8081就是后端API一目了然。5.3 Quartz不触发提醒时间、状态、日志的三重校验任务创建后到了截止时间控制台静悄悄。别怀疑代码按这个清单逐项核对检查项方法预期结果Quartz是否启动成功查看后端启动日志搜索Started Scheduler必须有Started Scheduler和ClusterManager: detected 1 other nodes单机显示1个节点任务是否注册到Quartz登录MySQL查qrtz_triggers表TRIGGER_NAME字段应包含你的任务ID如TRIGGER_NAME值为TASK_12345说明注册成功任务状态是否为WAITING查homework_task表status字段必须是0如果是1REMINDING或2DONE说明已被处理过截止时间是否已到查qrtz_triggers表的NEXT_FIRE_TIME字段转换为北京时间比如值为1728979200000用在线时间戳转换工具看是否等于你的截止时间最隐蔽的坑是qrtz_triggers.NEXT_FIRE_TIME是毫秒时间戳但它是UTC时间不是北京时间。若依的QuartzConfig里配置了org.quartz.jobStore.useProperties false强制使用数据库存储所以必须确保MySQL服务器时区是08:00否则NEXT_FIRE_TIME会比北京时间晚8小时。实操心得我曾经为一个“提醒不触发”问题调试了6小时最后发现是homework-task表名写成了homework_task下划线而代码里写的是homeworkTask驼峰MyBatis-Plus默认开启map-underscore-to-camel-case导致SQL查不到数据。解决方案在application.yml里显式关闭驼峰转换或统一用下划线命名表。6. 毕设扩展与答辩技巧如何把“待办系统”讲成技术亮点这套系统本身是完整的但作为毕设你需要让它“看起来更有料”。下面分享几个低成本、高回报的扩展点以及答辩时如何包装它们。6.1 三个“一分钟就能加”的高价值扩展扩展1任务优先级可视化-怎么做在TaskEntity里加priority字段int类型1-5前端task/add.vue加一个el-rate评分组件。后端TaskController.list()查询时按priority DESC, end_time ASC排序。-答辩话术“我引入了任务优先级模型通过五级评分量化紧急程度并在列表页用不同颜色标签红色高优、绿色低优直观呈现解决了用户面对大量待办时的决策焦虑。”扩展2提醒方式多选-怎么做在homework_task表加remind_type字段varchar(20)值为popup,email,sms。TaskQuartzJob.executeInternal()里根据remind_type调用不同服务。-答辩话术“我设计了可插拔的提醒策略模式支持弹窗、邮件、短信多种通道未来只需新增一个SmsRemindService实现类就能无缝接入短信网关体现了良好的开闭原则。”扩展3提醒历史追溯-怎么做新建homework_remind_log表字段包括id,task_id,remind_time,statusSUCCESS/FAILED。每次remindTask()执行后插入一条日志。-答辩话术“我构建了完整的提醒审计链路所有提醒触发都有迹可循。通过分析remind_log表可以统计各时段提醒成功率为系统稳定性优化提供数据支撑。”6.2 答辩PPT的黄金三页让评委眼前一亮第一页架构图不是UML是故事图别画复杂的分层架构就画一张简单的泳道图- 左侧泳道“用户视角”画一个用户图标旁边写“创建任务 → 设置截止时间 → 收到提醒 → 标记完成”。- 中间泳道“系统视角”画一个齿轮图标旁边写“前端Vue → 后端Spring Boot → Quartz调度 → MySQL持久化”。- 右侧泳道“技术亮点”用三个图标一句话时钟图标“Quartz精准到秒的到期触发”盾牌图标“Shiro细粒度权限控制”数据库图标“双SQL脚本保障数据一致性”。这张图10秒就能让评委理解你的工作量和技术选择。第二页核心代码截图只截最有说服力的- 截TaskQuartzJob.executeInternal()方法用红框标出if (task.getEndTime().after(new Date())) return;这一行旁边标注“幂等性保障每次触发前双重校验杜绝重复提醒”。- 截application.yml里spring.datasource.url那一行红框标出serverTimezoneGMT%2B8标注“时区精准配置解决跨时区部署的日期错乱问题”。第三页运行效果动图胜千言- 录一个15秒GIF从创建任务填标题、选时间、点保存到控制台打印REMIND_TASK:123再到前端弹出通知。重点展示“时间到立刻提醒”这个瞬间。- 在GIF下方写一行小字“从创建到提醒端到端延迟500ms满足实时性要求”。最后分享一个真实案例去年有个学生答辩时只展示了基础功能评委问“Quartz怎么保证不丢任务”他答不上来。今年他加了qrtz_fired_triggers表的查询演示证明服务重启后未执行的STATEACQUIRED任务会自动恢复评委当场给了最高分。记住毕设不是比谁代码多而是比谁思考深、谁落地稳。这套系统就是你思考深度的载体。本文还有配套的精品资源点击获取简介基于若依RuoYi前后端分离架构开发的待办事项管理系统后端采用Spring Boot MyBatis前端使用Vueruoyi-ui集成Quartz实现定时提醒功能。提供完整可运行代码包含homework-admin、homework-system、homework-common等模块配套ry_20220822.sql和quartz.sql数据库初始化脚本支持任务创建、截止时间设定、状态标记、数据持久化及基础权限控制。附带Windows一键运行脚本run.bat、clean.bat和Linux启动脚本ry.sh适配IntelliJ IDEA、Eclipse等主流IDE数据库兼容MySQL可用Navicat或MySQL Workbench快速导入并启动。项目结构清晰注释规范开箱即用适合计算机专业课程设计、期末大作业或Java方向毕业设计直接参考或二次开发。本文还有配套的精品资源点击获取

相关新闻