ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

SpringBoot+Vue疫情隔离管理系统:从数据库设计到部署避坑全指南

SpringBoot+Vue疫情隔离管理系统:从数据库设计到部署避坑全指南 先聊点实在的。每年毕业季和课设季后台咨询最多的一类需求就是Java前后端分离的管理系统而疫情隔离管理系统几乎是这几年的命题作文——需求明确、模块清晰、技术栈覆盖全拿来练手或验收都很合适。我自己用SpringBootVueMySQL完整做过一版从数据库建模到前后端联调、从部署上线到答辩演示前后折腾了大概两周。这篇就把整个项目的落地过程拆开讲包括技术栈选择逻辑、表结构设计、接口思路、前端权限控制、以及一堆不跑一遍根本发现不了的坑。如果你正准备做类似的管理系统或者想拿这套题练手照着走一遍能省下不少瞎试的时间。1. 为什么这套题适合做毕设/课设需求边界与技术覆盖度选毕设题目最忌讳的是两类一类是需求大得没边做半年也做不完另一类是技术点薄得可怜写文档时凑不出三章。疫情隔离管理系统恰好卡在中间偏左的位置——需求足够真实但边界又很清楚作为课设、毕设乃至学习项目都非常合适。1.1 需求场景天然合理不用自己编故事管理系统类项目最怕的是伪需求比如做一个图书管理系统实际没人会真的用。但隔离管理系统的场景是真实存在过的而且业务流程非常清晰从哪里来、住到哪、每天上报什么、多久解除、物资怎么分——每一环都是刚需。这意味着你的需求分析章节不用硬编直接按实际业务线梳理就行评审老师问起来你也能对答如流。更重要的是这个题目有明确的角色区分。管理员、隔离人员、医护/工作人员三者权限和操作内容完全不同这就天然引出了权限管理和多端交互而这恰好是管理系统评分的关键加分项。1.2 技术栈覆盖面足够写满一篇论文先列一下这套系统会触碰到的技术点后端SpringBoot框架搭建、Spring Security权限控制、JWT无状态认证、MyBatis-Plus数据持久化、Lombok简化开发、Hutool工具集前端Vue生态、Vue Router动态路由、Axios请求封装、Element UI组件库、ECharts数据可视化数据库MySQL表设计、外键逻辑、索引优化、事务处理部署Maven打包、前后端分离部署、Nginx反向代理可选这些点随便挑几个展开写都有足够的篇幅深度。相比单纯做一个CRUD系统它多了权限、状态流转、数据统计这些真正有分量的内容回答为什么用这个技术的时候也不会心虚。1.3 工作量的弹性空间大这是很多人忽略的一点。这套题目可以做得很大——比如加上在线申请隔离、物资库存预警、人员轨迹登记、多级审批流也可以做得小巧精悍——只保留核心的隔离人员登记、每日健康上报、解除隔离和统计看板。我建议按照自己的时间预算来决定范围课设的话十个左右核心接口就够了毕设的话再加审批流转和统计模块会更饱满。关键是可以随时扩展不用担心做到一半发现根本做不下去。2. 开工前的设计先把数据库表和角色权限想清楚很多人一上来就写代码写到一半发现表结构不对又回头改浪费的时间比写代码还多。我做这套系统时第一周基本全花在梳理业务流程和建表上。后面写接口的时候基本是一路顺畅几乎没有改过表结构。2.1 核心业务流转与状态机设计一个隔离人员从进入到离开会经历这样的流程登记入住 → 每日健康打卡 → 异常则转诊/观察 → 期满申请解除 → 审批通过 → 办理离开。这里最关键的是把状态设计好。我的做法是给隔离记录表设计一个状态字段用整数表示配合状态枚举类统一管理状态值含义后续可执行操作0已登记待入住安排房间状态转11隔离中每日上报健康数据隔离期满可申请解除2已提交解除申请管理员审批通过转3驳回转13已解除流程结束归档4异常转观察标记异常原因健康数据持续跟踪为什么要单独设计状态机而不是用布尔值因为业务里存在驳回回到原位这种回退操作只靠一个标记位根本表达不了完整流程。状态机配合后端的状态校验能有效避免非法流转比如未登记的记录不能直接变成隔离中这是答辩时可以说清楚的设计亮点。2.2 数据库表结构设计我的表设计分了两大块系统基础表和业务表。系统基础表主要是用户、角色、权限、公告业务表则是隔离人员、隔离记录、健康打卡、核酸记录、物资出入库。关键表结构如下用户表sys_userid、username、password、real_name、phone、role_id、status、create_time角色表sys_roleid、role_name、role_key、remark这里角色我固定在代码里写了三种admin管理员、doctor医护工作人员、patient隔离人员。不搞动态权限那么复杂但也不是完全没有权限控制——后端接口拦截按角色区分前端动态路由也是按角色生成的。隔离人员信息表quarantine_personid、person_name、id_card、phone、source_place来源地、arrive_time到达时间、health_status、room_id、record_id、create_time隔离记录表quarantine_recordid、person_id、room_id、start_date、plan_end_date、actual_end_date、status、note健康打卡表health_checkid、record_id、check_date、temperature、is_cough、is_fatigue、other_symptom、create_time这里我特意把健康打卡拆成独立表而不是在隔离记录里直接加字段因为打卡是每天一条一对多的关系如果塞在同一张表里查询最近7天体温趋势会非常痛苦。房间表quarantine_roomid、room_number、floor、building、capacity、used_count、status房间状态我用0空闲、1满员、2维护分配房间时校验使用人数是否达到容量上限。物资表material_infoid、name、specification、stock、unit、warning_line物资出入库流水material_recordid、material_id、type1入库 2出库、count、operator_id、create_time2.3 角色权限的落地方案权限这块我选了Spring Security JWT没有用Shiro。原因很简单Spring Security在SpringBoot项目里集成度高虽然学习曲线比Shiro陡一点但只要走通一次配置后面管理起来很顺手。后端权限拦截用的是注解方式在Controller方法上加权限标注。比如管理员才能操作物资出入库PreAuthorize(hasAuthority(admin)) PostMapping(/material/outbound) public Result outbound(RequestBody MaterialRecordDto dto) { // 出入库逻辑 }这样做的目的是核心接口双重保障前端路由只是限制了界面入口真正的防线在后端。演示或者答辩的时候完全可以现场演示一个普通用户直接调接口会被拦截返回403这一点很能体现系统的严谨性。3. SpringBoot后端实现从项目骨架到核心接口讲完设计进入代码环节。我不打算贴全套源码那种没什么意义重点是讲清楚关键代码思路和为什么这么做。完整的项目结构我会尽量在文中标注清楚跟着写一遍你也可以得到一套能跑通的前后端分离项目。3.1 项目结构规划后端我用Maven管理包结构如下com.example.quarantine ├── controller // 接口层 ├── service // 业务层 │ └── impl ├── mapper // MyBatis-Plus的Mapper接口 ├── entity // 数据库实体 ├── dto // 前端传参对象 ├── vo // 返回给前端的数据封装 ├── config // 配置类Security、CORS、MybatisPlus ├── common // 通用返回结果、异常处理 ├── utils // JWT工具、日期工具 └── job // 定时任务这种分层的逻辑很简单controller不写业务代码service处理核心逻辑mapper只做数据访问。项目小的时候会觉得有点绕但一旦业务复杂起来这样的结构能让你在两天后还记得自己写过什么。3.2 登录认证与JWT拦截器整个系统最先写的就是登录认证因为其他所有接口都依赖当前登录人信息。流程如下用户提交用户名和密码后端校验密码BCrypt加密比对校验通过后生成JWT令牌令牌里包含userId和roleKey前端拿到令牌后存到localStorage后续请求放在Authorization请求头后端用拦截器解析令牌抽出用户信息放入ThreadLocalJWT生成的核心代码很简单// 生成token有效期设为7天相对宽松方便演示 String token JWT.create() .withSubject(user.getUsername()) .withClaim(userId, user.getId()) .withClaim(role, user.getRoleKey()) .withExpiresAt(new Date(System.currentTimeMillis() 7 * 24 * 60 * 60 * 1000)) .sign(Algorithm.HMAC256(secretKey));我踩过的一个坑在这里JWT的过期时间一旦过短比如30分钟演示中途上个洗手间回来就过期了重新登录非常尴尬。毕设答辩场景建议把过期时间设成6到12小时兼顾安全性和演示体验。ThreadLocal这块也很关键后续所有业务接口想拿当前是谁在操作一条UserContext.getUserId()就行审计字段的填充非常方便。注意在拦截器里finally块中必须调用remove方法否则Tomcat线程池复用时会出现用户信息串线这个坑比较隐蔽容易产生诡异的数据归属错误。3.3 核心业务接口的设计思路我把核心接口按业务线拆了一遍每条线的逻辑都值得展开说一下。普通用户隔离人员的接口每日健康打卡一个用户当天只能提交一次后端要校验是否已存在今日记录查看自己的隔离记录和剩余天数提交解除隔离申请查看公告管理员的接口人员登记录入基本信息 → 分配房间 → 创建隔离记录三个操作放在一个事务里任何一个失败都要整体回滚每日体温统计按日期维度查询所有在住人员的今日打卡情况未打卡的标红提醒解除隔离审批查看申请列表 → 通过/驳回 → 修改隔离记录状态物资出入库管理出库时要校验库存够不够不够直接提示数据大屏接口统计在住人数、累计解除人数、今日体温异常数、房间利用率等这里重点说两个容易犯错的点。第一个是打卡接口的并发问题。理论上用户不会凌晨同时点提交但万一出现重复请求就会插入两条当日记录。解决方案是在数据库层面对record_id和check_date加唯一索引这样即便并发多插也会有一个失败再配合前端按钮置灰双保险。第二个是解除隔离的日期校验。有些演示会故意输入不合理的日期来测试系统我在Service层加了一行判断if (record.getPlanEndDate().isAfter(LocalDate.now())) { throw new BusinessException(隔离期限未到暂不能申请解除); }类似的校验在登记时也要做——入住日期不能晚于当前时间房间容量不能超员。这种防御式编程在答辩时很加分说明你考虑到了异常情况。3.4 定时任务自动识别未打卡人员隔离管理有一个很实际的场景每天早中晚三次系统得知道谁没打卡。我用了SpringBoot自带的Scheduled定时任务每天固定时间扫描一次把当日未打卡的用户记录查出来生成提醒通知。Scheduled(cron 0 0 20 * * ?) // 每天晚上8点执行 public void remindUncheckedPersons() { // 查询所有状态为隔离中且今天没有打卡记录的record // 生成待办提醒写入notice表 }定时任务看起来简单但有一个地方需要注意如果是多实例部署同一个任务会被执行多次。解决方式可以加分布式锁用MySQL的行锁或者Redis的setnx课设阶段单实例跑没有问题但如果项目文档里写到了高可用部署的字眼这块就得有说明否则容易被追问。3.5 全局异常处理与统一返回格式前后端分离的项目接口返回格式要统一否则前端处理起来非常痛苦。我的统一返回类结构是public class ResultT { private Integer code; // 200成功400业务失败401未登录403无权限500系统错误 private String message; private T data; }配合全局异常处理器不管是业务异常、参数校验异常还是系统异常最终都会转成这个结构返回给前端。前端axios拦截器里统一判断code非200就弹出错误提示代码量一下子省了很多。这一步看似基础但真的见过不少项目有的接口返回{success:true}有的返回{status:1}有的直接返回裸数据前端写着写着就疯了。统一响应体是前后端联调的第一前提。4. Vue前端实现动态路由、权限控制与核心页面前端我选的是Vue 2 Element UI虽然Vue 3也已经很成熟但毕设和课设环境里Element UI的资料存量最大遇到问题搜答案更容易。前端代码的模块划分很清晰核心是Api封装层、动态路由和几个业务难度较大的页面。4.1 前端工程结构和Api封装前端目录结构基本是标准Vue CLI工程src ├── api // 按业务模块拆分接口请求 │ ├── auth.js │ ├── user.js │ ├── health.js │ └── stats.js ├── router // 路由配置 ├── store // Vuex ├── views // 页面 │ ├── login │ ├── dashboard │ ├── patient // 隔离人员端 │ ├── admin // 管理端 │ └── common // 公告、个人中心等 ├── utils // 请求封装、token操作、权限指令 └── App.vueaxios请求封装是必写的一层核心拦截器逻辑如下service.interceptors.request.use(config { const token localStorage.getItem(token) if (token) { config.headers[Authorization] Bearer token } return config }) service.interceptors.response.use( response { const res response.data if (res.code 401) { // token过期跳回登录页 router.push(/login) return Promise.reject(new Error(登录已过期)) } if (res.code ! 200) { ElementUI.Message.error(res.message || 请求失败) return Promise.reject(new Error(res.message)) } return res }, error { ElementUI.Message.error(网络异常) return Promise.reject(error) } )这里关键的是在响应拦截器里统一处理401否则每个页面都要自己判断是否跳登录代码会非常啰嗦。4.2 动态路由与菜单权限动态路由的实现逻辑是这样的登录成功后后端根据角色返回该角色可以访问的菜单列表树形结构前端拿到菜单后动态添加路由同时渲染侧边栏菜单。// 根据后端返回的菜单标识动态生成路由 const generateRoutes (menus) { const routes [] menus.forEach(menu { if (menu.component Layout) { routes.push({ path: menu.path, component: Layout, children: menu.children.map(child ({ path: child.path, component: () import(/views/${child.component}), meta: { title: child.title, roles: child.roles } })) }) } }) return routes }动态路由的坑在于刷新页面时Vuex里的store数据会清空动态添加过的路由就丢了。解决办法是在全局路由守卫里做判断——如果store里没有菜单数据就重新请求一遍菜单并addRoutes再放行进入页面。这个逻辑几乎是必踩的我在第一次做的时候折腾了大半天才定位是刷新问题。前端菜单和按钮权限上我加了一个自定义指令v-permission细粒度控制按钮的显示隐藏。举个例子物资出库的按钮只有admin能看doctor角色看不到el-button v-permissionadmin clickhandleOutbound物资出库/el-button指令内部判断当前用户角色是否在允许列表内不在就直接移除DOM元素。但是要记住前端按钮隐藏只是体验优化接口层必须重复校验这是演示时被追问为什么普通用户调接口会失败的底气所在。4.3 核心页面健康打卡与数据大屏健康打卡页面是隔离人员端的核心我做得尽量简洁直观顶部显示当前隔离天数中间一个大大的体温输入框下面几个症状勾选项提交按钮。逻辑上最重要的是当天是否已打卡的判断已打卡状态显示今日已上报按钮置灰。el-card div classtemp-display span classlabel今日体温/span el-input-number v-modeltemperature :min35 :max42 :precision1/el-input-number span classunit℃/span /div el-checkbox-group v-modelsymptoms el-checkbox labelcough咳嗽/el-checkbox el-checkbox labelfatigue乏力/el-checkbox el-checkbox labelother其他不适/el-checkbox /el-checkbox-group el-button typeprimary :disabledisCheckedToday clicksubmitCheck {{ isCheckedToday ? 今日已上报 : 提交健康信息 }} /el-button /el-card体温数字的输入控制是重要的前端校验细节体温范围35—42摄氏度超出就提示请确认体温计读数这不仅是格式校验更是业务逻辑校验。真实系统里会直接用体温计对接课设阶段手动录入完全合理。数据大屏我用了ECharts。做了三个核心图表近7日体温趋势折线图、隔离人员来源地分布饼图、每日在住人数柱状图。这些图表都是后端统计接口返回结构化的数据前端直接传入ECharts的series不需要做复杂处理。多说一句ECharts图表在答辩演示时非常抢眼因为数据变化是动态的——打卡一个数就往上走。这种动起来的效果比静态页面有说服力得多。4.4 前端表单校验与交互细节Element UI的form校验默认就挺好用我主要补充了自定义校验规则。比如身份证号的正则校验、手机号格式校验、日期范围校验结束日期不能早于开始日期。这些细节不需要写很多代码但能明显提升系统的完成度。5. 部署与联调从本地到服务器的一次性走通这部分内容其实和具体的项目无关几乎是所有前后端分离项目的通用流程但也是大部分课设选手最容易卡住的地方。我按自己的操作顺序列一份详细的步骤清单照着做通常不会出问题。5.1 本地开发环境配置后端需要JDK 1.8或以上、Maven 3.6、MySQL 5.7/8.0前端需要Node.js 14。版本选择上我用的是SpringBoot 2.7.xJDK 1.8配套稳定。需要注意SpringBoot 2.7和3.x的本质差异——3.x要求JDK 17而且javax包名改成了jakarta很多网上复制来的老代码会直接报错。课设阶段建议别追新2.7.x是兼容性最好的版本。MySQL的坑主要在时区和连接参数上。连接串我推荐这样写jdbc:mysql://localhost:3306/quarantine_db?useUnicodetruecharacterEncodingutf8useSSLfalseserverTimezoneAsia/ShanghaiallowPublicKeyRetrievaltrueserverTimezoneAsia/Shanghai不写的话通常会出现8小时时差问题插入数据的时间比当前时间少8小时。allowPublicKeyRetrievaltrue是MySQL 8.0连接时的常见报错解决办法遇到Public Key Retrieval is not allowed时加上就通了。5.2 后端启动顺序与常见启动失败后端的启动顺序是先启动MySQL并执行初始化SQL脚本然后启动SpringBoot应用。第一次启动时最常遇到的报错有三类第一类是端口被占8080被其他程序占用。解决方案是换端口或者在配置里修改server.port我建议直接用9090这类不常用端口避免冲突。第二类是Mapper接口扫描不到报Invalid bound statement。这是MyBatis-Plus集成时常见的低错核心是检查启动类的MapperScan注解是否指向了正确的mapper包路径以及XML文件在resources目录下的路径是否与mapper接口包路径一致。第三类是数据库连不上报Communications link failure。先排查MySQL服务有没有启动再排查用户密码、数据库名是否正确最后才排查防火墙问题。这条排查顺序很重要很多人一上来就去看防火墙其实最简单的用户名密码错误才是最常发生的。5.3 前端打包与后端整合部署前端打包很简单npm run build之后生成dist目录。打包前建议先确认vue.config.js里设置了publicPath: ./否则用相对路径访问时会出现空白页或者资源404的问题。部署方式我推荐两种方式一前端dist目录放进后端SpringBoot的static/resources目录下打成一个Jar包然后java -jar运行前端访问端口和接口端口统一最省事也适合演示。需要注意的是后端要配置一下静态资源映射保证前端history路由模式下刷新页面时都落到index.html上使用Vue Router的createWebHistory时刷新404问题必须处理。方式二前端dist部署到Nginx后端接口反向代理到Java服务。这样做的好处是前后端完全分离但演示时需要同时保证两个服务都在运行。课设答辩时我建议方式一因为一个Jar包搞定所有事情拷贝到哪都能跑数据库脚本也一并提供评审老师自己动手复现的门槛最低。5.4 初始化数据的准备系统跑起来之后如果没有数据页面空空荡荡演示效果很差。我写了一个data.sql初始化脚本内置了三个角色的测试账号admin/123456、doctor/123456、patient/12345620个隔离人员的模拟数据分布在不同来源地最近7天的健康打卡数据包含几条体温偏高记录用来展示异常提醒房间数据3栋楼每层10间状态各异若干物资数据部分库存低于预警线这些模拟数据让图表有得画、列表有得翻、审批有得批演示效果完全不尴尬。6. 实战避坑这套系统最容易翻车的五个细节做了两三遍类似项目之后我总结出了一些坑基本隔一段时间就会在留言区看到同样的提问出现。这里统一说一遍希望你能绕开。6.1 跨域问题前后端分离开发时前端在8080端口后端在9090端口直接请求接口会因为跨域被浏览器拦截。后端我写了一个全局CORS配置Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping(/**) .allowedOriginPatterns(*) .allowedMethods(GET, POST, PUT, DELETE, OPTIONS) .allowedHeaders(*) .allowCredentials(true) .maxAge(3600); }前端开发模式下也可以配Vue CLI的devServer代理把/api开头的请求代理到后端地址这样可以保持请求相对路径统一devServer: { proxy: { /api: { target: http://localhost:9090, changeOrigin: true } } }生产环境下如果采用前后端合包部署就完全没有跨域问题。建议开发和生产两套方案都在文档里写明。6.2 前端刷新路由404这是Vue Router history模式的老问题。在生产环境如果前端静态资源由SpringBoot托管刷新一个子路径比如/admin/dashboard会直接404因为后端找不到这个路径。解决办法是加一个WebMvcConfigurer将非接口路径全部转发到index.htmlOverride public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController(/{spring:^[a-zA-Z0-9-_]}).setViewName(forward:/index.html); registry.addViewController(/**/{spring:^[a-zA-Z0-9-_]}).setViewName(forward:/index.html); }这个坑不跑一次根本发现不了但一旦遇到了其实解决起来就两行配置。6.3 日期类型在前后端传参时的序列化问题LocalDate和LocalDateTime类型如果不做任何配置返回给前端是数组格式或者会报Invalid value for epoch之类的错。一定要在全局配置里加上JSR310模块支持Bean public Jackson2ObjectMapperBuilderCustomizer jacksonCustomizer() { return builder - { builder.simpleDateFormat(yyyy-MM-dd HH:mm:ss); builder.serializers(new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(yyyy-MM-dd HH:mm:ss))); builder.deserializers(new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(yyyy-MM-dd HH:mm:ss))); }; }否则前端会拿到乱七八糟的时间格式ECharts的时间轴直接画不出来到时候排查会很烦躁。6.4 MySQL 8.0与5.7的SQL语法差异初始化SQL脚本如果同时兼容5.7和8.0要注意不要用8.0特有的语法。比如WITH ... AS的CTE在5.7不支持某些窗口函数也不支持。我写初始化脚本时只用了基础的CREATE TABLE和INSERT语句保证两个版本都能直接跑。统计类SQL自己注意一下版本兼容性。另外如果MySQL的sql_mode里严格模式和非严格模式有差异插入不合法数据会有不同的行为。建议开发环境统一用一个版本的MySQL不同小组一起开发时测试和生产环境版本尽量保持一致。6.5 事务问题登记人员时三步操作必须原子化登记隔离人员的接口涉及插入人员信息、分配房间、创建隔离记录三个步骤。如果中间某一步失败而前面已经插入的数据没回滚就会出现房间分配了但人员不存在或者人员存在但房间占用没释放。正确的做法是加上Transactional(rollbackFor Exception.class)让任何异常都触发回滚。这里有另一个隐藏的坑是事务只对RuntimeException回滚如果catch住了异常自己处理不抛出事务是不会回滚的。我还遇到过一个很坑的细节房间的已用数量字段在分配和解除时需要同时更新如果这两处更新不在同一个事务里并发情况下会出现数量不一致。演示时没有并发看起来正常但一旦考试现场有人反复刷新问题就暴露了。Transactional(rollbackFor Exception.class) public void registerPerson(PersonRegisterDto dto) { // 1. 插入隔离人员信息 // 2. 更新房间使用人数如果已满则抛出异常 // 3. 创建隔离记录 }6.6 演示前的数据重置如果是在答辩教室做演示建议准备一个一键重置脚本把数据库恢复到初始状态。因为演示过程中可能会把隔离记录审批完或者物资出库出到库存不足第二次演示就不好看了。我的做法是提供一个reset.sql执行后清空业务表并重新导入模拟数据演示前跑一遍干净利落。7. 还能往哪改进把课设项目拉到有亮点的思路如果做完上面这些还觉得不够有几个方向可以低成本地加分。这个加分指的是答辩或者README层面不是指无限堆功能。第一个是导入导出。用EasyExcel或者POI做一个人员信息Excel批量导入和隔离记录导出能省去手动录入的时间。这个功能实现不难但在管理系统里非常实用工作量也容易量化。第二个是图形验证码。登录时生成一个简单的算术验证码或图片验证码防止暴力破解。虽然在高强度真实场景下图形验证码防不住专业的攻击但作为演示功能完全够用还能体现你在安全方面的思考。我用Hutool的CaptchaUtil生成验证码集成成本很低。第三个是操作日志。记录每个管理员的关键操作如登记人员、审核申请、物资出入库等。实现方案可以是一个切面注解在需要记录的方法上加注解AOP自动写入日志表。这功能放在毕设里非常加分它体现的是审计意识。第四个是缓存优化。把公告列表、房间状态这类不常变化的数据用Spring Cache缓存到本地减少数据库压力。不需要引入Redis一个注解就能玩起来成本很低。我个人觉得如果时间有限优先做导入导出和操作日志因为这两个在演示时可观察性最强而且与管理系统这个主题的契合度最高。最后说点实践体会。做这类系统最重要的不是代码量大而是每一步都要知道自己为什么这么写。为什么用户表要单独分角色为什么健康打卡要单独建表为什么解除隔离要走审批流这些为什么想清楚了代码想写差都难。如果做这套系统的过程中你在某个问题上卡了两小时以上别硬撑去搜一下类似问题的处理方法甚至直接查官方文档比绕弯子快得多。希望这篇能让你少走点弯路顺顺利利写完答辩。
返回列表