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 { 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())), } }