Skip to content
Clone
c3eb022
66 lines 2.2 KB Rust
use config::ai::AiConfig;
use models::users::user::{self, ProfileVisibility};
use sea_orm::{ActiveModelTrait, ColumnTrait, DatabaseConnection, EntityTrait, QueryFilter, Set};
use time::OffsetDateTime;
use uuid::Uuid;
/// 解析(必要时创建)AI 系统用户。
///
/// 该用户以 `bot=true, system=true` 标记,无口令、不可登录,仅用于承载
/// AI 评审与评论的作者身份。
pub async fn resolve_bot_user(
db: &DatabaseConnection,
cfg: &AiConfig,
) -> Result<Uuid, sea_orm::DbErr> {
let username = cfg.bot_username.trim();
let lower = username.to_lowercase();
if let Some(row) = user::Entity::find()
.filter(user::Column::LowerName.eq(&lower))
.one(db)
.await?
{
return Ok(row.uid);
}
let uid = Uuid::now_v7();
let now = OffsetDateTime::now_utc();
let created = user::ActiveModel {
uid: Set(uid),
username: Set(username.to_string()),
lower_name: Set(lower.clone()),
display_name: Set(cfg.bot_display_name.trim().to_string()),
avatar_url: Set(String::new()),
is_active: Set(true),
is_restricted: Set(false),
prohibit_login: Set(true),
visibility: Set(ProfileVisibility::Public),
bot: Set(true),
system: Set(true),
last_login_at: Set(None),
last_login_ip_hash: Set(None),
version: Set(1),
passwd_hash: Set(None),
password_last_changed_at: Set(None),
passwd_version: Set(None),
totp_encrypted_secret: Set(None),
totp_enabled: Set(false),
totp_last_used_at: Set(None),
totp_last_counter: Set(None),
timezone: Set(None),
locale: Set(None),
language: Set(None),
created_at: Set(now),
updated_at: Set(now),
}
.insert(db)
.await;
match created {
Ok(row) => Ok(row.uid),
// 并发创建时另一进程已插入,回查即可。
Err(_) => user::Entity::find()
.filter(user::Column::LowerName.eq(&lower))
.one(db)
.await?
.map(|row| row.uid)
.ok_or_else(|| sea_orm::DbErr::RecordNotFound("ai bot user".to_string())),
}
}