SSM框架小型企业办公自动化系统设计与权限流转实践
2026/9/16 4:05:43 网站建设 项目流程

简介:基于SSM与MySQL的小型企业办公自动化系统,定位为Java方向的毕业设计项目,适合计算机专业学生用于课程设计、毕设答辩或企业信息化入门参考。系统完整覆盖管理员、部门经理、总经理、员工四类角色的权限与业务流程,包括审批流程管理、内部邮件收发、离职申请审核、工资核算发放、留言互动等功能,能有效解决中小企业办公信息分散、流程流转低效的问题。压缩包共430个文件,主要包含110个java源码、44个vue前端页面、162个svg图标,以及sql数据库脚本、doc/docx论文文档、bat一键部署脚本和配置说明等,资源整体约10.14MB。已有60人学习浏览。源码结构清晰,附带论文与部署说明,可直接导入Eclipse运行验证,也可作为二次开发或毕业设计修改的基础。

1. 一套可以“按角色走完流程”的SSM办公自动化系统

如果你的课程设计被要求“不是简单增删改查”,这个基于SSM+MySQL的小型企业办公自动化系统是一个合适的参考起点。它把办公场景切成公告、留言、内部邮件、工资发放、离职审批几条线:管理员搭框架,部门经理处理日常协作,总经理做最终决策,员工提交申请。相比单表CRUD,代码多了角色权限和状态流转约束,而SSM的配置显式写在XML中,便于讲清每个Bean的来源。适合熟悉JavaWeb但没接触过完整项目的读者,也适合需要快速交付可运行毕业设计的学生。文中的表结构、Mapper、部署脚本都可以直接对照源码修改。

2. 小型企业办公自动化的功能边界与SSM选型逻辑

2.1 三类角色的功能矩阵与权限控制切入点

系统预设了管理员、部门经理、总经理、员工四种身份,但业务核心是“员工发起、经理审核、总经理最终确认”这条线。先把功能矩阵列出来,后续写代码和写论文都按这张表展开。

角色关键功能涉及核心表
管理员管理部门、经理、总经理、员工、留言、工资、邮件、审批流程、离职申请dept, user, notice, salary, mail, approval, leave
部门经理发放工资、审核回复留言、管理工资、审核离职、查询下载邮件与审批流程salary, message, leave, mail, approval
总经理查询下载邮件和审批流程、审核离职、查询工资、查询员工与经理mail, approval, leave, salary, user
员工发布留言、发内部邮件、发离职申请、查公告和审批流程、查看本人工资message, mail, leave, notice, salary

从这张表能看出,权限不只是“能不能进菜单”,更重要的是数据范围限制。员工查看工资时只能看到user_id等于当前登录人的记录;部门经理可以看自己部门下所有员工的工资;总经理能看到所有部门。这种数据级权限如果只靠前端按钮隐藏完全不够,必须在后端Service层或MyBatis SQL里带上用户身份条件。

常见做法是在拦截器里拿到Session中保存的登录用户对象,再放入ThreadLocal或直接传给Service。这里给一个简化的登录拦截器,用于校验接口是否允许未登录访问。

public class LoginInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 从Session中取出登录用户 User loginUser = (User) request.getSession().getAttribute("loginUser"); if (loginUser == null) { // 没登录就强制跳转登录页 response.sendRedirect(request.getContextPath() + "/login.jsp"); return false; } // 放入UserContext,Service层可以通过静态方法获取当前用户 UserContext.set(loginUser); return true; } }

这段代码做了两件事:第一,从Session取出登录用户,没登录就强制跳回登录页,避免未授权的Controller被直接访问;第二,把当前用户放进UserContext,后续在Service层通过UserContext.get().getRole()判断角色。注意拦截器配置要排除登录页、静态资源和验证码接口,否则启动后第一次访问就会死循环。SpringMVC的XML里需要用<mvc:interceptors>显式注册,并写好exclude-mapping,这一步是很多SSM项目启动后白屏的主要原因之一。

2.2 为什么SSM在这种场景下比Spring Boot更好讲

现在新项目几乎都是Spring Boot,但这个毕业设计用SSM,不是技术上落后,而是为了把Spring容器、SpringMVC处理器映射、MyBatis会话管理这三层拆开,在Eclipse里能看到每一个XML的加载过程。

举个例子,Spring Boot的自动配置把数据源、事务管理器、Mapper扫描全部默认好,写起来快,但答辩被问到“Mapper接口和XML怎么绑定”时,很难一步步解释。SSM里你会在spring-mybatis.xml中看到类似下面的配置:

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <!-- 指定所有Mapper XML的路径 --> <property name="mapperLocations" value="classpath:mybatis/mapper/*.xml"/> </bean> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.system.dao"/> </bean>

这里sqlSessionFactory负责创建MyBatis的会话工厂,mapperLocations指定了所有Mapper XML的位置,MapperScannerConfigurer则把com.system.dao包下的接口自动代理成实现类。理解这个之后,前面功能矩阵里的每个DAO接口就只需写方法签名,不用手写实现类。这也直接决定你部署的时候,如果改过包名或者移动过XML位置,必须同步修改这几处配置,否则启动时会报BindingException

另外,SSM通常配合JSP或HTML+Ajax使用,而本项目的源码包里能看到IndexAsideStatic.vue.bakBreadCrumbs.vue.bak这类文件,说明前端的某些页面保留过Vue备份版本。拿到项目后不要被.bak文件干扰,它们是旧版前端组件的备份,真正的运行页面还是以WebContent或webapp目录下的JSP/静态页为准。理解这一点才能快速定位要改的页面,而不是打开一个.bak文件改了半天却发现它根本没被加载。

3. 数据库设计与MyBatis持久层实现

3.1 核心表结构:先定流程,再定字段

办公自动化系统里最容易设计烂的地方是审批表和工资表。很多初稿把“审批流程”做成一个字段approve_status,结果只能表达“通过/不通过”,无法记录“谁在什么时候提交、谁验证、谁批准”。更合理的做法是把审批过程拆成主表和记录表,也就是leave_apply主表存储申请主体,approval_flow存储每一步流转。系统核心表可以先按这个清单建立。

表名作用关键字段
user用户信息,区分角色id, username, password, role, dept_id
dept部门基础信息id, dept_name, manager_id
leave_apply离职申请主表id, user_id, status, apply_time
message留言及回复id, sender_id, receiver_id, content, reply_id
mail内部邮件id, sender_id, receiver_id, title, content, status
salary员工工资id, user_id, month, base_salary, bonus, deduction, is_settled
notice通知公告id, title, content, publisher_id, publish_time

这里先给出一张简化版员工离职申请表。

CREATE TABLE `leave_apply` ( `id` int(11) NOT NULL AUTO_INCREMENT, `user_id` int(11) NOT NULL COMMENT '员工ID', `reason` varchar(255) NOT NULL COMMENT '离职原因', `status` tinyint(4) DEFAULT '0' COMMENT '0草稿 1待部门经理审核 2待总经理审核 3已通过 4已驳回', `apply_time` datetime DEFAULT NULL, `manager_opinion` varchar(255) DEFAULT NULL COMMENT '部门经理意见', `gm_opinion` varchar(255) DEFAULT NULL COMMENT '总经理意见', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

这里用status字段配合两个意见字段,虽然简单,但已经能满足“员工发申请 -> 部门经理审核 -> 总经理终审”的顺序流转。ENGINE=InnoDB是为了后面使用事务,utf8mb4是为了避免中文和表情符号乱码。注意,在MySQL 5.7之前的版本里,utf8mb4需要手动设置,建议安装时就选对字符集,否则JSP页面提交中文数据后,数据库里会出现问号。

除了离职申请,还有message留言表、mail内部邮件表、salary工资表。工资表的关键字段建议如下:user_idbase_salarybonusdeductionmonthis_settled。其中is_settled表示该月工资是否已经结算,部门经理点击“发放工资”时,不是直接update所有记录,而是先检查当前月是否已有is_settled=1的记录,防止重复发放。

3.2 一个典型的多表Mapper:部门经理的审批列表

权限要求里,“部门经理查询审批流程”不是查leave_apply全表,而是查“本部门员工发起、且状态为待部门经理审核”的记录。此时SQL要join用户表,带上部门条件。这里给出MyBatis XML中的写法。

<select id="selectPendingLeave" parameterType="map" resultType="map"> <!-- 只查本部门的申请,同时过滤待部门经理审核的状态 --> SELECT l.id, u.username, l.reason, l.apply_time FROM leave_apply l INNER JOIN `user` u ON l.user_id = u.id WHERE u.dept_id = #{deptId} AND l.status = 1 AND l.dept_manager_id = #{managerId} ORDER BY l.apply_time DESC </select>

这段SQL返回的是Map,方便Controller直接转JSON,不必单独建VO对象。#{deptId}#{managerId}来自Controller传入的请求参数,实际项目里managerId应优先从UserContext中获取,不要信任前端传值,否则任意员工只要抓包改成别的managerId,就能看到其他部门的申请。注意resultType="map"的键名是数据库列名,如果列名是apply_time,前端拿到的就是applyTime还是apply_time,取决于MyBatis是否配置了驼峰映射。在spring-mybatis.xml中设置mapUnderscoreToCamelCasetrue即可解决。

3.3 工资发放与离职审批的事务配置

业务上有一个典型的并发问题:部门经理同时收到多条离职申请,如果第一笔审批失败,第二笔不能继续。因此凡是涉及“更新状态+插入审核记录+写日志”的Service方法,都要加事务。

在Spring配置里,事务的常见写法是:

<tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="approve*" propagation="REQUIRED"/> <tx:method name="pay*" propagation="REQUIRED"/> <tx:method name="query*" read-only="true"/> </tx:attributes> </tx:advice>

approve*pay*表示审批和工资发放相关方法需要事务,REQUIRED表示如果已存在事务则加入,否则新建;query*设为read-only="true"能减少MySQL锁开销。注意事务管理器默认只回滚RuntimeException,如果业务方法把异常catch住了然后返回false,事务不会回滚。我一般会在Service实现里先落库,再返回布尔值,同时把关键业务异常直接throw出去,或者在catch里手动TransactionAspectSupport.currentTransactionStatus().setRollbackOnly()。这条在答辩时主动讲出来,能比背概念加分很多。

4. 从源码到可运行:Eclipse部署与MySQL初始化

4.1 解压后的文件到底怎么用

拿到基于SSM+Mysql的小型企业办公自动化系统(源码+论文+部署说明).zip后,解压会看到一堆文件和目录。其中最容易被忽略的是IndexAsideStatic.vue.bakBreadCrumbs.vue.bak这类备份文件,它们不是Eclipse项目的标准文件,而是前端组件被替换前留下的历史版本。运行或提交作业前可以删除,不会影响系统。

真正决定能否跑起来的文件是1-install.bat2-run.bat。按照部署说明一般顺序是:先装好MySQL和JDK,然后执行1-install.bat完成数据库初始化,再执行2-run.bat启动Tomcat。如果环境没有安装MySQL,批处理会执行失败,这时需要手动导入SQL文件。文件用途可以对照下表。

文件/目录作用
1-install.bat初始化数据库、导入SQL脚本
2-run.bat启动Tomcat并输出控制台日志
IndexAsideStatic.vue.bak前端侧边栏组件旧版备份,可忽略
BreadCrumbs.vue.bak面包屑组件旧版备份,可忽略
.classpathEclipse项目编译路径配置
.projectEclipse项目标识文件

.classpath.project是Eclipse识别项目的关键,导入时不要覆盖掉。如果你用Eclipse的File -> Import -> Existing Projects into Workspace,系统会通过这两个文件自动识别源码目录和输出目录,不需要手动把Java文件拖进工程。

4.2 批处理脚本背后的日常操作

下面是一个常见的1-install.bat简化版,它做的事情和手工建库、导入数据一致。

@echo off set MYSQL_HOME=C:\Program Files\MySQL\MySQL Server 5.7 set DB_NAME=office_db set DB_USER=root set DB_PASS=123456 "%MYSQL_HOME%\bin\mysql.exe" -u%DB_USER% -p%DB_PASS% -e "create database if not exists %DB_NAME% default character set utf8mb4;" "%MYSQL_HOME%\bin\mysql.exe" -u%DB_USER% -p%DB_PASS% %DB_NAME% < script\init.sql echo database initialized.

mysql.exe -e执行建库语句,< script\init.sql把SQL文件重定向到MySQL客户端执行。注意这里的密码写死在bat里,仅适合本机安装。实际部署时如果你改了MySQL root密码,需要同步修改这里。2-run.bat一般是先检查Tomcat环境变量,然后调用catalina.bat run,让Tomcat在前台运行并输出日志,便于看到启动过程中有没有报错。

4.3 JDK、Tomcat、MySQL的版本组合与连接参数

SSM项目对版本敏感,最常见的坑是JDK编译级别与Tomcat不兼容。推荐组合是JDK 1.8 + Tomcat 8.5 + MySQL 5.7,这是这套代码最稳定的环境。如果本机已经装了JDK 11或17,Eclipse里可能出现Unsupported major.minor version,这时需要把项目Compile Level改回1.8,并且确认JRE System Library指向的是JDK 8。

组件推荐版本检查项
JDK1.8Eclipse中Compile Level为1.8
Tomcat8.5端口未占用,启动日志无异常
MySQL5.7字符集为utf8mb4,root密码和jdbc.properties一致

数据库连接参数一般在jdbc.properties中,典型的写法如下:

jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/office_db?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai jdbc.username=root jdbc.password=123456

这里characterEncoding=utf8保证Java和MySQL之间中文不乱码,serverTimezone=Asia/Shanghai是MySQL 8.0驱动必须的,否则会因为时区问题连接失败。如果你的项目里用的是旧驱动com.mysql.jdbc.Driver,说明它适配MySQL 5.x;如果改成com.mysql.cj.jdbc.Driver,则适配MySQL 8.x,两者不要混用。

5. 启动故障、权限验证与二次开发切入点

5.1 三个高频异常怎么定位

第一个异常是Invalid bound statement (not found),前面第二章提到的MapperScannerConfigurer配置错误会导致这个问题。排查顺序是:确认Mapper接口路径和XML命名空间是否一致,确认XML文件是否在mapperLocations指定的目录内,最后查XML中每个id是否和接口方法名完全一致,包括大小写。

第二个高频异常是中文乱码。JSP页面pageEncoding要设置为UTF-8,MySQL连接URL里要有characterEncoding=utf8,并且数据库建库时指定utf8mb4。三处只要有一处不一致,就会出现“页面正常,数据库问号”的情况。

第三个是Tomcat端口冲突。2-run.bat启动时如果提示Port 8080 was already in use,说明本机有其他服务占用8080。优先修改conf/server.xml里的Connector端口,而不是暴力杀掉进程,特别是开发环境可能有多个项目都要用8080。

5.2 打通一条入职到离职的验证路径

拿到系统后,不要只启动页面看菜单。建议按下面的步骤验证权限和流程是否能真正闭环。

步骤操作预期结果
1管理员创建部门经理和员工用户列表出现新账号
2员工登录,发留言、邮件、提交离职申请对应列表出现草稿或待审记录
3部门经理登录,审核留言、审批离职留言有回复,离职状态变为待总经理审核
4总经理登录,查询审批流程并终审离职状态变为已通过
5员工查询申请状态页面显示已通过

如果第2步之后,第3步部门经理看不到数据,优先检查数据权限SQL;如果第3步审核后第4步总经理看不到单据,说明状态没有从1流转到2,需要看Service里有没有调用下一步更新方法。这条路径跑通后,系统的核心模块就都验证过了。

5.3 后续扩展:把SSM项目往Spring Boot迁移时的关键改造点

这个项目的价值不止于交作业,如果你后面想继续用,常见改动是迁移到Spring Boot,让环境更现代。迁移时尽量别一次性改完,分三步走:先只引入spring-boot-starter-webmybatis-spring-boot-starter,保持原有MyBatis XML不动;再把配置项从jdbc.properties改成application.yml;最后用@MapperScan替换MapperScannerConfigurer。最容易踩坑的是事务注解,Spring Boot项目若不显式引入spring-boot-starter-jdbc,开箱自带的数据源可能无法使用原有连接池参数,导致启动时数据源初始化报错。

另一个切入点是给系统补一个简单的操作日志表,记录用户、操作时间、操作类型和IP。比如部门经理发放工资时,写一条oper_log记录。这个功能实现起来不难,但在答辩时可以作为“安全性改进”的亮点,比单纯扩大功能更受认可。

本文还有配套的精品资源,点击获取

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

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

立即咨询