
如果你正在为毕设选题发愁又想避开那些烂大街的“图书管理系统”“学生选课系统”那“基于微信小程序的大学生创新创业训练项目管理系统”确实是个值得考虑的方向。这类项目既有真实的业务背景又覆盖了小程序端、管理后台、后端接口、数据库设计一整条链路展示的时候能讲的东西非常多。我自己在实际带毕设和做项目辅导的过程中一直觉得大创项目管理系统是很典型的“麻雀虽小五脏俱全”的选题——它不复杂但每个环节都能踩到真实的开发问题做完以后你对整个Web小程序项目的理解会上一个台阶。这篇内容我就直接把整套系统的源码设计思路、模块拆分、关键实现、部署踩坑和答辩技巧全部拆开讲。不管你是打算拿这个题目做毕设还是想把它改成校园类管理系统作为项目经历都能从里面找到可以直接落地的方案。1. 项目概述与整体设计思路1.1 这套系统到底解决了什么问题大学生创新创业训练计划也就是常说的“大创项目”在很多高校里都是每年固定要走的流程。学生要发起申报指导老师要审核学院要组织评审学校要做立项公示中期各团队要交进展报告结题时还要验收成果和经费使用情况。没有系统的时候这套流程基本靠邮件、QQ群、Excel表格来回传递一个问题就是版本混乱老师邮箱里躺着十几个“最终版”申报书学院汇总表里同一个项目被改名复制了三次立项名单和结题材料对不上。这套管理系统的核心职责就是把“申报—审核—立项—中期—结题—归档”全部串起来。学生端用微信小程序提交材料老师和管理员在Web后台审核、导出、汇总数据进MySQL按角色控制权限按状态控制流程。对毕设来说这个业务闭环本身就足够撑起完整的架构设计和代码实现不会像普通CRUD那样没有灵魂。1.2 技术选型与架构设计我先说结论再解释为什么这么选。这套系统采用的技术栈是原生微信小程序 Spring Boot MyBatis Plus MySQL Vue3 Element Plus。前端的“小程序端”负责学生和教师的日常操作“Web管理后台”负责学院和校级管理员的批量操作后端统一提供RESTful接口。为什么小程序不用uniapp因为原生小程序对毕设来说足够而且少了编译链的干扰出了问题好排查。uniapp的优势在于多端复用但这个项目明确只需要微信小程序端没必要引入额外复杂度。为什么后端选Spring Boot而不是Node或Python因为高校毕设里Spring Boot的资料最多、面试认可度高、生态成熟而且作为Java学生用Spring Boot写接口基本是必备技能。数据库选MySQL免费、稳定、文档多配合MyBatis Plus可以减少写SQL的工作量。架构上分为三层小程序端、管理后台端、后端服务端。三者通过HTTP接口通信小程序端和管理后台共用同一套API只是页面和权限不同。后端按Controller-Service-Mapper三层分包每个角色一个权限维度每个业务流程对应一组状态机。整体设计追求的是“逻辑清晰、便于答辩讲解”而不是堆叠花哨技术。我个人的建议是毕设项目宁可技术栈朴实也要把业务逻辑做完整。答辩老师最怕听到你说“这个模块用了某某新框架”但一问业务流转就答不上来。Spring Boot Vue3 微信小程序这套组合足够交出一份体面的毕设。1.3 角色权限与业务闭环系统的角色分为四类学生、指导教师、学院管理员、校级管理员。如果需要还可以加一个“评审专家”角色用于院级评审阶段打分不过会让流程复杂不少毕设的话可以做成可选模块。角色核心操作数据范围学生填写申报书、上传附件、提交立项、提交中期/结题材料、查看审批进度本人及其项目的全部数据指导教师审核学生申报、确认指导关系、查看所带项目进展名下学生项目学院管理员审核本学院申报、导出汇总表、分配评审、管理本学院用户本学院数据校级管理员发布通知、校级立项、结题审核、全局统计、账号管理全系统数据权限控制我建议走RBAC模型用户表关联角色表再通过角色关联菜单和操作权限。但这里不必做太复杂的权限框架毕设能用拦截器注解实现“接口级权限控制”就够了展示的时候反而更容易讲明白。比如后端定义一个RequireRole(admin)注解拦截器里校验当前用户角色后决定是否放行代码简单演示直观。2. 核心业务模块与数据建模2.1 大创项目全流程状态设计大创项目的核心不是增删改查而是状态流转。我把整个项目生命周期拆成了以下状态每个状态对应一个操作动作每个动作又规定了可执行的角色。当前状态操作下一状态执行角色草稿提交申报待导师审核学生待导师审核通过待学院审核导师待导师审核退回草稿导师待学院审核学院通过待校级立项学院管理员待学院审核学院退回草稿学院管理员待校级立项立项通过立项已通过校级管理员立项已通过提交中期材料中期待审核学生中期待审核中期审核通过中期已通过校级管理员中期已通过提交结题材料结题待审核学生结题待审核结题通过已结题校级管理员这个状态机是整套系统的灵魂。在设计数据库时项目表里用一个status整型字段来记录当前状态同时在项目状态历史表里记录每次流转的时间点和操作人。你会发现只要状态机定义清楚后端Service层的代码就非常结构化基本就是switch (status)判断当前状态允许哪些操作然后执行对应的状态更新和审计记录。2.2 数据库表设计心得数据库是这个项目的重头戏答辩时老师大概率会翻你的表结构。我按模块把主要表列出来sys_user用户表字段包括openid、学号/工号、姓名、角色ID、所属学院、手机号、密码。sys_role角色表角色编码如student、teacher、college_admin、school_admin。project项目申报表字段包括项目名称、项目类型创新训练/创业训练/创业实践、负责人ID、指导教师ID、所属学院、项目简介、经费预算、当前状态。project_member项目成员表存放团队成员一个项目对应多条成员记录。project_file附件表记录申报书、中期报告、结题报告等文件的存储路径、上传人、上传时间、文件类型。project_log审批日志表记录谁在什么时间把项目从哪个状态变更为哪个状态以及审批意见。notice通知公告表管理员发布的通知。dict_data字典表用于存放项目类型、学院列表这类可扩展的枚举数据。字段设计上有几个实操建议。第一所有表都加create_time、update_time、deleted这三个字段前者方便排序和审计后者做逻辑删除防止误删数据后无法恢复。第二不要过度使用外键MyBatis Plus本身不推荐物理外键业务层保证数据一致性足够了。第三状态字段用整数而不是字符串比如0草稿、1待导师审核、2待学院审核这样排序和条件查询效率更高代码里定义常量或枚举类即可。2.3 附件管理与文件上传方案大创项目必然涉及文件申报书Word或PDF、中期报告、结题报告、成果图片。这部分我建议做一个统一的文件上传接口小程序端和后台共用上传后返回文件ID业务表里保存文件ID关联。文件存储位置毕设阶段直接用本机磁盘目录最省事。在配置文件里定义一个upload.path比如/data/uploads后端用MultipartFile接收文件后写入该目录文件名用UUID重命名避免中文名和重复名的问题。为了安全文件访问单独映射一个静态资源路径比如/files/**前端通过拼接URL访问。这里踩过一个坑很多人把文件直接放在项目的resources/static目录下重启服务文件就丢了或者打包后找不到路径。正确的是把上传目录配置在外部磁盘路径和项目代码分离。部署时只要保证这个目录有读写权限就行。如果你后续想上云把本地存储换成OSS也就是替换一个接口实现的事情不影响业务代码。3. 微信小程序端实现要点3.1 小程序工程结构与页面规划原生微信小程序的工程结构很清晰我习惯按下面的方式组织miniprogram/ ├── pages/ # 所有页面 │ ├── login/ # 登录页/手机号绑定 │ ├── home/ # 首页项目列表、快捷入口 │ ├── apply/ # 项目申报填写页 │ ├── detail/ # 项目详情/审批记录页 │ ├── profile/ # 个人中心 │ └── webview/ # 加载后台公告详情 ├── components/ # 自定义组件 ├── api/ # 接口请求模块按业务域拆分 ├── utils/ # 工具函数 ├── app.js # 全局逻辑 ├── app.json # 全局配置 └── app.wxss # 全局样式页面不需要太多能跑通核心流程就好。首页建议做成“工作台”风格学生看到的是“申报项目”“我的项目”两个核心入口老师看到的是“待我审核”“我的学生项目”管理员看到的是“待办审批”和“数据看板”。这样不同角色登录后首屏差异明显答辩演示时一眼就能看出系统的角色化设计。打包体积方面要注意小程序主包限制2MB如果图片资源多一定要把大图传到服务器本地只保留图标类小图。后期如果功能膨胀可以使用分包加载把“申报填写页”这类低频页面放到分包里。这是小程序开发的热门考点能在答辩时主动讲出来是很好的加分项。3.2 登录体系与用户身份绑定小程序端我采用的是“微信授权登录 手机号绑定”两段式登录。用户点“微信一键登录”时前端调用wx.login()拿到临时code传给后端后端再调用微信的code2Session接口换取openid和session_key。这里有个关键点openid是一个用户在小程序下的唯一标识但只有openid还不够系统需要知道这个微信用户对应哪个学号的学生所以第一次登录时要引导用户完成学号绑定或者在登录页提供手机号一键获取并自动匹配账号。手机号快速验证组件是目前比较推荐的做法用户点击按钮授权手机号前端拿到手机号后传给后端后端拿手机号去用户表查询并绑定openid。这样用户体验最顺滑而且手机号是高校系统里比较常用的账号标识。但要注意手机号获取能力需要企业主体小程序个人主体无法使用毕设阶段如果不想申请也可以直接用“学号密码”的登录方式把微信登录作为一个辅助入口。后端拿到openid后不要直接信任它作为登录凭证。我的做法是首次登录成功后生成一个自定义token比如JWT里面包含用户ID和角色返回给小程序端。小程序每次请求都在header里带上Authorization: Bearer token后端拦截器校验token并解析用户信息这样就不需要每次都查微信接口了。3.3 接口层封装与请求拦截小程序请求封装是每个项目都必须做好的基础工作。我在api/request.js里封装了一个request函数统一管理baseURL、超时时间、token注入和错误提示。核心思路是请求前从wx.getStorageSync(token)读取token加到header里收到响应后先判断HTTP状态码再判断业务状态码业务码为401时说明token过期清空本地登录态并跳转登录页其他业务错误统一wx.showToast提示。const request (url, method GET, data {}) { const token wx.getStorageSync(token) return new Promise((resolve, reject) { wx.request({ url: ${BASE_URL}${url}, method, data, header: { Content-Type: application/json, Authorization: token ? Bearer ${token} : }, success: (res) { if (res.data.code 200) { resolve(res.data.data) } else if (res.data.code 401) { wx.removeStorageSync(token) wx.reLaunch({ url: /pages/login/login }) reject(res.data) } else { wx.showToast({ title: res.data.message, icon: none }) reject(res.data) } }, fail: (err) reject(err) }) }) }这里还有两个容易忽略的点。第一表单提交要防重复点击提交按钮加loading状态请求期间禁止二次点击否则数据库里会出现两条重复的申报。第二列表页要考虑分页加载小程序端用onReachBottom触底加载下一页配合后端的MyBatis Plus分页插件简单又可靠。3.4 导航栏高度适配与UI细节小程序顶部导航栏高度适配是很多新手容易翻车的地方尤其当你要做自定义导航栏时。默认导航栏是系统渲染的不用管高度但很多项目为了视觉效果会自定义导航栏这时就需要动态获取状态栏高度和胶囊按钮位置。常见的适配方案是在app.js里调用wx.getSystemInfoSync()拿到statusBarHeight再调用wx.getMenuButtonBoundingClientRect()拿到胶囊按钮的位置信息两者结合计算出导航栏的实际高度。const systemInfo wx.getSystemInfoSync() const menuButton wx.getMenuButtonBoundingClientRect() const navBarHeight (menuButton.top - systemInfo.statusBarHeight) * 2 menuButton.height算出来的navBarHeight是自定义导航栏的总高度页面里用这个值设置占位View的高度。这样无论是刘海屏还是普通屏顶部布局都不会错位。这个适配代码建议封装成全局工具函数所有页面复用。UI细节上表单页要注意输入框的cursor-spacing属性避免键盘弹起时遮挡输入框。长列表要设置optimized或使用虚拟列表的思路减少渲染卡顿。这些都是小程序面试和答辩时能拿得出手的细节经验。4. 后端服务与管理系统后台4.1 后端分层与接口规范后端工程我按标准的三层结构组织controller处理请求参数和响应service处理业务逻辑mapper负责数据库操作另外有entity实体类、dto数据传输对象、vo返回视图对象。这里要特别强调一下DTO和VO的使用接收前端参数不要直接绑定实体类返回前端数据也不要直接暴露实体类。比如申报接口接收的是一个ProjectApplyDTO它包含申报表单字段但不会包含createTime、deleted这些字段返回给前端的是ProjectVO它额外包含“负责人姓名”“指导教师姓名”这种关联展示字段。这样做的目的是防止接口参数和数据库字段过度耦合后端逻辑改起来更安全。接口路径设计上我建议采用RESTful风格比如POST /api/project/apply提交项目申报GET /api/project/list按条件分页查询项目POST /api/project/audit审核项目审核动作统一走这个接口通过参数区分是导师审核还是学院审核GET /api/project/{id}查询项目详情GET /api/project/{id}/logs查询项目的审批记录统一响应结构也很重要。我定义了一个ResultT类包含code、message、data三个字段。code200表示成功code400表示参数错误code401表示未登录或token失效code500表示服务端异常。前端封装层只需要统一判断code即可不用针对每个接口单独写错误逻辑。4.2 Spring Boot关键配置解析application.yml里最核心的配置是数据源、MyBatis Plus和文件上传路径。我贴一个自己常用配置片段spring: datasource: url: jdbc:mysql://localhost:3306/innovation_project?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/Shanghai username: root password: 123456 servlet: multipart: max-file-size: 20MB max-request-size: 50MB mybatis-plus: global-config: db-config: logic-delete-field: deleted logic-delete-value: 1 logic-not-delete-value: 0 configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl upload: path: /data/uploads有几个点必须说清楚。第一serverTimezoneAsia/Shanghai一定要加否则MySQL连接会报时区错误或者时间字段存进数据库后差8小时。第二MyBatis Plus的逻辑删除配置只要加到全局所有表的deleted字段都会自动生效不需要在每个Mapper里单独写where deleted0。第三开发环境下开启SQL日志StdOutImpl排查问题时能看到完整SQL但上线前记得关掉。跨域问题也要处理因为小程序端请求不受浏览器同源策略限制但Vue后台运行在http://localhost:5173后端运行在http://localhost:8080两者端口不同存在跨域。我在后端写了一个全局CORS配置类放行了所有来源这样开发时省心。上线后如果域名固定可以再收紧。4.3 Vue3后台管理页面实战后台管理端我用Vue3 Vite Element Plus Pinia Vue Router搭建。登录页调后端登录接口成功后保存token到localStorage路由守卫里判断未登录就跳转登录页。页面规划按角色拆分。管理员登录后左侧菜单包括“项目审批”“项目管理”“用户管理”“通知管理”“数据统计”。项目审批页是核心用表格展示待审批项目点击“详情”弹抽屉查看申报书和附件点击“通过”或“退回”填写审批意见。这里有个交互上的建议审批意见不要用alert或messageBox的简单输入框而是做一个抽屉式审批表单因为学院管理员经常要填写较长意见弹窗里写长文本体验不好。表格列设计上我推荐展示项目名称、负责人、学院、项目类型、申请时间、当前状态、操作列。默认状态筛选项为“待导师审核/待学院审核/待校级立项”让管理员一进来就看到待办事项。导出功能可以用EasyExcel或前端exceljs毕设阶段我更推荐前端导出因为不需要额外向后端要数据接口直接对当前表格数据做导出即可演示效果直观。用户管理页要注意数据脱敏手机号不能明文展示全号中间四位用星号代替。这个细节虽然不起眼但很能体现开发者的数据安全意识答辩时讲出来是加分项。4.4 数据统计与可视化展示“数据统计”模块是让系统看起来完整的点睛之笔。我做了三个维度立项数量按学院分布、项目类型占比、年度立项趋势。后端在/api/statistics/overview接口里返回汇总数据前端用ECharts展示柱状图和饼图。统计SQL不算复杂主要用到GROUP BY。比如按学院统计立项项目数SELECT college_name, COUNT(*) AS project_count FROM project WHERE status 4 AND deleted 0 GROUP BY college_name小程序端如果要展示统计可以用ec-canvas组件但我建议把复杂图表放在Web后台小程序端只展示简单的进度卡片和待办数量。因为小程序包体积有限引入图表库要谨慎而且手指上滑动看图表的体验远不如电脑端。ECharts图表在Vue3项目中的适配是容易出问题的地方。记得要用echarts的按需引入只引入饼图、柱状图、组件和渲染器否则打包体积会很大。初始化图表时放在onMounted里并且要处理窗口尺寸变化时的resize事件。5. 从零到一跑通整套系统5.1 本地开发环境准备在开始写代码前先把环境准备好避免中途才发现版本不匹配。我建议的版本组合是JDK 8或17、MySQL 8.0、Node.js 18、微信开发者工具稳定版、Maven 3.6。数据库用Navicat或DataGrip连接都行。第一步在MySQL里创建数据库。因为系统涉及多表关联我直接提供一份init.sql脚本包含建库、建表、插入初始管理员账号和数据字典。执行脚本后数据库中会有一个默认的校级管理员账号admin/admin123方便第一次登录后台。这里要注意MySQL的字符集建库时统一使用utf8mb4否则存不了生僻字和表情符号。后端启动前要修改application.yml里的数据库账号密码确保和本机一致。前端后台项目要先执行npm install安装依赖然后npm run dev启动开发服务器。小程序端在微信开发者工具里导入项目目录填写自己的AppID如果没有账号可以用测试号。5.2 后端与后台启动步骤启动顺序上先启动MySQL再启动后端服务最后启动Vue后台和小程序。Spring Boot项目在IDEA里直接运行main方法即可或者用命令行mvn spring-boot:run。启动成功后浏览器访问http://localhost:8080/api/ping应该能看到接口返回成功信息。Vue3后台启动后通常跑在http://localhost:5173。因为后端接口不是同一个端口我建议在Vite配置里设置代理把所有/api路径的请求转发到http://localhost:8080这样前端代码里请求地址写/api/xxx即可不用写完整地址。生产部署时直接构建前端静态文件放到Nginx里同样通过Nginx反向代理后端接口。这里有一个很关键的配置点微信小程序端的baseURL不能写localhost因为真机预览时localhost指向的是手机本身而不是你的电脑。开发时用微信开发者工具的“不校验合法域名”选项可以临时用局域网IP访问后端比如http://192.168.1.100:8080。真机调试时手机和电脑必须在同一个局域网内。5.3 小程序端联调与真机预览小程序端联调的过程我建议按“登录→首页→列表→详情→提交”的顺序走。先验证登录接口能否拿到token再看首页的待办数量是否准确然后测列表分页、详情回显最后重点测项目申报的完整流程。真机预览前要进入微信开发者工具的“详情-本地设置”勾选“不校验合法域名、web-view业务域名、TLS版本以及HTTPS证书”。这是开发调试的关键开关不加这个勾所有请求都会被拦截。真机预览时手机会通过二维码加载项目首次加载会比较慢属于正常现象。预演答辩时我建议准备两台设备一台电脑打开Web后台一台手机打开小程序。演示流程可以是用学生账号在小程序里提交一个申报项目切换到老师账号审核再切换到学院管理员审核最后校级管理员立项。这套完整流程走下来比单独展示某个页面有说服力得多。5.4 上线部署前要准备的事如果这套系统要真正上线使用有几个硬性条件绕不开。第一注册微信小程序账号。个人主体可以注册但像微信支付、手机号快速验证这类功能个人主体用不了。如果用学校主体注册需要提供学校资质材料流程会慢一些。当前主体注册认证的费用规则请以微信公众平台官方说明为准。第二域名和备案。正式小程序要求所有请求域名必须是HTTPS且已备案而且微信公众平台里要配置request合法域名。毕设演示阶段不一定需要上线但如果你想写成“已部署上线”这些是必备条件。第三HTTPS证书。如果服务器用Nginx可以申请免费的SSL证书配置好HTTPS后在小程序后台添加域名白名单。但要注意开发者工具里勾选“不校验合法域名”只在开发阶段有效正式版小程序会强制校验。对于毕设场景我的建议是不需要真实上线只要能在本地完整跑通流程即可。答辩时主动说出“生产环境需要配置HTTPS域名当前演示环境做了本地部署”老师完全能理解反而觉得你对上线流程有概念。6. 常见问题与排查技巧实录6.1 高频报错与解决方案速查我把实际开发中遇到的高频问题整理成一张速查表每个问题都是真实踩过的。问题现象可能原因解决方案登录时调用code2Session报40029code过期或已被使用wx.login()返回的code五分钟内有效且只能用一次重新调用wx.login()获取新code登录报40013AppID无效检查小程序后台的AppID与开发者工具中的AppID是否一致后端接口返回中文乱码数据库连接未指定UTF-8url参数增加useUnicodetruecharacterEncodingutf8上传文件后访问404静态资源映射未配置Spring Boot增加WebMvcConfigurer把上传目录映射到/files/**时间字段保存后差8小时JDBC时区未指定serverTimezoneAsia/Shanghai替换原来的UTC小程序真机预览请求失败使用了localhost或未开启域名校验改用局域网IP并在开发者工具勾选“不校验合法域名”列表数据重复分页参数传递错误或提交按钮重复点击检查pageNum、pageSize参数提交按钮加loading防重复Vue后台登录后刷新失效token未持久化到localStorage登录成功后将token存入localStorage路由守卫从localStorage读取这里我要特别强调一下code2Session的40029问题。很多初学者会把wx.login()写在app.js的onLaunch里然后页面登录时又调一次导致第一个code被消费后第二个已经失效。正确的做法是只在用户主动点击“微信登录”按钮时调用wx.login()不要在全局生命周期里自动调用。6.2 容易被忽略的设计细节第一件容易被忽略的事是数据库字段命名避免关键字。有些同学把项目表命名为project没问题但字段名用了describe、level这种MySQL关键字导致SQL上报错。建议字段命名用project_desc、audit_level这样的组合词既能避开关键字又清晰。第二件是状态机的并发控制。如果学生在“待导师审核”状态下连点两次“撤回”按钮后端要做状态校验不能简单地update status草稿。正确的顺序是先查出当前项目状态判断是否等于“待导师审核”不等于就返回“当前状态不可操作”。简单说就是“先查后改”避免状态被覆盖。第三件是文件上传的目录权限。Linux服务器上如果上传目录没有写权限会报Permission denied而且这个错误往往要到生产环境才暴露。部署前先mkdir -p /data/uploads并chmod 777或者给运行用户授权免得演示时当场翻车。第四件是用户表里不要明文存密码。虽然很多毕设系统都存明文但如果你用了“学号密码”登录最好用BCrypt加密存储。答辩时老师只会问“密码怎么存的”回答“BCrypt加密不可逆”和“明文存储”是两个层次的印象。6.3 毕设演示时的加分技巧最后聊点答辩层面的经验。作为一个带过不少毕设项目的人我发现在演示大创管理系统时有几个细节特别容易加分。第一准备多角色测试账号。在“用户管理”页面里提前创建好学生账号、指导老师账号、学院管理员账号、校级管理员账号。演示时直接切换登录省得现场演示还要现注册。我通常在演示账号里放一组完整数据一条“草稿”状态的项目、一条“待导师审核”的项目、一条“立项已通过”的项目这样每个状态和操作都有数据可用。第二现场演示完整流程。从学生提交申报开始一路审批到立项。这一套流程走完系统的核心价值就讲透了比讲一百页PPT都有效果。注意演示前把网络调试好小程序真机和后端服务的IP要提前确认别等到答辩现场再找。第三主动讲设计取舍。比如答辩老师问“为什么不用uniapp”你就说“多端需求不明确原生小程序性能更好且排障简单”问“为什么不用Redis做缓存”你就说“当前并发和访问量不大MySQL足够支撑引入Redis会增加部署复杂度”。这种取舍式的回答比单纯说“我不会”或“老师教的”要高级得多。第四代码结构要能随手翻到。答辩时老师很可能会现场打开你的代码目录看包结构所以分包一定要命名清晰。controller、service、mapper、entity、dto、vo这些目录名称一定要规范不要让老师在你的工程里“寻宝”。最后想说的一点体会做完整套系统后我个人最大的体会是毕设项目的核心不在于功能多炫而在于逻辑能闭环。一个学生提交申报后数据经过导师审核、学院评审、校级立项每一步都有迹可循最终归档到结题材料——这套完整、自洽的业务流正是这套源码最值钱的地方。如果你也打算做类似的校园管理系统先把业务流程钻透再动手写代码后面的路会顺很多。项目做完之后可以把审批流程的配置改成通用模块以后接其他校内业务系统换一张审批表和几个状态枚举就能快速复用了。