From 63048f68000234bbf0a63b4dac225aa053f7f17a Mon Sep 17 00:00:00 2001 From: PARK BYUNG JUN Date: Fri, 19 Aug 2022 07:06:00 +0000 Subject: [PATCH] member_referrer is added --- Cargo.toml | 4 +- migrations/202206201240_member/up.sql | 8 +- .../202206201420_member_referrer/down.sql | 3 + .../202206201420_member_referrer/up.sql | 22 + src/compositions/member/composition.rs | 10 +- src/compositions/member/models.rs | 16 +- .../member_referrer/composition.rs | 143 ++++ src/compositions/member_referrer/mod.rs | 7 + src/compositions/member_referrer/models.rs | 54 ++ src/compositions/mod.rs | 1 + src/repositories/member/models.rs | 8 +- src/repositories/member/repository.rs | 18 +- src/repositories/member/schema.rs | 4 +- src/repositories/member_referrer/mod.rs | 9 + src/repositories/member_referrer/models.rs | 60 ++ .../member_referrer/repository.rs | 195 +++++ src/repositories/member_referrer/schema.rs | 20 + src/repositories/mod.rs | 1 + src/services/member/models.rs | 10 +- src/services/member/service.rs | 56 +- src/services/member_bank_account/service.rs | 1 - src/services/member_referrer/mod.rs | 2 + src/services/member_referrer/models.rs | 33 + src/services/member_referrer/service.rs | 791 ++++++++++++++++++ src/services/mod.rs | 1 + 25 files changed, 1405 insertions(+), 72 deletions(-) create mode 100644 migrations/202206201420_member_referrer/down.sql create mode 100644 migrations/202206201420_member_referrer/up.sql create mode 100644 src/compositions/member_referrer/composition.rs create mode 100644 src/compositions/member_referrer/mod.rs create mode 100644 src/compositions/member_referrer/models.rs create mode 100644 src/repositories/member_referrer/mod.rs create mode 100644 src/repositories/member_referrer/models.rs create mode 100644 src/repositories/member_referrer/repository.rs create mode 100644 src/repositories/member_referrer/schema.rs create mode 100644 src/services/member_referrer/mod.rs create mode 100644 src/services/member_referrer/models.rs create mode 100644 src/services/member_referrer/service.rs diff --git a/Cargo.toml b/Cargo.toml index 586dbc6..48db697 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,7 +31,7 @@ tokio = { version = "1", features = ["macros", "rt-multi-thread"] } tokio-cron-scheduler = { version = "0" } uuid = { version = "0", features = ["serde", "v4", "v5"] } -beteran-protobuf-rust = { git = "https://gitlab.loafle.net/bet/beteran-protobuf-rust.git", tag = "v0.1.64-snapshot" } -beteran-common-rust = { git = "https://gitlab.loafle.net/bet/beteran-common-rust.git", tag = "v0.1.48-snapshot" } +beteran-protobuf-rust = { git = "https://gitlab.loafle.net/bet/beteran-protobuf-rust.git", tag = "v0.1.66-snapshot" } +beteran-common-rust = { git = "https://gitlab.loafle.net/bet/beteran-common-rust.git", tag = "v0.1.50-snapshot" } [build-dependencies] diff --git a/migrations/202206201240_member/up.sql b/migrations/202206201240_member/up.sql index c4ddd48..19b10d0 100644 --- a/migrations/202206201240_member/up.sql +++ b/migrations/202206201240_member/up.sql @@ -12,8 +12,8 @@ CREATE TABLE IF NOT EXISTS members ( mobile_phone_number TEXT, state MEMBER_STATE DEFAULT 'normal', state_changed_at BIGINT, - referrer_member_id UUID, - referred_count BIGINT NOT NULL DEFAULT 0, + parent_member_id UUID, + child_member_count BIGINT NOT NULL DEFAULT 0, last_signined_ip TEXT, last_signined_at BIGINT, created_at BIGINT NOT NULL DEFAULT (extract(epoch from now()) * 1000), @@ -30,8 +30,8 @@ CREATE TABLE IF NOT EXISTS members ( CONSTRAINT fk_members_member_level_id FOREIGN KEY(member_level_id) REFERENCES member_levels(id), - CONSTRAINT fk_members_referrer_member_id - FOREIGN KEY(referrer_member_id) + CONSTRAINT fk_members_parent_member_id + FOREIGN KEY(parent_member_id) REFERENCES members(id) ); diff --git a/migrations/202206201420_member_referrer/down.sql b/migrations/202206201420_member_referrer/down.sql new file mode 100644 index 0000000..e62e607 --- /dev/null +++ b/migrations/202206201420_member_referrer/down.sql @@ -0,0 +1,3 @@ +DROP INDEX idx_member_referrers_member_id; +DROP TRIGGER tg_member_referrers_updated_at; +DROP TABLE member_referrers; diff --git a/migrations/202206201420_member_referrer/up.sql b/migrations/202206201420_member_referrer/up.sql new file mode 100644 index 0000000..eee896d --- /dev/null +++ b/migrations/202206201420_member_referrer/up.sql @@ -0,0 +1,22 @@ +CREATE TABLE IF NOT EXISTS member_referrers ( + id UUID DEFAULT uuid_generate_v4(), + member_id UUID NOT NULL, + can_use BOOLEAN NOT NULL DEFAULT TRUE, + memo TEXT, + created_at BIGINT NOT NULL DEFAULT (extract(epoch from now()) * 1000), + updated_at BIGINT NOT NULL DEFAULT (extract(epoch from now()) * 1000), + PRIMARY KEY (id), + CONSTRAINT fk_member_referrers_member_id + FOREIGN KEY(member_id) + REFERENCES members(id) +); + +CREATE INDEX idx_member_referrers_member_id ON member_referrers (member_id); + +-- trigger (updated_at) +CREATE TRIGGER tg_member_referrers_updated_at + BEFORE UPDATE + ON member_referrers + FOR EACH ROW + EXECUTE PROCEDURE update_updated_at_column(); + diff --git a/src/compositions/member/composition.rs b/src/compositions/member/composition.rs index 621e52b..a54d4a1 100644 --- a/src/compositions/member/composition.rs +++ b/src/compositions/member/composition.rs @@ -17,8 +17,8 @@ SELECT m.mobile_phone_number as m_mobile_phone_number, m.state as m_state, m.state_changed_at as m_state_changed_at, - m.referrer_member_id as m_referrer_member_id, - m.referred_count as m_referred_count, + m.parent_member_id as m_parent_member_id, + m.child_member_count as m_child_member_count, m.last_signined_ip as m_last_signined_ip, m.last_signined_at as m_last_signined_at, m.created_at as m_created_at, @@ -60,8 +60,8 @@ SELECT _m.mobile_phone_number as _m_mobile_phone_number, _m.state as _m_state, _m.state_changed_at as _m_state_changed_at, - _m.referrer_member_id as _m_referrer_member_id, - _m.referred_count as _m_referred_count, + _m.parent_member_id as _m_parent_member_id, + _m.child_member_count as _m_child_member_count, _m.last_signined_ip as _m_last_signined_ip, _m.last_signined_at as _m_last_signined_at, _m.created_at as _m_created_at, @@ -95,7 +95,7 @@ FROM members as m INNER JOIN member_levels ml ON ml.id = m.member_level_id LEFT OUTER JOIN members _m - ON _m.id = m.referrer_member_id + ON _m.id = m.parent_member_id LEFT OUTER JOIN member_bank_accounts mba ON mba.member_id = m.id LEFT OUTER JOIN banks _b diff --git a/src/compositions/member/models.rs b/src/compositions/member/models.rs index 4a92db7..507f727 100644 --- a/src/compositions/member/models.rs +++ b/src/compositions/member/models.rs @@ -33,9 +33,9 @@ pub struct MemberModel { /// pub state_changed_at: Option, /// - pub referrer_member: Option<_Member>, + pub parent_member: Option<_Member>, /// - pub referred_count: i64, + pub child_member_count: i64, /// pub last_signined_ip: Option, /// @@ -50,9 +50,9 @@ pub struct MemberModel { impl QueryableByName for MemberModel { fn build>(row: &R) -> diesel::deserialize::Result { - let referrer_member = match row + let parent_member = match row .get::, Option>( - "m_referrer_member_id", + "m_parent_member_id", )? { Some(_) => Some(_Member { id: row.get("_m_id")?, @@ -65,8 +65,8 @@ impl QueryableByName for MemberModel { mobile_phone_number: row.get("_m_mobile_phone_number")?, state: row.get("_m_state")?, state_changed_at: row.get("_m_state_changed_at")?, - referrer_member_id: row.get("_m_referrer_member_id")?, - referred_count: row.get("_m_referred_count")?, + parent_member_id: row.get("_m_parent_member_id")?, + child_member_count: row.get("_m_child_member_count")?, last_signined_ip: row.get("_m_last_signined_ip")?, last_signined_at: row.get("_m_last_signined_at")?, created_at: row.get("_m_created_at")?, @@ -144,8 +144,8 @@ impl QueryableByName for MemberModel { state: row.get("m_state")?, state_changed_at: row.get("m_state_changed_at")?, bank_account: member_bank_account, - referrer_member, - referred_count: row.get("m_referred_count")?, + parent_member, + child_member_count: row.get("m_child_member_count")?, last_signined_ip: row.get("m_last_signined_ip")?, last_signined_at: row.get("m_last_signined_at")?, created_at: row.get("m_created_at")?, diff --git a/src/compositions/member_referrer/composition.rs b/src/compositions/member_referrer/composition.rs new file mode 100644 index 0000000..6551b23 --- /dev/null +++ b/src/compositions/member_referrer/composition.rs @@ -0,0 +1,143 @@ +//! +//! + +use super::models; +use crate::repositories; +use diesel::{result::Error, sql_query, RunQueryDsl}; + +static MEMBER_QUERY: &str = " +SELECT + mr.id as mr_id, + mr.member_id as mr_member_id, + mr.can_use as mr_can_use, + mr.memo as mr_memo, + mr.created_at as mr_created_at, + mr.updated_at as mr_updated_at, + + _m.id as _m_id, + _m.site_id as _m_site_id, + _m.member_class_id as _m_member_class_id, + _m.member_level_id as _m_member_level_id, + _m.username as _m_username, + _m.password as _m_password, + _m.nickname as _m_nickname, + _m.mobile_phone_number as _m_mobile_phone_number, + _m.state as _m_state, + _m.state_changed_at as _m_state_changed_at, + _m.parent_member_id as _m_parent_member_id, + _m.child_member_count as _m_child_member_count, + _m.last_signined_ip as _m_last_signined_ip, + _m.last_signined_at as _m_last_signined_at, + _m.created_at as _m_created_at, + _m.updated_at as _m_updated_at, + _m.deleted_at as _m_deleted_at + +FROM member_referrers as m + INNER JOIN members _m + ON _m.id = mr.member_id +"; + +pub struct Composition {} + +impl std::fmt::Debug for Composition { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + f.debug_struct("Composition of members").finish() + } +} + +impl Default for Composition { + fn default() -> Self { + Self::new() + } +} + +impl Composition { + /// + pub fn new() -> Composition { + Composition {} + } + + /// + pub fn select( + &self, + conn: &diesel::PgConnection, + id: uuid::Uuid, + ) -> Result, Error> { + let query = format!( + " + {} + WHERE + m.id = $1 + ", + MEMBER_QUERY + ); + + match sql_query(query) + .bind::(id) + .get_result::(conn) + { + Ok(m) => Ok(Some(m)), + Err(e) => match e { + diesel::result::Error::NotFound => Ok(None), + _ => Err(e), + }, + } + } + + /// + pub fn select_all( + &self, + conn: &diesel::PgConnection, + find_all: &repositories::member_referrer::models::FindAll, + ) -> Result, Error> { + use std::fmt::Write; + + let mut query = String::new(); + write!(&mut query, "{}", MEMBER_QUERY) + .map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?; + + let mut query_where = String::new(); + + if let Some(s) = &find_all.search { + if let Some(sp) = s.member_id { + if !query_where.is_empty() { + write!(&mut query_where, " AND ") + .map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?; + } + write!(&mut query_where, "mr.member_id = '{}'", sp) + .map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?; + } + if let Some(sp) = s.can_use { + if !query_where.is_empty() { + write!(&mut query_where, " AND ") + .map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?; + } + write!(&mut query_where, "mr.can_use = '{}'", sp) + .map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?; + } + if let Some(sp) = &s.memo_like { + if !query_where.is_empty() { + write!(&mut query_where, " AND ") + .map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?; + } + write!(&mut query_where, "mr.memo like '{}'", sp) + .map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?; + } + } + + if !query_where.is_empty() { + write!(&mut query, " WHERE {}", query_where) + .map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?; + } + + println!("query: {}", query); + + match sql_query(query).get_results::(conn) { + Ok(m) => Ok(m), + Err(e) => match e { + diesel::result::Error::NotFound => Ok(vec![]), + _ => Err(e), + }, + } + } +} diff --git a/src/compositions/member_referrer/mod.rs b/src/compositions/member_referrer/mod.rs new file mode 100644 index 0000000..e0b4e90 --- /dev/null +++ b/src/compositions/member_referrer/mod.rs @@ -0,0 +1,7 @@ +//! +//! + +/// +pub mod composition; +/// +pub mod models; diff --git a/src/compositions/member_referrer/models.rs b/src/compositions/member_referrer/models.rs new file mode 100644 index 0000000..f2cdf6c --- /dev/null +++ b/src/compositions/member_referrer/models.rs @@ -0,0 +1,54 @@ +//! +//! +use crate::repositories::member::models::Member as _Member; +use diesel::deserialize::QueryableByName; + +/// +#[derive(Eq, Hash, PartialEq, Debug, Clone)] +pub struct MemberReferrerModel { + /// + pub id: uuid::Uuid, + /// + pub member: _Member, + /// + pub can_use: bool, + /// + pub memo: Option, + /// + pub created_at: i64, + /// + pub updated_at: i64, +} + +impl QueryableByName for MemberReferrerModel { + fn build>(row: &R) -> diesel::deserialize::Result { + let member = _Member { + id: row.get("_m_id")?, + site_id: row.get("_m_site_id")?, + member_class_id: row.get("_m_member_class_id")?, + member_level_id: row.get("_m_member_level_id")?, + username: row.get("_m_username")?, + password: row.get("_m_password")?, + nickname: row.get("_m_nickname")?, + mobile_phone_number: row.get("_m_mobile_phone_number")?, + state: row.get("_m_state")?, + state_changed_at: row.get("_m_state_changed_at")?, + parent_member_id: row.get("_m_parent_member_id")?, + child_member_count: row.get("_m_child_member_count")?, + last_signined_ip: row.get("_m_last_signined_ip")?, + last_signined_at: row.get("_m_last_signined_at")?, + created_at: row.get("_m_created_at")?, + updated_at: row.get("_m_updated_at")?, + deleted_at: row.get("_m_deleted_at")?, + }; + + Ok(MemberReferrerModel { + id: row.get("mr_id")?, + member, + can_use: row.get("mr_can_use")?, + memo: row.get("mr_memo")?, + created_at: row.get("mr_created_at")?, + updated_at: row.get("mr_updated_at")?, + }) + } +} diff --git a/src/compositions/mod.rs b/src/compositions/mod.rs index d1df18e..997a973 100644 --- a/src/compositions/mod.rs +++ b/src/compositions/mod.rs @@ -1,3 +1,4 @@ pub mod identity; pub mod member; +pub mod member_referrer; pub mod site; diff --git a/src/repositories/member/models.rs b/src/repositories/member/models.rs index 63ceef0..ddea5d5 100644 --- a/src/repositories/member/models.rs +++ b/src/repositories/member/models.rs @@ -26,9 +26,9 @@ pub struct Member { /// pub state_changed_at: Option, /// - pub referrer_member_id: Option, + pub parent_member_id: Option, /// - pub referred_count: i64, + pub child_member_count: i64, /// pub last_signined_ip: Option, /// @@ -52,7 +52,7 @@ pub struct NewMember { /// pub member_level_id: uuid::Uuid, /// - pub referrer_member_id: Option, + pub parent_member_id: Option, /// pub username: String, /// @@ -113,7 +113,7 @@ pub struct FindAllSearch { /// pub member_level_id: Option, /// - pub referrer_member_id: Option, + pub parent_member_id: Option, /// pub username_like: Option, /// diff --git a/src/repositories/member/repository.rs b/src/repositories/member/repository.rs index f4eec64..6489b4b 100644 --- a/src/repositories/member/repository.rs +++ b/src/repositories/member/repository.rs @@ -291,7 +291,7 @@ impl Repository { } /// - pub fn update_increase_referred_count( + pub fn increase_child_member_count( &self, conn: &diesel::PgConnection, id: uuid::Uuid, @@ -299,7 +299,21 @@ impl Repository { use members::dsl; diesel::update(dsl::members.filter(dsl::id.eq(id))) - .set(dsl::referred_count.eq(dsl::referred_count + 1)) + .set(dsl::child_member_count.eq(dsl::child_member_count + 1)) + .execute(conn) + .map(|c| c as u64) + } + + /// + pub fn decrease_child_member_count( + &self, + conn: &diesel::PgConnection, + id: uuid::Uuid, + ) -> Result { + use members::dsl; + + diesel::update(dsl::members.filter(dsl::id.eq(id))) + .set(dsl::child_member_count.eq(dsl::child_member_count - 1)) .execute(conn) .map(|c| c as u64) } diff --git a/src/repositories/member/schema.rs b/src/repositories/member/schema.rs index 935cc22..6e56938 100644 --- a/src/repositories/member/schema.rs +++ b/src/repositories/member/schema.rs @@ -39,9 +39,9 @@ table! { /// state_changed_at -> Nullable, /// - referrer_member_id -> Nullable, + parent_member_id -> Nullable, /// - referred_count -> BigInt, + child_member_count -> BigInt, /// last_signined_ip -> Nullable, /// diff --git a/src/repositories/member_referrer/mod.rs b/src/repositories/member_referrer/mod.rs new file mode 100644 index 0000000..bef7c9e --- /dev/null +++ b/src/repositories/member_referrer/mod.rs @@ -0,0 +1,9 @@ +//! +//! + +/// +pub mod models; +/// +pub mod repository; +/// +pub mod schema; diff --git a/src/repositories/member_referrer/models.rs b/src/repositories/member_referrer/models.rs new file mode 100644 index 0000000..b46a3e6 --- /dev/null +++ b/src/repositories/member_referrer/models.rs @@ -0,0 +1,60 @@ +use super::schema::member_referrers; +use beteran_common_rust as bcr; + +/// +#[derive(Eq, Hash, Identifiable, Queryable, PartialEq, Debug, Clone)] +#[table_name = "member_referrers"] +pub struct MemberReferrer { + /// + pub id: uuid::Uuid, + /// + pub member_id: uuid::Uuid, + /// + pub can_use: bool, + /// + pub memo: Option, + /// + pub created_at: i64, + /// + pub updated_at: i64, +} + +/// +#[derive(Insertable, Debug, Clone)] +#[table_name = "member_referrers"] +pub struct NewMemberReferrer { + /// + pub member_id: uuid::Uuid, +} + +/// +#[derive(AsChangeset, Debug, Clone)] +#[table_name = "member_referrers"] +pub struct ModifyMemberReferrer { + /// + pub can_use: bool, + /// + pub memo: Option, +} + +/// +#[derive(Debug, Clone)] +pub struct FindAllSearch { + /// + pub member_id: Option, + /// + pub can_use: Option, + /// + pub memo_like: Option, +} + +/// +#[derive(Debug, Clone)] +pub struct FindAll { + /// + pub search: Option, + /// + pub pagination: Option, + /// + pub sorts: Option>, +} diff --git a/src/repositories/member_referrer/repository.rs b/src/repositories/member_referrer/repository.rs new file mode 100644 index 0000000..39d3231 --- /dev/null +++ b/src/repositories/member_referrer/repository.rs @@ -0,0 +1,195 @@ +//! +//! +use super::{models, schema::member_referrers}; +use beteran_common_rust as bcr; +use diesel::prelude::*; +use diesel::result::Error; + +/// +pub struct Repository {} + +impl std::fmt::Debug for Repository { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + f.debug_struct("Repository of member_referrers").finish() + } +} + +impl Default for Repository { + fn default() -> Self { + Self::new() + } +} + +impl Repository { + /// + pub fn new() -> Repository { + Repository {} + } + + /// + pub fn insert( + &self, + conn: &diesel::PgConnection, + new_resource: &models::NewMemberReferrer, + ) -> Result { + let inserted = diesel::insert_into(member_referrers::table) + .values(new_resource) + .get_result::(conn)?; + + Ok(inserted) + } + + /// + pub fn select( + &self, + conn: &diesel::PgConnection, + id: uuid::Uuid, + ) -> Result, Error> { + match member_referrers::table + .find(id as uuid::Uuid) + .first::(conn) + { + Ok(m) => Ok(Some(m)), + Err(e) => match e { + diesel::result::Error::NotFound => Ok(None), + _ => Err(e), + }, + } + } + + /// + pub fn select_by_member_id( + &self, + conn: &diesel::PgConnection, + member_id: uuid::Uuid, + ) -> Result, Error> { + use member_referrers::dsl; + + match member_referrers::table + .filter(dsl::member_id.eq(member_id)) + .first::(conn) + { + Ok(m) => Ok(Some(m)), + Err(e) => match e { + diesel::result::Error::NotFound => Ok(None), + _ => Err(e), + }, + } + } + + /// + pub fn select_all_count( + &self, + conn: &diesel::PgConnection, + find_all: &models::FindAll, + ) -> Result { + let mut q = member_referrers::table.into_boxed(); + + if let Some(s) = &find_all.search { + if let Some(sp) = s.member_id { + q = q.filter(member_referrers::dsl::member_id.eq(sp)); + } + if let Some(sp) = s.can_use { + q = q.filter(member_referrers::dsl::can_use.eq(sp)); + } + if let Some(sp) = &s.memo_like { + q = q.filter(member_referrers::dsl::memo.like(sp)); + } + } + + q.count().get_result(conn) + } + + /// + pub fn select_all( + &self, + conn: &diesel::PgConnection, + find_all: &models::FindAll, + ) -> Result, Error> { + let mut q = member_referrers::table.into_boxed(); + + if let Some(s) = &find_all.search { + if let Some(sp) = s.member_id { + q = q.filter(member_referrers::dsl::member_id.eq(sp)); + } + if let Some(sp) = s.can_use { + q = q.filter(member_referrers::dsl::can_use.eq(sp)); + } + if let Some(sp) = &s.memo_like { + q = q.filter(member_referrers::dsl::memo.like(sp)); + } + } + + if let Some(p) = &find_all.pagination { + let page = p.page.unwrap_or(1); + + if let Some(page_size) = p.page_size { + q = q.offset(((page - 1) * page_size) as i64); + q = q.limit(page_size as i64); + } + } + if let Some(orderbys) = &find_all.sorts { + for s in orderbys { + match s { + bcr::models::pagination::Sort::ASC(property) => match property.as_str() { + "member_id" => { + q = q.order_by(member_referrers::member_id.asc()); + } + "can_use" => { + q = q.order_by(member_referrers::can_use.asc()); + } + "created_at" => { + q = q.order_by(member_referrers::created_at.asc()); + } + "updated_at" => { + q = q.order_by(member_referrers::updated_at.asc()); + } + _ => {} + }, + bcr::models::pagination::Sort::DESC(property) => match property.as_str() { + "member_id" => { + q = q.order_by(member_referrers::member_id.desc()); + } + "can_use" => { + q = q.order_by(member_referrers::can_use.desc()); + } + "created_at" => { + q = q.order_by(member_referrers::created_at.desc()); + } + "updated_at" => { + q = q.order_by(member_referrers::updated_at.desc()); + } + + _ => {} + }, + }; + } + } + + q.load::(conn) + } + + /// + pub fn update( + &self, + conn: &diesel::PgConnection, + id: uuid::Uuid, + modify: &models::ModifyMemberReferrer, + ) -> Result { + use member_referrers::dsl; + + diesel::update(dsl::member_referrers.filter(dsl::id.eq(id))) + .set(modify) + .execute(conn) + .map(|c| c as u64) + } + + /// + pub fn delete(&self, conn: &diesel::PgConnection, id: uuid::Uuid) -> Result { + use member_referrers::dsl; + + diesel::delete(member_referrers::table.filter(dsl::id.eq(id))) + .execute(conn) + .map(|c| c as u64) + } +} diff --git a/src/repositories/member_referrer/schema.rs b/src/repositories/member_referrer/schema.rs new file mode 100644 index 0000000..1308324 --- /dev/null +++ b/src/repositories/member_referrer/schema.rs @@ -0,0 +1,20 @@ +//! +//! + +table! { + /// + member_referrers(id) { + /// + id -> Uuid, + /// + member_id -> Uuid, + /// + can_use -> Bool, + /// + memo -> Nullable, + /// + created_at -> BigInt, + /// + updated_at -> BigInt, + } +} diff --git a/src/repositories/mod.rs b/src/repositories/mod.rs index a68e53a..2c0f9d7 100644 --- a/src/repositories/mod.rs +++ b/src/repositories/mod.rs @@ -6,6 +6,7 @@ pub mod member_bank_withdraw; pub mod member_class; pub mod member_level; pub mod member_permission; +pub mod member_referrer; pub mod member_role; pub mod member_session; pub mod resource; diff --git a/src/services/member/models.rs b/src/services/member/models.rs index 10733dc..717716c 100644 --- a/src/services/member/models.rs +++ b/src/services/member/models.rs @@ -35,8 +35,8 @@ impl From<&repositories::member::models::Member> for bpr::models::member::Member site_id: d.site_id.to_string(), member_class_id: d.member_class_id.to_string(), member_level_id: d.member_level_id.to_string(), - referrer_member_id: d.referrer_member_id.map(|d| d.to_string()), - referred_count: d.referred_count as u64, + parent_member_id: d.parent_member_id.map(|d| d.to_string()), + child_member_count: d.child_member_count as u64, username: d.username.clone(), nickname: d.nickname.clone(), mobile_phone_number: d.mobile_phone_number.clone(), @@ -66,11 +66,11 @@ impl From<&compositions::member::models::MemberModel> for bpr::models::member::M .bank_account .as_ref() .map(|d| bpr::models::member_bank_account::MemberBankAccountModel::from(d)), - referrer_member: d - .referrer_member + parent_member: d + .parent_member .as_ref() .map(bpr::models::member::Member::from), - referred_count: d.referred_count as u64, + child_member_count: d.child_member_count as u64, username: d.username.clone(), nickname: d.nickname.clone(), mobile_phone_number: d.mobile_phone_number.clone(), diff --git a/src/services/member/service.rs b/src/services/member/service.rs index b9d5323..f486bc1 100644 --- a/src/services/member/service.rs +++ b/src/services/member/service.rs @@ -200,7 +200,7 @@ impl Service<'_> { }) })?; - let referrer_member_id = match request.referrer_member_username { + let parent_member_id = match request.referrer_member_username { Some(referrer_member_username) => { match self .member_repository @@ -303,7 +303,7 @@ impl Service<'_> { site_id, member_class_id, member_level_id, - referrer_member_id, + parent_member_id, username: request.username, password: password_hash, nickname: request.nickname, @@ -504,18 +504,7 @@ impl Service<'_> { } }; - let ( - site_id, - member_class_id, - member_level_id, - referrer_member_id, - username_like, - nickname_like, - mobile_phone_number_like, - last_signined_ip, - state, - deleted_at, - ) = match request.search { + let search = match request.search { Some(s) => { let site_id = match s.site_id { Some(d) => match uuid::Uuid::from_str(d.as_str()) { @@ -577,16 +566,16 @@ impl Service<'_> { }, None => None, }; - let referrer_member_id = match s.referrer_member_id { + let parent_member_id = match s.parent_member_id { Some(d) => match uuid::Uuid::from_str(d.as_str()) { Ok(dd) => Some(dd), Err(e) => { return Err(bcr::error::rpc::Error::InvalidParams( bcr::error::rpc::InvalidParams { - message: "invalid referrer_member_id param".to_string(), + message: "invalid parent_member_id param".to_string(), detail: bcr::error::rpc::InvalidParamsDetail { location: "request".to_string(), - param: "referrer_member_id".to_string(), + param: "parent_member_id".to_string(), value: d.clone(), error_type: bcr::error::rpc::InvalidParamsType::Required, message: e.to_string(), @@ -598,20 +587,20 @@ impl Service<'_> { None => None, }; - ( + Some(repositories::member::models::FindAllSearch { site_id, member_class_id, member_level_id, - referrer_member_id, - s.username_like, - s.nickname_like, - s.mobile_phone_number_like, - s.last_signined_ip, - s.state.map(repositories::member::schema::MemberState::from), - s.deleted_at.map(|d| d > 0), - ) + parent_member_id, + username_like: s.username_like, + nickname_like: s.nickname_like, + mobile_phone_number_like: s.mobile_phone_number_like, + last_signined_ip: s.last_signined_ip, + state: s.state.map(repositories::member::schema::MemberState::from), + deleted_at: s.deleted_at.map(|d| d > 0), + }) } - None => (None, None, None, None, None, None, None, None, None, None), + None => None, }; let conn = self.pool.get().map_err(|e| { @@ -623,18 +612,6 @@ impl Service<'_> { })?; let find_all = repositories::member::models::FindAll { - search: Some(repositories::member::models::FindAllSearch { - site_id, - member_class_id, - member_level_id, - referrer_member_id, - username_like, - nickname_like, - mobile_phone_number_like, - last_signined_ip, - state, - deleted_at, - }), pagination: request .pagination .as_ref() @@ -646,6 +623,7 @@ impl Service<'_> { .map(beteran_common_rust::models::pagination::Sort::from) .collect(), ), + search, }; let m = self diff --git a/src/services/member_bank_account/service.rs b/src/services/member_bank_account/service.rs index 9dbff96..3a7f3ce 100644 --- a/src/services/member_bank_account/service.rs +++ b/src/services/member_bank_account/service.rs @@ -3,7 +3,6 @@ use std::str::FromStr; -use super::models; use crate::compositions; use crate::repositories; use beteran_common_rust as bcr; diff --git a/src/services/member_referrer/mod.rs b/src/services/member_referrer/mod.rs new file mode 100644 index 0000000..b9e52db --- /dev/null +++ b/src/services/member_referrer/mod.rs @@ -0,0 +1,2 @@ +pub mod models; +pub mod service; diff --git a/src/services/member_referrer/models.rs b/src/services/member_referrer/models.rs new file mode 100644 index 0000000..4d3e3de --- /dev/null +++ b/src/services/member_referrer/models.rs @@ -0,0 +1,33 @@ +use crate::compositions; +use crate::repositories; +use beteran_protobuf_rust as bpr; + +impl From<&repositories::member_referrer::models::MemberReferrer> + for bpr::models::member_referrer::MemberReferrer +{ + fn from(d: &repositories::member_referrer::models::MemberReferrer) -> Self { + bpr::models::member_referrer::MemberReferrer { + id: d.id.to_string(), + member_id: d.member_id.to_string(), + can_use: d.can_use, + memo: d.memo.clone(), + created_at: d.created_at as u64, + updated_at: d.updated_at as u64, + } + } +} + +impl From<&compositions::member_referrer::models::MemberReferrerModel> + for bpr::models::member_referrer::MemberReferrerModel +{ + fn from(d: &compositions::member_referrer::models::MemberReferrerModel) -> Self { + bpr::models::member_referrer::MemberReferrerModel { + id: d.id.to_string(), + member: Some(bpr::models::member::Member::from(&d.member)), + can_use: d.can_use, + memo: d.memo.clone(), + created_at: d.created_at as u64, + updated_at: d.updated_at as u64, + } + } +} diff --git a/src/services/member_referrer/service.rs b/src/services/member_referrer/service.rs new file mode 100644 index 0000000..7fdbe6d --- /dev/null +++ b/src/services/member_referrer/service.rs @@ -0,0 +1,791 @@ +//! +//! + +use std::str::FromStr; + +use crate::compositions; +use crate::repositories; +use beteran_common_rust as bcr; +use beteran_protobuf_rust as bpr; +use diesel::{ + r2d2::{ConnectionManager, Pool}, + PgConnection, +}; +use prost::Message; + +/// +pub struct Service { + connection_broker: nats::asynk::Connection, + queue_broker: String, + pool: Pool>, + site_composition: compositions::site::composition::Composition, + member_referrer_repository: repositories::member_referrer::repository::Repository, + member_referrer_composition: compositions::member_referrer::composition::Composition, +} + +impl std::fmt::Debug for Service { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + f.debug_struct("Service of service.member.service.identity") + .finish() + } +} + +impl Service { + /// + pub fn new( + connection_broker: nats::asynk::Connection, + queue_broker: String, + pool: Pool>, + ) -> Service { + Service { + connection_broker, + queue_broker, + pool, + site_composition: compositions::site::composition::Composition::new(), + member_referrer_repository: repositories::member_referrer::repository::Repository::new(), + member_referrer_composition: compositions::member_referrer::composition::Composition::new(), + } + } + + pub async fn subscribe(&self) -> std::result::Result<(), std::boxed::Box> { + futures::try_join!( + self.create_member_referrer(), + self.list_member_referrers(), + self.get_member_referrer(), + self.update_member_referrer(), + self.delete_member_referrer(), + ) + .map(|_| ()) + } + + fn check_site( + &self, + conn: &diesel::PgConnection, + url: Option, + site_id: uuid::Uuid, + ) -> Result { + match self + .site_composition + .select_by_url(conn, url, site_id) + .map_err(|e| { + bcr::error::rpc::Error::Server(bcr::error::rpc::Server { + code: bpr::protobuf::rpc::Error::SERVER_00, + message: format!("server {}", e), + data: None, + }) + })? { + Some(s) => Ok(s), + None => Err(bcr::error::rpc::Error::InvalidParams( + bcr::error::rpc::InvalidParams { + message: "invalid site_url information".to_string(), + detail: bcr::error::rpc::InvalidParamsDetail { + location: "request".to_string(), + param: "client.site_url".to_string(), + value: "".to_string(), + error_type: bcr::error::rpc::InvalidParamsType::None, + message: "".to_string(), + }, + }, + )), + } + } + + async fn create_member_referrer(&self) -> Result<(), Box> { + let s = self + .connection_broker + .queue_subscribe( + bpr::ss::member_referrer::SUBJECT_CREATE_MEMBER_REFERRER, + self.queue_broker.as_str(), + ) + .await?; + + while let Some(message) = s.next().await { + if let Err(e) = async { + let req = + bpr::ss::member_referrer::CreateMemberReferrerRequest::decode(message.data.as_slice()) + .map_err(|e| { + bcr::error::rpc::Error::InvalidRequest(bcr::error::rpc::InvalidRequest { + message: format!("invalid request: {}", e), + }) + })?; + + let client = match req.client { + Some(c) => c, + None => { + return Err(bcr::error::rpc::Error::InvalidParams( + bcr::error::rpc::InvalidParams { + message: "invalid client information".to_string(), + detail: bcr::error::rpc::InvalidParamsDetail { + location: "request".to_string(), + param: "client".to_string(), + value: "".to_string(), + error_type: bcr::error::rpc::InvalidParamsType::Required, + message: "".to_string(), + }, + }, + )); + } + }; + let request = match req.request { + Some(r) => r, + None => { + return Err(bcr::error::rpc::Error::InvalidParams( + bcr::error::rpc::InvalidParams { + message: "invalid request information".to_string(), + detail: bcr::error::rpc::InvalidParamsDetail { + location: "request".to_string(), + param: "request".to_string(), + value: "".to_string(), + error_type: bcr::error::rpc::InvalidParamsType::Required, + message: "".to_string(), + }, + }, + )); + } + }; + let member_id = uuid::Uuid::from_str(request.member_id.as_str()).map_err(|e| { + bcr::error::rpc::Error::InvalidParams(bcr::error::rpc::InvalidParams { + message: "invalid member_id param".to_string(), + detail: bcr::error::rpc::InvalidParamsDetail { + location: "request".to_string(), + param: "member_id".to_string(), + value: request.member_id.clone(), + error_type: bcr::error::rpc::InvalidParamsType::Required, + message: e.to_string(), + }, + }) + })?; + + let conn = self.pool.get().map_err(|e| { + bcr::error::rpc::Error::Server(bcr::error::rpc::Server { + code: bpr::protobuf::rpc::Error::SERVER_00, + message: format!("server {}", e), + data: None, + }) + })?; + + let new_member_referrer = + repositories::member_referrer::models::NewMemberReferrer { member_id }; + let s = self + .member_referrer_repository + .insert(&conn, &new_member_referrer) + .map_err(|e| { + bcr::error::rpc::Error::Server(bcr::error::rpc::Server { + code: bpr::protobuf::rpc::Error::SERVER_00, + message: format!("server {}", e), + data: None, + }) + })?; + + let mr = self + .member_referrer_composition + .select(&conn, s.id) + .map_err(|e| { + bcr::error::rpc::Error::Server(bcr::error::rpc::Server { + code: bpr::protobuf::rpc::Error::SERVER_00, + message: format!("server {}", e), + data: None, + }) + })?; + + message + .respond( + bpr::ss::member_referrer::CreateMemberReferrerResponse { + error: None, + result: Some( + bpr::ss::member_referrer::create_member_referrer_response::Result { + member_referrer: mr + .as_ref() + .map(bpr::models::member_referrer::MemberReferrerModel::from), + }, + ), + } + .encode_to_vec(), + ) + .await + .map_err(|e| { + bcr::error::rpc::Error::Server(bcr::error::rpc::Server { + code: bpr::protobuf::rpc::Error::SERVER_00, + message: format!("server {}", e), + data: None, + }) + })?; + + Ok::<(), bcr::error::rpc::Error>(()) + } + .await + { + message + .respond( + bpr::ss::member_referrer::CreateMemberReferrerResponse { + error: Some(bpr::protobuf::rpc::Error::from(e)), + result: None, + } + .encode_to_vec(), + ) + .await?; + } + } + + Ok(()) + } + + async fn list_member_referrers(&self) -> Result<(), Box> { + let s = self + .connection_broker + .queue_subscribe( + bpr::ss::member_referrer::SUBJECT_LIST_MEMBER_REFERRERS, + self.queue_broker.as_str(), + ) + .await?; + + while let Some(message) = s.next().await { + if let Err(e) = async { + let req = + bpr::ss::member_referrer::ListMemberReferrersRequest::decode(message.data.as_slice()) + .map_err(|e| { + bcr::error::rpc::Error::InvalidRequest(bcr::error::rpc::InvalidRequest { + message: format!("invalid request: {}", e), + }) + })?; + + let client = match req.client { + Some(c) => c, + None => { + return Err(bcr::error::rpc::Error::InvalidParams( + bcr::error::rpc::InvalidParams { + message: "invalid client information".to_string(), + detail: bcr::error::rpc::InvalidParamsDetail { + location: "request".to_string(), + param: "client".to_string(), + value: "".to_string(), + error_type: bcr::error::rpc::InvalidParamsType::Required, + message: "".to_string(), + }, + }, + )); + } + }; + let request = match req.request { + Some(r) => r, + None => { + return Err(bcr::error::rpc::Error::InvalidParams( + bcr::error::rpc::InvalidParams { + message: "invalid request information".to_string(), + detail: bcr::error::rpc::InvalidParamsDetail { + location: "request".to_string(), + param: "request".to_string(), + value: "".to_string(), + error_type: bcr::error::rpc::InvalidParamsType::Required, + message: "".to_string(), + }, + }, + )); + } + }; + let search = match request.search { + Some(s) => { + let member_id = match s.member_id { + Some(d) => match uuid::Uuid::from_str(d.as_str()) { + Ok(dd) => Some(dd), + Err(e) => { + return Err(bcr::error::rpc::Error::InvalidParams( + bcr::error::rpc::InvalidParams { + message: "invalid member_id param".to_string(), + detail: bcr::error::rpc::InvalidParamsDetail { + location: "request".to_string(), + param: "member_id".to_string(), + value: d.clone(), + error_type: bcr::error::rpc::InvalidParamsType::Required, + message: e.to_string(), + }, + }, + )); + } + }, + None => None, + }; + + Some(repositories::member_referrer::models::FindAllSearch { + member_id, + can_use: s.can_use, + memo_like: s.memo_like, + }) + } + None => None, + }; + + let conn = self.pool.get().map_err(|e| { + bcr::error::rpc::Error::Server(bcr::error::rpc::Server { + code: bpr::protobuf::rpc::Error::SERVER_00, + message: format!("server {}", e), + data: None, + }) + })?; + + let find_all = repositories::member_referrer::models::FindAll { + search, + pagination: request + .pagination + .as_ref() + .map(bcr::models::pagination::Pagination::from), + sorts: Some( + request + .sorts + .iter() + .map(beteran_common_rust::models::pagination::Sort::from) + .collect(), + ), + }; + + let count = self + .member_referrer_repository + .select_all_count(&conn, &find_all) + .map_err(|e| { + bcr::error::rpc::Error::Server(bcr::error::rpc::Server { + code: bpr::protobuf::rpc::Error::SERVER_00, + message: format!("server {}", e), + data: None, + }) + })?; + + let list = self + .member_referrer_composition + .select_all(&conn, &find_all) + .map_err(|e| { + bcr::error::rpc::Error::Server(bcr::error::rpc::Server { + code: bpr::protobuf::rpc::Error::SERVER_00, + message: format!("server {}", e), + data: None, + }) + })?; + + message + .respond( + bpr::ss::member_referrer::ListMemberReferrersResponse { + error: None, + result: Some( + bpr::ss::member_referrer::list_member_referrers_response::Result { + member_referrers: list + .iter() + .map(|d| bpr::models::member_referrer::MemberReferrerModel::from(d)) + .collect(), + }, + ), + } + .encode_to_vec(), + ) + .await + .map_err(|e| { + bcr::error::rpc::Error::Server(bcr::error::rpc::Server { + code: bpr::protobuf::rpc::Error::SERVER_00, + message: format!("server {}", e), + data: None, + }) + })?; + + Ok::<(), bcr::error::rpc::Error>(()) + } + .await + { + message + .respond( + bpr::ss::member_referrer::ListMemberReferrersResponse { + error: Some(bpr::protobuf::rpc::Error::from(e)), + result: None, + } + .encode_to_vec(), + ) + .await?; + } + } + + Ok(()) + } + + async fn get_member_referrer(&self) -> Result<(), Box> { + let s = self + .connection_broker + .queue_subscribe( + bpr::ss::member_referrer::SUBJECT_GET_MEMBER_REFERRER, + self.queue_broker.as_str(), + ) + .await?; + + while let Some(message) = s.next().await { + if let Err(e) = async { + let req = + bpr::ss::member_referrer::GetMemberReferrerRequest::decode(message.data.as_slice()) + .map_err(|e| { + bcr::error::rpc::Error::InvalidRequest(bcr::error::rpc::InvalidRequest { + message: format!("invalid request: {}", e), + }) + })?; + let client = match req.client { + Some(c) => c, + None => { + return Err(bcr::error::rpc::Error::InvalidParams( + bcr::error::rpc::InvalidParams { + message: "invalid client information".to_string(), + detail: bcr::error::rpc::InvalidParamsDetail { + location: "request".to_string(), + param: "client".to_string(), + value: "".to_string(), + error_type: bcr::error::rpc::InvalidParamsType::Required, + message: "".to_string(), + }, + }, + )); + } + }; + let request = match req.request { + Some(r) => r, + None => { + return Err(bcr::error::rpc::Error::InvalidParams( + bcr::error::rpc::InvalidParams { + message: "invalid request information".to_string(), + detail: bcr::error::rpc::InvalidParamsDetail { + location: "request".to_string(), + param: "request".to_string(), + value: "".to_string(), + error_type: bcr::error::rpc::InvalidParamsType::Required, + message: "".to_string(), + }, + }, + )); + } + }; + let id = uuid::Uuid::from_str(request.id.as_str()).map_err(|e| { + bcr::error::rpc::Error::InvalidParams(bcr::error::rpc::InvalidParams { + message: "invalid id param".to_string(), + detail: bcr::error::rpc::InvalidParamsDetail { + location: "request".to_string(), + param: "id".to_string(), + value: request.id.clone(), + error_type: bcr::error::rpc::InvalidParamsType::Required, + message: e.to_string(), + }, + }) + })?; + + let conn = self.pool.get().map_err(|e| { + bcr::error::rpc::Error::Server(bcr::error::rpc::Server { + code: bpr::protobuf::rpc::Error::SERVER_00, + message: format!("server {}", e), + data: None, + }) + })?; + + let s = self + .member_referrer_composition + .select(&conn, id) + .map_err(|e| { + bcr::error::rpc::Error::Server(bcr::error::rpc::Server { + code: bpr::protobuf::rpc::Error::SERVER_00, + message: format!("server {}", e), + data: None, + }) + })?; + + message + .respond( + bpr::ss::member_referrer::GetMemberReferrerResponse { + error: None, + result: Some( + bpr::ss::member_referrer::get_member_referrer_response::Result { + member_referrer: s + .map(|d| bpr::models::member_referrer::MemberReferrerModel::from(&d)), + }, + ), + } + .encode_to_vec(), + ) + .await + .map_err(|e| { + bcr::error::rpc::Error::Server(bcr::error::rpc::Server { + code: bpr::protobuf::rpc::Error::SERVER_00, + message: format!("server {}", e), + data: None, + }) + })?; + + Ok::<(), bcr::error::rpc::Error>(()) + } + .await + { + message + .respond( + bpr::ss::member_referrer::GetMemberReferrerResponse { + error: Some(bpr::protobuf::rpc::Error::from(e)), + result: None, + } + .encode_to_vec(), + ) + .await?; + } + } + + Ok(()) + } + + async fn update_member_referrer(&self) -> Result<(), Box> { + let s = self + .connection_broker + .queue_subscribe( + bpr::ss::member_referrer::SUBJECT_UPDATE_MEMBER_REFERRER, + self.queue_broker.as_str(), + ) + .await?; + + while let Some(message) = s.next().await { + if let Err(e) = async { + let req = + bpr::ss::member_referrer::UpdateMemberReferrerRequest::decode(message.data.as_slice()) + .map_err(|e| { + bcr::error::rpc::Error::InvalidRequest(bcr::error::rpc::InvalidRequest { + message: format!("invalid request: {}", e), + }) + })?; + let client = match req.client { + Some(c) => c, + None => { + return Err(bcr::error::rpc::Error::InvalidParams( + bcr::error::rpc::InvalidParams { + message: "invalid client information".to_string(), + detail: bcr::error::rpc::InvalidParamsDetail { + location: "request".to_string(), + param: "client".to_string(), + value: "".to_string(), + error_type: bcr::error::rpc::InvalidParamsType::Required, + message: "".to_string(), + }, + }, + )); + } + }; + let request = match req.request { + Some(r) => r, + None => { + return Err(bcr::error::rpc::Error::InvalidParams( + bcr::error::rpc::InvalidParams { + message: "invalid request information".to_string(), + detail: bcr::error::rpc::InvalidParamsDetail { + location: "request".to_string(), + param: "request".to_string(), + value: "".to_string(), + error_type: bcr::error::rpc::InvalidParamsType::Required, + message: "".to_string(), + }, + }, + )); + } + }; + let id = uuid::Uuid::from_str(request.id.as_str()).map_err(|e| { + bcr::error::rpc::Error::InvalidParams(bcr::error::rpc::InvalidParams { + message: "invalid id param".to_string(), + detail: bcr::error::rpc::InvalidParamsDetail { + location: "request".to_string(), + param: "id".to_string(), + value: request.id.clone(), + error_type: bcr::error::rpc::InvalidParamsType::Required, + message: e.to_string(), + }, + }) + })?; + + let conn = self.pool.get().map_err(|e| { + bcr::error::rpc::Error::Server(bcr::error::rpc::Server { + code: bpr::protobuf::rpc::Error::SERVER_00, + message: format!("server {}", e), + data: None, + }) + })?; + + let modify_member_referrer = repositories::member_referrer::models::ModifyMemberReferrer { + can_use: request.can_use, + memo: request.memo, + }; + + let _affected = self + .member_referrer_repository + .update(&conn, id, &modify_member_referrer) + .map_err(|e| { + bcr::error::rpc::Error::Server(bcr::error::rpc::Server { + code: bpr::protobuf::rpc::Error::SERVER_00, + message: format!("server {}", e), + data: None, + }) + })?; + + let s = self + .member_referrer_composition + .select(&conn, id) + .map_err(|e| { + bcr::error::rpc::Error::Server(bcr::error::rpc::Server { + code: bpr::protobuf::rpc::Error::SERVER_00, + message: format!("server {}", e), + data: None, + }) + })?; + + message + .respond( + bpr::ss::member_referrer::UpdateMemberReferrerResponse { + error: None, + result: Some( + bpr::ss::member_referrer::update_member_referrer_response::Result { + member_referrer: s + .map(|d| bpr::models::member_referrer::MemberReferrerModel::from(&d)), + }, + ), + } + .encode_to_vec(), + ) + .await + .map_err(|e| { + bcr::error::rpc::Error::Server(bcr::error::rpc::Server { + code: bpr::protobuf::rpc::Error::SERVER_00, + message: format!("server {}", e), + data: None, + }) + })?; + + Ok::<(), bcr::error::rpc::Error>(()) + } + .await + { + message + .respond( + bpr::ss::member_referrer::UpdateMemberReferrerResponse { + error: Some(bpr::protobuf::rpc::Error::from(e)), + result: None, + } + .encode_to_vec(), + ) + .await?; + } + } + + Ok(()) + } + + async fn delete_member_referrer(&self) -> Result<(), Box> { + let s = self + .connection_broker + .queue_subscribe( + bpr::ss::member_referrer::SUBJECT_DELETE_MEMBER_REFERRER, + self.queue_broker.as_str(), + ) + .await?; + + while let Some(message) = s.next().await { + if let Err(e) = async { + let req = + bpr::ss::member_referrer::DeleteMemberReferrerRequest::decode(message.data.as_slice()) + .map_err(|e| { + bcr::error::rpc::Error::InvalidRequest(bcr::error::rpc::InvalidRequest { + message: format!("invalid request: {}", e), + }) + })?; + let client = match req.client { + Some(c) => c, + None => { + return Err(bcr::error::rpc::Error::InvalidParams( + bcr::error::rpc::InvalidParams { + message: "invalid client information".to_string(), + detail: bcr::error::rpc::InvalidParamsDetail { + location: "request".to_string(), + param: "client".to_string(), + value: "".to_string(), + error_type: bcr::error::rpc::InvalidParamsType::Required, + message: "".to_string(), + }, + }, + )); + } + }; + let request = match req.request { + Some(r) => r, + None => { + return Err(bcr::error::rpc::Error::InvalidParams( + bcr::error::rpc::InvalidParams { + message: "invalid request information".to_string(), + detail: bcr::error::rpc::InvalidParamsDetail { + location: "request".to_string(), + param: "request".to_string(), + value: "".to_string(), + error_type: bcr::error::rpc::InvalidParamsType::Required, + message: "".to_string(), + }, + }, + )); + } + }; + let id = uuid::Uuid::from_str(request.id.as_str()).map_err(|e| { + bcr::error::rpc::Error::InvalidParams(bcr::error::rpc::InvalidParams { + message: "invalid id param".to_string(), + detail: bcr::error::rpc::InvalidParamsDetail { + location: "request".to_string(), + param: "id".to_string(), + value: request.id.clone(), + error_type: bcr::error::rpc::InvalidParamsType::Required, + message: e.to_string(), + }, + }) + })?; + + let conn = self.pool.get().map_err(|e| { + bcr::error::rpc::Error::Server(bcr::error::rpc::Server { + code: bpr::protobuf::rpc::Error::SERVER_00, + message: format!("server {}", e), + data: None, + }) + })?; + + let _affected = self + .member_referrer_repository + .delete(&conn, id) + .map_err(|e| { + bcr::error::rpc::Error::Server(bcr::error::rpc::Server { + code: bpr::protobuf::rpc::Error::SERVER_00, + message: format!("server {}", e), + data: None, + }) + })?; + + message + .respond( + bpr::ss::member_referrer::DeleteMemberReferrerResponse { + error: None, + result: Some(bpr::ss::member_referrer::delete_member_referrer_response::Result {}), + } + .encode_to_vec(), + ) + .await + .map_err(|e| { + bcr::error::rpc::Error::Server(bcr::error::rpc::Server { + code: bpr::protobuf::rpc::Error::SERVER_00, + message: format!("server {}", e), + data: None, + }) + })?; + + Ok::<(), bcr::error::rpc::Error>(()) + } + .await + { + message + .respond( + bpr::ss::member_referrer::DeleteMemberReferrerResponse { + error: Some(bpr::protobuf::rpc::Error::from(e)), + result: None, + } + .encode_to_vec(), + ) + .await?; + } + } + + Ok(()) + } +} diff --git a/src/services/mod.rs b/src/services/mod.rs index 0d66f24..f36c0b7 100644 --- a/src/services/mod.rs +++ b/src/services/mod.rs @@ -6,4 +6,5 @@ pub mod member_bank_deposit; pub mod member_bank_withdraw; pub mod member_class; pub mod member_level; +pub mod member_referrer; pub mod site;