SpringBoot+Vue+MyBatis+MySQL企业OA管理系统落地实战

发布时间:2026/10/20 6:55:29
SpringBoot+Vue+MyBatis+MySQL企业OA管理系统落地实战 最近几年总有人问我说想做一个企业内部的管理系统问我用什么技术栈、怎么搭结构、哪些坑要注意。说实话企业OA这种项目单看每个功能都不难难的是把所有模块捏合成一个完整、稳定、能真正上线用的系统。我前前后后参与过几个OA项目的开发从最开始自己闷头写后端到后来用SpringBootVueMyBatisMySQL这套组合拳完整落地了一个企业级OA管理系统中间踩过的坑和总结出来的经验足够写成一篇文章了。这篇文章就围绕这个技术架构来聊从业务拆解、数据库设计、权限控制、审批流实现到最后的部署上线把整个完整版OA系统怎么搭起来的思路和细节都过一遍给正在规划或者已经开始做类似项目的人一个参考。1. 企业OA到底在管什么先理清业务边界再做技术设计很多开发者拿到OA需求的第一反应是找框架、建工程、写登录。这个顺序其实是错的。OA系统最大的难点从来不是某段代码怎么写而是在动工之前你有没有把这个系统到底要管哪些事彻底想清楚。业务边界不清晰做出来的东西要么功能堆砌、要么关键流程缺失后期改起来非常痛苦。1.1 核心业务模块拆解审批流、考勤、公告、会议、文档、人事我接手的那套完整版OA系统业务模块大致分为六块审批中心、考勤管理、公告通知、会议管理、文档中心、人事基础信息管理。每一块单独拿出来都能做成一个独立的小系统但在OA里它们要共享同一套用户体系、组织架构和权限模型这就是OA和单点业务系统的本质区别。审批中心是灵魂。请假、报销、用章、采购申请都走审批流。一个流程要能支持多级审批、条件分支、加签转签、撤回、驳回、抄送。考勤管理做打卡记录、请假销假、加班调休和月度统计。这块要跟审批中心联动——请假审批通过之后考勤数据要自动扣减。公告通知承担信息发布和已读回执功能发布范围要能按部门、按角色圈选。会议管理管会议室预订、会议通知和会议纪要上传要处理冲突检测。文档中心解决企业内部文档的集中存储和权限查看问题按目录树组织不同的部门只能看到自己权限范围内的文档。人事基础信息管理是后台的支撑模块维护员工档案、部门架构和岗位信息。我的建议是无论标题里有没有提到企业级三个字做OA的第一件事就是把上面这些业务模块列出一张表逐项标注哪些是第一期就要做的、哪些可以二期再做。我那个项目的做法是第一期做审批、考勤、公告、人事这四个核心模块会议和文档放第二期。理由很简单审批和考勤是企业日常运转最刚需的部分先把主干跑通后续模块再慢慢挂上去。1.2 角色与权限模型决定了系统的复杂度上限OA系统的企业级三个字很大程度上体现在权限模型的完整度上。一套权限模型的好坏直接决定了后面所有模块能走多远。我采用的模型是经典的用户-角色-权限三层结构加上部门维度做数据隔离用户表关联角色表角色表关联权限表这是横向的功能权限控制 用户所属部门决定数据可见范围这是纵向的数据权限控制打个比方A部门的部门经理和B部门的部门经理拥有相同的角色、相同的功能权限都能看到员工管理菜单但A部门的经理只能查询和编辑A部门下的员工B部门的经理也一样。功能权限大家相同数据范围各管各的。这就是功能权限和数据权限的分离设计也是企业级OA系统最常见、最实用的权限方案。功能权限控制你能看到哪些菜单、能点击哪些按钮对应后端接口的访问控制。数据权限控制你能看到哪些数据典型场景是部门隔离、本人数据隔离、全部数据可见三种级别。把这两层拆开权限梳理才不会乱。很多人做OA时角色权限做得过于简单比如直接用角色编号判断能不能访问某个URL结果业务一复杂就到处打补丁。正确的做法是建立完整的权限点表每个接口、每个按钮都对应一个权限标识角色再关联权限标识集合。2. SpringBoot Vue MyBatis这套组合为什么是中小企业OA的首选技术选型永远没有绝对的最好只有最合适。SpringBootVueMyBatisMySQL这套组合说不上技术多么前沿但它非常适合企业OA管理系统这种典型的企业级Web应用场景。原因也很简单生态成熟、招人容易、资料丰富、稳定性强。做企业项目最怕的不是技术旧而是团队里的人搞不定、出了问题找不到解决方案。2.1 技术分工后端、前端、持久层的各自定位这套架构里每一层的职责边界很清楚这也是我选它的重要原因。SpringBoot负责后端业务逻辑和接口暴露。它内置了Tomcat简化了Spring的XML配置写RESTful接口非常效率。Spring Security或者自定义拦截器可以嵌在里面处理认证授权Spring的声明式事务管理做审批这类多表操作时特别可靠。Vue负责前端页面渲染和交互。Vue的组件化开发模式很适合OA这种页面多、模块杂的系统。每个业务模块拆成独立的组件菜单、路由、状态管理各司其职开发效率比传统的JSP模板高得多。MyBatis负责数据库操作。它比JPA更灵活SQL自己控制适合做审批流、考勤统计这类复杂报表查询。OA系统的查询条件经常是动态拼出来的MyBatis的where标签和foreach标签在这种场景下非常好用。MySQL负责数据存储。开源免费、稳定可靠配合InnoDB引擎的行级锁和事务支持应对企业内部几百人甚至几千人的并发访问完全够用。提示选MyBatis而不是MyBatis-Plus我个人的看法是底座仍然选MyBatis但可以引入MyBatis-Plus作为增强工具处理单表CRUD复杂查询自己写XML。这样既保留了SQL灵活性又不浪费精力在重复的单表操作上。2.2 对比其他组合的取舍逻辑很多人会问为什么不选Spring Cloud微服务架构或者为什么不前后端不分离用Thymeleaf。我说一下我的真实看法。面对几百人规模的企业OA单体应用完全能扛住。微服务带来的分布式事务、服务治理、链路追踪问题在这个规模下属于纯粹的复杂度浪费。前后端分离的好处在于开发和部署时前端后端互不干扰。前端团队和后端团队可以并行开发部署时前端静态文件扔到Nginx后端打成Jar包独立运行扩展和故障排查都方便。如果用传统模板渲染改个页面样式都要重启后端服务不灵活。用Vue纯前端渲染还有一个现实好处页面交互体验比表格页刷新好很多审批流程里那种复杂的表单控件、流程状态流转的即时反馈只有前端渲染才能做到流畅。当然这套组合也有它的痛点比如SEO支持差、首屏加载稍慢但在企业内部系统里这些都不是致命问题。OA是登录后才能用的系统不需要搜索引擎收录首屏加载通过路由懒加载和静态资源压缩也能优化到可接受范围。2.3 项目分层结构与目录规划一个清晰的项目分层可以让多人协作时不打架也可以让后续维护的人一看就懂。我维护的那套OA系统后端按下面的结构来划分包名com.company.oa ├── controller // 接口层接收前端请求返回统一响应结果 ├── service // 业务层处理实际业务逻辑事务在这里控制 ├── mapper // 数据访问层对应MyBatis的Mapper接口 ├── entity // 数据库实体类对应表结构 ├── dto // 数据传输对象接收前端参数或组装返回数据 ├── vo // 视图对象前端页面需要的数据结构 ├── config // 配置文件类如跨域配置、拦截器注册、Shiro/JWT配置 ├── utils // 工具类如日期处理、Excel导入导出、文件上传 └── common // 公共类统一返回体、异常处理、常量定义前端Vue工程用Vue CLI或Vite搭建目录按照模块去拆分才不会被后续加进来的需求打乱src ├── api // 所有接口请求定义按模块拆文件user.js、approval.js、attend.js ├── views // 页面组件按模块建文件夹views/system、views/approval ├── components // 公共组件上传组件、富文本编辑器、表单组件 ├── router // 路由配置结合权限做动态路由注册 ├── store // Vuex状态管理存用户信息、权限点列表、全局缓存数据 ├── utils // axios封装、日期格式化、文件下载等公共方法 └── assets // 静态资源我在做目录规划时有一个体会后端的entity、dto、vo千万不要混着用。很多开发图省事一个实体类从头传到尾前端要什么字段就往里面加最后实体类膨胀得面目全非还引发JSON序列化把密码字段返回给前端的乌龙。分层虽然代码量多一点但每个类的职责单一出了问题定位极快。3. 数据库设计一张表一张表地把业务落成模型数据库设计是整个OA系统里最重要、也最考验经验的部分。表结构没设计好后面每个业务模块开发时都会觉得别扭。我这次核心库采用MySQL 8.0版本默认存储引擎InnoDB字符集utf8mb4。这样排序规则不需要额外处理中文同时也兼容emoji字符。3.1 用户、角色、部门与权限五张核心表的设计权限相关的五张表是整个系统的地基这五张表设计好了其他业务表都好说sys_user用户表字段包括id、username、password、real_name、dept_id、status、create_time。密码存加密后的值绝不能明文存储。sys_dept部门表字段包括id、parent_id、dept_name、order_num、status。parent_id实现部门树结构一个顶级部门下面挂多个子部门。sys_role角色表字段包括id、role_name、role_code、remark、status。sys_menu菜单权限表字段包括id、parent_id、menu_name、url、perms、menu_type、order_num。这个表既管菜单展示也管功能权限点的定义。menu_type区分目录、菜单、按钮三种类型按钮类型的权限点对应前端按钮的显示隐藏和后端接口的访问控制。sys_user_role和sys_role_menu用户角色关联表、角色菜单关联表都是多对多关系的中间表。这五张核心表做出来之后配合一个递归查询工具就能组成完整的菜单树和权限列表。我在设计时还加了一个小技巧菜单表里增加了路由路径和组件路径字段这样前端菜单渲染出来后可以直接通过路由懒加载定位到对应的Vue组件不需要前后端各维护一套菜单数据。3.2 审批流表的建模思路流程实例、审批记录、表单数据审批流是OA系统公认最复杂的模块数据库设计上我把它拆成了三个层次oa_approval_process审批流程定义表。记录一个流程有哪些审批节点、每个节点的审批类型、多级审批对应的是哪个部门角色。比如请假流程定义为主管审批到部门经理再到人事备案流程定义表负责固化这个模板。oa_approval_instance审批实例表。员工发起一次请假就生成一条审批实例记录。它关联到流程定义同时记录当前的审批节点序号、流程状态审批中、已通过、已驳回、已撤回。oa_approval_record审批记录表。每次有人审批操作就插入一条记录记录操作人、操作时间、审批意见、操作类型同意、驳回、转签、加签等。这就是审批意见的时间轴前端展示的时候是按时间倒序拉出来的。表单的明细数据怎么处理我的做法是单独建一张业务申请表单表。比如请假申请有开始时间、结束时间、请假天数、请假事由这些字段不适合放到通用的审批实例表里因为不同业务类型字段差别太大。于是我用一张oa_approval_form_data表以JSON字段的形式存储具体业务表单内容审批实例表只保留公共字段。MySQL的JSON类型在这里很好用既灵活又不用频繁改表结构。注意这种JSON存储方案要搭配一个表单校验机制。前端提交表单时要保证必要的业务字段都有值后端在开启审批实例时要对JSON里的关键字段做校验比如请假天数必须是正数、日期必须不冲突。不要偷懒不校验否则后面做统计报表时会发现脏数据多到怀疑人生。3.3 MyBatis下复杂查询的SQL写法与性能注意事项审批记录列表、考勤统计、待办事项查询这些都是OA系统的高频查询SQL写得不好很影响体验。MyBatis里最常用的几个动态SQL标签我这里列一个实际场景。以考勤月度统计为例要查出某部门某个月每个人的出勤天数、请假天数、迟到次数我的Mapper XML大概是这样的思路SELECT u.real_name, COUNT(DISTINCT CASE WHEN a.attend_type NORMAL AND a.status NORMAL THEN a.attend_date END) AS normal_days, COUNT(DISTINCT CASE WHEN a.attend_type LEAVE THEN a.attend_date END) AS leave_days FROM sys_user u LEFT JOIN oa_attendance a ON a.user_id u.id AND a.attend_date BETWEEN #{startDate} AND #{endDate} WHERE u.dept_id IN (SELECT id FROM sys_dept WHERE parent_id #{deptId} OR id #{deptId}) GROUP BY u.id这条SQL里有两个值得注意的点LEFT JOIN的筛选条件写在ON子句里而不是WHERE子句里这是SQL的基本功。写在WHERE里会把LEFT JOIN退化成INNER JOIN导致没有考勤记录的员工被过滤掉统计结果会缺人。部门范围用递归子查询去适配部门树的父子关系。不过要注意如果部门层级很深这种子查询性能会下降。部门层级通常很浅一到三级就结束了所以实际运行没问题。性能方面我的心得体会是给外键字段建索引要不遗余力。oa_approval_record表的instance_id、approver_idoa_attendance表的user_id数据量过了十万之后有没有索引性能差异是几十倍的。另外审批列表的分页查询不要用LIMIT 100000, 20这种深分页方式可以改成基于上次查询的最大id或时间点做游标分页响应速度会稳定很多。4. 从登录到权限控制认证与授权这条主链路怎么打通登录和权限控制这条链路是企业OA系统的安全命脉。从用户输入用户名密码到访问某个按钮触发的接口中间要经过认证、鉴权两层检查然后把用户信息和权限上下文贯穿到整个请求周期里。做得完整系统才配叫企业级。4.1 JWT令牌方案的选择与拦截器设计前后端分离架构下Session的维护成本比较高跨域场景还容易遇到Cookie携带问题我选择用JWT来做登录态管理。基本流程是用户输入用户名密码后端校验通过后生成JWT令牌令牌里包含用户id、用户名、角色编码等必要信息设置合理的过期时间比如8小时。前端登录成功后把JWT令牌存到localStorage里。前端每次发请求时在axios的请求拦截器里把令牌附加到Authorization头中。后端配置拦截器对需要认证的接口从请求头里解析令牌校验签名和有效期通过后放行。拦截器的设计有几个升级点需要注意。把不需要登录的接口排除在外比如登录接口、验证码接口、密码重置接口这些对应的URL要在拦截器白名单里配置好。令牌刷新机制可以做。如果前端判断令牌快过期了可以用一个长期有效的refresh token去换新的access token避免用户正在审批流程操作到一半突然被强制下线。令牌内不能放敏感信息比如完整的手机号、家庭住址之类。JWT默认只是Base64编码并不是加密任何一个拿到令牌的人都可以解析出payload里的明文内容。我一般只在令牌里放用户的id和登录账号其他用户信息每次请求时再从数据库查一次这样即使账号资料有变动下一次请求也能拿到最新数据。4.2 按钮级权限的Vue路由守卫实现登录之外前端要解决的是这个用户登录进来后能看到哪些菜单、哪些按钮。我们需要做到按钮级的细粒度权限控制而不是简单粗暴地靠路由隐藏页面。动态路由注册。用户登录成功后后端返回该用户的菜单树和权限点集合存入Vuex。前端遍历菜单树生成路由再用router.addRoutes注册动态路由然后让页面跳转到第一个有权限的菜单。路由守卫配合。router.beforeEach里判断用户是否已登录、当前访问的路由是否在动态路由列表中不在则跳转到404页面或者提示无权限。按钮权限用自定义指令。在Vue里注册一个v-permission指令传入权限标识指令内部判断当前用户的权限点集合是否包含该标识不包含就移除这个DOM元素。// 自定义按钮权限指令的核心逻辑 Vue.directive(permission, { inserted(el, binding) { const requiredPermission binding.value const permissionList store.getters.permissions || [] if (!permissionList.includes(requiredPermission)) { el.parentNode el.parentNode.removeChild(el) } } })页面模板里这样用button v-permissionapproval:leave:add发起请假/button这样即便有人绕过前端直接调用后端接口后端拦截器里对approval:leave:add权限点也会做鉴权两头堵死。4.3 用户会话安全与密码加密的实操要点密码安全在OA这种企业内部系统里容易被低估很多人觉得内网系统无所谓。但企业级系统就该按企业级标准来做何况外网访问的场景并不少见。密码存储用BCrypt加密Spring Security里自带的BCryptPasswordEncoder可以直接用。BCrypt的特点是为每个密码生成随机的盐相同的密码加密后的结果也不一样这样就算数据库泄露撞库成本也高很多。不要用MD5或者SHA这些纯哈希算法没有加盐的话用彩虹表几秒钟就能破解。登录接口要防暴力破解。我的做法是连续输错五次密码后该账号锁定十五分钟同时登录接口接一个简单的图形验证码。验证码不复杂但能把自动化的撞库工具挡在门外。另外密码过期策略也可以加进来设置九十天强制用户修改密码很多安全审计都对这项有要求。系统里的操作日志和审计日志也不能少。用户登录、发起审批、审批通过、修改密码、导出数据这些关键操作都要落日志表。出了安全问题或者业务纠纷日志就是唯一的追溯依据。日志表的设计不复杂字段就是操作人、操作时间、操作类型、操作内容、请求IP和操作结果。千万不要嫌麻烦就不做后面想要补审计功能的时候会后悔当初没留数据。5. 审批流模块的实战设计这是OA系统的灵魂审批流做得好不好直接决定了OA系统能不能真正投入使用。我见过太多伪审批流只支持一级审批部门经理批完就结束了稍微复杂点的流程就跑不通。企业里的真实审批场景非常灵活今天这个部门增加一个会签节点明天那个流程要加一个抄送人如果设计的时候不考虑扩展性后期会改到怀疑人生。5.1 审批流程引擎节点、条件、操作人不做复杂的工作流引擎比如Flowable、Activiti那种原因很简单人力资源有限学习成本高而且大部分企业的OA审批场景用不到那么重的引擎。我用的是自己设计的轻量级流程引擎基于节点配置来驱动。流程定义表的设计大致是这样的思路每个流程包含多个节点每个节点配置审批类型、审批人来源和节点顺序。审批人来源有三种常见方式都在建表时预留好指定固定角色比如人事经理审批适合流程相对固定的场景。发起人的部门负责人这种最常见请假、报销基本都是先经直属主管审批。上一节点指定的审批人用于加签、会签场景。流程条件分支是另一个重点。用一个条件表达式字段比如请假天数大于三天时需要走部门经理审批三天以内只需要主管审批。这个字段存一个JSON表达式后端在流转时动态解析表达式根据结果决定下一个节点是哪个。表达式引擎不需要引入复杂的规则引擎简单场景下用Java的ScriptEngine或者自己解析JSON都能满足。5.2 前端发起审批与后端状态机的对应关系审批过程本质是一个状态机。我定义了六种状态草稿、审批中、已通过、已驳回、已撤回、已结束。状态流转图我列在下面方便你对着实现。发起成功后草稿变为审批中。当前节点审批人同意且还有下一节点时还是审批中但current_node指向下一节点。当前节点审批人同意且没有下一节点时状态变为已通过。任一节点审批人驳回状态变为已驳回。审批人还未审批时发起人可以撤销申请状态变为已撤回。后端接口设计对应着这套状态机接口要控制状态变更的合法性。比如只有审批中状态的实例才能提交审批操作只有待当前用户审批的节点才能操作。所有状态变更的入口都要校验防止有人通过直接调接口的方式跳过审批环节。审批表单的数据流是这样的前端将表单数据打包成JSON连同流程定义编码一起提交给后端后端根据流程定义编码查到第一个审批节点创建审批实例和第一条审批记录状态设为审批中。业务数据JSON存到oa_approval_form_data表。之后每次审批操作时后端根据当前节点查下一节点更新实例状态插入审批记录。5.3 加签、转签、撤回等特殊场景的状态流转常规的同意和驳回只是审批流的地基企业实际使用中一定会遇到特殊场景设计时必须提前考虑。整理一下我在实战中实现过的三种特殊操作加签。当前审批人觉得需要让其他人先审批可以在自己审批之前添加一个附加节点。加签分为前加签和后加签两种。前加签是让被加签人先审批审批完再回到当前审批人后加签是自己审批完后再让被加签人审批。实现上前加签节点直接插到当前节点之前后加签节点插到当前节点之后。转签。当前审批人把审批任务转给另一个人处理自己不再参与。实现上只需要把当前节点的待办从自己名下转移到目标人名下在审批记录里插入一条转签记录即可。撤回。发起人在当前节点还没有被处理时可以撤回申请。这个操作有严格的前置条件当前节点必须还在审批中且没有审批人操作过。一旦审批人已经处理撤回入口就要关闭。这几个场景加下来审批模块的代码量会显著增加但系统的可用性也会明显提升。我记得给某工地项目做OA演示的时候对方人事总监现场提了一个需求说采购流程里财务总监需要和部门经理并行审批俩人必须都同意才能过。这种并行会签的需求需要把状态机从单一线性链路扩展成多分支汇聚实现上要引入节点级别的通过率判断。这一步扩展属于整个审批流里最复杂的部分我建议是在第一版先跑通线性链路会签并行放到二期迭代。先把主干流程用起来再逐步完善特殊场景而不是一上来就追求完美那样项目周期会拉得很长。6. 部署与上线前要检查的细节清单很多项目开发过程很顺利一到部署上线就各种状况百出。我经历过服务器上数据库中文乱码、前端打包后接口路径不对、定时任务时区偏移好几个小时等等问题。把这些经验沉淀成一份检查清单每次上线前照着过一遍能省去非常多的麻烦。6.1 环境配置与打包注意细节后端SpringBoot项目打包成可执行Jar包部署在Linux服务器的Tomcat容器之外独立运行。有几个配置容易被忽略MySQL连接串要带编码参数characterEncodingutf8和useSSLfalse、serverTimezoneAsia/Shanghai这三个参数接上才稳妥。第一个解决中文乱码第二个解决开发环境SSL证书警告第三个解决日期时间时区差8小时的问题。生产环境的配置文件和本地开发环境分开用SpringBoot的多环境配置特性。application-dev.yml放本地开发配置application-prod.yml放生产配置通过启动参数--spring.profiles.activeprod切换环境。数据库密码、Redis密码这些敏感信息不要写在配置文件里明文存储可以放在环境变量或者配置中心里引用。前端Vue项目打包之前要检查vue.config.js里的publicPath配置。部署在域名根路径下就设为/如果部署在某个子路径下就要设置为对应路径。这个配置错了打包上线后会发现JS和CSS全部加载不出来控制台全是404。构建之前还要注意Node版本和npm依赖的锁定。我遇到过同事本地Vue项目能正常构建但服务器上构建就报错的情况就是因为package.json里依赖版本写的是^1.0.0这种带范围的形式两边安装到的依赖版本不一致。解决方法是使用package-lock.json或者yarn的lock文件锁定每位依赖的精确版本。6.2 数据库初始化与数据迁移数据库迁移这件事我强烈建议用Flyway或者Liquibase这类工具来管理SQL脚本的版本变更。开发过程中表结构一直在微调如果用人工在测试环境执行SQL很容易出现某个环境漏执行了某条语句导致代码跑起来直接报字段不存在这种问题。用Flyway之后项目的资源目录下放版本化的SQL脚本按顺序执行db/migration ├── V1__init_schema.sql ├── V2__add_oa_approval_model.sql └── V3__add_attendance_leave_days.sql启动SpringBoot项目时Flyway自动检测脚本版本没执行过的自动执行执行过的记录在flyway_schema_history表中不再重复执行。初始数据也要妥善处理。管理员账号、系统角色、菜单权限这些基础数据放在初始化脚本里。我习惯用V1__init_schema.sql建表V2__init_data.sql插基础数据这样在一台全新的服务器上从零部署时只需要一个Jar包加一个数据库实例就能把整套系统拉起来省去很多手工操作。6.3 上线前必须做的压测和备份策略上线压测不能省。企业内部用的人可能只有几百人但关键是上班高峰期大家几乎同时登录打卡查待办。我用JMeter模拟过200个并发用户同时打卡和查询待办请求之前没有做任何优化时接口平均响应时间超过3秒系统CPU直接飙升。后来做了两个优化给高频查询接口加Redis缓存比如待办数量、个人信息这类不经常变动的数据缓存5到10秒就够了。优化了Nginx的worker_processes配置和Tomcat的线程池配置。Tomcat默认的100线程在200并发下会出现请求排队阻塞我把max-threads调整到200min-spare-threads调整到20队列长度也做了调整。压测之后平均响应时间降到了800毫秒以内这个数据放在OA系统里算是比较理想了。备份策略这块有两个误区要注意。一是认为有数据库备份就万事大吉二是备份了但从来没有演练过恢复。我的建议是数据库每日凌晨2点做全量备份同时开启binlog备份这样能实现时间点恢复。备份文件要存到和服务器不同的存储空间防止机器故障或者误操作把服务器上的备份文件也一起删掉。最重要的是每三个月必须做一次恢复演练确认备份文件真的能用。我见过不止一次备份脚本一直正常运行但实际恢复时才发现备份文件损坏的情况。到那时再后悔就来不及了数据库一旦损坏没有可用备份对企业来说是灾难级别的。我实际操作下来发现OA系统这种项目最花时间的不在单个技术点而在把所有模块拧在一起的工程化能力和对各种异常场景的提前预判。数据库表结构设计前多花一天画清楚ER图后续开发就能少花一周改代码权限模型一开始就做到功能权限和数据权限分离后续加新模块就能直接往里面套审批流状态机画清楚再动手后面出bug的概率会小很多。现在这套SpringBootVueMyBatisMySQL的完整版OA管理系统我把它整理成了可部署的源码包数据库里预置了基础菜单权限和几个演示账号。如果有人正在找一套可以二次开发的企业OA基础工程拿这份源码当起点比从零搭框架要省不少时间。最后再分享一个小技巧二次开发时改代码之前先把数据库脚本备份一份、把原有代码跑一遍熟悉整体流程再动手动会轻松很多。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询