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

158 lines
4.8 KiB
Rust

use crate::{AppService, error::AppError};
use chrono::Utc;
use models::users::user_relation;
use sea_orm::*;
use serde::{Deserialize, Serialize};
use session::Session;
use uuid::Uuid;
#[derive(Deserialize, Serialize, Clone, Debug, utoipa::ToSchema)]
pub struct SubscriptionInfo {
pub id: i64,
pub user_uid: Uuid,
pub target_uid: Uuid,
pub subscribed_at: chrono::DateTime<Utc>,
pub is_active: bool,
}
impl From<user_relation::Model> for SubscriptionInfo {
fn from(sub: user_relation::Model) -> Self {
SubscriptionInfo {
id: sub.id,
user_uid: sub.user,
target_uid: sub.target,
subscribed_at: sub.created_at,
is_active: true, // user_relation doesn't have is_active, we treat follow as active
}
}
}
impl AppService {
pub async fn user_subscribe_target(
&self,
context: Session,
target: String,
) -> Result<(), AppError> {
let user_uid = context.user().ok_or(AppError::Unauthorized)?;
let target_user = self.utils_find_user_by_username(target).await?;
let target_uid = target_user.uid;
let existing = user_relation::Entity::find()
.filter(user_relation::Column::User.eq(user_uid))
.filter(user_relation::Column::Target.eq(target_uid))
.filter(user_relation::Column::RelationType.eq("follow"))
.one(&self.db)
.await?;
if existing.is_some() {
return Err(AppError::NotFound("Already subscribed".to_string()));
}
let subscription = user_relation::ActiveModel {
user: Set(user_uid),
target: Set(target_uid),
relation_type: Set("follow".to_string()),
created_at: Set(Utc::now()),
..Default::default()
};
subscription.insert(&self.db).await?;
Ok(())
}
pub async fn user_unsubscribe_target(
&self,
context: Session,
target: String,
) -> Result<(), AppError> {
let user_uid = context.user().ok_or(AppError::Unauthorized)?;
let target_user = self.utils_find_user_by_username(target).await?;
let target_uid = target_user.uid;
user_relation::Entity::delete_many()
.filter(user_relation::Column::User.eq(user_uid))
.filter(user_relation::Column::Target.eq(target_uid))
.filter(user_relation::Column::RelationType.eq("follow"))
.exec(&self.db)
.await?;
Ok(())
}
pub async fn user_is_subscribed_to_target(
&self,
context: Session,
target: String,
) -> Result<bool, AppError> {
let user_uid = context.user().ok_or(AppError::Unauthorized)?;
let target_user = self.utils_find_user_by_username(target).await?;
let target_uid = target_user.uid;
let subscription = user_relation::Entity::find()
.filter(user_relation::Column::User.eq(user_uid))
.filter(user_relation::Column::Target.eq(target_uid))
.filter(user_relation::Column::RelationType.eq("follow"))
.one(&self.db)
.await?;
Ok(subscription.is_some())
}
pub async fn user_get_subscribers(
&self,
_context: Session,
target: String,
) -> Result<Vec<SubscriptionInfo>, AppError> {
let target_user = self.utils_find_user_by_username(target).await?;
let target_uid = target_user.uid;
let subscribers = user_relation::Entity::find()
.filter(user_relation::Column::Target.eq(target_uid))
.filter(user_relation::Column::RelationType.eq("follow"))
.order_by_desc(user_relation::Column::CreatedAt)
.all(&self.db)
.await?;
Ok(subscribers
.into_iter()
.map(SubscriptionInfo::from)
.collect())
}
pub async fn user_get_subscription_count(
&self,
_context: Session,
username: String,
) -> Result<u64, AppError> {
let user_uid = self.utils_find_user_by_username(username).await?.uid;
let count = user_relation::Entity::find()
.filter(user_relation::Column::User.eq(user_uid))
.filter(user_relation::Column::RelationType.eq("follow"))
.count(&self.db)
.await?;
Ok(count)
}
pub async fn user_get_subscriber_count(
&self,
_context: Session,
target: String,
) -> Result<u64, AppError> {
let target_user = self.utils_find_user_by_username(target).await?;
let target_uid = target_user.uid;
let count = user_relation::Entity::find()
.filter(user_relation::Column::Target.eq(target_uid))
.filter(user_relation::Column::RelationType.eq("follow"))
.count(&self.db)
.await?;
Ok(count)
}
}