1. 项目背景与需求分析
律师咨询系统是当前法律服务行业数字化转型的重要工具。随着互联网+法律服务的深度融合,传统线下咨询模式已无法满足用户对便捷性、即时性和隐私保护的需求。本项目采用SpringBoot+Vue技术栈构建,旨在打造一个功能完备、安全可靠的在线法律咨询平台。
系统核心需求包括:
- 用户角色管理(普通用户、律师、管理员)
- 在线咨询与即时通讯功能
- 案件管理与文档存储
- 预约与时间管理
- 支付与账单系统
- 知识库与常见问题解答
2. 技术架构设计
2.1 前后端分离架构
系统采用典型的前后端分离架构:
code复制前端(Vue.js) ← HTTP/WebSocket → 后端(SpringBoot)
↑
(API调用)
↓
数据库/文件存储
这种架构的优势在于:
- 前后端可以并行开发,提高效率
- Vue的响应式特性优化用户体验
- SpringBoot提供稳定的RESTful API
- 更易于实现水平扩展
2.2 技术选型依据
后端技术栈:
- SpringBoot 2.7.x:简化配置,快速开发
- Spring Security:认证与授权
- WebSocket:实时通讯
- MyBatis-Plus:简化数据库操作
- Redis:缓存与会话管理
前端技术栈:
- Vue 3.x:组合式API开发
- Element Plus:UI组件库
- Axios:HTTP客户端
- Vue Router:路由管理
- Vuex/Pinia:状态管理
3. 核心功能实现
3.1 用户认证系统
采用JWT+Spring Security实现安全的认证机制:
java复制// 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()
.anyRequest().authenticated()
.and()
.addFilter(new JwtAuthenticationFilter(authenticationManager()))
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
}
关键点:
- 采用无状态会话管理
- 密码使用BCrypt加密存储
- 实现角色分级权限控制
- 定期刷新令牌机制
3.2 实时咨询功能
基于WebSocket实现律师与用户的实时通讯:
java复制@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/topic");
config.setApplicationDestinationPrefixes("/app");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/ws-chat")
.setAllowedOrigins("*")
.withSockJS();
}
}
前端实现关键代码:
javascript复制// Vue组件中建立WebSocket连接
setup() {
const socket = new SockJS('/ws-chat')
const stompClient = Stomp.over(socket)
stompClient.connect({}, () => {
stompClient.subscribe('/topic/messages', (message) => {
// 处理接收到的消息
})
})
const sendMessage = (msg) => {
stompClient.send("/app/chat", {}, JSON.stringify(msg))
}
return { sendMessage }
}
4. 数据库设计
4.1 核心表结构
用户表(users)
sql复制CREATE TABLE `users` (
`id` bigint NOT NULL AUTO_INCREMENT,
`username` varchar(50) NOT NULL,
`password` varchar(100) NOT NULL,
`real_name` varchar(50) DEFAULT NULL,
`phone` varchar(20) DEFAULT NULL,
`email` varchar(100) DEFAULT NULL,
`avatar` varchar(255) DEFAULT NULL,
`user_type` tinyint NOT NULL COMMENT '1-普通用户 2-律师 3-管理员',
`license_number` varchar(50) DEFAULT NULL COMMENT '律师执业证号',
`specialty` varchar(255) DEFAULT NULL COMMENT '专业领域',
`status` tinyint DEFAULT '1',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `idx_username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
咨询会话表(consultations)
sql复制CREATE TABLE `consultations` (
`id` bigint NOT NULL AUTO_INCREMENT,
`user_id` bigint NOT NULL,
`lawyer_id` bigint NOT NULL,
`start_time` datetime NOT NULL,
`end_time` datetime DEFAULT NULL,
`status` tinyint DEFAULT '0' COMMENT '0-进行中 1-已完成 2-已取消',
`payment_status` tinyint DEFAULT '0',
`payment_amount` decimal(10,2) DEFAULT NULL,
`rating` tinyint DEFAULT NULL,
`feedback` text,
PRIMARY KEY (`id`),
KEY `idx_user` (`user_id`),
KEY `idx_lawyer` (`lawyer_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
5. 关键问题解决方案
5.1 文件安全存储
律师咨询系统涉及敏感文件上传,采用以下安全措施:
- 文件服务器独立部署
- 实现文件加密存储
- 严格的访问权限控制
- 文件哈希校验机制
java复制@Service
public class FileStorageService {
@Value("${file.upload-dir}")
private String uploadDir;
public String storeFile(MultipartFile file, Long userId) {
String originalFilename = StringUtils.cleanPath(file.getOriginalFilename());
String fileExtension = FilenameUtils.getExtension(originalFilename);
String storedFilename = UUID.randomUUID() + "." + fileExtension;
Path targetLocation = Paths.get(uploadDir).resolve(storedFilename);
Files.copy(file.getInputStream(), targetLocation, StandardCopyOption.REPLACE_EXISTING);
// 记录文件元数据到数据库
FileMetadata metadata = new FileMetadata();
metadata.setUserId(userId);
metadata.setOriginalName(originalFilename);
metadata.setStoredName(storedFilename);
metadata.setFileType(file.getContentType());
metadata.setSize(file.getSize());
metadata.setUploadTime(new Date());
fileMetadataRepository.save(metadata);
return storedFilename;
}
}
5.2 咨询计时与计费
实现精确的咨询计时与自动计费功能:
java复制@Service
public class ConsultationService {
@Scheduled(fixedRate = 60000) // 每分钟检查一次
public void checkOngoingConsultations() {
List<Consultation> ongoing = consultationRepository
.findByStatus(ConsultationStatus.ONGOING);
ongoing.forEach(consultation -> {
long duration = Duration.between(
consultation.getStartTime(),
LocalDateTime.now()
).toMinutes();
if (duration >= 1) { // 每分钟计费一次
BigDecimal chargeAmount = consultation.getLawyer()
.getRatePerMinute()
.multiply(new BigDecimal(duration));
consultation.setPaymentAmount(chargeAmount);
consultationRepository.save(consultation);
// 发送计费通知
notificationService.sendBillingNotification(
consultation.getUser(),
consultation
);
}
});
}
}
6. 系统部署方案
6.1 生产环境配置
推荐部署架构:
code复制Nginx (负载均衡)
├── Vue前端服务(端口80)
└── SpringBoot应用(端口8080)
├── MySQL主从集群
└── Redis哨兵集群
Nginx配置示例:
nginx复制upstream backend {
server 127.0.0.1:8080;
}
server {
listen 80;
server_name lawconsult.example.com;
location / {
root /var/www/law-consult-frontend;
try_files $uri $uri/ /index.html;
}
location /api {
proxy_pass http://backend;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /ws {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
}
}
6.2 性能优化建议
-
数据库优化:
- 合理设计索引
- 使用连接池配置
- 读写分离
-
前端优化:
- 组件懒加载
- 路由懒加载
- 使用CDN加速静态资源
-
缓存策略:
- Redis缓存热点数据
- 实现二级缓存
- 合理的缓存失效策略
7. 开发经验分享
在实际开发过程中,有几个关键点值得注意:
- WebSocket连接稳定性:
- 实现自动重连机制
- 添加心跳检测
- 处理网络异常情况
javascript复制// Vue中增强的WebSocket连接
function connectWebSocket() {
const socket = new SockJS('/ws-chat')
const stompClient = Stomp.over(socket)
stompClient.reconnect_delay = 5000
const onError = () => {
setTimeout(connectWebSocket, 5000)
}
stompClient.connect({}, () => {
// 成功连接逻辑
stompClient.subscribe('/topic/messages', handleMessage)
// 启动心跳
setInterval(() => {
stompClient.send("/heartbeat")
}, 30000)
}, onError)
}
- 文件上传安全处理:
- 限制文件类型
- 病毒扫描
- 大小限制
- 重命名存储
java复制public void validateFile(MultipartFile file) {
// 检查文件大小
if (file.getSize() > 10 * 1024 * 1024) {
throw new FileSizeLimitExceededException("文件大小不能超过10MB");
}
// 检查文件类型
String contentType = file.getContentType();
if (!ALLOWED_TYPES.contains(contentType)) {
throw new InvalidFileTypeException("不支持的文件类型");
}
// 检查文件扩展名
String originalFilename = file.getOriginalFilename();
String extension = FilenameUtils.getExtension(originalFilename);
if (!ALLOWED_EXTENSIONS.contains(extension.toLowerCase())) {
throw new InvalidFileTypeException("不支持的文件扩展名");
}
}
- 咨询会话状态管理:
- 使用状态机模式管理会话生命周期
- 处理异常状态转换
- 记录完整的状态变更日志
java复制public enum ConsultationState {
PENDING,
ONGOING,
COMPLETED,
CANCELLED,
PAYMENT_PENDING,
ARCHIVED
}
@Service
public class ConsultationStateMachine {
private final StateMachineFactory<ConsultationState, ConsultationEvent> factory;
public void changeState(Long consultationId, ConsultationEvent event) {
StateMachine<ConsultationState, ConsultationEvent> sm = factory.getStateMachine(consultationId.toString());
sm.sendEvent(event);
// 记录状态变更
Consultation consultation = consultationRepository.findById(consultationId)
.orElseThrow(() -> new ConsultationNotFoundException(consultationId));
consultation.setStatus(sm.getState().getId());
consultationRepository.save(consultation);
}
}
8. 项目扩展方向
完成基础功能后,可以考虑以下扩展:
-
智能法律助手:
- 集成NLP技术分析咨询内容
- 自动生成法律文书草稿
- 相似案例推荐
-
移动端适配:
- 开发React Native或Flutter应用
- 实现PWA渐进式Web应用
- 微信小程序接入
-
数据分析看板:
- 律师服务数据分析
- 用户咨询热点分析
- 服务质量评估系统
-
区块链存证:
- 重要咨询记录上链
- 电子合同区块链存证
- 时间戳服务集成
这个基于SpringBoot+Vue的律师咨询系统项目涵盖了现代Web开发的完整技术栈,从需求分析到技术实现,再到部署优化,每个环节都需要仔细考量。在实际开发中,特别要注意法律行业对数据安全和隐私保护的特殊要求,确保系统设计符合相关法律法规。
