简介这是一套面向计算机专业本科生的微信小程序毕业设计实战项目聚焦个人日程管理场景兼顾前端交互体验与后端业务逻辑完整性适用于课程设计、毕设选题及Java小程序全栈能力训练。资源包含1175个文件涵盖163个JS逻辑脚本、128个Vue组件、111个Java后端服务类、80个WXSS样式文件及231个PNG界面素材完整呈现小程序UI层、WXML结构层、Java服务层与MySQL数据层的协同实现压缩包40.44MB结构清晰含3个批处理脚本install/run/build便于本地快速部署。已有160人学习下载提供配套演示视频编号156、详细功能说明文档及可运行源码覆盖管理员侧的用户管理、日程分类工作/会面/用餐/重要日、系统配置等全模块同时支持用户端个人信息维护与日程增删改查具备真实可用性与教学示范价值。1. 为什么一个“个人日程安排”小程序值得花三个月做毕设不是所有毕设都得追热点、堆算法。去年带某高校计算机专业课设时A同学最初想做“AI会议纪要生成”两周后卡在语音识别准确率上反复重训模型而隔壁组用同样技术栈做的“个人日程安排系统”答辩当天被三位导师同时追问“你是怎么处理跨天重复事件的”——这恰恰说明小功能不等于低深度真实场景里的边界条件才是检验工程能力的试金石。这个微信小程序毕业设计项目表面看是“记个待办、设个提醒”但实际覆盖了完整闭环用户端小程序→ API网关Java后端→ 数据持久化MySQL→ 管理端含多角色权限→ 全流程演示验证。它不依赖第三方AI服务不涉及敏感数据却把权限控制管理员/普通用户、时间逻辑跨日/周期/优先级、状态同步本地缓存服务端强一致、前端性能长列表虚拟滚动、页面级loading防抖全揉进一个可交付包里。适合课程设计快速上手也撑得起毕业答辩的技术纵深——尤其当你需要解释“为什么不用uni-app而坚持原生小程序框架”“为什么日程表单提交要分两步校验”时每处设计都有据可依。提示本方案默认读者已掌握HTML/CSS/JavaScript基础熟悉微信开发者工具基本操作Java后端需了解Spring Boot MyBatis整合数据库需理解索引与事务隔离级别。未覆盖环境搭建细节聚焦“为什么这么设计”和“怎么避免翻车”。2. 总体架构设计前后端分离的三层结构与四类核心模块职责划分整个系统采用清晰的分层架构小程序端作为纯展示层不处理业务逻辑Java后端承担全部API服务、权限校验、事务管理MySQL负责数据持久化与关系建模。这种结构让各模块职责明确便于学生独立调试、导师逐层验收。2.1 前端架构基于微信原生框架的模块化组织小程序目录严格按功能域拆分避免pages下文件堆积pages/index/首页日历视图 今日待办卡片含状态色标pages/schedule/日程增删改查支持拖拽调整时间段pages/meeting/会面管理含地点坐标、参会人选择器pages/admin/管理员专属入口路由守卫强制拦截非授权访问关键设计点在于状态管理解耦所有列表数据不直接绑定data而是通过getApp().globalData统一维护缓存副本并在onPullDownRefresh时触发wx.request拉取最新快照。这样既避免频繁请求又保证下拉刷新的感知一致性。2.2 后端架构Spring Boot MyBatis-Plus 的轻量级服务层后端采用标准MVC分层controller仅做参数接收、登录态校验JWT Token解析、返回统一封装格式ResultTservice核心业务逻辑如ScheduleService中实现“创建日程时自动检查时间冲突”mapperMyBatis-Plus自动生成CRUD手动编写复杂查询如“查询本周高优先级未完成日程”特别注意application.yml中的关键配置spring: datasource: url: jdbc:mysql://localhost:3306/schedule_db?useSSLfalseserverTimezoneAsia/ShanghaiallowPublicKeyRetrievaltrue username: root password: 123456 mybatis-plus: configuration: map-underscore-to-camel-case: true # 自动转换下划线字段名到驼峰属性 global-config: db-config: id-type: assign_id # 使用雪花算法生成ID避免MySQL自增主键暴露业务量注意serverTimezoneAsia/Shanghai必须显式声明否则MySQL 8.0版本会出现java.sql.SQLException: The server time zone value XXX is unrecognized错误——这是学生部署时最高频的翻车点之一。2.3 数据库设计6张表支撑全业务场景的最小完备集MySQL共6张表满足范式要求且兼顾查询效率表名主要字段关键约束设计意图userid, openid, nickname, avatar, role (0-普通/1-管理员)openid唯一索引微信登录凭证与角色绑定scheduleid, user_id, title, start_time, end_time, priority, status(user_id, start_time)联合索引支持按用户时间范围高效查询meetingid, schedule_id, location, participants, meeting_link外键关联schedule.id会面作为日程的扩展属性存在meal_planid, user_id, date, meal_type(1-早/2-午/3-晚), dish_name(user_id, date)唯一索引防止同一用户同日重复添加餐食important_dateid, user_id, title, target_date, remind_days_beforetarget_date索引重要日期如考试、纪念日独立建模sys_logid, user_id, action, ip, create_timecreate_time降序索引管理员操作审计留痕所有时间字段均使用datetime类型非timestamp避免时区转换引发的显示错乱status字段采用整型枚举0-待开始/1-进行中/2-已完成/3-已取消比字符串更节省空间且利于SQL条件优化。2.4 权限控制RBAC模型在小程序场景下的极简落地本系统未引入复杂权限框架而是通过双层校验实现安全可控前端路由守卫在app.js中监听wx.getStorageSync(role)跳转admin/前强制判断值是否为1否则重定向至index页并弹窗提示后端接口拦截所有/admin/**路径的Controller方法添加PreAuthorize(hasRole(ADMIN))注解配合UserDetailsServiceImpl中getAuthorities()方法返回[ROLE_ADMIN]或[ROLE_USER]。这种设计平衡了安全性与学习成本——学生能直观看到“哪里加判断”“哪里配注解”无需深入Spring Security源码。3. 核心模块实现从日程创建到跨天重复事件的完整链路3.1 日程创建模块表单校验、时间冲突检测与事务回滚用户在pages/schedule/add页面填写日程时前端先执行基础校验开始时间不能晚于结束时间start_time end_time时间跨度不超过72小时防误操作输入超长事件标题长度1~30字符/^[\u4e00-\u9fa5\w\s]{1,30}$/正则后端ScheduleController.create()方法中关键逻辑如下PostMapping(/create) public ResultString create(RequestBody ScheduleDTO dto, RequestHeader(Authorization) String token) { Long userId jwtUtil.getUserIdFromToken(token); // 1. 检查时间冲突同一用户在[start,end)区间内是否存在status!3的日程 LambdaQueryWrapperSchedule conflictQw new LambdaQueryWrapper(); conflictQw.eq(Schedule::getUserId, userId) .ne(Schedule::getStatus, 3) // 排除已取消 .lt(Schedule::getStartTime, dto.getEndTime()) .gt(Schedule::getEndTime, dto.getStartTime()); if (scheduleService.count(conflictQw) 0) { return Result.fail(时间冲突该时段已有其他日程); } // 2. 插入主表 Schedule schedule new Schedule(); schedule.setUserId(userId); schedule.setTitle(dto.getTitle()); schedule.setStartTime(dto.getStartTime()); schedule.setEndTime(dto.getEndTime()); schedule.setPriority(dto.getPriority()); schedule.setStatus(0); // 默认待开始 scheduleService.save(schedule); // 3. 若为会面插入meeting表同一事务 if (dto.getMeeting() ! null) { Meeting meeting new Meeting(); meeting.setScheduleId(schedule.getId()); meeting.setLocation(dto.getMeeting().getLocation()); meeting.setParticipants(dto.getMeeting().getParticipants()); meeting.setMeetingLink(dto.getMeeting().getMeetingLink()); meetingService.save(meeting); } return Result.success(创建成功); }设计说明此处scheduleService.save()与meetingService.save()处于同一Spring事务中若第二步失败第一步自动回滚。学生常忽略Transactional注解需加在service层而非controller否则事务不生效。3.2 日历视图模块本地渲染性能优化与跨月数据预加载小程序端pages/index/index.wxml中日历采用scroll-view包裹7×6网格42天而非动态wx:for渲染scroll-view scroll-xtrue classcalendar-scroll view classweek-row view wx:for{{weekDays}} wx:keyindex classweek-day{{item}}/view /view view classdate-grid !-- 预生成42个view通过hidden控制显隐 -- view wx:for{{dateList}} wx:keyindex classdate-cell {{item.isCurrentMonth ? current : other}} hidden{{!item.show}} text classdate-num{{item.day}}/text view wx:if{{item.schedules.length 0}} classschedule-badge text{{item.schedules.length}}/text /view /view /view /scroll-viewdateList由utils/calendar.js生成包含show(是否显示)、isCurrentMonth(是否当月)、schedules(当日日程数组)等字段。关键优化在于onLoad时预加载当前月及前后各1个月的数据共3个月存入getApp().globalData.calendarCache切换月份时先查缓存命中则直接渲染未命中再发请求schedules数组按priority降序排列高优先级日程始终置顶显示。这种策略将首屏渲染时间从1.2s降至380ms实测iPhone 12避免用户滑动时白屏闪烁。3.3 管理员模块用户批量导入与日程统计报表的务实实现管理员后台pages/admin/user-manage提供Excel批量导入功能前端使用wx.chooseMessageFile选择.xlsx文件调用wx.uploadFile上传至/admin/import-users接口后端用Apache POI解析Excel逐行校验openid长度是否为28位微信规范role值是否为0或1同一openid是否已存在去重校验通过后调用userMapper.insertBatchSomeColumn()批量插入比循环insert快5倍以上。统计报表pages/admin/report则通过SQL聚合实现SELECT DATE_FORMAT(start_time, %Y-%m) as month, COUNT(*) as total_count, SUM(CASE WHEN status 2 THEN 1 ELSE 0 END) as completed_count, ROUND(AVG(TIMESTAMPDIFF(MINUTE, start_time, end_time)), 1) as avg_duration_min FROM schedule WHERE user_id IN (SELECT id FROM user WHERE role 0) AND start_time DATE_SUB(NOW(), INTERVAL 6 MONTH) GROUP BY DATE_FORMAT(start_time, %Y-%m) ORDER BY month DESC;提示报表SQL中DATE_FORMAT与TIMESTAMPDIFF函数需MySQL 5.7支持若学生使用低版本应替换为YEAR(start_time)*100MONTH(start_time)和(UNIX_TIMESTAMP(end_time)-UNIX_TIMESTAMP(start_time))/60。4. 常见问题排查5个高频翻车点与血泪解决方案4.1 现象小程序真机调试时登录后wx.getStorageSync(token)为空原因微信开发者工具中wx.setStorageSync写入的token不会同步到真机且真机首次启动未触发onLaunch中的登录逻辑。解决在app.js的onShow生命周期中增加兜底判断onShow() { const token wx.getStorageSync(token); if (!token) { // 强制重新登录 wx.navigateTo({ url: /pages/auth/login }); } }同时确保login接口返回的token通过wx.setStorageSync(token, res.data.token)持久化且Authorization请求头拼接为Bearer token。4.2 现象Java后端返回{code:500,msg:Internal Server Error}日志无报错原因MyBatis-Plus的save()方法对空对象或主键冲突抛出DuplicateKeyException但全局异常处理器未捕获该异常类型。解决在GlobalExceptionHandler.java中补充ExceptionHandler(DuplicateKeyException.class) public ResultString handleDuplicateKey(DuplicateKeyException e) { log.error(主键冲突异常, e); return Result.fail(数据已存在请勿重复提交); }并检查user表openid字段是否设置了UNIQUE KEY约束。4.3 现象日历页面滑动卡顿Android手机尤为明显原因date-grid中每个date-cell都绑定了bindtap事件且wx:if在大量节点上频繁切换触发重排重绘。解决将bindtap移至外层scroll-view通过event.detail.x计算点击列替换wx:if为hidden属性hidden仅控制显隐不销毁节点对dateList做Object.freeze()冻结防止Vue式响应式劫持开销。4.4 现象MySQL查询important_date时remind_days_before为负数导致提醒失效原因前端传参未校验用户可能输入-5表示“提前5天提醒”但后端SQL中DATE_SUB(target_date, INTERVAL remind_days_before DAY)遇到负数会变成DATE_ADD逻辑反转。解决在ImportantDateService中强制归一化int remindDays Math.abs(dto.getRemindDaysBefore()); // 统一取绝对值 // 查询时用DATE_SUB(target_date, INTERVAL ? DAY)并在前端表单添加min0属性限制输入。4.5 现象管理员删除用户后其名下日程仍显示在日历中原因schedule表未设置ON DELETE CASCADE且user_id外键约束被禁用为兼容部分学生MySQL配置。解决在UserService.removeById()中手动清理关联数据Override Transactional public boolean removeById(Serializable id) { // 先删除关联日程 scheduleService.remove(new LambdaQueryWrapperSchedule().eq(Schedule::getUserId, id)); // 再删除用户 return super.removeById(id); }注意此操作必须加Transactional否则removeById失败时日程已删数据不一致。5. 毕设答辩与验收用三份材料讲清技术深度与工程闭环5.1 答辩PPT结构拒绝功能罗列聚焦三个技术决策点一份能过关的答辩PPT绝不是“我做了登录、日程、统计”这种流水账。我通常建议学生用以下三页讲透技术深度第一页为什么选原生小程序而非uni-app列对比表格维度原生小程序uni-app本项目选择理由包体积~1.2MB~2.8MB含vue运行时毕设演示需快速加载避免扫码后等待调试体验微信开发者工具断点精准到行HBuilderX断点偶发失效答辩现场演示容错率更高API兼容性wx.openLocation等地图API直连需uni.openLocation适配层会面管理模块依赖原生定位精度第二页时间冲突检测的两种实现与最终选型方案A前端计算拉取用户全部日程在JS中遍历比对——简单但数据量大时卡顿且无法保证并发安全方案BSQL区间查询start_time ? AND end_time ?——利用MySQL索引毫秒级响应服务端强一致最终选择B在答辩时当场演示并发创建两个重叠日程证明后端拦截有效可录屏备用。第三页如何验证“系统可用”而非“代码跑通”列出4项可量化的验收指标登录成功率 ≥ 99.9%模拟100次扫码失败≤1次日程创建平均耗时 ≤ 350msChrome DevTools Network面板截图日历首屏渲染 ≤ 400ms真机录屏秒表计时管理员批量导入1000条用户数据 ≤ 8秒后台日志import finished in X ms提示答辩时不要说“我测试了”要展示“测试过程与结果”。比如拿出1-install.bat执行后的控制台截图箭头标出BUILD SUCCESS拿出2-run.bat启动日志圈出Tomcat started on port(s): 8080。5.2 演示视频脚本156号视频的黄金3分钟结构根据提供的演示视频编号156其脚本应严格遵循“问题-动作-结果”三段式0:00-0:45痛点切入手机录屏打开微信搜索“日程管理”小程序进入后显示空白页“请先登录”提示制造真实感0:46-2:10核心操作扫码登录 → 展示pages/auth/login页面输入测试账号创建日程 → 填写“团队周会”设置时间“明天10:00-11:30”勾选“会面”输入腾讯会议链接查看日历 → 滑动到明日点击日期格子弹出详情页并显示“会议链接可一键复制”管理员视角 → 切换账号进入admin/导入50条测试用户生成近30天日程统计图表2:11-3:00压力验证在pages/schedule/add中故意输入重叠时间点击提交弹出红色提示“时间冲突”返回首页下拉刷新观察日历右上角loading动画持续≤0.5秒结束语“所有功能均通过真机测试源码已按模块注释可直接复现。”5.3 源码交付清单让导师一眼看出工作量与规范性交付的.rar包内文件必须体现工程素养我要求学生按此结构整理【微信小程序毕业设计】个人日程安排系统/ ├── /docs/ # 文档目录必含 │ ├── 需求规格说明书.md # 用例图业务流程图draw.io导出PNG嵌入 │ ├── 数据库设计说明书.md # ER图6张表字段说明含索引标注 │ └── 部署手册.md # 从安装JDK到启动Tomcat的逐条命令含截图位置标记 ├── /frontend/ # 小程序源码微信开发者工具可直接打开 │ ├── app.js / app.json │ ├── pages/ # 按功能分目录非扁平化 │ └── utils/ # calendar.js / request.js 独立封装 ├── /backend/ # Java后端IDEA可直接导入 │ ├── pom.xml # 明确标注spring-boot-starter-web 2.7.18等版本 │ ├── src/main/java/com/example/schedule/ │ │ ├── controller/ # RestController注解清晰 │ │ ├── service/ # Service Transactional标注完整 │ │ └── mapper/ # Mapper注解或XML文件存在 │ └── src/main/resources/application.yml ├── /database/ # SQL脚本含初始化数据 │ └── schedule_db_init.sql # CREATE TABLE INSERT INTO admin/user测试数据 └── /video/ # 演示视频MP4格式命名156.mp4从那以后我每次指导毕设都强制学生在/docs/下先写完三份文档再碰代码——因为文档是思考的具象化而代码只是执行的结果。当导师问“你为什么这样设计”时翻出数据库设计说明书.md里那句“为支持按用户时间范围高效查询建立(user_id, start_time)联合索引”比背诵一百遍理论更有说服力。希望帮到你。本文还有配套的精品资源点击获取