mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
feat: add get workspace subs
This commit is contained in:
2
frontend/rust-lib/Cargo.lock
generated
2
frontend/rust-lib/Cargo.lock
generated
@ -183,7 +183,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "appflowy-cloud-billing-client"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud-Billing-Client?rev=196d8ccbc6a63604f1ac56c66e772efd365818aa#196d8ccbc6a63604f1ac56c66e772efd365818aa"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud-Billing-Client?rev=c608c4ec97bae19bad212742eeb4e3475845742a#c608c4ec97bae19bad212742eeb4e3475845742a"
|
||||
dependencies = [
|
||||
"client-api",
|
||||
"reqwest",
|
||||
|
@ -100,7 +100,7 @@ yrs = "0.18.7"
|
||||
# scripts/tool/update_client_api_rev.sh new_rev_id
|
||||
# ⚠️⚠️⚠️️
|
||||
client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "ef8e6f3" }
|
||||
appflowy-cloud-billing-client = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud-Billing-Client", rev = "196d8ccbc6a63604f1ac56c66e772efd365818aa" }
|
||||
appflowy-cloud-billing-client = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud-Billing-Client", rev = "c608c4ec97bae19bad212742eeb4e3475845742a" }
|
||||
|
||||
[profile.dev]
|
||||
opt-level = 1
|
||||
|
@ -1,4 +1,6 @@
|
||||
use appflowy_cloud_billing_client::entities::{RecurringInterval, SubscriptionPlan};
|
||||
use appflowy_cloud_billing_client::entities::{
|
||||
RecurringInterval, SubscriptionPlan, WorkspaceSubscriptionStatus,
|
||||
};
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
|
||||
@ -22,6 +24,7 @@ use flowy_user_pub::cloud::{UserCloudService, UserCollabParams, UserUpdate, User
|
||||
use flowy_user_pub::entities::{
|
||||
AFCloudOAuthParams, AuthResponse, Role, UpdateUserProfileParams, UserCredentials, UserProfile,
|
||||
UserWorkspace, WorkspaceInvitation, WorkspaceInvitationStatus, WorkspaceMember,
|
||||
WorkspaceSubscription,
|
||||
};
|
||||
use lib_infra::box_any::BoxAny;
|
||||
use lib_infra::future::FutureResult;
|
||||
@ -487,17 +490,31 @@ where
|
||||
let try_get_client = self.server.try_get_client();
|
||||
let workspace_id = workspace_id.to_string();
|
||||
FutureResult::new(async move {
|
||||
let subscription_plan = to_workspace_subscription_plan(workspace_subscription_plan)?;
|
||||
let client = try_get_client?;
|
||||
let payment_link = client
|
||||
.create_subscription(
|
||||
&workspace_id,
|
||||
to_recurring_interval(recurring_interval),
|
||||
to_workspace_subscription_plan(workspace_subscription_plan),
|
||||
subscription_plan,
|
||||
&success_url,
|
||||
)
|
||||
.await?;
|
||||
Ok(payment_link)
|
||||
// Ok(())
|
||||
})
|
||||
}
|
||||
|
||||
fn get_workspace_subscriptions(&self) -> FutureResult<Vec<WorkspaceSubscription>, FlowyError> {
|
||||
let try_get_client = self.server.try_get_client();
|
||||
FutureResult::new(async move {
|
||||
let client = try_get_client?;
|
||||
let workspace_subscriptions = client
|
||||
.list_subscription()
|
||||
.await?
|
||||
.into_iter()
|
||||
.map(to_workspace_subscription)
|
||||
.collect();
|
||||
Ok(workspace_subscriptions)
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -606,9 +623,36 @@ fn to_recurring_interval(r: flowy_user_pub::entities::RecurringInterval) -> Recu
|
||||
|
||||
fn to_workspace_subscription_plan(
|
||||
s: flowy_user_pub::entities::SubscriptionPlan,
|
||||
) -> SubscriptionPlan {
|
||||
) -> Result<SubscriptionPlan, FlowyError> {
|
||||
match s {
|
||||
flowy_user_pub::entities::SubscriptionPlan::Pro => SubscriptionPlan::Pro,
|
||||
flowy_user_pub::entities::SubscriptionPlan::Team => SubscriptionPlan::Team,
|
||||
flowy_user_pub::entities::SubscriptionPlan::Pro => Ok(SubscriptionPlan::Pro),
|
||||
flowy_user_pub::entities::SubscriptionPlan::Team => Ok(SubscriptionPlan::Team),
|
||||
flowy_user_pub::entities::SubscriptionPlan::None => Err(FlowyError::new(
|
||||
ErrorCode::InvalidParams,
|
||||
"Invalid subscription plan",
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
fn to_workspace_subscription(s: WorkspaceSubscriptionStatus) -> WorkspaceSubscription {
|
||||
WorkspaceSubscription {
|
||||
workspace_id: s.workspace_id,
|
||||
subscription_plan: match s.workspace_plan {
|
||||
appflowy_cloud_billing_client::entities::WorkspaceSubscriptionPlan::Pro => {
|
||||
flowy_user_pub::entities::SubscriptionPlan::Pro
|
||||
},
|
||||
appflowy_cloud_billing_client::entities::WorkspaceSubscriptionPlan::Team => {
|
||||
flowy_user_pub::entities::SubscriptionPlan::Team
|
||||
},
|
||||
_ => flowy_user_pub::entities::SubscriptionPlan::None,
|
||||
},
|
||||
recurring_interval: match s.recurring_interval {
|
||||
RecurringInterval::Month => flowy_user_pub::entities::RecurringInterval::Month,
|
||||
RecurringInterval::Year => flowy_user_pub::entities::RecurringInterval::Year,
|
||||
},
|
||||
is_active: matches!(
|
||||
s.subscription_status,
|
||||
appflowy_cloud_billing_client::entities::SubscriptionStatus::Active
|
||||
),
|
||||
}
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ use uuid::Uuid;
|
||||
use crate::entities::{
|
||||
AuthResponse, Authenticator, RecurringInterval, Role, SubscriptionPlan, UpdateUserProfileParams,
|
||||
UserCredentials, UserProfile, UserTokenState, UserWorkspace, WorkspaceInvitation,
|
||||
WorkspaceInvitationStatus, WorkspaceMember,
|
||||
WorkspaceInvitationStatus, WorkspaceMember, WorkspaceSubscription,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
@ -277,6 +277,10 @@ pub trait UserCloudService: Send + Sync + 'static {
|
||||
) -> FutureResult<String, FlowyError> {
|
||||
FutureResult::new(async { Err(FlowyError::not_support()) })
|
||||
}
|
||||
|
||||
fn get_workspace_subscriptions(&self) -> FutureResult<Vec<WorkspaceSubscription>, FlowyError> {
|
||||
FutureResult::new(async { Err(FlowyError::not_support()) })
|
||||
}
|
||||
}
|
||||
|
||||
pub type UserUpdateReceiver = tokio::sync::mpsc::Receiver<UserUpdate>;
|
||||
|
@ -428,6 +428,14 @@ pub enum RecurringInterval {
|
||||
}
|
||||
|
||||
pub enum SubscriptionPlan {
|
||||
None,
|
||||
Pro,
|
||||
Team,
|
||||
}
|
||||
|
||||
pub struct WorkspaceSubscription {
|
||||
pub workspace_id: String,
|
||||
pub subscription_plan: SubscriptionPlan,
|
||||
pub recurring_interval: RecurringInterval,
|
||||
pub is_active: bool,
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ use validator::Validate;
|
||||
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
|
||||
use flowy_user_pub::entities::{
|
||||
RecurringInterval, Role, SubscriptionPlan, WorkspaceInvitation, WorkspaceMember,
|
||||
WorkspaceSubscription,
|
||||
};
|
||||
use lib_infra::validator_fn::required_not_empty_str;
|
||||
|
||||
@ -223,19 +224,29 @@ pub enum RecurringIntervalPB {
|
||||
}
|
||||
|
||||
impl From<RecurringIntervalPB> for RecurringInterval {
|
||||
fn from(value: RecurringIntervalPB) -> Self {
|
||||
match value {
|
||||
fn from(r: RecurringIntervalPB) -> Self {
|
||||
match r {
|
||||
RecurringIntervalPB::Month => RecurringInterval::Month,
|
||||
RecurringIntervalPB::Year => RecurringInterval::Year,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<RecurringInterval> for RecurringIntervalPB {
|
||||
fn from(r: RecurringInterval) -> Self {
|
||||
match r {
|
||||
RecurringInterval::Month => RecurringIntervalPB::Month,
|
||||
RecurringInterval::Year => RecurringIntervalPB::Year,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(ProtoBuf_Enum, Clone, Default, Debug)]
|
||||
pub enum SubscriptionPlanPB {
|
||||
#[default]
|
||||
Pro = 0,
|
||||
Team = 1,
|
||||
None = 0,
|
||||
Pro = 1,
|
||||
Team = 2,
|
||||
}
|
||||
|
||||
impl From<SubscriptionPlanPB> for SubscriptionPlan {
|
||||
@ -243,6 +254,17 @@ impl From<SubscriptionPlanPB> for SubscriptionPlan {
|
||||
match value {
|
||||
SubscriptionPlanPB::Pro => SubscriptionPlan::Pro,
|
||||
SubscriptionPlanPB::Team => SubscriptionPlan::Team,
|
||||
SubscriptionPlanPB::None => SubscriptionPlan::None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<SubscriptionPlan> for SubscriptionPlanPB {
|
||||
fn from(value: SubscriptionPlan) -> Self {
|
||||
match value {
|
||||
SubscriptionPlan::Pro => SubscriptionPlanPB::Pro,
|
||||
SubscriptionPlan::Team => SubscriptionPlanPB::Team,
|
||||
SubscriptionPlan::None => SubscriptionPlanPB::None,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -252,3 +274,35 @@ pub struct PaymentLinkPB {
|
||||
#[pb(index = 1)]
|
||||
pub payment_link: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, ProtoBuf, Default, Clone)]
|
||||
pub struct RepeatedWorkspaceSubscriptionPB {
|
||||
#[pb(index = 1)]
|
||||
pub items: Vec<WorkspaceSubscriptionPB>,
|
||||
}
|
||||
|
||||
#[derive(Debug, ProtoBuf, Default, Clone)]
|
||||
pub struct WorkspaceSubscriptionPB {
|
||||
#[pb(index = 1)]
|
||||
pub workspace_id: String,
|
||||
|
||||
#[pb(index = 2)]
|
||||
pub subscription_plan: SubscriptionPlanPB,
|
||||
|
||||
#[pb(index = 3)]
|
||||
pub recurring_interval: RecurringIntervalPB,
|
||||
|
||||
#[pb(index = 4)]
|
||||
pub is_active: bool,
|
||||
}
|
||||
|
||||
impl From<WorkspaceSubscription> for WorkspaceSubscriptionPB {
|
||||
fn from(s: WorkspaceSubscription) -> Self {
|
||||
Self {
|
||||
workspace_id: s.workspace_id,
|
||||
subscription_plan: s.subscription_plan.into(),
|
||||
recurring_interval: s.recurring_interval.into(),
|
||||
is_active: s.is_active,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -785,3 +785,17 @@ pub async fn subscribe_workspace_handler(
|
||||
let payment_link = manager.subscribe_workspace(params).await?;
|
||||
data_result_ok(PaymentLinkPB { payment_link })
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "debug", skip_all, err)]
|
||||
pub async fn get_workspace_subscriptions_handler(
|
||||
manager: AFPluginState<Weak<UserManager>>,
|
||||
) -> DataResult<RepeatedWorkspaceSubscriptionPB, FlowyError> {
|
||||
let manager = upgrade_manager(manager)?;
|
||||
let subs = manager
|
||||
.get_workspace_subscriptions()
|
||||
.await?
|
||||
.into_iter()
|
||||
.map(WorkspaceSubscriptionPB::from)
|
||||
.collect::<Vec<_>>();
|
||||
data_result_ok(RepeatedWorkspaceSubscriptionPB { items: subs })
|
||||
}
|
||||
|
@ -73,6 +73,7 @@ pub fn init(user_manager: Weak<UserManager>) -> AFPlugin {
|
||||
.event(UserEvent::AcceptWorkspaceInvitation, accept_workspace_invitations_handler)
|
||||
// Billing
|
||||
.event(UserEvent::SubscribeWorkspace, subscribe_workspace_handler)
|
||||
.event(UserEvent::GetWorkspaceSubscriptions, get_workspace_subscriptions_handler)
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug, Display, Hash, ProtoBuf_Enum, Flowy_Event)]
|
||||
@ -235,6 +236,9 @@ pub enum UserEvent {
|
||||
|
||||
#[event(input = "SubscribeWorkspacePB", output = "PaymentLinkPB")]
|
||||
SubscribeWorkspace = 51,
|
||||
|
||||
#[event(output = "RepeatedWorkspaceSubscriptionPB")]
|
||||
GetWorkspaceSubscriptions = 52,
|
||||
}
|
||||
|
||||
pub trait UserStatusCallback: Send + Sync + 'static {
|
||||
|
@ -11,6 +11,7 @@ use flowy_sqlite::schema::user_workspace_table;
|
||||
use flowy_sqlite::{query_dsl::*, DBConnection, ExpressionMethods};
|
||||
use flowy_user_pub::entities::{
|
||||
Role, UserWorkspace, WorkspaceInvitation, WorkspaceInvitationStatus, WorkspaceMember,
|
||||
WorkspaceSubscription,
|
||||
};
|
||||
use lib_dispatch::prelude::af_spawn;
|
||||
|
||||
@ -420,6 +421,16 @@ impl UserManager {
|
||||
|
||||
Ok(payment_link)
|
||||
}
|
||||
|
||||
#[instrument(level = "info", skip(self), err)]
|
||||
pub async fn get_workspace_subscriptions(&self) -> FlowyResult<Vec<WorkspaceSubscription>> {
|
||||
let res = self
|
||||
.cloud_services
|
||||
.get_user_service()?
|
||||
.get_workspace_subscriptions()
|
||||
.await?;
|
||||
Ok(res)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn save_user_workspaces(
|
||||
|
Reference in New Issue
Block a user