1. 项目概述:SpringBoot+Vue3全栈律所案件管理系统
这套基于SpringBoot2+Vue3的律师事务所案件管理系统,是我在2023年为某中型律所交付的数字化解决方案。系统采用前后端分离架构,后端使用SpringBoot2+MyBatis-Plus+MySQL8.0技术栈,前端基于Vue3+Element Plus实现。经过半年生产环境验证,目前稳定支撑日均200+案件流程处理,较传统Excel管理方式效率提升约300%。
提示:系统完整源码包含15个核心模块,其中"智能文书生成"和"时效预警"模块获得客户高度评价,这些实战经验将在后文详细拆解
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 技术架构深度解析
2.1 后端技术选型依据
选择SpringBoot2而非SpringBoot3的主要考虑是:
- 客户服务器环境为JDK11(SpringBoot3需JDK17)
- MyBatis-Plus 3.5.3版本对动态租户隔离的支持更成熟
- 历史项目迁移成本(原有部分组件暂不支持SpringBoot3)
数据库选型对比:
| 候选方案 | 事务支持 | 法律文书存储 | 成本 | 最终选择原因 |
|---|---|---|---|---|
| MySQL8.0 | ACID | JSON字段支持 | 免费 | 全文检索性能优化 |
| PostgreSQL | ACID | 原生JSONB | 免费 | 运维资源不足 |
| Oracle | ACID | CLOB存储 | 高昂 | 预算限制 |
2.2 前端架构设计要点
Vue3组合式API在复杂业务中的优势:
javascript复制// 案件时间轴组件逻辑复用示例
const useCaseTimeline = (caseId) => {
const events = ref([])
const loading = ref(false)
const fetchEvents = async () => {
loading.value = true
try {
const res = await api.get(`/cases/${caseId}/timeline`)
events.value = res.data.map(item => ({
...item,
// 处理法律事件特殊日期格式
timestamp: dayjs(item.legalDate).format('YYYY-MM-DD HH:mm:ss')
}))
} finally {
loading.value = false
}
}
return { events, loading, fetchEvents }
}
3. 核心功能实现细节
3.1 案件全生命周期管理
数据库表设计关键点:
sql复制CREATE TABLE `legal_case` (
`id` BIGINT NOT NULL COMMENT '案件ID',
`case_number` VARCHAR(50) NOT NULL COMMENT '案号',
`case_type` ENUM('民事','刑事','行政') NOT NULL,
`client_id` BIGINT NOT NULL COMMENT '委托人ID',
`responsible_lawyer` VARCHAR(20) NOT NULL COMMENT '承办律师',
`contradiction_points` JSON DEFAULT NULL COMMENT '争议焦点(JSON数组)',
`milestones` JSON DEFAULT NULL COMMENT '关键节点日期',
`is_sensitive` BIT(1) DEFAULT 0 COMMENT '是否涉密',
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `idx_case_number` (`case_number`),
KEY `idx_client` (`client_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
3.2 文书智能生成系统
基于Freemarker的文书模板引擎实现:
java复制@Service
public class DocumentGenerator {
@Autowired
private Configuration freemarkerConfig;
public byte[] generateLegalDoc(Long templateId, Map<String, Object> data) {
Template template = freemarkerConfig.getTemplate("legal/" + templateId + ".ftl");
try (StringWriter writer = new StringWriter()) {
template.process(data, writer);
return writer.toString().getBytes(StandardCharsets.UTF_8);
} catch (Exception e) {
throw new DocumentGenerationException("文书生成失败", e);
}
}
}
4. 典型问题排查实录
4.1 时效预警延迟问题
现象:系统在凌晨3点出现预警通知堆积
排查过程:
- 检查Spring Schedule配置:
java复制@Scheduled(cron = "0 0 9,15 * * ?") // 实际配置为每天9点和15点执行
public void checkDeadlines() {
// 预警逻辑
}
- 发现服务器时区设置为UTC+0(应为UTC+8)
- 验证方案:
sql复制-- 临时修正方案
SET GLOBAL time_zone = '+8:00';
- 最终解决方案:在Dockerfile中明确时区
dockerfile复制ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime
4.2 Vue3内存泄漏排查
Edge浏览器下出现的组件卸载异常:
javascript复制// 错误示例 - 未清理的事件监听
onMounted(() => {
window.addEventListener('resize', handleResize)
})
// 正确写法
onMounted(() => {
window.addEventListener('resize', handleResize)
})
onUnmounted(() => {
window.removeEventListener('resize', handleResize)
})
使用Chrome DevTools的Memory面板验证组件卸载效果,发现未清理的监听器会导致Vue组件实例无法被GC回收。
5. 安全合规实践
5.1 敏感数据加密方案
采用MyBatis-Plus字段级加密:
java复制@TableName(value = "client_info")
public class Client {
@TableField(typeHandler = AESEncryptHandler.class)
private String idNumber; // 身份证号
@TableField(typeHandler = AESEncryptHandler.class)
private String phone;
// 其他非敏感字段...
}
public class AESEncryptHandler implements TypeHandler<String> {
private static final String KEY = "secureKey123!";
@Override
public void setParameter(...) {
// 加密逻辑
}
@Override
public String getResult(...) {
// 解密逻辑
}
}
5.2 操作审计日志设计
基于Spring AOP的审计切面:
java复制@Aspect
@Component
public class AuditLogAspect {
@Autowired
private AuditLogService logService;
@Around("@annotation(auditLog)")
public Object around(ProceedingJoinPoint pjp, AuditLog auditLog) throws Throwable {
long start = System.currentTimeMillis();
Object result = pjp.proceed();
AuditLogEntry entry = new AuditLogEntry();
entry.setOperation(auditLog.value());
entry.setParams(JsonUtils.toJson(pjp.getArgs()));
entry.setDuration(System.currentTimeMillis() - start);
entry.setUserId(SecurityUtils.getCurrentUserId());
logService.asyncSave(entry);
return result;
}
}
6. 性能优化关键点
6.1 MySQL全文检索优化
针对法律条文检索的特殊处理:
sql复制ALTER TABLE legal_document
ADD FULLTEXT INDEX ft_idx_content (content)
WITH PARSER ngram
COMMENT '中文法律条文全文索引';
-- 查询示例
SELECT * FROM legal_document
WHERE MATCH(content) AGAINST('"合同解除" AND "违约责任"' IN BOOLEAN MODE);
6.2 Vue3组件懒加载方案
路由级代码分割配置:
javascript复制const routes = [
{
path: '/cases',
component: () => import(/* webpackChunkName: "cases" */ '@/views/CaseList.vue'),
children: [
{
path: ':id',
component: () => import(/* webpackChunkName: "case-detail" */ '@/views/CaseDetail.vue')
}
]
}
]
7. 部署实战经验
7.1 Docker Compose编排要点
数据库初始化关键配置:
yaml复制services:
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASS}
MYSQL_DATABASE: legal_system
MYSQL_INITDB_SKIP_TZINFO: 0
volumes:
- ./init.sql:/docker-entrypoint-initdb.d/init.sql
- mysql_data:/var/lib/mysql
ports:
- "3306:3306"
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 5s
timeout: 3s
retries: 10
7.2 Nginx前端优化配置
针对法律文书大文件下载的优化:
nginx复制server {
# 其他配置...
client_max_body_size 50M;
location /download/ {
add_header Content-Disposition 'attachment';
proxy_buffering on;
proxy_buffer_size 16k;
proxy_busy_buffers_size 24k;
proxy_buffers 64 16k;
}
location /api/ {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Connection "";
}
}
这套系统在实际运行中,我们发现法律行业的数字化有几个特别需要注意的细节:首先是日期计算的严谨性(诉讼时效、举证期限等),我们专门开发了法律日期计算引擎;其次是文书版本的严格管控,采用Git-like的版本控制机制;最后是权限体系的精细度,需要实现"同一案件不同律师可见信息不同"的复杂控制。这些经验在通用管理系统中往往不会遇到,却是法律行业软件的核心竞争力所在。
