
2. 核心业务逻辑拆解2.1 角色权限模型一票否决还是分级放权集体命题系统的权限设计比普通后台管理系统讲究得多我把角色拆成四级系统管理员、学科组长、命题教师、审核教师。每一级对应一套按钮权限前端用指令控制渲染后端在接口层做二次校验前端隐藏按钮只是体验优化真正的防线永远在后端。教研组长是这套系统的核心角色拥有题库、出卷、发布全流程的最终权限。命题教师负责录入题目、维护答案解析、参与在线组卷但不能发布。审核教师是另一个独立的角色负责从试卷质量维度把关——题目是否符合新课标、难度系数是否合理、是否覆盖双向细目表。这里有个很关键的细节审核教师和命题教师必须互斥。同一个教师在A科目是命题人但在B科目可能是审核人所以角色不能挂在全局要按科目-角色绑定。我在数据库里用的是用户-科目-角色联动表而不是简单的用户角色表这样每个科目内部都有完整的闭环跨科目也不会乱。这个权限模型跑了一个学期后中间有过一次打回确认的争议。某位命题老师觉得自己出的题目答案没问题但审核老师认为情境设计太老旧双方僵持不下。系统里补了一个争议仲裁入口由教研组长直接裁决这个功能实际使用的频率不高但存在本身就能减少大量线下沟通成本。2.2 命题流程引擎状态机驱动的审校闭环一次完整的集体命题要走完这六步创建任务、分配细目、成员命题、系统组卷、全员审核、发布归档。每道题都挂在任务状态机上状态包括拟定中待审核已打回已通过已选用每次流转都记录操作人和时间。这里我踩过一个坑最初把状态字段设计成字符串存进题目表结果审核打回原因只能写在备注里流转历史完全丢失追溯问题非常痛苦。后来单独建了一张审核流水表所有状态变更都往里面追加记录提问、答复、修改说明全部留痕。拿考试出现超纲题时查责任归属的场景来说这张流水表可以在五分钟内理清是谁加的知识点、谁审核通过的、当时备注了什么理由。组卷环节是整个系统的关键也是审核老师的核心工作台。教研组长先定义好试卷模板——包含大题的顺序、每种大题下的小题数量、分值和难度区间然后选择知识点覆盖范围系统按约束条件自动抽题生成一版初稿。初稿在这里并不是直接可用还需要经过一轮人工调换顺序不合适可以拖拽难度偏高可以一键替换同知识点下的备选题所有修改都会生成修订记录防止有人改完试卷后说不清谁改的。这套流程跑下来一次月考命题从创建任务到定稿一般三到四天能走完。3. 前端核心实现Vue工程中的关键设计3.1 细目表组件让双向细目表在网页上活起来双向细目表是这个系统里信息密度最高的界面。我在前端做了两套组件一套是只读展示的查阅模式供普通教师按知识点和认知层次查看分值分布另一套是编辑模式供教研组长制定命题蓝图。编辑模式基本可以看成网页版Excel行是知识点集合列是识记、理解、应用、分析、评价这几个认知层次单元格里填对应分值。组件实现用的是vue-good-table嵌套结构横向滚动锁定前两列知识标签中间格子支持悬停高亮显示所对应的知识点-认知层次。对组卷而言这个表不仅是展示配置更是抽题算法的输入源——它的JSON结构直接作为组卷策略传给后端。为了让修改可追溯每次编辑保存时都生成快照版本组卷的时候可以指定引用哪个版本。比如组长把细目表改成A版试抽一次不满意还能回退到B版重来不用手动恢复数据。细目表组件里有个细节值得单独说单元格的校验规则。有些教研组长习惯先填总分再反推每题分值所以组件必须支持行求和、列求和自动计算并在总分跟试卷总分不一致时弹出红色警示。比如组长套用的模板是100分制但细目表里所有单元格加出来是96分系统会直接标红并提醒还差4分,这比事后人工核对靠谱得多。而且每个单元格里可以附加允许误差标记比如某道应用题的知识点覆盖了两个认知层次分数可以拆开挂避免一个单元格只能填一个数字的僵硬限制。3.2 组卷预览与人工调卷工作台预览工作台直接决定教研组长愿不愿意用这套系统。它左侧放细目目标右侧是虚拟A4预览区上面按试卷模板实时渲染每一道题滚动浏览时左侧知识点进度条跟着联动——看到哪个知识点区域侧边导航就高亮到哪。视觉上很直观组长一眼能看出选择题部分覆盖的知识点是不是太密、题干顺序是不是违和。调卷工作台里我把常用操作集中在工具栏上移、下移、替换、移除、插入。替换是一个高频操作实际实现是弹窗展示同一知识点下三道备选题目并给出难度系数和预估作答时长的对比条不必挨个打开题目详情。对于组长觉得不合适的题直接点击替换即可备选题不够时还可以一键跳转到题库页面重新录题录完自动刷新备选池。这个工作台开发时调试最久的是拖拽排序和虚拟滚动的冲突最终换了版本才稳定下来后面实测拖300多道题的滚动完全没有卡顿。3.3 附件管理与其他业务模块选题录入不只是文字还要支持图片、公式和附件数学试卷里大量公式是避不开的。前端里公式编辑用的是富文本扩展插件支持LaTeX语法渲染解析后的公式直接以图片形式存储同时保留源码用于二次编辑。试卷模板中每道题都可以挂多个附件系统在上传时做了文件类型与大小限制图片控制在单张2MB以内附件上限10MB兼容常见的PDF、Word格式。日常教学场景还会用到班级成绩导入、答题卡扫描答案导入和成绩分析功能。成绩分析属于后续迭代版本里加的但这套系统在最初设计时预留了相关的数据字段和接口避免后面重新设计。我之前维护过几个教务系统很明白先预埋好字段、再逐步开放功能这个思路在职业教育信息化里有多重要。4. 技术选型与工程化实践4.1 前端工程搭建与关键依赖项目基础框架选了Vue 2.6加Element UI 2.x。这套组合在不少院校和政企项目里依然是存量主力组件生态成熟、中文文档齐全、招人容易新入职的初级前端基本能直接上手。组件库选型方面几个核心依赖是富文本编辑器用于题目录入模块支持公式编辑树形表格用于知识点管理的层级展示图片预览与裁剪工具用于题目图片上传浏览器端Excel解析与生成工具用于细目表的导入导出。打包构建用的是Vue CLI 4配了按需加载的路由懒加载主应用首屏加载JS控制在1.2MB以内。国内容器环境普遍对带宽不太敏感把加载优化做在CDN分包和懒加载上就够了。主题定制方面Element UI的SCSS变量统一改了主色和圆角文件放到项目的公用样式目录下配色上专门配了教育类系统常用的蓝白基调。4.2 目录结构与模块边界src目录按业务和通用层做了清晰划分每个模块用独立的views、components、store、api、router子目录组织。组卷模块目录单独拎出来细目表操作、调卷工具栏、预览渲染、历史版本对比这些组件都放在自己模块下互相之间通过Pinia Store共享状态不跨目录引用。权限控制对应src/permission.js里面拦路由通过store里缓存的权限码做校验和跳转。后端返回的菜单树直接渲染侧边栏前端不再单独维护路由表这样菜单权限的增删完全由后端配置控制新增加一个学科也只需要在后台加数据前端不用发版。跨模块复用集中在api和utils目录。api目录按后端业务模块拆分例如题库管理组卷管理审核管理各自对应一个职责文件里面统一封装axios实例配置了token拦截、401跳转、错误消息提示和取消重复请求的逻辑。这些代码是所有业务模块共享的也是后续接手项目的人最需要先读的部分。4.3 状态管理Vuex 的模块化设计状态管理用了Vuex并做了模块化设计。我划分了四个核心模块分别是用户信息模块、题库模块、组卷模块和全局UI模块。user模块存用户资料和权限码数组token放localStorage每次刷新通过接口重新拉取个人信息question模块缓存当前正在编辑的题目详情防止切换页面丢草稿paper模块管理组卷工作台的状态包括当前预览试卷、细目表版本、调卷历史记录app模块负责侧边栏折叠、页面标签、全局loading。这里面最需要细心的是组卷模块undo/redo的state还原。工作台里组长连续调整了十几道题的位置突然想回退两步如果每次只把试卷JSON快照存在组件内页面切换再回来就全丢了。这里用Vuex统一管理一个操作栈每次增删改都推入一个新的试卷快照回退操作是弹出当前快照并恢复展示。快照乘以每份试卷几百KB的体积内存开销还在可接受范围实际使用中也没有遇到卡顿。5. 组卷算法与核心逻辑实现5.1 抽题策略从约束条件到实时出卷组卷环节本质上是个多条件组合优化问题我做的算法是按约束逐层过滤选池再对冲突项做回退重选。第一步由组长在界面上选定考试类型、总分、时长、试题难度分布范围和知识点覆盖范围系统先把符合难度和知识点范围的全部题目加载进候选池然后按题型和各小问数量要求从池子里随机抽取并生成试卷。算法落地时踩过不少坑。其中一个典型场景是某次期中考试组长要求选择题难度系数必须分布在0.5到0.7之间但候选池里符合这个难度区间的选择题只有12道而卷子要求20道算法直接空转。后来改成先按严格条件抽抽不满就把难度范围放宽并在预览页明确标注有X题低于目标难度系数组长自己决定是否接受。这个宽严结合加提示的策略比死守硬约束体验好很多。抽题结果还做了合理性校验重点检查重复知识点覆盖、同一来源的题目是否集中以及选项间是否存在雷同。比如填空题同时抽中两道都考抛物线焦点坐标的题算法会自动把后一道标记为知识点重复并给出可替换的备选题避免一份卷子同一知识点考三遍的尴尬。5.2 后端接口复用与前端算法配合算法主体我放在了后端前端只负责传参和渲染结果。这样设计的考虑在于题库数据量大如果前端一次性拉取全部题目到浏览器过滤网络开销和内存压力都太大而且组卷策略可能后续还要升级成更复杂的多目标优化模型接口化更容易平滑迭代。前端仍然保留了一套轻量级的快速估算逻辑组长在细目表里调整单个单元格的难度系数时前端立刻估算该知识点可能抽到的题目数量和预估分值区间并显示按此条件组卷命中预计12题、预估平均难度0.62。这个数字是离线计算缓存出来的近似值精度不用很高目的是帮组长在提交组卷前心里有数。实际提交组卷后后端返回精确结果并覆盖预览如果差异较大前端会用较明显的标记提示组长方便及时调整预设条件。5.3 智能换题与人工干预的结合完全靠算法生成的试卷大概率不能满足所有要求所以系统设计了智能换题模块。每次换题时系统优先推荐同知识点、同题型、难度最接近原题的备选同时避开与已选题目选项雷同的题目。这个推荐用到的是一套打分排序逻辑把知识点相似度、难度差值、区分度偏差和近三次考试的使用情况进行加权求和排名最高的三道作为推荐。组长可以一键接受推荐也可以手动选择操作路径很短。整套流程下来的实测体验是一位有经验的教研组长从发起组卷到调完卷大约花费二十到三十分钟对比以前线下传纸质题、开教研会逐题审核的效率整个命题周期能压缩一半以上。6. 常见问题与调试实录6.1 编辑器相关问题的排查公式编辑器在某个浏览器内核版本里渲染错乱图片变形且无法保存。排查后定位到是浏览器对MathML的兼容性问题换用图片渲染方案就能解决。这类问题在跨平台校园网环境里很常见我的建议是富文本公式功能尽量选兼容性更好、打包体积更小的方案并用正则对非法HTML标签做入库前过滤避免脏数据污染。还有一次富文本编辑器里粘贴Word内容后样式全部丢失反而带了大量内联样式。后来调研了几个方案最终用文本过滤加白名单样式处理只保留字体加粗、斜体、下划线和行内代码等常用格式再入库。现在所有教师录题都会先经历这个净化流程数据库里的内容干净多了。6.2 权限脑子转不过弯跨学科互斥问题前面提到审核者和命题者互斥但实际业务里一位老师可能教多个班级跨两个学科都有命题任务。最初按学科判断互斥时老师反馈自己既是A学科命题人又是B学科审核人登录后权限混乱前端同时渲染了命题和审核两个入口操作时后端鉴权也出现冲突。解决思路是把角色绑定从用户级细化到用户-学科级再次确认后发现表格联查里多条件失效已按组合唯一索引修复。这个场景对权限模型设计是个很好的提醒抽象的RBAC模型落地时一定要考虑业务维度的复杂性权限判断必须带上下文不能只认用户全局角色。6.3 题库录入效率低批量导入的优化过程老师们最抵触的就是录题效率低初期一个个录入题目确实烦。后来做了批量导入功能支持按学科的Excel模板导出、填写后上传上传时校验必填字段、题型合法性和知识点编码是否存在错误行会返回具体原因。这个功能上线后题库建设速度明显提升接下来一个月就沉淀了数千道有效题目。批量导入的问题主要集中在Excel模板里的知识点层级格式不统一有的老师填了父节点有的填了末级子节点。后来前端做了解析后自动匹配路径的处理老数据洗了一遍知识点编码统一后才正式开放批量导入功能。6.4 性能优化大数据量下的列表卡顿处理题库管理页最初渲染三千多道题时列表卡顿明显。排查发现是每行都内联渲染了知识点路径标签和操作按钮加上Vue数据绑定页面重渲染频繁性能直线下降。后来优化为分页加载加虚拟滚动方案列表只渲染当前屏内的行并为行内操作按钮绑定防抖页面交互才流畅起来。细目表组件的滚动卡顿也曾让人头疼问题出在滚动监听触发全量重绘优化后改成了局部更新和节流处理三百行以内的细目表滚动流畅度恢复到正常水平。另一类性能问题是组卷结果返回大JSON时预览渲染白屏后来加了一层拆分渲染按题型分段渲染配合loading骨架屏体验提升明显。7. 部署与环境适配7.1 生产环境部署案例部署环境用了某国产化服务器加云数据库的配置网络环境走校内教育网对公网带宽占用不大。前端打包产物扔到云服务器上经过Nginx做静态资源托管接口走反向代理转发到后端应用。整体部署方案不复杂但需要注意跨域、代理和静态缓存配置。印象比较深的是有次静态资源版本更新后部分教师浏览器还是旧版前端打开页面白屏。排查后是Nginx缓存策略没配好eset版本号没更新。后来在gzip和缓存设置里统一配置了带哈希文件名的资源缓存一年、入口文件不缓存这个问题就彻底消失了。这种部署细节虽然小但实际影响用户体感很大。7.2 浏览器兼容性与设备适配教育类系统最常见的访问设备还是Windows上的老旧Chrome内核浏览器以及少量的国产双核浏览器。开发时我特意规避了比较新的CSS特性如容器查询、subgrid这类较新特性未使用事件处理也兼顾了IE时代的兼容写法。现在整体兼容性表现良好旧的笔记本访问系统没有明显问题。移动端适配也做了基础优化主要面向手机端临时查看题库场景核心页面采用了响应式布局表格在窄屏下自动横向滚动。组卷工作台这种重度操作页面则建议在PC端使用移动端打开会提示用户切换设备避免误操作影响组卷结果。8. 测试与复盘8.1 测试用例设计的重点系统测试覆盖比较全面功能测试按模块推进核心关注权限互斥策略、组卷算法边界条件以及并发场景下的数据一致性。单独提一下并发问题的排查多位老师同时提交题库审核时偶发出现审核记录写错的问题。后来定位是主键生成策略没有体事务锁改用数据库唯一约束加分布式ID后解决。回归测试阶段我把重点放在三个高风险链路公式图片上传完整性、组卷后预览渲染准确性、权限判定在跨角色场景下的正确性。这也是整个系统中最容易出问题的三条链路保障它们稳定后整体运维压力会小很多。8.2 上线后的真实使用反馈系统上线后的第一个学期学校累计组织了多次网上集体命题活动覆盖多个主要学科命题任务完成率达到九成左右。老师反馈最好的功能是细目表让命题规划一目了然和组卷预览所见即所得最想继续改进的是自动难度校准和更多题型的公式模板支持。在这个过程中我也重新理解了好用的含义教务系统不只是把线下流程搬到线上更重要的是用结构化数据把经验沉淀下来。教研组长往年对难度把控的经验在系统里变成了可量化的难度系数、区分度历史记录这些经验数据比任何静态制度都更宝贵。8.3 项目维护与后续迭代方向系统整体架构对后续迭代已经有预留题库模块打算增加从历年真题导入的识别工具分析模块会把组卷后的实测数据、成绩分布和试题难度反馈闭环生成更精准的难度预估模型权限层未来会开放年级组与学校两级审批链适配更复杂的组织架构。前端升级到Vue 3的改造计划也在稳步推进目前评估下来组件重构的工作量主要集中在细目表编辑和调卷工具栏。这个系统前前后后从需求确认、原型评审、开发测试到上线培训我全程参与下来最大的感受是技术选型只是基础真正决定项目成败的是对业务场景的理解深度和细节上的反复打磨。系统里很多设计在demo阶段看不出来价值真正滚完一个学期的命题任务后价值才一点点凸显出来。最后分享一个小技巧在推进这类系统时一定要一遍又一遍地让真实用户参与测试——不是让他们看演示而是让他们亲手录一道题、组一份卷、跑一次审校流程。用户在实际操作中提出的每一条不满几乎都对应着产品下一步的优化方向。