gitdataai/libs/service/user/repository.rs
2026-04-15 09:08:09 +08:00

118 lines
3.4 KiB
Rust

use crate::AppService;
use crate::error::AppError;
use chrono::Utc;
use models::repos::repo;
use models::users::user;
use sea_orm::prelude::*;
use sea_orm::*;
use serde::{Deserialize, Serialize};
use session::Session;
use utoipa::{IntoParams, ToSchema};
use uuid::Uuid;
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct UserRepoInfo {
pub uid: Uuid,
pub repo_name: String,
pub description: Option<String>,
pub default_branch: String,
pub is_private: bool,
pub storage_path: String,
pub created_at: chrono::DateTime<Utc>,
pub updated_at: chrono::DateTime<Utc>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct UserReposResponse {
pub username: String,
pub repos: Vec<UserRepoInfo>,
pub total_count: u64,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema, IntoParams)]
pub struct UserReposQuery {
pub page: Option<u64>,
pub per_page: Option<u64>,
}
impl AppService {
pub async fn get_user_repos(
&self,
context: Session,
username: String,
query: UserReposQuery,
) -> Result<UserReposResponse, AppError> {
let target_user = user::Entity::find()
.filter(user::Column::Username.eq(&username))
.one(&self.db)
.await?
.ok_or(AppError::UserNotFound)?;
let current_user_uid = context.user();
let is_owner = current_user_uid
.map(|uid| uid == target_user.uid)
.unwrap_or(false);
let has_admin_privilege = false;
let page = std::cmp::Ord::max(query.page.unwrap_or(1), 1);
let per_page = std::cmp::Ord::min(std::cmp::Ord::max(query.per_page.unwrap_or(20), 1), 100);
let offset = (page - 1) * per_page;
let mut condition = Condition::all().add(repo::Column::CreatedBy.eq(target_user.uid));
if !is_owner && !has_admin_privilege {
condition = condition.add(repo::Column::IsPrivate.eq(false));
}
let total_count = repo::Entity::find()
.filter(condition.clone())
.count(&self.db)
.await?;
let repos = repo::Entity::find()
.filter(condition)
.order_by_desc(repo::Column::CreatedAt)
.limit(per_page)
.offset(offset)
.all(&self.db)
.await?;
let repo_infos: Vec<UserRepoInfo> = repos
.into_iter()
.map(|r| UserRepoInfo {
uid: r.id,
repo_name: r.repo_name,
description: r.description,
default_branch: r.default_branch,
is_private: r.is_private,
storage_path: r.storage_path,
created_at: r.created_at,
updated_at: r.updated_at,
})
.collect();
Ok(UserReposResponse {
username: target_user.username,
repos: repo_infos,
total_count,
})
}
pub async fn get_current_user_repos(
&self,
context: Session,
query: UserReposQuery,
) -> Result<UserReposResponse, AppError> {
let user_uid = context.user().ok_or(AppError::Unauthorized)?;
let user = user::Entity::find()
.filter(user::Column::Uid.eq(user_uid))
.one(&self.db)
.await?
.ok_or(AppError::UserNotFound)?;
self.get_user_repos(context, user.username, query).await
}
}