在传统律师事务所的日常运营中,案件管理往往面临着诸多痛点。纸质档案堆积如山,每次查找案件资料都需要耗费大量时间;案件进度更新不及时,律师和客户之间信息不同步;重要文书版本混乱,难以追踪最新修改。这些问题不仅降低了工作效率,也影响了客户体验。
我们团队曾为某中型律所提供技术咨询,亲眼目睹他们的行政人员每天要花2-3小时手工整理案件档案。某次重要庭审前,律师甚至找不到最新版本的辩护词,最终不得不请求延期审理。这种低效的管理方式促使我们开发这套前后端分离的案件管理系统。
后端采用Spring Boot主要基于三个考量:
前端选择Vue.js则是因为:
code复制[前端层] Vue.js + ElementUI
↑↓ HTTP/HTTPS
[API网关层] Spring Boot RESTful API
↑↓
[业务逻辑层] Service组件
↑↓
[数据访问层] MyBatis + MySQL
↑
[辅助服务] Elasticsearch + Redis
案件状态机设计是关键,我们定义了5种基本状态:
java复制public enum CaseStatus {
DRAFT("草稿"),
PENDING("待受理"),
PROCESSING("办理中"),
ARCHIVED("已归档"),
REJECTED("已拒接");
private String desc;
// 省略getter/setter
}
状态转换通过Spring State Machine实现:
java复制@Configuration
@EnableStateMachine
public class CaseStateMachineConfig {
// 配置状态转换规则
public void configure(StateMachineTransitionConfigurer<CaseStatus, String> transitions) {
transitions
.withExternal()
.source(CaseStatus.DRAFT)
.target(CaseStatus.PENDING)
.event("SUBMIT")
.and()
.withExternal()
.source(CaseStatus.PENDING)
.target(CaseStatus.PROCESSING)
.event("ACCEPT");
}
}
为解决文书版本混乱问题,我们设计了双重版本机制:
/cases/{caseId}/docs/v{version}路径存储关键代码片段:
java复制public DocumentVersion uploadDocument(MultipartFile file, String caseId) {
// 生成版本号
int newVersion = documentService.getLatestVersion(caseId) + 1;
// 存储文件
String objectName = "cases/" + caseId + "/docs/v" + newVersion;
minioClient.putObject(bucketName, objectName, file.getInputStream());
// 保存版本记录
return documentRepository.save(new DocumentVersion(caseId, newVersion));
}
系统定义四种角色:
权限控制通过Spring Security实现:
java复制@PreAuthorize("hasRole('PARTNER') or @caseAccessControl.canAccessCase(#caseId)")
@GetMapping("/cases/{caseId}")
public CaseDetail getCaseDetail(@PathVariable String caseId) {
// 业务逻辑
}
为避免频繁查询数据库,我们采用双Token机制:
Token刷新接口示例:
java复制@PostMapping("/auth/refresh")
public ResponseEntity refreshToken(@Valid @RequestBody RefreshTokenRequest request) {
String username = jwtUtil.validateRefreshToken(request.getRefreshToken());
String newAccessToken = jwtUtil.generateAccessToken(username);
return ResponseEntity.ok(new TokenResponse(newAccessToken));
}
案件检索采用多字段组合索引:
json复制{
"mappings": {
"properties": {
"case_title": {"type": "text", "analyzer": "ik_max_word"},
"client_name": {"type": "keyword"},
"case_status": {"type": "integer"},
"create_time": {"type": "date"}
}
}
}
使用Redis实现三级缓存:
缓存注解示例:
java复制@Cacheable(value = "case", key = "#caseId", unless = "#result == null")
public Case getCaseById(String caseId) {
return caseRepository.findById(caseId);
}
使用Docker Compose编排服务:
yaml复制version: '3'
services:
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: ${DB_PASSWORD}
volumes:
- mysql_data:/var/lib/mysql
elasticsearch:
image: elasticsearch:7.12.0
environment:
- discovery.type=single-node
ulimits:
memlock:
soft: -1
hard: -1
推荐使用Prometheus+Grafana监控:
初期使用单条插入导致性能瓶颈,优化后:
xml复制<insert id="batchInsert" parameterType="java.util.List">
INSERT INTO case_log
(case_id, operation, operator)
VALUES
<foreach collection="list" item="item" separator=",">
(#{item.caseId}, #{item.operation}, #{item.operator})
</foreach>
</insert>
发现案件列表渲染卡顿,通过以下措施解决:
这套系统在某律所上线后,案件查询时间从平均15分钟缩短至10秒内,文书版本错误率降为零。特别提醒:数据库连接池配置要根据实际业务量调整,我们初期使用默认配置在高并发时出现了连接泄漏问题。