☰
SpringBoot2+Vue3教师工作量管理系统:从手工台账到在线审核
2026/10/14 7:10:56 网站建设 项目流程

每年学期末都是教务口最焦灼的时候。我接触过好几所学校的教务管理系统改造,教师工作量核算这件事,几乎每个学校都有自己的“土办法”,而且几乎每个土办法都带着同样的毛病——几十个Excel文件来回传,版本对不上,计算公式全靠人工心算,审核流程说不清楚。今天要聊的这个Java Web教师工作量管理系统,就是用SpringBoot2 + Vue3 + MyBatis-Plus + MySQL8.0这套组合,把“手工台账”变成“在线化流程”的一套完整落地项目。它解决的问题很具体:教师在线填报工作量、系统按规则自动计算、系部和教务两级审核、全程留痕可追溯。对正在做毕业设计、练手项目,或者想给学校信息化建设打样的开发者来说,这套系统的设计思路和源码结构都很有参考价值。下面我会按照实际开发的顺序,把技术选型的原因、数据库设计、核心业务逻辑、前端实现和部署踩坑完整捋一遍。

1. 为什么需要一个在线教师工作量管理系统:从Excel台账说起

1.1 手工统计的三个典型痛点

先还原一下场景。某高校的教务处,每学期末要收集全校各系部教师的工作量数据。系部教学秘书把表格发到微信群里,老师们下载填写,再打包发回来。你只要做过一次就知道,这种方式的坑简直是“连环雷”。

第一个痛点是版本混乱。“工作量统计表-最终版.xlsx”“工作量统计表-改3.xlsx”“工作量统计表-千万别动这个版本.xlsx”……同一个学期能出现七八个版本,最后汇总的人根本不知道哪份是准的。第二个痛点是公式不透明。不同系部的计算方法不一样,有的按课时乘系数,有的按课程类别单独计分,审核人核对的时候要拿计算器一项项算,速度慢还容易错。第三个痛点是追溯困难。某位老师对计算结果有异议,想查当初申报时填的是什么,审核人是谁、改了什么,Excel里完全没有记录,只能翻聊天记录。

这三个痛点本质上都指向同一件事:工作量核算不仅是一个“统计动作”,更是一个“管理流程”。流程就意味着要有提交、审核、驳回、归档这些环节,每一环都要留痕。而Excel完全承载不了这种流程。

1.2 系统顶层设计的四个核心诉求

在动手写代码之前,梳理清楚“系统要解决什么”比选技术栈更关键。我当时给这个项目定的目标是四个词:可填报、可审核、可计算、可追溯。

可填报,指的是教师端要有清晰的申报界面,按教学工作量、科研工作量、管理服务工作量分类填写,支持附件佐证。可审核,指的是系部负责人和教务处管理员能分级审批,审核通过的才能进入统计。可计算,指的是系统要把课时、系数、折算标准这些规则配置化,前端填报后后端自动算分,不需要人工计算器。可追溯,指的是每一次提交和审核都要写入日志表,谁在什么时间做了什么操作,全部可以查。

这四个诉求直接决定了后面的数据库表结构和接口设计。你要知道,这四件事做扎实了,这个系统就算换一套技术栈重新实现,核心骨架也不会变。反过来说,如果一上来就纠结“用Vue2还是Vue3”“用不用Redis”,那大概率会做成一个界面好看但业务无法落地的花架子。

2. 技术选型的真实考量:为什么是SpringBoot2+Vue3+MyBatis-Plus+MySQL8.0

2.1 后端选型:SpringBoot2是当前最稳的“基本盘”

很多人在SpringBoot2和SpringBoot3之间纠结。这个项目我选了SpringBoot2,主要原因是生态兼容性。MyBatis-Plus对SpringBoot3的官方适配在早期并不完善,很多第三方库、代码生成器、文档示例都还是基于SpringBoot2的写法。对于管理系统这类业务密集型项目,我们追的不是新特性,而是稳定和资料齐全。

SpringBoot2.7.x这条线,嵌入的Spring Framework 5.3.x足够成熟,内置Tomcat、参数校验、统一异常处理这些能力完全够用。而且网上能找到的海量教程、踩坑记录都是这个版本,遇到问题基本上搜索一下就能解决。做管理系统,最怕的是“框架版本太新导致没人踩过坑”,所以选SpringBoot2是务实的决定。

2.2 ORM选型:MyBatis-Plus把CRUD效率拉满

MyBatis-Plus这个库,说它是“为管理系统而生的ORM”不过分。内置的BaseMapper提供了insert、deleteById、selectById、selectPage这些现成方法,写单表操作基本不用手写SQL。最常用的几个功能在本项目里的价值很大:

  • 分页插件:工作量申报列表、审核列表都需要分页,PaginationInnerInterceptor一配上,Page对象直接用。
  • 条件构造器:LambdaQueryWrapper写起来比拼接SQL安全多了,比如按学期筛选、按教师姓名模糊查询,代码干净且没有SQL注入风险。
  • 代码生成器:从数据库表自动生成实体类、Mapper接口、Service,虽然是老生长谈,但对管理系统来说能省掉大量重复劳动。

业务复杂的地方,比如多表联查、统计报表,仍然可以手写XML SQL。MyBatis-Plus并不排斥自定义SQL,它照顾的是80%的简单CRUD,剩下的20%交还给原生MyBatis能力,这个分寸感很重要。

2.3 前端选型:Vue3+Vite+Element Plus的组合拳

前端为什么选Vue3而不是继续守着Vue2?因为Vue3的组合式API(Composition API)在管理系统的开发体验上提升明显。一个工作量申报页面,涉及表单数据、校验规则、附件列表、计算结果显示,用Options API写,逻辑容易散在data、methods、watch里,而用setup函数可以按业务维度组织代码,比如“申报逻辑”一块、“计算逻辑”一块,维护起来清楚很多。

构建工具用Vite不是Webpack,最大的感受就是冷启动快。管理系统规模不算大,Webpack的打包速度尚可,但开发时改一行代码的HMR热更新,Vite几乎是秒级,Webpack有时候要等两三秒,你来我往之间,一天的开发效率差距就很明显了。

组件库选Element Plus,因为它就是为后台管理系统量身定制的。表格的筛选、排序、分页,表单的校验、动态增减,这些都是管理系统的刚需,Element Plus开箱即用,不需要自己造轮子。项目里我配合了Pinia做状态管理,主要存登录用户信息、角色权限列表,以及申报表单的临时状态。

2.4 数据库选型:MySQL8.0带来的实用能力

MySQL8.0相比5.7,在这个项目里最常用的新特性是窗口函数和公用表表达式(CTE)。做统计报表的时候,比如按院系统计各教师工作量的排名,用ROW_NUMBER()窗口函数一条SQL就能搞定,不用在Java代码里做一堆循环分组。另外8.0的JSON类型也很实用,比如工作量申报的附件信息、审核意见的多条记录,虽然我拆了独立表,但一些弹性字段用JSON存方便很多。

字符集方面,MySQL8.0默认就是utf8mb4,emoji和生僻字都能存,不用像5.7那样建库时还要手动指定。这虽然是小事,但对有非中文字符需求的系统来说,能少踩一个经典的“中文乱码坑”。

技术组件选型理由替代方案对比
SpringBoot2.7生态成熟、资料丰富、与周边库兼容稳定SpringBoot3新特性多,但部分库适配晚
MyBatis-Plus内建CRUD与分页插件,开发效率高JPA上手快但复杂查询不直观;纯MyBatis灵活但样板代码多
Vue3 + Vite组合式API组织业务逻辑清晰,HMR快Vue2生态老,Webpack启动慢
MySQL8.0窗口函数、CTE、JSON类型实用5.7没有窗口函数,统计报表SQL写起来繁琐

看到这里你应该能感觉到,这套选型没什么“炫技”的成分,每一样都是冲着管理系统的实际开发效率去的。对刚入门或者做毕设的同学来说,照着这个组合走,踩坑面是最小的。

3. 数据模型设计:一个“申报+审核”为核心的表结构方案

3.1 五大基础表的职责划分

数据库设计决定了一个业务系统能走多远。教师工作量管理系统,我拆成了五大基础域:用户权限域、工作量申报域、审核流程域、规则配置域、日志审计域。

用户权限域相对常规,一张sys_user表存登录账号、姓名、所属院系、角色编码,角色就四种:ROLE_TEACHER(教师)、ROLE_DEPARTMENT(系部审核员)、ROLE_ADMIN(教务处管理员)、ROLE_SYSTEM(系统管理员)。RBAC(基于角色的访问控制)模型足够,不需要做更细的权限点控制。

工作量申报域是核心。一张teacher_workload表作为主表,字段包括:申报人ID、所属院系、学期、工作量类别(教学/科研/管理服务)、工作量标题、工作量描述、自评分、折算状态、审核状态、附件ID列表。考虑到“一键生成个人汇总”这类需求,我建议主表拆分出明细表workload_item,一条申报对应多条明细,比如“教学工作量”可以有多门课程,每门课一行明细,这样总量统计和单项审核都方便。

审核流程域不是简单加一个status字段就完事,而是单独建了一张audit_record表。字段包括主表ID、审核人ID、审核动作(提交/通过/驳回)、审核意见、审核时间。这样设计的核心价值在于:审核历史可以完整还原。某个老师的工作量被驳回了,他能看到谁驳的、为什么驳。教务处年终汇总时,也能统计每个审核人的处理数量。

规则配置域是为了把“计算逻辑”从代码中剥离出来。我设计了workload_rule表,字段包括工作量类别、子类编码、计量单位、换算系数、是否启用。系统管理员可以在页面上调整系数,比如“理论课时系数1.0,实验课时系数0.8”,调整后新申报单自动按新规则计算,旧申报单保存的是计算快照,互不影响。

日志审计域用作兜底。简单的操作日志表记录关键操作,比如登录、提交申报、审核通过、导出数据。这部分属于“平时没用,出事救命”的模块,不做的话,后期排查问题只能靠猜。

3.2 主从表设计:工作量申报为什么不搞“一张大表”

有同学会问,为什么不把所有字段塞到一张表里?比如把课程名、课时、系数都放在申报主表里。我建议拆主从表的原因有三个。

第一,工作量差异太大。教学工作量要有课程名、学时、课程性质、学生人数;科研工作量要有成果类型、成果等级、承担角色。这些字段差异很大,塞进一张大表会有大量冗余空字段。第二,审核粒度更细。教务处很可能只对某一条课程明细提出异议,而不是驳掉整个申报。拆了明细表,审核就能精确到行。第三,扩展性好。明年可能新增“社会服务工作量”,只需要往明细表加类型,不需要改主表结构。

建表的时候有几个字段我建议大家都加上:is_deleted逻辑删除标记、create_time和update_time自动填充。MyBatis-Plus的自动填充功能配合@TableField(fill = FieldFill.INSERT)注解,插入时自动写创建时间,更新时自动写修改时间,省心很多。逻辑删除用@TableLogic注解,查询时自动过滤已删除数据,防止误删真数据。

3.3 索引设计与查询路径

这个系统查询最频繁的是两类接口:教师个人申报列表和审核人待办列表。个人列表的查询条件通常是user_id + semester + workload_type,所以建一个联合索引idx_user_semester_type,顺序是(user_id, semester, workload_type)。审核人待办列表的查询条件是audit_status + department_id + semester,对应建idx_status_dep_semester。

索引不是越多越好,写多读少的表要克制。比如audit_record表,查询基本都带着workload_id,一个普通索引就够了,多余的索引只会拖慢INSERT速度。很多人忽略这一点,最后索引建了一堆,数据库写入变慢,其实是得不偿失。

4. 后端核心逻辑拆解:计算规则、状态机与批量导入

4.1 工作量计算规则如何用代码表达

工作量计算是系统的“心脏”。规则设定大致如下:

  • 教学工作量 = 课程学时 × 课程类别系数 × 班型系数
  • 科研工作量 = 成果基础分 × 承担角色系数
  • 管理服务工作量 = 岗位基础分 × 学期考核系数

这些规则我放进了workload_rule表,而不是写死在Java代码里。后端计算时,先从规则表查出当前学期启用的规则集,缓存到本地Map,然后遍历明细表逐行计算。以教学工作量为例,伪代码如下:

// 查询当前学期启用的规则,key为子类编码 Map<String, WorkloadRule> ruleMap = getRuleMap(semester, workloadType); for (WorkloadItem item : itemList) { WorkloadRule rule = ruleMap.get(item.getSubType()); if (rule == null) { // 未配置规则时记录错误,拒绝提交 continue; } // 教学工作量 = 课时 * 类别系数 * 班型系数 BigDecimal amount = item.getHours() .multiply(rule.getCategoryFactor()) .multiply(item.getClassFactor()); item.setCalculatedAmount(amount.setScale(2, RoundingMode.HALF_UP)); }

注意两点:一是计算用BigDecimal而不是double,避免浮点运算精度丢失;二是提交前计算一次并保存快照到明细表的calculated_amount字段,审核人和老师看到的是一个“冻结”的结果。就算管理员后面改了规则系数,历史申报单的得分也不受影响,这是业务上很重要的一致性保证。

4.2 审核状态机的设计:草稿、提交、系部审核、教务审核、归档

审核流程我设计成了五态模型:DRAFT(草稿)、SUBMITTED(已提交)、DEPT_APPROVED(系部通过)、DEPT_REJECTED(系部驳回)、ADMIN_APPROVED(教务通过)、ADMIN_REJECTED(教务驳回)、ARCHIVED(已归档)。

这组状态看起来多,实际上流转路径很清晰:教师从DRAFT发起提交进入SUBMITTED;系部审核员在SUBMITTED状态下有权通过或驳回;通过后进入DEPT_APPROVED,教务处管理员继续审核;如果系部驳回了,回到DRAFT,教师修改后可再次提交;教务通过后进入ADMIN_APPROVED,最终学期结束后由系统管理员执行归档操作进入ARCHIVED。

实现时我在后端写了一个状态机工具类,核心是一个Map维护“当前状态-允许的下一个状态”关系,而不是散落一地的if-else。比如:

private static final Map<Integer, Set<Integer>> ALLOWED_TRANSITIONS = new HashMap<>(); static { ALLOWED_TRANSITIONS.put(DRAFT, Set.of(SUBMITTED)); ALLOWED_TRANSITIONS.put(SUBMITTED, Set.of(DEPT_APPROVED, DEPT_REJECTED)); ALLOWED_TRANSITIONS.put(DEPT_APPROVED, Set.of(ADMIN_APPROVED, ADMIN_REJECTED)); // ... }

这样做的最大好处是,非法状态流转会直接抛异常,而不是静默失败。比如教师把已归档的申报单再提交,状态机直接拦截,谁都没办法绕过流程乱操作。

4.3 批量导入Excel数据的事务边界

除了在线填报,系统还支持教务管理员批量导入课时数据。比如从教务系统导出一张全院课表Excel,按教师姓名匹配后批量生成申报草稿。Excel导入用了EasyExcel库,读取流程分三步:校验表头模板、逐行校验数据合法性、按批次写入数据库。

这里最容易出问题的是事务边界。一次性导入几千行,如果全部包在一个大事务里,某一行出错会导致整个批次回滚,用户还得从头再来。我的做法是把“校验”和“写入”分开:先全量校验Excel内容,把错误行汇总成列表返回给前端;只有校验全部通过,才进入写入阶段。写入阶段按100行一个批次提交,每个批次独立事务。这样即使写入中段出现数据库异常,失败也只会影响当前批次,前面成功的批次不受影响。日志里记录清楚每个批次的起止行号,排查具体是哪条数据有问题就很容易。

4.4 权限控制方案:Spring Security + JWT的落地写法

这个系统的后端接口权限控制,我用的是Spring Security + JWT的组合。登录接口放行静态资源,其余接口按角色加注解。实现方式是在Spring Security的过滤链里配置JWT认证过滤器,解析请求头里的Token,把用户ID和角色塞进SecurityContext,然后在Controller方法上用@PreAuthorize("hasRole('TEACHER')")这类注解做精细控制。

举两个例子:

@PostMapping("/workload") @PreAuthorize("hasRole('TEACHER')") public ApiResult<Void> submit(@RequestBody @Valid WorkloadSubmitDTO dto) { // 教师角色才能提交申报单 } @PostMapping("/audit/{workloadId}/approve") @PreAuthorize("hasRole('DEPARTMENT') or hasRole('ADMIN')") public ApiResult<Void> approve(@PathVariable Long workloadId, @RequestBody AuditDTO dto) { // 系部审核员和教务管理员都有审核权限 }

第二个接口的细粒度权限是“不同角色操作不同审核状态”:系部审核员只能在SUBMITTED状态操作,教务管理员只能在DEPT_APPROVED状态操作。这个逻辑我放在Service层判断,从状态机里读取当前状态对应的允许角色,防止某个角色把不属于自己环节的单子给审核了。

5. 前端Vue3工程实现:从路由守卫到申报表单

5.1 动态路由与按钮级权限

前端第一个需要考虑的是权限控制。系统登录后返回当前用户信息和角色列表,前端根据角色动态生成可访问的菜单。具体做法是:路由表分成两部分,基础路由(登录页、404页)在代码里写死;业务路由(教师申报、审核列表、系统管理)放在一个常量Map里,登录后根据角色筛选并addRoute动态注册。

这样做的效果很直接:教师账号访问不了审核管理页面,因为他压根没有这条路由;即使手动输入路径,也会被路由守卫拦截跳转404。操作按钮层面额外做了一层自定义指令v-permission,比如审核按钮只在当前用户具备审核角色时显示。这两层配合下来,权限体验比较完整。

// 路由守卫核心逻辑 router.beforeEach((to, from, next) => { const token = useUserStore().token if (!token) { next({ path: '/login', query: { redirect: to.fullPath } }) } else { next() } })

5.2 申报填写页与联动计算

申报页面是教师使用频率最高的页面。我的设计是:左侧选择工作量类别,中间是主表单,右侧是动态明细表格。教师选择“教学工作量”后,明细表格自动渲染出课程名称、学时、课程类别、班型系数等列;选择“科研工作量”则切换成成果类型、成果等级、参与角色等列。

联动计算在这里很关键。教师每填写一行明细,系统调用后端的计算接口实时返回该行的折算分和总分,不需要等提交后再知道结果。这样教师在填报过程中就能看到“我这学期各项工作折算下来是多少分”,有疑问当场调整,减少后期来回驳回。实现时用Vue的watch监听明细数据变化,防抖300毫秒后调用计算接口,避免每次输入都发请求。

表单校验用Element Plus的规则配置,库函数在文本框失焦时触发校验,明细表格每行也做行内校验,比如学时必须为正整数、课程名称不能为空。校验不过的申报单无法提交,前端拦住了一大批脏数据。

5.3 审核面板:列表、详情、审批三区联动

审核页面我做得比较细致。左侧是待办列表,中间是申报详情,右侧是审批操作区。点击列表中的某条申报,中间区域展示主表信息和明细表格,右侧显示当前状态、可执行操作按钮(通过/驳回)和意见输入框。审核人不需要跳转页面就能完成全部操作,这个体验在实际使用中反馈很好。

列表接口每次返回20条待办,并附带每条的申报人姓名、工作总量、当前状态。审核人最关心的是“哪些单子工作量异常大”或者“哪些单子等待时间最长”,所以我在列表项里加了工作量分值显示,并允许按分值排序。这个小功能不是必需,但确实能帮审核人提高效率。

审批操作提交时,前端会把workloadId、审核动作、意见文本一起POST给后端。成功后立即刷新待办列表,并把详情区和审批区重置。有个细节是:如果审核人正在审批某条数据时,另一位管理员已经审批过了,后端会返回状态冲突错误码,前端弹出提示“该申报已处理,请刷新列表”,这个处理非常有必要。

5.4 统计报表页的图表展示

统计报表页是给教务处领导看的。按院系维度展示工作量分布柱状图,按教师维度展示排名条形图,按工作量类别展示饼图。图表库用的ECharts,通过后端聚合接口返回数据,前端接收后转换为ECharts需要的格式。

聚合接口的SQL是一大亮点。比如统计各院系的总工作量,核心查询是这样的:

SELECT department_id, SUM(calculated_amount) AS total_amount FROM teacher_workload WHERE semester = #{semester} AND status = 'ADMIN_APPROVED' GROUP BY department_id ORDER BY total_amount DESC

只统计审核通过且归档的数据,避免草稿数据进入报表。这一点必须在SQL层面过滤,否则报表数字和最终绩效数据对不上,领导一眼就能看出问题。

6. 部署上线与实战踩坑:从开发机到服务器的最后一公里

6.1 MySQL8.0的字符集和时区陷阱

先说数据库的坑。很多人在本机连MySQL8.0一切正常,部署到服务器就报错,第一个要检查的是JDBC连接串。MySQL8.0的驱动类名变成了com.mysql.cj.jdbc.Driver,连接串一定要带上serverTimezone和useSSL参数:

spring: datasource: url: jdbc:mysql://localhost:3306/workload_system?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true

不写serverTimezone,连接时可能报“Communications link failure”或者时区异常;不写useSSL=false,MySQL8.0默认开启SSL,某些服务器环境下会连接超时。allowPublicKeyRetrieval=true这个参数也建议加上,因为MySQL8.0的密码认证用了caching_sha2_password,首次连接需要获取公钥,不加可能报错。

数据库初始化时,记得把所有表都设置为utf8mb4。如果建库时忘了指定,插入中文后很容易出现乱码。一个保险的检查方式,登录MySQL后执行SHOW CREATE TABLE查看字符集。

6.2 跨域问题的处理策略

前后端分离最常遇到的就是跨域。开发环境下,Vite默认端口是5173,后端是8080,前端调用接口必然跨域。我的处理方式是:后端写一个全局CORS配置类,允许本机开发地址的跨域请求;生产部署时,前端静态资源由Nginx托管,后端接口通过Nginx反向代理到同一个域名下,从而彻底消灭跨域。

生产环境下的Nginx配置示例:

server { listen 80; server_name your-domain.com; # 前端静态资源 location / { root /usr/share/nginx/html; index index.html; 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; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }

注意try_files配置,Vue是单页应用,刷新非首页路由时如果不加这个配置,Nginx会返回404,这是SPA部署最常见的坑。前后端都在同一个域名下之后,前端请求改为/api开头的相对路径,跨域问题就不会再出现。

6.3 文件上传路径不能写死

申报单需要上传附件佐证材料,比如教学大纲扫描件、获奖证书照片。开发环境下文件路径写一个本地绝对路径没问题,但部署到服务器上必须改成可配置项。我在application.yml里用自定义属性upload.path配置上传目录,然后启动时自动创建目录。

上传功能还要注意两个细节:一是限制文件大小和类型,比如Spring Boot的配置项spring.servlet.multipart.max-file-size设置为10MB,并在Controller层校验文件扩展名白名单;二是文件名要重命名,使用UUID加时间戳的方式避免重名覆盖。顺序上建议先保存文件、再记录数据库记录,如果数据库写入失败要同步删除已保存的文件,保证一致性。

6.4 部署脚本和进程守护

最后说下部署的运维细节。后端打成jar包后,用systemd写一个服务脚本就能开机自启、崩溃自动拉起,比你手动java -jar可靠得多。关键配置是ExecStart里的启动命令和WorkingDirectory,注意指定生产环境的配置文件项:

[Unit] Description=Workload System Backend After=network.target mysqld.service [Service] User=deploy ExecStart=/usr/bin/java -Xms512m -Xmx1024m -jar /opt/workload-system/workload-system.jar --spring.profiles.active=prod SuccessExitStatus=143 Restart=always RestartSec=10 [Install] WantedBy=multi-user.target

加上Restart=always之后,进程异常退出时systemd会在10秒后自动拉起。这个Action对长期运行的服务来说非常关键,没人愿意半夜被电话叫起来手动重启进程。

7. 含文档的价值:让系统从“能跑”变成“能交接”

7.1 四份核心文档的定位

这个项目标题里特别标注了【含文档】,我觉得这是很有分量的卖点。很多毕设和练手项目只给源码,接手的人看着几千行代码无从下手。而这套系统带的文档,我建议至少包含四类。

需求说明书用来对齐业务边界。教师能做什么、审核人能做什么、管理员能做什么、什么字段必填、状态怎么流转,这些用文字加表格写清楚。数据库设计文档用表格列出每张表的字段、类型、注释和索引说明,新人对数据模型一目了然。接口文档用Swagger生成最好,每个接口的入参出参、鉴权要求都自动导出,省时又准确。部署文档则要写清楚环境要求、初始化步骤、配置文件修改点、常见异常处理,保证换一台机器也能快速跑起来。

7.2 二次开发时最需要“留白”的地方

文档的意义不只是给别人看,也是给自己留后路。这半年你写过的类,三个月后自己看着都陌生,何况是另一个接手的人。我在写文档时发现,最值得记录的不是“代码怎么写”,而是“为什么这样设计”。

比如“工作量申报为什么要拆主从表”“审核状态机为什么要用Map维护流转关系”“计算规则为什么要从代码中剥离到数据库”这类决策记录,写下来之后,后续扩展的人就不会盲目推翻原有设计。否则新来的人看到主从表觉得复杂,顺手改成一张大表,整个系统的工作量统计逻辑就可能崩掉。

7.3 文档驱动的二次开发流程建议

如果后续有人要在这个系统上做二次开发,我的建议是:先改文档,再改代码。比如新增一种工作量类型,第一步在需求说明书中补充该类型的字段、计算规则、审核流程;第二步在数据库设计文档里增加明细表的子类型编码;第三步在workload_rule表插入新规则数据;最后才是写前端页面。这种“文档驱动”的流程看起来慢,实际上能避免大量返工。我见过太多人上来就改代码,结果改到一半发现字段不够用、状态没覆盖、报表统计漏了,这时候再回头补文档,往往已经是一团乱麻了。

系统上线这几个月,最大的体会是:教师工作量管理这类业务,难点从来不在技术,而在于“规则能不能讲清楚、流程能不能走通、数据能不能追溯”。SpringBoot2+Vue3这套技术栈只是把业务规则承载下来的手段。真正让项目成功的,是前面花了不少时间做的数据库设计、状态机定义和规则配置化——这些底层骨架设计清楚了,后面的编码反而像是按图索骥。

如果你正要做一个类似的教务管理或企业考核系统,我建议你也把一半的精力放在业务梳理上:拿一张纸,把填报对象、审核链路、计算规则、统计口径全部画清楚,再打开IDE写代码。这一步做完,你的项目已经成功了一大半。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询