158 lines
4.8 KiB
Rust
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)
|
|
}
|
|
}
|