- 新增 3 个 SeaORM Entity: ai_chat_session / ai_chat_message / ai_tool_call_log - ChatSessionService: create / list / get / close / rename - ChatMessageService: save_message / list_messages / save_tool_call_log - 参数封装为 SaveMessageParams / SaveToolCallLogParams 避免 clippy too_many_arguments - AiState 注册 chat_session + chat_message 服务 - erp-server main.rs 初始化注入
102 lines
3.2 KiB
Rust
102 lines
3.2 KiB
Rust
use sea_orm::{
|
|
ActiveModelTrait, ColumnTrait, DatabaseConnection, EntityTrait, QueryFilter, QueryOrder, Set,
|
|
};
|
|
use uuid::Uuid;
|
|
|
|
use crate::entity::ai_chat_session;
|
|
|
|
pub struct ChatSessionService {
|
|
db: DatabaseConnection,
|
|
}
|
|
|
|
impl ChatSessionService {
|
|
pub fn new(db: DatabaseConnection) -> Self {
|
|
Self { db }
|
|
}
|
|
|
|
pub async fn create(
|
|
&self,
|
|
tenant_id: Uuid,
|
|
user_id: Uuid,
|
|
patient_id: Option<Uuid>,
|
|
title: Option<String>,
|
|
) -> Result<ai_chat_session::Model, sea_orm::DbErr> {
|
|
let id = Uuid::now_v7();
|
|
let now = chrono::Utc::now();
|
|
let model = ai_chat_session::ActiveModel {
|
|
id: Set(id),
|
|
tenant_id: Set(tenant_id),
|
|
user_id: Set(user_id),
|
|
patient_id: Set(patient_id),
|
|
title: Set(title),
|
|
status: Set("active".to_string()),
|
|
metadata: Set(None),
|
|
created_at: Set(now),
|
|
updated_at: Set(now),
|
|
created_by: Set(Some(user_id)),
|
|
updated_by: Set(Some(user_id)),
|
|
deleted_at: Set(None),
|
|
version_lock: Set(1),
|
|
};
|
|
let result = model.insert(&self.db).await?;
|
|
Ok(result)
|
|
}
|
|
|
|
pub async fn list(
|
|
&self,
|
|
tenant_id: Uuid,
|
|
user_id: Uuid,
|
|
) -> Result<Vec<ai_chat_session::Model>, sea_orm::DbErr> {
|
|
ai_chat_session::Entity::find()
|
|
.filter(ai_chat_session::Column::TenantId.eq(tenant_id))
|
|
.filter(ai_chat_session::Column::UserId.eq(user_id))
|
|
.filter(ai_chat_session::Column::DeletedAt.is_null())
|
|
.filter(ai_chat_session::Column::Status.ne("closed"))
|
|
.order_by_desc(ai_chat_session::Column::UpdatedAt)
|
|
.all(&self.db)
|
|
.await
|
|
}
|
|
|
|
pub async fn get(
|
|
&self,
|
|
tenant_id: Uuid,
|
|
session_id: Uuid,
|
|
) -> Result<Option<ai_chat_session::Model>, sea_orm::DbErr> {
|
|
ai_chat_session::Entity::find()
|
|
.filter(ai_chat_session::Column::TenantId.eq(tenant_id))
|
|
.filter(ai_chat_session::Column::Id.eq(session_id))
|
|
.filter(ai_chat_session::Column::DeletedAt.is_null())
|
|
.one(&self.db)
|
|
.await
|
|
}
|
|
|
|
pub async fn close(&self, tenant_id: Uuid, session_id: Uuid) -> Result<bool, sea_orm::DbErr> {
|
|
let session = self.get(tenant_id, session_id).await?;
|
|
let Some(session) = session else {
|
|
return Ok(false);
|
|
};
|
|
let mut active: ai_chat_session::ActiveModel = session.into();
|
|
active.status = Set("closed".to_string());
|
|
active.updated_at = Set(chrono::Utc::now());
|
|
active.update(&self.db).await?;
|
|
Ok(true)
|
|
}
|
|
|
|
pub async fn rename(
|
|
&self,
|
|
tenant_id: Uuid,
|
|
session_id: Uuid,
|
|
new_title: String,
|
|
) -> Result<bool, sea_orm::DbErr> {
|
|
let session = self.get(tenant_id, session_id).await?;
|
|
let Some(session) = session else {
|
|
return Ok(false);
|
|
};
|
|
let mut active: ai_chat_session::ActiveModel = session.into();
|
|
active.title = Set(Some(new_title));
|
|
active.updated_at = Set(chrono::Utc::now());
|
|
active.update(&self.db).await?;
|
|
Ok(true)
|
|
}
|
|
}
|