Vue+SSM构建企业混合办公管理系统实践
1. 项目背景与核心需求解析这个系统是面向现代混合办公场景的一体化管理解决方案。随着企业办公模式的多样化传统的线下考勤和纸质请假流程已经无法满足实际需求。我们团队最近为一家中型科技公司开发的这套系统整合了活动报名、居家办公考勤和电子请假三大核心功能模块。系统采用前后端分离架构前端使用Vue.js框架实现后端基于SSMSpringSpringMVCMyBatis技术栈。特别设计了三种角色权限体系管理员拥有系统配置、数据统计和审批权限部门主管可查看下属员工的考勤状态和请假审批普通员工参与活动报名、提交考勤和请假申请2. 技术选型与架构设计2.1 前端技术栈决策选择Vue 2.x版本而非Vue 3.x主要基于以下考虑企业现有技术栈兼容性团队已有Vue 2.x项目经验第三方组件库支持Element UI在Vue 2.x生态更成熟开发效率Vue 2.x的Options API更适合业务逻辑复杂的后台系统前端工程化配置要点// vue.config.js关键配置 module.exports { devServer: { proxy: { /api: { target: http://localhost:8080, changeOrigin: true, pathRewrite: { ^/api: } } } }, chainWebpack: config { config.plugin(html).tap(args { args[0].title 企业办公管理系统 return args }) } }2.2 后端技术方案SSM框架组合的优势体现在Spring控制反转和面向切面编程简化业务逻辑SpringMVCRESTful API设计支持前后端分离MyBatis灵活SQL管理满足复杂报表查询需求数据库设计关键表结构CREATE TABLE attendance ( id int(11) NOT NULL AUTO_INCREMENT, user_id int(11) NOT NULL, date date NOT NULL, check_in time DEFAULT NULL, check_out time DEFAULT NULL, status tinyint(4) NOT NULL COMMENT 0-正常 1-迟到 2-早退 3-缺勤, work_type tinyint(4) NOT NULL COMMENT 0-办公室 1-居家, remark varchar(255) DEFAULT NULL, PRIMARY KEY (id), KEY idx_user_date (user_id,date) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;3. 核心功能实现细节3.1 混合考勤模块居家办公考勤的特殊处理逻辑地理位置校验集成腾讯地图JS API进行位置签到人脸识别验证调用百度AI开放平台实现活体检测工作时间计算自动扣除午休时间可配置考勤状态机设计stateDiagram [*] -- 未打卡 未打卡 -- 正常出勤: 按时打卡 未打卡 -- 迟到: 超过规定时间 正常出勤 -- 早退: 提前下班 正常出勤 -- 正常下班: 按时下班 迟到 -- 正常下班: 补足工作时间3.2 智能请假审批流请假业务规则引擎实现假期类型关联不同审批流程病假、年假、事假自动计算剩余假期额度与考勤系统联动自动标记请假日期审批状态枚举设计public enum LeaveStatus { PENDING(0, 待审批), APPROVED(1, 已批准), REJECTED(2, 已拒绝), CANCELLED(3, 已取消); private final int code; private final String desc; // constructor and getters }3.3 活动报名系统特色功能实现活动名额实时统计与显示报名截止时间自动提醒活动日历视图与个人日程同步报名表单验证逻辑示例export default { data() { return { rules: { name: [{ required: true, message: 请输入姓名, trigger: blur }], mobile: [ { required: true, message: 请输入手机号, trigger: blur }, { pattern: /^1[3-9]\d{9}$/, message: 手机号格式不正确 } ], department: [{ required: true, message: 请选择部门, trigger: change }] } } } }4. 权限控制与接口安全4.1 基于角色的访问控制(RBAC)权限树形结构设计系统管理 ├─ 用户管理 ├─ 角色管理 └─ 日志管理 考勤管理 ├─ 考勤记录 ├─ 异常处理 └─ 统计报表 请假管理 ├─ 我的请假 ├─ 待我审批 └─ 请假统计 活动管理 ├─ 活动发布 ├─ 报名管理 └─ 活动归档4.2 JWT认证实现Spring Security配置要点Configuration EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { Override protected void configure(HttpSecurity http) throws Exception { http.csrf().disable() .authorizeRequests() .antMatchers(/api/auth/**).permitAll() .antMatchers(/api/admin/**).hasRole(ADMIN) .antMatchers(/api/manager/**).hasRole(MANAGER) .anyRequest().authenticated() .and() .addFilter(new JwtAuthenticationFilter(authenticationManager())) .addFilter(new JwtAuthorizationFilter(authenticationManager())); } }前端路由守卫示例router.beforeEach((to, from, next) { const hasToken localStorage.getItem(token) if (to.matched.some(record record.meta.requiresAuth)) { if (!hasToken) { next(/login) } else { const userRole store.getters.role if (to.meta.roles !to.meta.roles.includes(userRole)) { next(/403) } else { next() } } } else { next() } })5. 性能优化实践5.1 前端加载优化路由懒加载配置const UserManagement () import(./views/UserManagement.vue) const AttendanceReport () import(./views/AttendanceReport.vue)关键资源预加载link relpreload href/fonts/element-icons.woff asfont crossorigin组件级代码分割components: { DatePicker: () import(element-ui/lib/date-picker) }5.2 后端接口优化MyBatis二级缓存配置cache evictionLRU flushInterval60000 size512 readOnlytrue/SQL优化案例-- 原查询 SELECT * FROM attendance WHERE user_id ? AND date BETWEEN ? AND ? -- 优化后 SELECT date, MAX(CASE WHEN check_in IS NOT NULL THEN 1 ELSE 0 END) AS has_check_in, MAX(CASE WHEN check_out IS NOT NULL THEN 1 ELSE 0 END) AS has_check_out FROM attendance WHERE user_id ? AND date BETWEEN ? AND ? GROUP BY date6. 项目部署与运维6.1 前端部署方案Nginx生产环境配置要点server { listen 80; server_name office.example.com; location / { root /usr/share/nginx/html; index index.html; try_files $uri $uri/ /index.html; } location /api { proxy_pass http://backend-server; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } gzip on; gzip_types text/plain application/javascript application/x-javascript text/css; }6.2 后端CI/CD流程Jenkins pipeline关键阶段pipeline { agent any stages { stage(Checkout) { steps { git branch: main, url: gitexample.com:project.git } } stage(Build) { steps { sh mvn clean package -DskipTests } } stage(Test) { steps { sh mvn test } } stage(Deploy) { steps { sshPublisher( publishers: [ sshPublisherDesc( configName: production-server, transfers: [ sshTransfer( sourceFiles: target/*.war, removePrefix: target, remoteDirectory: /opt/tomcat/webapps ) ] ) ] ) } } } }7. 典型问题排查实录7.1 跨域问题解决方案开发环境配置Configuration public class CorsConfig implements WebMvcConfigurer { Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping(/**) .allowedOrigins(*) .allowedMethods(GET, POST, PUT, DELETE) .allowCredentials(true) .maxAge(3600); } }生产环境注意事项必须严格限制allowedOrigins为可信域名列表避免使用通配符*7.2 大文件上传优化分片上传前端实现async function chunkedUpload(file, url, chunkSize 2 * 1024 * 1024) { const chunks Math.ceil(file.size / chunkSize) const md5 await calculateMD5(file) for (let i 0; i chunks; i) { const start i * chunkSize const end Math.min(file.size, start chunkSize) const chunk file.slice(start, end) const formData new FormData() formData.append(file, chunk) formData.append(chunkNumber, i 1) formData.append(totalChunks, chunks) formData.append(identifier, md5) await axios.post(url, formData, { headers: { Content-Type: multipart/form-data } }) } }后端合并逻辑public void mergeFiles(String fileName, String fileMd5, int totalChunks) throws IOException { String tempDir /upload/temp/ fileMd5; String destPath /upload/files/ fileName; try (FileOutputStream fos new FileOutputStream(destPath)) { for (int i 1; i totalChunks; i) { File chunkFile new File(tempDir, i .part); Files.copy(chunkFile.toPath(), fos); chunkFile.delete(); } } new File(tempDir).delete(); }8. 项目扩展与演进8.1 移动端适配方案基于Vue的响应式布局技巧/* 小屏幕设备样式 */ media (max-width: 768px) { .form-container { width: 95%; padding: 10px; } .el-dialog { width: 90% !important; } }8.2 微服务化改造Spring Cloud集成规划服务拆分认证服务考勤服务请假服务活动服务统一网关Spring Cloud Gateway服务注册Nacos配置中心Nacos Config8.3 数据分析扩展考勤数据统计示例public MapString, Object getAttendanceStats(Integer userId, DateRange range) { MapString, Object stats new HashMap(); // 出勤率计算 Long totalDays attendanceMapper.countWorkDays(userId, range); Long presentDays attendanceMapper.countPresentDays(userId, range); stats.put(attendanceRate, totalDays 0 ? String.format(%.1f%%, presentDays * 100.0 / totalDays) : N/A); // 迟到早退统计 stats.put(lateTimes, attendanceMapper.countLateTimes(userId, range)); stats.put(earlyTimes, attendanceMapper.countEarlyTimes(userId, range)); // 居家办公占比 Long remoteDays attendanceMapper.countRemoteDays(userId, range); stats.put(remotePercentage, totalDays 0 ? String.format(%.1f%%, remoteDays * 100.0 / totalDays) : N/A); return stats; }在实际项目开发中我们发现表单验证的交互体验对用户满意度影响很大。通过引入异步验证和防抖处理系统表单提交成功率提升了35%。特别是在请假申请场景实时显示可用假期余额和自动计算请假时长这两个小功能获得了90%以上的用户好评。

相关新闻

从经典MMO源码剖析游戏服务器核心架构与设计思想

从经典MMO源码剖析游戏服务器核心架构与设计思想

1. 项目概述:从一份源码到一套架构思维如果你是一名C后台开发者,或者对游戏服务器这个“黑盒”充满好奇,那么一份名为“热血江湖”的服务端C源代码,其价值远超一份可以编译运行的代码。它更像是一张被时间定格的手术解剖图&#x…

2026/10/12 11:06:41 阅读更多 →
前端工程化与微前端架构方案落地:升级前先做这几项确认

前端工程化与微前端架构方案落地:升级前先做这几项确认

前端工程化与微前端架构方案落地:升级前先做这几项确认说明:本文的依赖冲突和协作问题均为示例场景。版本策略、隔离方式与回滚范围取决于宿主、子应用和共享依赖的实际契约。1. 周五晚上的紧急撤回:3个子应用在基座升级后全部报 Invalid Hoo…

2026/10/13 15:03:30 阅读更多 →
高效图像序列处理:5步掌握视频合成核心技巧

高效图像序列处理:5步掌握视频合成核心技巧

高效图像序列处理:5步掌握视频合成核心技巧 【免费下载链接】ComfyUI-VideoHelperSuite Nodes related to video workflows 项目地址: https://gitcode.com/gh_mirrors/co/ComfyUI-VideoHelperSuite 在AI视频创作中,你是否遇到过这样的困扰&#…

2026/10/13 2:17:31 阅读更多 →

最新新闻

大模型API成本优化:三层缓存设计与语义缓存实战指南

大模型API成本优化:三层缓存设计与语义缓存实战指南

上个月底的模型服务计费后台让我有点坐不住了——一个日活不到两百人的内部文档问答工具,账单比上个月翻了将近四倍。翻完调用日志,原因并不复杂:大量请求在问相似的问题,而每一次请求都在为完全相同的系统提示词和检索上下文全额…

2026/10/14 20:31:49 阅读更多 →
别在PPT上“二次创业”了:书匠策AI把论文的“视觉翻译”这件事想明白了

别在PPT上“二次创业”了:书匠策AI把论文的“视觉翻译”这件事想明白了

书匠策AI官网:www.shujiangce.com 微信公众号搜一搜:书匠策AI 你好,我是你们的论文写作科普博主。 今天想和你聊一个我观察了很久的“学术怪现象”:很多研究生能把三万字论文写得逻辑严密,却搞不定十五页的答辩PPT。…

2026/10/14 20:31:49 阅读更多 →
你的论文在“装”人类吗?书匠策AI官网www.shujiangce.com:一场关于“去AI味”的坦白局

你的论文在“装”人类吗?书匠策AI官网www.shujiangce.com:一场关于“去AI味”的坦白局

书匠策AI官网:www.shujiangce.com,微信公众号搜一搜“书匠策AI 你有没有想过一个问题:当你熬夜手写的那段综述,被系统判定为“高度疑似AI生成”时,真正被冒犯的到底是谁? 是那个逐字敲键盘的你&#xf…

2026/10/14 20:31:49 阅读更多 →
端侧多模态嵌入模型EmbeddingGemma 2:7.4亿参数下的隐私搜索与量化部署实践

端侧多模态嵌入模型EmbeddingGemma 2:7.4亿参数下的隐私搜索与量化部署实践

1. 端侧多模态嵌入模型到底在解决什么问题1.1 从一个真实痛点说起做过搜索或者推荐系统的朋友应该都有体会:传统方案是把用户查询和文档都送到云端服务器,由大模型算出向量表示,再返回相似度结果。这套流程在大多数场景下跑得挺顺&#xff0c…

2026/10/14 20:31:49 阅读更多 →
书匠策AI官网www.shujiangce.com:期刊论文的“熵减外挂”——一个教育博主的反直觉观察

书匠策AI官网www.shujiangce.com:期刊论文的“熵减外挂”——一个教育博主的反直觉观察

官网:www.shujiangce.com ,微信公众号搜一搜“书匠策AI 各位同学好。我是那个整天在后台被你们追问“论文到底怎么下手”的教育博主。 今天我想聊一个反直觉的东西。 你们一定见过太多“AI一键生成论文”的宣传了。但我今天要说的这件事&#xff0c…

2026/10/14 20:31:49 阅读更多 →
T3 Stack全栈模板:端到端类型安全的工程实践指南

T3 Stack全栈模板:端到端类型安全的工程实践指南

t3code是我最近在整理的一个全栈模板项目代号,准确说,它不是某个第三方框架,而是我把过去两年用 T3 Stack 搭建、迭代、上线过的几套实际业务系统里沉淀出来的代码组织方式,集中到了一个可复现的模板里。这个模板的核心是端到端类…

2026/10/14 20:30:49 阅读更多 →

日新闻

AnyPS5通用适配层设计:兼容性与性能的工程取舍

AnyPS5通用适配层设计:兼容性与性能的工程取舍

1. 从"AnyPS5"这个名字说起:它到底想解决什么问题第一次看到"AnyPS5"这个标题,我脑子里冒出来的第一个念头是:这大概率是一个围绕"跨平台运行"或者"通用适配"做文章的项目。名字里的"Any"…

2026/10/14 0:00:41 阅读更多 →
Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

1. 项目概述:Flutter跨平台二手交易应用开发作为一名长期从事移动应用开发的工程师,我最近完成了一个基于Flutter框架的二手物品交易平台项目。这个项目最吸引我的地方在于它完美结合了Flutter的跨平台优势与HarmonyOS的生态特性,实现了"…

2026/10/14 0:00:41 阅读更多 →
DFS算法解决飞机降落调度问题实战

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景,也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间,确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中,这类问题直接关系到飞行安全和机…

2026/10/14 0:00:41 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/14 16:30:29 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 22:01:27 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 7:53:34 阅读更多 →