docs: 添加项目文档包括总览、架构、流程引擎和服务层
新增以下文档文件: - PROJECT_OVERVIEW.md 项目总览文档 - BACKEND_ARCHITECTURE.md 后端架构文档 - FRONTEND_ARCHITECTURE.md 前端架构文档 - FLOW_ENGINE.md 流程引擎文档 - SERVICES.md 服务层文档 - ERROR_HANDLING.md 错误处理模块文档 文档内容涵盖项目整体介绍、技术架构、核心模块设计和实现细节
This commit is contained in:
853
docs/SERVICES.md
Normal file
853
docs/SERVICES.md
Normal file
@ -0,0 +1,853 @@
|
||||
# 服务层文档
|
||||
|
||||
## 概述
|
||||
|
||||
服务层是 UdminAI 的业务逻辑核心,负责处理各种业务操作,包括用户管理、权限控制、流程管理、定时任务、系统监控等功能。
|
||||
|
||||
## 架构设计
|
||||
|
||||
### 服务模块结构
|
||||
|
||||
```
|
||||
services/
|
||||
├── mod.rs # 服务模块导出
|
||||
├── user_service.rs # 用户服务
|
||||
├── role_service.rs # 角色服务
|
||||
├── permission_service.rs # 权限服务
|
||||
├── flow_service.rs # 流程服务
|
||||
├── schedule_job_service.rs # 定时任务服务
|
||||
├── system_service.rs # 系统服务
|
||||
├── log_service.rs # 日志服务
|
||||
└── notification_service.rs # 通知服务
|
||||
```
|
||||
|
||||
### 设计原则
|
||||
|
||||
- **单一职责**: 每个服务专注于特定业务领域
|
||||
- **依赖注入**: 通过参数传递数据库连接等依赖
|
||||
- **错误处理**: 统一的错误处理和返回格式
|
||||
- **异步支持**: 所有服务方法都是异步的
|
||||
- **事务支持**: 支持数据库事务操作
|
||||
|
||||
## 用户服务 (user_service.rs)
|
||||
|
||||
### 核心功能
|
||||
|
||||
#### 1. 用户认证
|
||||
```rust
|
||||
/// 用户登录验证
|
||||
pub async fn authenticate(
|
||||
db: &DatabaseConnection,
|
||||
username: &str,
|
||||
password: &str,
|
||||
) -> Result<UserDoc, AppError>
|
||||
```
|
||||
|
||||
**功能**:
|
||||
- 用户名/密码验证
|
||||
- 密码哈希比较
|
||||
- 登录状态更新
|
||||
- 登录日志记录
|
||||
|
||||
#### 2. 用户管理
|
||||
```rust
|
||||
/// 创建用户
|
||||
pub async fn create_user(
|
||||
db: &DatabaseConnection,
|
||||
req: CreateUserReq,
|
||||
) -> Result<UserDoc, AppError>
|
||||
|
||||
/// 更新用户信息
|
||||
pub async fn update_user(
|
||||
db: &DatabaseConnection,
|
||||
id: &str,
|
||||
req: UpdateUserReq,
|
||||
) -> Result<UserDoc, AppError>
|
||||
|
||||
/// 删除用户
|
||||
pub async fn delete_user(
|
||||
db: &DatabaseConnection,
|
||||
id: &str,
|
||||
) -> Result<(), AppError>
|
||||
```
|
||||
|
||||
#### 3. 用户查询
|
||||
```rust
|
||||
/// 分页查询用户列表
|
||||
pub async fn list_users(
|
||||
db: &DatabaseConnection,
|
||||
page: u64,
|
||||
page_size: u64,
|
||||
filters: Option<UserFilters>,
|
||||
) -> Result<PageResp<UserDoc>, AppError>
|
||||
|
||||
/// 根据ID获取用户
|
||||
pub async fn get_user_by_id(
|
||||
db: &DatabaseConnection,
|
||||
id: &str,
|
||||
) -> Result<Option<UserDoc>, AppError>
|
||||
```
|
||||
|
||||
### 数据传输对象
|
||||
|
||||
#### UserDoc - 用户文档
|
||||
```rust
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct UserDoc {
|
||||
pub id: String,
|
||||
pub username: String,
|
||||
pub email: Option<String>,
|
||||
pub display_name: Option<String>,
|
||||
pub avatar: Option<String>,
|
||||
pub status: UserStatus,
|
||||
pub roles: Vec<String>,
|
||||
pub created_at: DateTime<FixedOffset>,
|
||||
pub updated_at: DateTime<FixedOffset>,
|
||||
}
|
||||
```
|
||||
|
||||
#### CreateUserReq - 创建用户请求
|
||||
```rust
|
||||
#[derive(Debug, Deserialize, Validate)]
|
||||
pub struct CreateUserReq {
|
||||
#[validate(length(min = 3, max = 50))]
|
||||
pub username: String,
|
||||
#[validate(length(min = 6))]
|
||||
pub password: String,
|
||||
#[validate(email)]
|
||||
pub email: Option<String>,
|
||||
pub display_name: Option<String>,
|
||||
pub roles: Vec<String>,
|
||||
}
|
||||
```
|
||||
|
||||
### 安全特性
|
||||
|
||||
- **密码加密**: 使用 bcrypt 进行密码哈希
|
||||
- **输入验证**: 使用 validator 进行参数验证
|
||||
- **权限检查**: 集成权限服务进行访问控制
|
||||
- **审计日志**: 记录用户操作日志
|
||||
|
||||
## 角色服务 (role_service.rs)
|
||||
|
||||
### 核心功能
|
||||
|
||||
#### 1. 角色管理
|
||||
```rust
|
||||
/// 创建角色
|
||||
pub async fn create_role(
|
||||
db: &DatabaseConnection,
|
||||
req: CreateRoleReq,
|
||||
) -> Result<RoleDoc, AppError>
|
||||
|
||||
/// 更新角色
|
||||
pub async fn update_role(
|
||||
db: &DatabaseConnection,
|
||||
id: &str,
|
||||
req: UpdateRoleReq,
|
||||
) -> Result<RoleDoc, AppError>
|
||||
|
||||
/// 删除角色
|
||||
pub async fn delete_role(
|
||||
db: &DatabaseConnection,
|
||||
id: &str,
|
||||
) -> Result<(), AppError>
|
||||
```
|
||||
|
||||
#### 2. 权限分配
|
||||
```rust
|
||||
/// 为角色分配权限
|
||||
pub async fn assign_permissions(
|
||||
db: &DatabaseConnection,
|
||||
role_id: &str,
|
||||
permission_ids: Vec<String>,
|
||||
) -> Result<(), AppError>
|
||||
|
||||
/// 移除角色权限
|
||||
pub async fn remove_permissions(
|
||||
db: &DatabaseConnection,
|
||||
role_id: &str,
|
||||
permission_ids: Vec<String>,
|
||||
) -> Result<(), AppError>
|
||||
```
|
||||
|
||||
#### 3. 用户角色管理
|
||||
```rust
|
||||
/// 为用户分配角色
|
||||
pub async fn assign_user_roles(
|
||||
db: &DatabaseConnection,
|
||||
user_id: &str,
|
||||
role_ids: Vec<String>,
|
||||
) -> Result<(), AppError>
|
||||
|
||||
/// 获取用户角色
|
||||
pub async fn get_user_roles(
|
||||
db: &DatabaseConnection,
|
||||
user_id: &str,
|
||||
) -> Result<Vec<RoleDoc>, AppError>
|
||||
```
|
||||
|
||||
### 数据传输对象
|
||||
|
||||
#### RoleDoc - 角色文档
|
||||
```rust
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct RoleDoc {
|
||||
pub id: String,
|
||||
pub name: String,
|
||||
pub description: Option<String>,
|
||||
pub permissions: Vec<String>,
|
||||
pub is_system: bool,
|
||||
pub created_at: DateTime<FixedOffset>,
|
||||
pub updated_at: DateTime<FixedOffset>,
|
||||
}
|
||||
```
|
||||
|
||||
## 权限服务 (permission_service.rs)
|
||||
|
||||
### 核心功能
|
||||
|
||||
#### 1. 权限检查
|
||||
```rust
|
||||
/// 检查用户权限
|
||||
pub async fn check_user_permission(
|
||||
db: &DatabaseConnection,
|
||||
user_id: &str,
|
||||
resource: &str,
|
||||
action: &str,
|
||||
) -> Result<bool, AppError>
|
||||
|
||||
/// 检查角色权限
|
||||
pub async fn check_role_permission(
|
||||
db: &DatabaseConnection,
|
||||
role_id: &str,
|
||||
resource: &str,
|
||||
action: &str,
|
||||
) -> Result<bool, AppError>
|
||||
```
|
||||
|
||||
#### 2. 权限管理
|
||||
```rust
|
||||
/// 创建权限
|
||||
pub async fn create_permission(
|
||||
db: &DatabaseConnection,
|
||||
req: CreatePermissionReq,
|
||||
) -> Result<PermissionDoc, AppError>
|
||||
|
||||
/// 获取权限树
|
||||
pub async fn get_permission_tree(
|
||||
db: &DatabaseConnection,
|
||||
) -> Result<Vec<PermissionTreeNode>, AppError>
|
||||
```
|
||||
|
||||
### 权限模型
|
||||
|
||||
#### 资源-动作模型
|
||||
- **资源 (Resource)**: 系统中的实体 (user, role, flow, job)
|
||||
- **动作 (Action)**: 对资源的操作 (create, read, update, delete)
|
||||
- **权限 (Permission)**: 资源和动作的组合
|
||||
|
||||
#### 权限继承
|
||||
- 角色权限继承
|
||||
- 用户权限继承
|
||||
- 权限组合计算
|
||||
|
||||
## 流程服务 (flow_service.rs)
|
||||
|
||||
### 核心功能
|
||||
|
||||
#### 1. 流程管理
|
||||
```rust
|
||||
/// 创建流程
|
||||
pub async fn create_flow(
|
||||
db: &DatabaseConnection,
|
||||
req: CreateFlowReq,
|
||||
) -> Result<FlowDoc, AppError>
|
||||
|
||||
/// 更新流程
|
||||
pub async fn update_flow(
|
||||
db: &DatabaseConnection,
|
||||
id: &str,
|
||||
req: UpdateFlowReq,
|
||||
) -> Result<FlowDoc, AppError>
|
||||
|
||||
/// 发布流程
|
||||
pub async fn publish_flow(
|
||||
db: &DatabaseConnection,
|
||||
id: &str,
|
||||
) -> Result<FlowDoc, AppError>
|
||||
```
|
||||
|
||||
#### 2. 流程执行
|
||||
```rust
|
||||
/// 执行流程
|
||||
pub async fn execute_flow(
|
||||
db: &DatabaseConnection,
|
||||
flow_id: &str,
|
||||
input: serde_json::Value,
|
||||
options: ExecuteOptions,
|
||||
) -> Result<ExecutionResult, AppError>
|
||||
|
||||
/// 获取执行状态
|
||||
pub async fn get_execution_status(
|
||||
db: &DatabaseConnection,
|
||||
execution_id: &str,
|
||||
) -> Result<ExecutionStatus, AppError>
|
||||
```
|
||||
|
||||
#### 3. 流程版本管理
|
||||
```rust
|
||||
/// 创建流程版本
|
||||
pub async fn create_flow_version(
|
||||
db: &DatabaseConnection,
|
||||
flow_id: &str,
|
||||
version_data: FlowVersionData,
|
||||
) -> Result<FlowVersionDoc, AppError>
|
||||
|
||||
/// 获取流程版本列表
|
||||
pub async fn list_flow_versions(
|
||||
db: &DatabaseConnection,
|
||||
flow_id: &str,
|
||||
) -> Result<Vec<FlowVersionDoc>, AppError>
|
||||
```
|
||||
|
||||
### 数据传输对象
|
||||
|
||||
#### FlowDoc - 流程文档
|
||||
```rust
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct FlowDoc {
|
||||
pub id: String,
|
||||
pub name: String,
|
||||
pub description: Option<String>,
|
||||
pub category: String,
|
||||
pub status: FlowStatus,
|
||||
pub version: String,
|
||||
pub design: serde_json::Value,
|
||||
pub created_by: String,
|
||||
pub created_at: DateTime<FixedOffset>,
|
||||
pub updated_at: DateTime<FixedOffset>,
|
||||
}
|
||||
```
|
||||
|
||||
#### ExecutionResult - 执行结果
|
||||
```rust
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct ExecutionResult {
|
||||
pub execution_id: String,
|
||||
pub status: ExecutionStatus,
|
||||
pub result: Option<serde_json::Value>,
|
||||
pub error: Option<String>,
|
||||
pub start_time: DateTime<FixedOffset>,
|
||||
pub end_time: Option<DateTime<FixedOffset>>,
|
||||
pub duration_ms: Option<u64>,
|
||||
}
|
||||
```
|
||||
|
||||
## 定时任务服务 (schedule_job_service.rs)
|
||||
|
||||
### 核心功能
|
||||
|
||||
#### 1. 任务管理
|
||||
```rust
|
||||
/// 创建定时任务
|
||||
pub async fn create_schedule_job(
|
||||
db: &DatabaseConnection,
|
||||
req: CreateScheduleJobReq,
|
||||
) -> Result<ScheduleJobDoc, AppError>
|
||||
|
||||
/// 更新任务
|
||||
pub async fn update_schedule_job(
|
||||
db: &DatabaseConnection,
|
||||
id: &str,
|
||||
req: UpdateScheduleJobReq,
|
||||
) -> Result<ScheduleJobDoc, AppError>
|
||||
|
||||
/// 启用/禁用任务
|
||||
pub async fn toggle_job_status(
|
||||
db: &DatabaseConnection,
|
||||
id: &str,
|
||||
enabled: bool,
|
||||
) -> Result<ScheduleJobDoc, AppError>
|
||||
```
|
||||
|
||||
#### 2. 任务调度
|
||||
```rust
|
||||
/// 注册任务到调度器
|
||||
pub async fn register_job_to_scheduler(
|
||||
scheduler: &JobScheduler,
|
||||
job: &ScheduleJobDoc,
|
||||
) -> Result<(), AppError>
|
||||
|
||||
/// 从调度器移除任务
|
||||
pub async fn unregister_job_from_scheduler(
|
||||
scheduler: &JobScheduler,
|
||||
job_id: &str,
|
||||
) -> Result<(), AppError>
|
||||
```
|
||||
|
||||
#### 3. 执行历史
|
||||
```rust
|
||||
/// 记录任务执行
|
||||
pub async fn record_job_execution(
|
||||
db: &DatabaseConnection,
|
||||
execution: JobExecutionRecord,
|
||||
) -> Result<(), AppError>
|
||||
|
||||
/// 获取执行历史
|
||||
pub async fn get_job_execution_history(
|
||||
db: &DatabaseConnection,
|
||||
job_id: &str,
|
||||
page: u64,
|
||||
page_size: u64,
|
||||
) -> Result<PageResp<JobExecutionRecord>, AppError>
|
||||
```
|
||||
|
||||
### 调度特性
|
||||
|
||||
- **Cron 表达式**: 支持标准 Cron 表达式
|
||||
- **时区支持**: 支持不同时区的任务调度
|
||||
- **并发控制**: 防止任务重复执行
|
||||
- **失败重试**: 支持任务失败重试
|
||||
- **执行超时**: 支持任务执行超时控制
|
||||
|
||||
## 系统服务 (system_service.rs)
|
||||
|
||||
### 核心功能
|
||||
|
||||
#### 1. 系统信息
|
||||
```rust
|
||||
/// 获取系统信息
|
||||
pub async fn get_system_info() -> Result<SystemInfo, AppError>
|
||||
|
||||
/// 获取系统状态
|
||||
pub async fn get_system_status(
|
||||
db: &DatabaseConnection,
|
||||
redis: &RedisConnection,
|
||||
) -> Result<SystemStatus, AppError>
|
||||
```
|
||||
|
||||
#### 2. 健康检查
|
||||
```rust
|
||||
/// 数据库健康检查
|
||||
pub async fn check_database_health(
|
||||
db: &DatabaseConnection,
|
||||
) -> Result<HealthStatus, AppError>
|
||||
|
||||
/// Redis 健康检查
|
||||
pub async fn check_redis_health(
|
||||
redis: &RedisConnection,
|
||||
) -> Result<HealthStatus, AppError>
|
||||
```
|
||||
|
||||
#### 3. 系统配置
|
||||
```rust
|
||||
/// 获取系统配置
|
||||
pub async fn get_system_config(
|
||||
db: &DatabaseConnection,
|
||||
) -> Result<SystemConfig, AppError>
|
||||
|
||||
/// 更新系统配置
|
||||
pub async fn update_system_config(
|
||||
db: &DatabaseConnection,
|
||||
config: SystemConfig,
|
||||
) -> Result<(), AppError>
|
||||
```
|
||||
|
||||
### 监控指标
|
||||
|
||||
#### SystemStatus - 系统状态
|
||||
```rust
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct SystemStatus {
|
||||
pub uptime: u64,
|
||||
pub memory_usage: MemoryUsage,
|
||||
pub cpu_usage: f64,
|
||||
pub disk_usage: DiskUsage,
|
||||
pub database_status: HealthStatus,
|
||||
pub redis_status: HealthStatus,
|
||||
pub active_connections: u32,
|
||||
pub request_count: u64,
|
||||
pub error_count: u64,
|
||||
}
|
||||
```
|
||||
|
||||
## 日志服务 (log_service.rs)
|
||||
|
||||
### 核心功能
|
||||
|
||||
#### 1. 日志记录
|
||||
```rust
|
||||
/// 记录操作日志
|
||||
pub async fn log_operation(
|
||||
db: &DatabaseConnection,
|
||||
log: OperationLog,
|
||||
) -> Result<(), AppError>
|
||||
|
||||
/// 记录系统日志
|
||||
pub async fn log_system_event(
|
||||
db: &DatabaseConnection,
|
||||
event: SystemEvent,
|
||||
) -> Result<(), AppError>
|
||||
```
|
||||
|
||||
#### 2. 日志查询
|
||||
```rust
|
||||
/// 查询操作日志
|
||||
pub async fn query_operation_logs(
|
||||
db: &DatabaseConnection,
|
||||
filters: LogFilters,
|
||||
page: u64,
|
||||
page_size: u64,
|
||||
) -> Result<PageResp<OperationLogDoc>, AppError>
|
||||
|
||||
/// 查询系统日志
|
||||
pub async fn query_system_logs(
|
||||
db: &DatabaseConnection,
|
||||
filters: LogFilters,
|
||||
page: u64,
|
||||
page_size: u64,
|
||||
) -> Result<PageResp<SystemLogDoc>, AppError>
|
||||
```
|
||||
|
||||
#### 3. 日志分析
|
||||
```rust
|
||||
/// 获取日志统计
|
||||
pub async fn get_log_statistics(
|
||||
db: &DatabaseConnection,
|
||||
time_range: TimeRange,
|
||||
) -> Result<LogStatistics, AppError>
|
||||
|
||||
/// 获取错误日志趋势
|
||||
pub async fn get_error_log_trend(
|
||||
db: &DatabaseConnection,
|
||||
time_range: TimeRange,
|
||||
) -> Result<Vec<ErrorTrendPoint>, AppError>
|
||||
```
|
||||
|
||||
### 日志类型
|
||||
|
||||
#### OperationLog - 操作日志
|
||||
```rust
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct OperationLog {
|
||||
pub user_id: String,
|
||||
pub operation: String,
|
||||
pub resource: String,
|
||||
pub resource_id: Option<String>,
|
||||
pub details: serde_json::Value,
|
||||
pub ip_address: Option<String>,
|
||||
pub user_agent: Option<String>,
|
||||
pub timestamp: DateTime<FixedOffset>,
|
||||
}
|
||||
```
|
||||
|
||||
#### SystemEvent - 系统事件
|
||||
```rust
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct SystemEvent {
|
||||
pub event_type: String,
|
||||
pub level: LogLevel,
|
||||
pub message: String,
|
||||
pub details: serde_json::Value,
|
||||
pub source: String,
|
||||
pub timestamp: DateTime<FixedOffset>,
|
||||
}
|
||||
```
|
||||
|
||||
## 通知服务 (notification_service.rs)
|
||||
|
||||
### 核心功能
|
||||
|
||||
#### 1. 通知发送
|
||||
```rust
|
||||
/// 发送邮件通知
|
||||
pub async fn send_email_notification(
|
||||
config: &EmailConfig,
|
||||
notification: EmailNotification,
|
||||
) -> Result<(), AppError>
|
||||
|
||||
/// 发送短信通知
|
||||
pub async fn send_sms_notification(
|
||||
config: &SmsConfig,
|
||||
notification: SmsNotification,
|
||||
) -> Result<(), AppError>
|
||||
|
||||
/// 发送系统通知
|
||||
pub async fn send_system_notification(
|
||||
db: &DatabaseConnection,
|
||||
notification: SystemNotification,
|
||||
) -> Result<(), AppError>
|
||||
```
|
||||
|
||||
#### 2. 通知模板
|
||||
```rust
|
||||
/// 创建通知模板
|
||||
pub async fn create_notification_template(
|
||||
db: &DatabaseConnection,
|
||||
template: NotificationTemplate,
|
||||
) -> Result<NotificationTemplateDoc, AppError>
|
||||
|
||||
/// 渲染通知模板
|
||||
pub async fn render_notification_template(
|
||||
template: &NotificationTemplate,
|
||||
variables: &serde_json::Value,
|
||||
) -> Result<String, AppError>
|
||||
```
|
||||
|
||||
#### 3. 通知历史
|
||||
```rust
|
||||
/// 记录通知历史
|
||||
pub async fn record_notification_history(
|
||||
db: &DatabaseConnection,
|
||||
history: NotificationHistory,
|
||||
) -> Result<(), AppError>
|
||||
|
||||
/// 查询通知历史
|
||||
pub async fn query_notification_history(
|
||||
db: &DatabaseConnection,
|
||||
filters: NotificationFilters,
|
||||
page: u64,
|
||||
page_size: u64,
|
||||
) -> Result<PageResp<NotificationHistoryDoc>, AppError>
|
||||
```
|
||||
|
||||
### 通知渠道
|
||||
|
||||
- **邮件通知**: SMTP 邮件发送
|
||||
- **短信通知**: SMS 短信发送
|
||||
- **系统通知**: 站内消息通知
|
||||
- **Webhook**: HTTP 回调通知
|
||||
- **推送通知**: 移动端推送
|
||||
|
||||
## 服务集成
|
||||
|
||||
### 依赖注入
|
||||
|
||||
```rust
|
||||
// 服务依赖注入示例
|
||||
pub struct ServiceContainer {
|
||||
pub db: DatabaseConnection,
|
||||
pub redis: RedisConnection,
|
||||
pub scheduler: JobScheduler,
|
||||
pub email_config: EmailConfig,
|
||||
pub sms_config: SmsConfig,
|
||||
}
|
||||
|
||||
impl ServiceContainer {
|
||||
pub fn user_service(&self) -> UserService {
|
||||
UserService::new(&self.db)
|
||||
}
|
||||
|
||||
pub fn flow_service(&self) -> FlowService {
|
||||
FlowService::new(&self.db, &self.redis)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 事务管理
|
||||
|
||||
```rust
|
||||
/// 事务执行示例
|
||||
pub async fn create_user_with_roles(
|
||||
db: &DatabaseConnection,
|
||||
user_req: CreateUserReq,
|
||||
role_ids: Vec<String>,
|
||||
) -> Result<UserDoc, AppError> {
|
||||
let txn = db.begin().await?;
|
||||
|
||||
// 创建用户
|
||||
let user = user_service::create_user(&txn, user_req).await?;
|
||||
|
||||
// 分配角色
|
||||
role_service::assign_user_roles(&txn, &user.id, role_ids).await?;
|
||||
|
||||
txn.commit().await?;
|
||||
Ok(user)
|
||||
}
|
||||
```
|
||||
|
||||
### 缓存策略
|
||||
|
||||
```rust
|
||||
/// 缓存使用示例
|
||||
pub async fn get_user_with_cache(
|
||||
db: &DatabaseConnection,
|
||||
redis: &RedisConnection,
|
||||
user_id: &str,
|
||||
) -> Result<Option<UserDoc>, AppError> {
|
||||
// 先从缓存获取
|
||||
if let Some(cached_user) = redis.get(&format!("user:{}", user_id)).await? {
|
||||
return Ok(Some(serde_json::from_str(&cached_user)?));
|
||||
}
|
||||
|
||||
// 从数据库获取
|
||||
if let Some(user) = user_service::get_user_by_id(db, user_id).await? {
|
||||
// 写入缓存
|
||||
redis.setex(
|
||||
&format!("user:{}", user_id),
|
||||
3600, // 1小时过期
|
||||
&serde_json::to_string(&user)?,
|
||||
).await?;
|
||||
Ok(Some(user))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 错误处理
|
||||
|
||||
### 统一错误类型
|
||||
|
||||
```rust
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum ServiceError {
|
||||
#[error("数据库错误: {0}")]
|
||||
DatabaseError(#[from] sea_orm::DbErr),
|
||||
|
||||
#[error("验证错误: {0}")]
|
||||
ValidationError(String),
|
||||
|
||||
#[error("权限不足")]
|
||||
PermissionDenied,
|
||||
|
||||
#[error("资源不存在: {0}")]
|
||||
ResourceNotFound(String),
|
||||
|
||||
#[error("业务逻辑错误: {0}")]
|
||||
BusinessLogicError(String),
|
||||
}
|
||||
```
|
||||
|
||||
### 错误处理模式
|
||||
|
||||
```rust
|
||||
/// 统一错误处理
|
||||
pub async fn handle_service_result<T>(
|
||||
result: Result<T, ServiceError>,
|
||||
) -> Result<T, AppError> {
|
||||
match result {
|
||||
Ok(value) => Ok(value),
|
||||
Err(ServiceError::ValidationError(msg)) => {
|
||||
Err(AppError::BadRequest(msg))
|
||||
},
|
||||
Err(ServiceError::PermissionDenied) => {
|
||||
Err(AppError::Forbidden("权限不足".to_string()))
|
||||
},
|
||||
Err(ServiceError::ResourceNotFound(resource)) => {
|
||||
Err(AppError::NotFound(format!("{}不存在", resource)))
|
||||
},
|
||||
Err(e) => Err(AppError::InternalServerError(e.to_string())),
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 性能优化
|
||||
|
||||
### 数据库优化
|
||||
|
||||
- **连接池**: 使用数据库连接池
|
||||
- **查询优化**: 优化 SQL 查询语句
|
||||
- **索引使用**: 合理使用数据库索引
|
||||
- **批量操作**: 使用批量插入/更新
|
||||
|
||||
### 缓存优化
|
||||
|
||||
- **热点数据缓存**: 缓存频繁访问的数据
|
||||
- **查询结果缓存**: 缓存复杂查询结果
|
||||
- **缓存预热**: 系统启动时预加载缓存
|
||||
- **缓存更新**: 及时更新过期缓存
|
||||
|
||||
### 并发优化
|
||||
|
||||
- **异步处理**: 使用异步编程模型
|
||||
- **并发控制**: 合理控制并发数量
|
||||
- **锁优化**: 减少锁的使用和持有时间
|
||||
- **无锁设计**: 使用无锁数据结构
|
||||
|
||||
## 测试策略
|
||||
|
||||
### 单元测试
|
||||
|
||||
```rust
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_create_user() {
|
||||
let db = setup_test_db().await;
|
||||
let req = CreateUserReq {
|
||||
username: "test_user".to_string(),
|
||||
password: "password123".to_string(),
|
||||
email: Some("test@example.com".to_string()),
|
||||
display_name: None,
|
||||
roles: vec![],
|
||||
};
|
||||
|
||||
let result = create_user(&db, req).await;
|
||||
assert!(result.is_ok());
|
||||
|
||||
let user = result.unwrap();
|
||||
assert_eq!(user.username, "test_user");
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 集成测试
|
||||
|
||||
```rust
|
||||
#[tokio::test]
|
||||
async fn test_user_role_integration() {
|
||||
let container = setup_test_container().await;
|
||||
|
||||
// 创建角色
|
||||
let role = create_test_role(&container.db).await;
|
||||
|
||||
// 创建用户
|
||||
let user = create_test_user(&container.db).await;
|
||||
|
||||
// 分配角色
|
||||
let result = role_service::assign_user_roles(
|
||||
&container.db,
|
||||
&user.id,
|
||||
vec![role.id.clone()],
|
||||
).await;
|
||||
|
||||
assert!(result.is_ok());
|
||||
|
||||
// 验证权限
|
||||
let has_permission = permission_service::check_user_permission(
|
||||
&container.db,
|
||||
&user.id,
|
||||
"user",
|
||||
"read",
|
||||
).await.unwrap();
|
||||
|
||||
assert!(has_permission);
|
||||
}
|
||||
```
|
||||
|
||||
## 最佳实践
|
||||
|
||||
### 服务设计
|
||||
|
||||
- **接口设计**: 设计清晰的服务接口
|
||||
- **参数验证**: 严格验证输入参数
|
||||
- **返回值**: 统一返回值格式
|
||||
- **文档注释**: 为公开方法添加文档注释
|
||||
|
||||
### 数据处理
|
||||
|
||||
- **数据验证**: 在服务层进行数据验证
|
||||
- **数据转换**: 合理进行数据类型转换
|
||||
- **数据清理**: 及时清理无用数据
|
||||
- **数据备份**: 重要操作前备份数据
|
||||
|
||||
### 安全考虑
|
||||
|
||||
- **权限检查**: 在服务层进行权限检查
|
||||
- **输入过滤**: 过滤恶意输入
|
||||
- **敏感数据**: 保护敏感数据不泄露
|
||||
- **审计日志**: 记录重要操作的审计日志
|
||||
Reference in New Issue
Block a user