在传统律师事务所的日常运营中,案件管理往往依赖纸质档案和人工记录,这种方式不仅效率低下,还存在信息丢失、查询困难等问题。作为一名参与过多个法律科技项目的开发者,我深知一套专业的案件管理系统对律所数字化转型的重要性。本文将详细介绍基于Spring Boot+Vue的企业级案件管理系统,这套系统已经在3家中小型律所实际部署运行,平均提升案件处理效率40%以上。
系统采用前后端分离架构,后端使用Spring Boot 2.7+MyBatis Plus,前端采用Vue 3+Element Plus,数据库使用MySQL 8.0。这种技术组合既保证了系统的稳定性,又具有良好的扩展性。特别在数据安全方面,系统实现了客户联系信息加密存储、操作日志全记录等企业级特性,完全符合律师行业的合规要求。
后端选择Spring Boot而非传统SSM框架,主要基于三点考虑:
前端选用Vue.js+Element Plus的组合,实测比传统jQuery方案开发效率提升3倍以上。Element Plus的表格和表单组件特别适合案件管理这类数据密集型应用,其内置的响应式设计也完美适配律所常见的多设备访问场景。
数据库方面,MySQL 8.0的JSON字段支持让我们可以灵活存储案件的特殊属性(如多选的专业领域),而Window函数则大大简化了案件统计报表的实现。
系统包含12张核心数据表,其中案件信息表(case_info)的设计最具代表性:
sql复制CREATE TABLE `case_info` (
`case_id` varchar(32) NOT NULL COMMENT '案件ID',
`case_title` varchar(100) NOT NULL COMMENT '案件标题',
`client_id` varchar(32) NOT NULL COMMENT '客户ID',
`lawyer_id` varchar(32) NOT NULL COMMENT '负责律师ID',
`case_status` int NOT NULL DEFAULT '0' COMMENT '0-进行中 1-已结案',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`case_desc` text COMMENT '案件描述',
`important_level` int DEFAULT '1' COMMENT '重要等级1-5',
`deadline` date DEFAULT NULL COMMENT '截止日期',
PRIMARY KEY (`case_id`),
KEY `idx_client` (`client_id`),
KEY `idx_lawyer` (`lawyer_id`),
KEY `idx_status` (`case_status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
几个关键设计要点:
系统将案件流程划分为6个标准状态:
每个状态转换都通过工作流引擎驱动,确保符合律所的标准操作规程。以下是状态变更的核心代码:
java复制@Transactional
public void changeCaseStatus(String caseId, CaseStatus targetStatus) {
CaseInfo caseInfo = caseMapper.selectById(caseId);
if (!caseInfo.getStatus().canTransferTo(targetStatus)) {
throw new BusinessException("非法状态变更");
}
// 记录状态变更日志
CaseLog log = new CaseLog();
log.setLogType(LogType.STATUS_CHANGE);
log.setContent(String.format("案件状态从%s变更为%s",
caseInfo.getStatus().getDesc(),
targetStatus.getDesc()));
caseLogMapper.insert(log);
// 更新案件状态
caseInfo.setStatus(targetStatus);
caseMapper.updateById(caseInfo);
// 触发相关通知
notifyService.sendStatusChangeNotice(caseInfo);
}
为保护客户隐私,系统对敏感字段采用AES加密存储。我们自定义了MyBatis的类型处理器:
java复制public class EncryptTypeHandler extends BaseTypeHandler<String> {
private static final String KEY = "secureKey123!@#"; // 实际项目应从配置读取
@Override
public void setNonNullParameter(PreparedStatement ps, int i,
String parameter, JdbcType jdbcType) throws SQLException {
ps.setString(i, AESUtil.encrypt(parameter, KEY));
}
@Override
public String getNullableResult(ResultSet rs, String columnName)
throws SQLException {
String encrypted = rs.getString(columnName);
return encrypted != null ? AESUtil.decrypt(encrypted, KEY) : null;
}
// 其他重载方法...
}
在Mapper XML中的使用示例:
xml复制<resultMap id="ClientResult" type="ClientInfo">
<result column="client_phone" property="phone"
typeHandler="com.law.handler.EncryptTypeHandler"/>
</resultMap>
系统设计5种角色:
权限粒度控制到按钮级别,前端通过v-permission指令实现:
vue复制<el-button
v-permission="'case:edit'"
@click="handleEdit">
编辑案件
</el-button>
后端采用Spring Security的注解控制:
java复制@PreAuthorize("hasAuthority('case:delete')")
@DeleteMapping("/cases/{id}")
public Result deleteCase(@PathVariable String id) {
// 删除逻辑
}
除功能权限外,系统还实现了数据行级权限控制。例如实习律师只能查看自己参与的案件,这通过MyBatis的拦截器动态修改SQL实现:
java复制@Intercepts(@Signature(type= Executor.class, method="query",
args={MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}))
public class DataPermissionInterceptor implements Interceptor {
@Override
public Object intercept(Invocation invocation) throws Throwable {
// 获取当前用户
User user = SecurityUtils.getCurrentUser();
if (user.getRole() == Role.INTERN) {
// 修改SQL添加过滤条件
BoundSql boundSql = ((MappedStatement)invocation.getArgs()[0])
.getBoundSql(invocation.getArgs()[1]);
String newSql = boundSql.getSql() + " AND lawyer_id = '"
+ user.getUserId() + "'";
resetSql(invocation, newSql);
}
return invocation.proceed();
}
}
当需要删除客户信息时,系统会检查是否存在关联案件,避免数据不一致。我们采用数据库外键约束+业务逻辑双重保障:
java复制@Transactional
public void deleteClient(String clientId) {
// 检查关联案件
Integer caseCount = caseMapper.countByClientId(clientId);
if (caseCount > 0) {
throw new BusinessException("该客户存在关联案件,不可删除");
}
// 逻辑删除
clientMapper.logicDelete(clientId);
// 记录操作日志
logService.saveDeleteLog(LogType.CLIENT, clientId);
}
使用乐观锁解决并发修改问题,在案件表中增加version字段:
java复制@Transactional
public void updateCase(CaseInfo caseInfo) {
CaseInfo dbCase = caseMapper.selectById(caseInfo.getCaseId());
if (dbCase.getVersion() != caseInfo.getVersion()) {
throw new OptimisticLockException("案件已被其他用户修改");
}
caseInfo.setVersion(caseInfo.getVersion() + 1);
caseMapper.updateById(caseInfo);
}
推荐以下服务器配置:
关键JVM参数:
bash复制-server -Xms2g -Xmx2g -XX:+UseG1GC
-XX:MaxGCPauseMillis=200
-XX:MetaspaceSize=256m
java复制@Cacheable(value = "case", key = "#caseId")
public CaseDetailVO getCaseDetail(String caseId) {
// 查询逻辑
}
yaml复制spring:
datasource:
hikari:
maximum-pool-size: 20
connection-timeout: 30000
idle-timeout: 600000
max-lifetime: 1800000
javascript复制const CaseList = () => import('./views/case/List.vue');
这套系统在实际部署中表现出色,在某律所的压测中可以达到: