律所案件管理系统实战:Spring Boot+Vue前后端分离开发与部署指南
1. 项目概述律所案件管理系统到底在管什么先说结论这套系统就是给律师事务所做“案子全生命周期管理”的数字化底座后端用 Spring Boot 提供接口服务前端用 Vue 做交互界面MySQL 负责数据持久化。如果你接手过或者打算接手这类项目你会发现它并不是一个“通用后台管理系统”那么简单它的核心难点不在增删改查而在于业务模型的设计——案件状态怎么流转、收费怎么算、文书怎么归档、权限怎么隔离合伙人、主办律师、助理、行政看到的完全是不同的东西。律所的业务场景和普通企业管理系统有明显差异。一个案子从咨询到立案、开庭、判决、执行中间涉及客户信息、证据材料、法律文书、费用节点、时间节点这些数据敏感度高、关联性强、归档要求严格。而市面上很多通用 CRM 根本管不了“举证期限提醒”“风险代理费分段计算”这类细分需求。所以这套系统的价值在于它把律师办案过程中“散落在微信聊天记录、Excel 表格、纸质卷宗里的信息”集中到一个可追溯、可统计、可权限控制的平台上。说回这套源码本身它属于典型的“前后端分离 RBAC 权限模型 业务模块化”结构非常适合用来做毕业设计、技术转岗练手项目或者中小律所直接二次开发落地。如果你正在学 Spring Boot 和 Vue 的整合它也是一份不错的“标准答案”统一响应结果、JWT 登录认证、MyBatis-Plus 操作数据库、Vue Router 动态路由、Axios 请求封装这些工程化套路在里面都有体现。我自己拿到这类源码的第一反应不是急着点运行而是先把数据库脚本从头到尾看一遍。为什么因为很多看起来“可直接运行”的项目真正卡壳的地方往往不在代码而在数据库版本、字符集、驱动配置这些“环境死角”上。这篇文章就从架构设计、业务拆解、运行实操、二次开发、避坑经验五个维度把这套系统讲透。1.1 这套系统的典型应用场景律所案件管理系统常见的应用场景包括三个层面。第一层面是行政数字化包括立案登记、结案归档、卷宗借阅、利益冲突检索这些是律所管理的基础动作第二层面是财务管控包括律师费收款计划、风险代理费计提、发票台账、案件成本核算这个模块直接关系到律所的钱袋子第三层面是运营分析包括案件数量趋势、律师创收排名、结案平均周期、客户来源分析属于为合伙人决策服务的部分。你可以把这三个层面理解成系统先把每个案件“立了案”然后跟着案件走完收费和支出的流程最后把数据聚合成报表。市面上流传比较广的律所管理系统源码一般会覆盖前两个层面第三个层面的统计报表模块根据项目完整度不同会有差异。你拿到这套源码后可以先对照这三个层面看看到底缺了哪块再决定是直接跑起来用还是做二次开发。2. 核心业务模块与技术选型背后的逻辑2.1 为什么是 Spring Boot Vue MySQL 这个组合先说技术选型。这套组合在 2024 年之后几乎成了中小型管理系统的“标准配置”原因很实际Spring Boot 让 Java 后端的开发成本大幅降低内置 Tomcat、自动配置、生态成熟招人好招、代码可控Vue 的优势在于组件化和响应式律所这类系统有大量“列表-详情-表单”的交互界面Vue Element UI 能非常高效地搭建MySQL 则是最稳妥的关系型数据库选择事务支持、备份恢复、运维资料都齐全对律所这种一天几千条操作记录的中小规模系统绰绰有余。从项目结构上看这套源码通常分三个部分后端服务Spring Boot 工程、前端工程Vue CLI 或 Vite 创建、数据库脚本SQL 文件。三者通过 RESTful API 连接。如果你看到的版本里前端代码和后端代码放在同一个仓库的不同文件夹下那就是标准的前后端分离式布局。这种布局的好处是前端可以单独部署到 Nginx后端可以单独打包成 JAR 跑在服务器上哪天要做负载均衡、接口扩容都不会被前端拖累。有个细节值得注意这套系统里权限模块的设计思路通常是“用户-角色-菜单-按钮”四层。也就是说用户不直接绑定权限而是通过角色关联菜单和按钮权限。这样做的好处是律所里“行政人员只能录案子不能看财务数据”“律师只能看到自己的案子”“合伙人能看到全所数据”这类需求可以通过配置角色来实现而不用改一行代码。2.2 案件管理的业务闭环拆解不管代码怎么写律所案件管理的核心是“案件的业务闭环”也就是线索/咨询 - 利益冲突检索 - 立案审批 - 分配承办人 - 办案过程管理 - 节点提醒 - 结案归档 - 统计报表。在这套系统里每一步都对应具体的表结构设计。举个例子立案登记时你需要一个“案件主表”存储案件编号、案件类型、立案日期、审级程序、当前状态 一个“当事人信息表”原告/被告/第三人/委托代理人 一个“承办团队表”主办律师、协办律师、助理。这三张表通过案件 ID 关联缺一不可。很多新手在开发类似系统时只建了一张案件表把所有当事人信息塞进一个字段后面做统计和检索时就会非常痛苦。办案过程管理同样值得细说。一个诉讼案件从立案到结案中间有立案、送达、举证、开庭、判决、上诉、执行等多个法定节点。这套系统里常见的做法是维护一个“案件节点表”每条节点记录关联案件 ID、节点类型、计划日期、实际完成日期、负责人。这样做的好处是定时任务每天扫描一遍节点表把“距离开庭还有 3 天”的案件推送给承办律师这个功能完全可以独立于主流程实现不侵入业务代码。收费管理是律所系统里最“特殊”的部分。律师费的收费方式包括固定收费、按标的额比例收费、风险代理收费、小时计费系统需要支持在立案时生成收费计划并记录每一笔实际到账。比如风险代理合同约定“回款后按 15% 收取”那么案件执行回款时系统要能自动按回款金额计算应收律师费并生成待收款记录。这套逻辑如果设计得干净财务人员月底对账会非常省心。2.3 文书管理模块如何做到实用文书这块是很多通用系统做不好、而律所系统必须做的事。律所日常产生大量法律文书包括起诉状、答辩状、代理词、法律意见书、委托合同、所函每一份都要有版本记录、审核记录、用印记录。这套源码里文书管理的常见实现方式是文件上传到本地目录或对象存储数据库里记录文件元数据文件名、大小、上传人、关联案件、文书类型同时保留一份“文书模板库”。这里有个实战中的注意点文件存储路径不要带中文不要用前端上传时的原始文件名直接落盘。我见过不少项目因为文件名里有中文和特殊符号导致下载时 URL 解析失败或者服务器的文件系统编码跟数据库编码不一致出现乱码。常规做法是在后端生成一个 UUID 或时间戳形式的文件名原始文件名存入数据库字段下载时再通过响应头还原。3. 项目运行实操从零到能在浏览器里看到登录页3.1 本地环境准备清单先把环境装齐这一步是最容易出问题的地方特别是数据库和 Node 版本。我列一个针对这套源码的推荐环境组件推荐版本说明JDK1.8 或 11大多数 Spring Boot 2.x 体系源码用 1.8少部分新代码要求 11Maven3.6用 IDEA 自带或独立安装均可MySQL5.7 或 8.0建议 8.0注意驱动版本Node.js14 到 16如果前端用 Vue CLI 4 node-sassNode 版本太高会直接安装失败前端包管理器npm 或 yarn建议 npm配合国内镜像IDEIDEA 或 VS Code后端 IDEA前端 VS Code两边同时开关于 Node 版本这里必须多说一句。很多“可直接运行”的前端项目锁定的依赖版本是三年前的如果你直接拿 Node 18、20 去npm install大概率会报node-sass相关的编译错误。这时候不要硬刚最快的方案是装一个 Node 16.20.2或者用 nvm 切换版本。如果项目用的是 Vite Vue 3那 Node 16 基本没有障碍。拿到项目后先看package.json里的依赖再决定 Node 版本能省大量时间。3.2 数据库初始化与配置细节数据库这一步核心是“建库、导数据、改配置”。一般源码包里会有一个.sql文件用 Navicat 或命令行执行。这里建议手动创建数据库再选择 SQL 文件导入而不是直接运行整个 SQL 文件里的 CREATE DATABASE 语句因为字符集容易被默认值带偏。CREATE DATABASE IF NOT EXISTS law_firm DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;导入完成后重点检查三张核心表有没有数据用户表sys_user 或 t_user、角色表、菜单表。如果这三张表是空的那登录页面基本是打不开的或者登录成功后没有菜单加载出来。还有一点MySQL 8.0 默认的认证插件是caching_sha2_password而 Spring Boot 2.x 老版本连接池驱动可能不认需要留意application.yml里的数据库连接配置。遇到过连不上数据库的十有八九是时区或驱动问题。spring: datasource: url: jdbc:mysql://localhost:3306/law_firm?useUnicodetruecharacterEncodingutf8useSSLfalseserverTimezoneAsia/Shanghai username: root password: your_password driver-class-name: com.mysql.cj.jdbc.Driver注意serverTimezoneAsia/Shanghai这个参数。如果不加数据库连上后报时区错误连启动都过不去。密码如果含有特殊字符记得在 YAML 里加引号否则会被解析成别的意思。3.3 后端启动步骤详解后端启动理论上只有三步导入 Maven 工程、等待依赖下载、启动 Application 类。但实际操作中Maven 依赖下载是第一个坎。国内直接访问中央仓库很慢建议在settings.xml中配置阿里云镜像。配置完镜像后IDEA 里点右侧 Maven 面板的刷新按钮让依赖重新解析。等依赖下载完后找到启动类通常叫Application.java或者XXXApplication.java位置在src/main/java下的某个包路径里。启动类上标注了SpringBootApplication右键点 Run。启动过程中重点观察控制台日志端口是否被占用默认 8080如果被占用会报Port already in useBanner 之后是否有建表语句或初始化语句执行是否出现Started Application in X seconds寻找中间的启动耗时数字能直观判断启动是否成功。然后打开浏览器访问http://localhost:8080或后端配置的context-path。如果项目配置了 Swagger还可以直接访问/swagger-ui.html或/doc.html来查看接口列表这对后面联调很有帮助。3.4 前端启动与联调配置前端启动前先确认后端接口地址的配置。Vue 项目里一般有个.env.development文件或者src/utils/request.js里写死了baseURL。常见配置是VUE_APP_BASE_URL http://localhost:8080如果你前后端都要本地跑这里可以保持默认。但要注意一件事跨域。你从前端开发服务器比如 8081 端口去请求后端 8080 端口会触发浏览器同源策略所以后端要么配置了 CORS要么前端用 Webpack/Vite 的 proxy 做代理转发。这套源码里两种方式都可能出现推荐的方式是前端配置代理因为代理不会暴露后端端口更贴近生产环境。// vue.config.js module.exports { devServer: { port: 8081, proxy: { /api: { target: http://localhost:8080, changeOrigin: true } } } }配置好代理后npm install安装依赖再npm run serve启动。这里提醒一句npm install失败的时候先把node_modules整个删掉再重装不要在原目录里反复补救。解决完安装问题后浏览器打开前端地址能看到登录页并且能登录成功这就是“可直接运行”的核心验证标准。4. 源码结构与二次开发实操要点4.1 后端工程的包结构设计拿到源码后先从整体上理解后端的包结构。常见的分层如下com.example.lawfirm ├── controller // 接口层接收前端请求 ├── service // 业务逻辑层 │ └── impl // 接口实现 ├── mapper // MyBatis 的 Mapper 接口 ├── entity // 数据库实体类 ├── dto // 数据传输对象 ├── vo // 视图对象 ├── config // 配置类安全、跨域、拦截器等 ├── common // 统一响应、异常处理、工具类 └── utils // 工具类这套分层的好处是职责清晰。Controller 只负责参数接收和响应封装不写业务逻辑Service 里放事务控制和规则判断Mapper 只做数据库操作。如果你要加一个新功能比如“新增一种案件类型”流程就是数据库建表 - 建 Entity - 建 Mapper 接口和 XML - 写 Service 接口和实现 - 写 Controller - 前端写页面一条线走下来不会乱。有个不少初学者会踩的坑在 Controller 里直接写 JDBC 操作或者复杂循环处理。这种写法短期内能跑但系统复杂度一上来就是灾难。这套源码的代码风格就是给你当“正确示范”用的建议沿用它的分层方式不要自己破坏结构。4.2 鉴权方案JWT 还是 Session律所管理系统因为涉及敏感数据登录鉴权和权限控制是安全的重头戏。目前主流源码采用两种方案一种是传统的 Session 拦截器另一种是无状态的 JWT。两种都有应用但从近年趋势看Spring Boot Vue 前后端分离项目里 JWT 更常见。JWT 方案的核心流程是用户登录成功后后端生成 Token其中包含用户 ID、用户名、角色信息、过期时间前端把 Token 存在 localStorage 或 Vuex/Pinia 里每次请求在 Axios 拦截器中带Authorization: Bearer token头。后端通过拦截器或 Spring Security 过滤器验证 Token解析出用户信息后放行。这里分享一个实战经验Token 里只放必要信息不要把整个用户对象塞进去。因为 Token 一旦签发服务端无法主动让它失效除非做黑名单塞进去的角色变更、手机号等敏感信息多个分发渠道后容易引安全事故。如果需要动态权限变更生效建议在拦截器里每次从数据库查询一次用户状态或者维护一个 Token 黑名单的 Redis 缓存。4.3 前端路由与权限控制的联动前端部分Vue 2 Element UI 的写法比较常见也有部分新版源码用 Vue 3 Element Plus Vite。不管哪个版本权限控制的核心套路都是“动态路由”登录成功后后端返回当前用户的菜单列表前端把这个列表按层级渲染成侧边栏并通过router.addRoutes动态注册路由。这种方案和你平时看到的“前端写死路由”不一样好处是“不同角色看到的菜单天然不同”后端没返回的菜单前端路由表里根本不存在下级无权用户连 URL 路径都打不开。举例来说管理员登录后返回“系统管理”菜单里面含“用户管理”“角色管理”“菜单权限”三个子项普通律师登录后只返回“我的案件”“日程提醒”等菜单这样从入口上就隔离了功能权限。与动态路由配合的是按钮级权限通常用自定义指令v-permission或 VX 全局方法判断用户权能列表里是否有某个权限标识。实现方式是后端把按钮权限码列表也放进登录返回结果前端存到SessionStorage中自定义指令里对这个权限码数组做 includes 判断没有权限就移除 DOM 元素。4.4 文件上传与文书归档的实现前面提到文书管理模块在律所系统里的重要地位这里说下具体实现时易被忽略的细节。后端接收文件的上传接口通常用 Spring Boot 的MultipartFile参数这里有几个规范要遵守限制文件大小在application.yml里设置spring.servlet.multipart.max-file-size和max-request-size按“案件/文书类型/日期”分目录存储方便人工回查不允许上传可执行文件白名单校验扩展名前端也要做后端更要严格校验上传成功后将文件的相对路径和元数据一并插入数据库spring: servlet: multipart: max-file-size: 20MB max-request-size: 50MB前端上传时用 Element Upload 组件的action属性指定后端接口加上 Token 请求头。这里有个常见坑el-upload组件默认用file作为字段名后端的MultipartFile参数如果取名不是file要在data属性或后端参数上做对应调整否则文件永远传不上去报 “Required part file is not present”。5. 部署到服务器与生产环境优化5.1 前端打包与 Nginx 配置开发跑通之后下一步往往是把系统部署到一台真正的服务器上。前端的构建产物是纯静态文件执行npm run build后会生成dist目录这个目录可以直接扔给 Nginx 托管。Nginx 这里的核心配置是“前端静态资源 后端接口反向代理”两个部分。前端路由如果用的是 history 模式还要额外配置try_files否则刷新页面时报 404。我在实际部署时踩过这个坑记得非常清楚。server { listen 80; server_name your-domain.com; location / { root /var/www/html/dist; index index.html; try_files $uri $uri/ /index.html; } location /api { proxy_pass http://127.0.0.1:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }部署完成后不要急着把开发环境的安全配置直接搬上去要改几个地方关闭后端接口的springdoc或swagger文档、把数据库密码改成强密码、在 Nginx 层加上访问频率限制、开启 HTTPS。这些属于生产化改造虽然源码本身的部署文档不一定提到但真正用到律所场景时是躲不开的。5.2 数据库备份与定时任务律所案管系统一天的核心数据量其实不大但数据价值极高数据库备份是必须做的。推荐直接用 MySQL 自带的mysqldump做每日凌晨的全量备份保留最近 7 份即可。因为系统体量很小全量备份的成本比增量备份的成本低得多也更容易恢复。0 2 * * * mysqldump -uroot -p密码 law_firm /backup/law_firm_$(date \%Y\%m\%d).sql再说一下定时任务。前述的“开庭提醒”功能依赖定时任务在后台扫描案件节点表。Spring Boot 中的实现方式很简单在定时任务类上标注Scheduled(cron ...)但要注意定时任务默认是单线程串行执行的如果你有多个定时任务建议配置一个线程池或者用异步注解避免一个任务卡住全队列阻塞。6. 常见问题排查与避坑实录6.1 启动与运行高频问题速查下面这些是我在跑同类项目时高频遇到的问题整理成表现象直接原因解决方案后端启动报数据库连接失败时区参数缺失、驱动版本不对连接串加serverTimezoneAsia/Shanghai驱动改成com.mysql.cj.jdbc.Driver前端安装依赖报node-sass错误Node 版本过高用 nvm 切换到 Node 16.x或改用sass重装依赖登录后菜单不显示菜单表无数据、用户角色未关联检查数据库初始化数据重点看用户-角色-菜单关联表上传文件失败 “Required part”请求参数名不匹配前端data里指定file字段或后端参数名改为file前端请求接口 404代理未生效、baseURL 不对检查.env文件和 vue.config.js 的代理配置端口被占用8080 被其他服务占用改端口或杀掉占用进程中文乱码数据库字符集不是 utf8mb4建库时指定字符集连接串加characterEncodingutf8刷新前端页面 404路由为 history 模式、Nginx 没配 try_filesNginx 加try_files $uri $uri/ /index.html排查问题时有一个通用原则先从数据层排除再从依赖层排除最后看代码逻辑。很多“灵感乍现”的 bug最后定位下来都是别人没按规范操作留下的坑。6.2 二次开发时的三个避坑经验第一个经验不要大面积改数据库字段名尽量用扩展表。源码跑起来后的第一周你会觉得一切都很自由但当你想加一个字段时直接改原表可能引发一连串连锁反应。更安全的做法是新建一张“扩展信息表”用业务主键关联到原表这样原系统所有代码都不用动新功能只在新增代码里接入。第二个经验改造前端页面时优先用全局样式覆盖不要随便改组件库内部样式。Element UI 的样式通过scoped作用域处理即使加了scoped某些深层样式依然需要::v-deep才能生效。如果你发现改了样式没反应先检查是不是选择器权重和深度作用域的问题再去折腾组件库源码。第三个经验自己写的接口一定要模拟异常情况。律所业务里案件的收款状态、审批状态这些字段是不能随便改的要是因为代码逻辑漏洞导致状态被错误流转后续对账会非常麻烦。所以做二次开发时接口里要加上参数校验、状态校验、事务回滚不要只写通了一个正常流程就完事。6.3 从“能跑”到“能用”的最后一公里很多人拿到源码跑通了就觉得万事大吉但离真正投入使用还差得远。从“能跑”到“能用”关键点在于补数据、补规范、补流程。你需要在系统里先把律师团队、管理员账号、案件类型字典、收费标准模板、文书模板这些基础数据配好否则即便功能齐全员工打开系统也没法用。另一个容易忽略的是“角色隔离规则”比如普通律师能不能看全所案件列表、助理能不能操作财务收款这些要在权限模型里一点点调细才能保证数据安全。在律所这个环境里系统的稳定和数据的准确比功能的丰富程度重要得多。一个功能很全但偶尔报错的系统律师们用两天就会放弃回归到微信和 Excel 的老路上。反而是一个功能不多但稳定、数据准、提醒及时的系统能慢慢扎根下来。我在实际项目中体会到这类案管系统的成功落地三分靠代码七分靠数据初始化和使用习惯培养。代码只是载体真正让系统“活”起来的是案件录入的规范程度和律师们对提醒机制的信任度。如果你准备用这套源码做二次开发建议先把基础流程走通再逐步加功能不要一上来就想着一口气打造一个“全功能超级系统”。最后分享一个小技巧如果你在跑这套系统的过程中被某个“诡异 bug”卡了很久先去看日志而不是去翻源码逻辑。Spring Boot 的日志里几乎会把所有问题的线索都打出来很多时候你离答案只差一次不厌其烦的日志跟踪。