betting is added
This commit is contained in:
parent
6edcc2d615
commit
62b501d6bb
|
@ -36,7 +36,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.85-snapshot" }
|
||||
beteran-common-rust = { git = "https://gitlab.loafle.net/bet/beteran-common-rust.git", tag = "v0.1.71-snapshot" }
|
||||
beteran-protobuf-rust = { git = "https://gitlab.loafle.net/bet/beteran-protobuf-rust.git", tag = "v0.1.86-snapshot" }
|
||||
beteran-common-rust = { git = "https://gitlab.loafle.net/bet/beteran-common-rust.git", tag = "v0.1.72-snapshot" }
|
||||
|
||||
[build-dependencies]
|
||||
|
|
|
@ -2,4 +2,5 @@ DROP INDEX idx_api_kgon_betting_history_vendor_id;
|
|||
DROP INDEX idx_api_kgon_betting_history_game_id;
|
||||
DROP INDEX idx_api_kgon_betting_history_created_at;
|
||||
DROP INDEX idx_api_kgon_betting_history_utc_created_at;
|
||||
DROP INDEX idx_api_kgon_betting_history_site_username;
|
||||
DROP TABLE api_kgon_betting_history;
|
||||
|
|
|
@ -29,3 +29,4 @@ CREATE INDEX idx_api_kgon_betting_history_vendor_id ON api_kgon_betting_history
|
|||
CREATE INDEX idx_api_kgon_betting_history_game_id ON api_kgon_betting_history (game_id);
|
||||
CREATE INDEX idx_api_kgon_betting_history_created_at ON api_kgon_betting_history (created_at);
|
||||
CREATE INDEX idx_api_kgon_betting_history_utc_created_at ON api_kgon_betting_history (utc_created_at);
|
||||
CREATE INDEX idx_api_kgon_betting_history_site_username ON api_kgon_betting_history (site_username);
|
||||
|
|
517
src/compositions/betting/composition.rs
Normal file
517
src/compositions/betting/composition.rs
Normal file
|
@ -0,0 +1,517 @@
|
|||
use super::models;
|
||||
use beteran_common_rust as bcr;
|
||||
use diesel::{result::Error, sql_query, RunQueryDsl};
|
||||
use std::fmt::Write;
|
||||
|
||||
static MEMBER_COUNT_QUERY: &str = "
|
||||
SELECT
|
||||
COUNT(akbh.id)
|
||||
FROM api_kgon_betting_history as akbh
|
||||
INNER JOIN members _m
|
||||
ON _m.username = akbh.site_username
|
||||
";
|
||||
|
||||
static MEMBER_QUERY: &str = "
|
||||
SELECT
|
||||
akbh.id as akbh_id ,
|
||||
akbh.vendor_id as akbh_vendor_id ,
|
||||
akbh.vendor_name as akbh_vendor_name ,
|
||||
akbh.game_id as akbh_game_id ,
|
||||
akbh.game_name as akbh_game_name ,
|
||||
akbh.game_category as akbh_game_category ,
|
||||
akbh.game_type as akbh_game_type ,
|
||||
akbh.currency as akbh_currency ,
|
||||
akbh.cash as akbh_cash ,
|
||||
akbh.before_cash as akbh_before_cash ,
|
||||
akbh.after_cash as akbh_after_cash ,
|
||||
akbh.key as akbh_key ,
|
||||
akbh.ref_id as akbh_ref_id ,
|
||||
akbh.o_ref_id as akbh_o_ref_id ,
|
||||
akbh.group_key as akbh_group_key ,
|
||||
akbh.is_bonus as akbh_is_bonus ,
|
||||
akbh.is_promo as akbh_is_promo ,
|
||||
akbh.is_jackpot as akbh_is_jackpot ,
|
||||
akbh.site_username as akbh_site_username ,
|
||||
akbh.betting_type as akbh_betting_type ,
|
||||
akbh.category as akbh_category ,
|
||||
akbh.created_at as akbh_created_at ,
|
||||
akbh.utc_created_at as akbh_utc_created_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 api_kgon_betting_history as akbh
|
||||
INNER JOIN members _m
|
||||
ON _m.username = akbh.site_username
|
||||
";
|
||||
|
||||
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 Composition {
|
||||
///
|
||||
pub fn new() -> Composition {
|
||||
Composition {}
|
||||
}
|
||||
|
||||
///
|
||||
pub fn select(
|
||||
&self,
|
||||
conn: &diesel::PgConnection,
|
||||
id: String,
|
||||
) -> Result<Option<models::BettingHistoryModel>, Error> {
|
||||
let query = format!(
|
||||
"
|
||||
{}
|
||||
WHERE
|
||||
akbh.id = $1
|
||||
",
|
||||
MEMBER_QUERY
|
||||
);
|
||||
|
||||
match sql_query(query)
|
||||
.bind::<diesel::sql_types::Text, _>(id)
|
||||
.get_result::<models::BettingHistoryModel>(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<Option<models::BettingHistoryModel>, Error> {
|
||||
let query = format!(
|
||||
"
|
||||
{}
|
||||
WHERE
|
||||
m.id = $1
|
||||
",
|
||||
MEMBER_QUERY
|
||||
);
|
||||
|
||||
match sql_query(query)
|
||||
.bind::<diesel::sql_types::Uuid, _>(member_id)
|
||||
.get_result::<models::BettingHistoryModel>(conn)
|
||||
{
|
||||
Ok(m) => Ok(Some(m)),
|
||||
Err(e) => match e {
|
||||
diesel::result::Error::NotFound => Ok(None),
|
||||
_ => Err(e),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn get_ordery_by(&self, find_all: &models::FindAll) -> Result<String, Error> {
|
||||
let mut query_ordery_by = String::new();
|
||||
|
||||
if let Some(sorts) = &find_all.sorts {
|
||||
for s in sorts {
|
||||
if !query_ordery_by.is_empty() {
|
||||
write!(&mut query_ordery_by, " , ")
|
||||
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||
}
|
||||
|
||||
let (property, sort) = match s {
|
||||
bcr::pagination::Sort::ASC(property) => (property.clone(), "ASC".to_string()),
|
||||
bcr::pagination::Sort::DESC(property) => (property.clone(), "DESC".to_string()),
|
||||
};
|
||||
|
||||
let property = match property.as_str() {
|
||||
"member_id" => "_m.id".to_string(),
|
||||
"username" => "_m.username".to_string(),
|
||||
"nickname" => "_m.nickname".to_string(),
|
||||
"vendor_id" => "akbh.vendor_id".to_string(),
|
||||
"vendor_name" => "akbh.vendor_name".to_string(),
|
||||
"game_id" => "akbh.game_id".to_string(),
|
||||
"game_name" => "akbh.game_name".to_string(),
|
||||
"game_category" => "akbh.game_category".to_string(),
|
||||
"game_type" => "akbh.game_type".to_string(),
|
||||
"currency" => "akbh.currency".to_string(),
|
||||
"cash" => "akbh.cash".to_string(),
|
||||
"before_cash" => "akbh.before_cash".to_string(),
|
||||
"after_cash" => "akbh.after_cash".to_string(),
|
||||
"key" => "akbh.key".to_string(),
|
||||
"ref_id" => "akbh.ref_id".to_string(),
|
||||
"o_ref_id" => "akbh.o_ref_id".to_string(),
|
||||
"group_key" => "akbh.group_key".to_string(),
|
||||
"is_bonus" => "akbh.is_bonus".to_string(),
|
||||
"is_promo" => "akbh.is_promo".to_string(),
|
||||
"is_jackpot" => "akbh.is_jackpot".to_string(),
|
||||
"site_username" => "akbh.site_username".to_string(),
|
||||
"betting_type" => "akbh.betting_type".to_string(),
|
||||
"category" => "category.id".to_string(),
|
||||
"created_at" => "akbh.created_at".to_string(),
|
||||
"utc_created_at" => "akbh.utc_created_at".to_string(),
|
||||
_ => "".to_string(),
|
||||
};
|
||||
|
||||
if !property.is_empty() {
|
||||
write!(&mut query_ordery_by, "{} {}", property, sort)
|
||||
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(query_ordery_by)
|
||||
}
|
||||
|
||||
fn get_find_all(&self, find_all: &models::FindAll) -> Result<String, Error> {
|
||||
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, "_m.id = '{}'", sp)
|
||||
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||
}
|
||||
|
||||
if let Some(sp) = s.vendor_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, "akbh.vendor_id = {}", sp)
|
||||
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||
}
|
||||
|
||||
if let Some(sp) = &s.vendor_name {
|
||||
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, "akbh.vendor_name = '{}'", sp)
|
||||
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||
}
|
||||
if let Some(sp) = &s.vendor_name_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, "akbh.vendor_name like '{}'", sp)
|
||||
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||
}
|
||||
|
||||
if let Some(sp) = s.game_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, "akbh.game_id = {}", sp)
|
||||
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||
}
|
||||
|
||||
if let Some(sp) = &s.game_name {
|
||||
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, "akbh.game_name = '{}'", sp)
|
||||
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||
}
|
||||
if let Some(sp) = &s.game_name_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, "akbh.game_name like '{}'", sp)
|
||||
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||
}
|
||||
|
||||
if let Some(sp) = &s.game_category {
|
||||
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, "akbh.game_category = '{}'", sp)
|
||||
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||
}
|
||||
if let Some(sp) = &s.game_category_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, "akbh.game_category like '{}'", sp)
|
||||
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||
}
|
||||
|
||||
if let Some(sp) = &s.game_type {
|
||||
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, "akbh.game_type = '{}'", sp)
|
||||
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||
}
|
||||
if let Some(sp) = &s.game_type_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, "akbh.game_type like '{}'", sp)
|
||||
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||
}
|
||||
|
||||
if let Some(sp) = &s.currency {
|
||||
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, "akbh.currency = '{}'", sp)
|
||||
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||
}
|
||||
if let Some(sp) = &s.currency_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, "akbh.currency like '{}'", sp)
|
||||
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||
}
|
||||
|
||||
if let Some(sp) = &s.key {
|
||||
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, "akbh.key = '{}'", sp)
|
||||
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||
}
|
||||
if let Some(sp) = &s.key_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, "akbh.key like '{}'", sp)
|
||||
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||
}
|
||||
|
||||
if let Some(sp) = &s.ref_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, "akbh.ref_id = '{}'", sp)
|
||||
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||
}
|
||||
if let Some(sp) = &s.ref_id_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, "akbh.ref_id like '{}'", sp)
|
||||
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||
}
|
||||
|
||||
if let Some(sp) = &s.o_ref_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, "akbh.o_ref_id = '{}'", sp)
|
||||
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||
}
|
||||
if let Some(sp) = &s.o_ref_id_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, "akbh.o_ref_id like '{}'", sp)
|
||||
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||
}
|
||||
|
||||
if let Some(sp) = &s.group_key {
|
||||
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, "akbh.group_key = '{}'", sp)
|
||||
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||
}
|
||||
if let Some(sp) = &s.group_key_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, "akbh.group_key like '{}'", sp)
|
||||
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||
}
|
||||
|
||||
if let Some(sp) = s.is_bonus {
|
||||
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, "akbh.is_bonus = '{}'", sp)
|
||||
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||
}
|
||||
|
||||
if let Some(sp) = s.is_promo {
|
||||
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, "akbh.is_promo = '{}'", sp)
|
||||
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||
}
|
||||
|
||||
if let Some(sp) = s.is_jackpot {
|
||||
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, "akbh.is_jackpot = '{}'", sp)
|
||||
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||
}
|
||||
|
||||
if let Some(sp) = &s.site_username {
|
||||
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, "akbh.site_username = '{}'", sp)
|
||||
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||
}
|
||||
if let Some(sp) = &s.site_username_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, "akbh.site_username like '{}'", sp)
|
||||
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||
}
|
||||
|
||||
if let Some(sp) = &s.betting_type {
|
||||
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, "akbh.betting_type = '{}'", sp)
|
||||
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||
}
|
||||
if let Some(sp) = &s.betting_type_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, "akbh.betting_type like '{}'", sp)
|
||||
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||
}
|
||||
|
||||
if let Some(sp) = &s.category {
|
||||
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, "akbh.category = '{}'", sp)
|
||||
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||
}
|
||||
if let Some(sp) = &s.category_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, "akbh.category like '{}'", sp)
|
||||
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(query_where)
|
||||
}
|
||||
|
||||
///
|
||||
pub fn select_all_count(
|
||||
&self,
|
||||
conn: &diesel::PgConnection,
|
||||
find_all: &models::FindAll,
|
||||
) -> Result<i64, Error> {
|
||||
use diesel::sql_types::BigInt;
|
||||
|
||||
#[derive(QueryableByName)]
|
||||
struct Count {
|
||||
#[sql_type = "BigInt"]
|
||||
count: i64,
|
||||
}
|
||||
|
||||
let mut query = String::new();
|
||||
write!(&mut query, "{}", MEMBER_COUNT_QUERY)
|
||||
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||
|
||||
let query_where = self.get_find_all(find_all)?;
|
||||
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_result::<Count>(conn) {
|
||||
Ok(m) => Ok(m.count),
|
||||
Err(e) => match e {
|
||||
diesel::result::Error::NotFound => Ok(0),
|
||||
_ => Err(e),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
pub fn select_all(
|
||||
&self,
|
||||
conn: &diesel::PgConnection,
|
||||
find_all: &models::FindAll,
|
||||
) -> Result<Vec<models::BettingHistoryModel>, Error> {
|
||||
let mut query = String::new();
|
||||
write!(&mut query, "{}", MEMBER_QUERY)
|
||||
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||
|
||||
let query_where = self.get_find_all(find_all)?;
|
||||
if !query_where.is_empty() {
|
||||
write!(&mut query, " WHERE {}", query_where)
|
||||
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||
}
|
||||
let query_ordery_by = self.get_ordery_by(find_all)?;
|
||||
if !query_ordery_by.is_empty() {
|
||||
write!(&mut query, " ORDER BY {}", query_ordery_by)
|
||||
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||
}
|
||||
|
||||
println!("query: {}", query);
|
||||
|
||||
match sql_query(query).get_results::<models::BettingHistoryModel>(conn) {
|
||||
Ok(m) => Ok(m),
|
||||
Err(e) => match e {
|
||||
diesel::result::Error::NotFound => Ok(vec![]),
|
||||
_ => Err(e),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
pub mod composition;
|
||||
pub mod models;
|
193
src/compositions/betting/models.rs
Normal file
193
src/compositions/betting/models.rs
Normal file
|
@ -0,0 +1,193 @@
|
|||
use beteran_common_rust as bcr;
|
||||
use beteran_protobuf_rust as bpr;
|
||||
use diesel::deserialize::QueryableByName;
|
||||
|
||||
///
|
||||
#[derive(PartialEq, Debug, Clone)]
|
||||
pub struct BettingHistoryModel {
|
||||
///
|
||||
pub id: String,
|
||||
///
|
||||
pub member: bpr::models::member::Member,
|
||||
///
|
||||
pub vendor_id: i64,
|
||||
///
|
||||
pub vendor_name: String,
|
||||
///
|
||||
pub game_id: i64,
|
||||
///
|
||||
pub game_name: String,
|
||||
///
|
||||
pub game_category: String,
|
||||
///
|
||||
pub game_type: String,
|
||||
///
|
||||
pub currency: String,
|
||||
///
|
||||
pub cash: f64,
|
||||
///
|
||||
pub before_cash: f64,
|
||||
///
|
||||
pub after_cash: f64,
|
||||
///
|
||||
pub key: String,
|
||||
///
|
||||
pub ref_id: String,
|
||||
///
|
||||
pub o_ref_id: String,
|
||||
///
|
||||
pub group_key: Option<String>,
|
||||
///
|
||||
pub is_bonus: bool,
|
||||
///
|
||||
pub is_promo: bool,
|
||||
///
|
||||
pub is_jackpot: bool,
|
||||
///
|
||||
pub site_username: String,
|
||||
///
|
||||
pub betting_type: String,
|
||||
///
|
||||
pub category: String,
|
||||
///
|
||||
pub created_at: i64,
|
||||
///
|
||||
pub utc_created_at: i64,
|
||||
}
|
||||
|
||||
impl QueryableByName<diesel::pg::Pg> for BettingHistoryModel {
|
||||
fn build<R: diesel::row::NamedRow<diesel::pg::Pg>>(row: &R) -> diesel::deserialize::Result<Self> {
|
||||
let member = bpr::models::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")?,
|
||||
nickname: row.get("_m_nickname")?,
|
||||
mobile_phone_number: row.get("_m_mobile_phone_number")?,
|
||||
state: row.get("_m_state")?,
|
||||
state_changed_at: row
|
||||
.get::<diesel::sql_types::Nullable<diesel::sql_types::BigInt>, Option<i64>>(
|
||||
"_m_state_changed_at",
|
||||
)?
|
||||
.map(|v| v as u64),
|
||||
parent_member_id: row.get("_m_parent_member_id")?,
|
||||
child_member_count: row.get::<diesel::sql_types::BigInt, i64>("_m_child_member_count")?
|
||||
as u64,
|
||||
last_signined_ip: row.get("_m_last_signined_ip")?,
|
||||
last_signined_at: row
|
||||
.get::<diesel::sql_types::Nullable<diesel::sql_types::BigInt>, Option<i64>>(
|
||||
"_m_last_signined_at",
|
||||
)?
|
||||
.map(|v| v as u64),
|
||||
created_at: row.get::<diesel::sql_types::BigInt, i64>("_m_created_at")? as u64,
|
||||
updated_at: row.get::<diesel::sql_types::BigInt, i64>("_m_updated_at")? as u64,
|
||||
deleted_at: row
|
||||
.get::<diesel::sql_types::Nullable<diesel::sql_types::BigInt>, Option<i64>>(
|
||||
"_m_deleted_at",
|
||||
)?
|
||||
.map(|v| v as u64),
|
||||
};
|
||||
|
||||
Ok(BettingHistoryModel {
|
||||
id: row.get("akbh_id")?,
|
||||
member,
|
||||
vendor_id: row.get("akbh_vendor_id")?,
|
||||
vendor_name: row.get("akbh_vendor_name")?,
|
||||
game_id: row.get("akbh_game_id")?,
|
||||
game_name: row.get("akbh_game_name")?,
|
||||
game_category: row.get("akbh_game_category ")?,
|
||||
game_type: row.get("akbh_game_type")?,
|
||||
currency: row.get("akbh_currency")?,
|
||||
cash: row.get("akbh_cash")?,
|
||||
before_cash: row.get("akbh_before_cash")?,
|
||||
after_cash: row.get("akbh_after_cash")?,
|
||||
key: row.get("akbh_key")?,
|
||||
ref_id: row.get("akbh_ref_id")?,
|
||||
o_ref_id: row.get("akbh_o_ref_id")?,
|
||||
group_key: row.get("akbh_group_key")?,
|
||||
is_bonus: row.get("akbh_is_bonus")?,
|
||||
is_promo: row.get("akbh_is_promo")?,
|
||||
is_jackpot: row.get("akbh_is_jackpot")?,
|
||||
site_username: row.get("akbh_site_username")?,
|
||||
betting_type: row.get("akbh_betting_type")?,
|
||||
category: row.get("akbh_category")?,
|
||||
created_at: row.get("akbh_created_at")?,
|
||||
utc_created_at: row.get("akbh_utc_created_at")?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct FindAllSearch {
|
||||
///
|
||||
pub member_id: Option<String>,
|
||||
///
|
||||
pub vendor_id: Option<i64>,
|
||||
///
|
||||
pub vendor_name: Option<String>,
|
||||
///
|
||||
pub vendor_name_like: Option<String>,
|
||||
///
|
||||
pub game_id: Option<i64>,
|
||||
///
|
||||
pub game_name: Option<String>,
|
||||
///
|
||||
pub game_name_like: Option<String>,
|
||||
///
|
||||
pub game_category: Option<String>,
|
||||
///
|
||||
pub game_category_like: Option<String>,
|
||||
///
|
||||
pub game_type: Option<String>,
|
||||
///
|
||||
pub game_type_like: Option<String>,
|
||||
///
|
||||
pub currency: Option<String>,
|
||||
///
|
||||
pub currency_like: Option<String>,
|
||||
///
|
||||
pub key: Option<String>,
|
||||
///
|
||||
pub key_like: Option<String>,
|
||||
///
|
||||
pub ref_id: Option<String>,
|
||||
///
|
||||
pub ref_id_like: Option<String>,
|
||||
///
|
||||
pub o_ref_id: Option<String>,
|
||||
///
|
||||
pub o_ref_id_like: Option<String>,
|
||||
///
|
||||
pub group_key: Option<String>,
|
||||
///
|
||||
pub group_key_like: Option<String>,
|
||||
///
|
||||
pub is_bonus: Option<bool>,
|
||||
///
|
||||
pub is_promo: Option<bool>,
|
||||
///
|
||||
pub is_jackpot: Option<bool>,
|
||||
///
|
||||
pub site_username: Option<String>,
|
||||
///
|
||||
pub site_username_like: Option<String>,
|
||||
///
|
||||
pub betting_type: Option<String>,
|
||||
///
|
||||
pub betting_type_like: Option<String>,
|
||||
///
|
||||
pub category: Option<String>,
|
||||
///
|
||||
pub category_like: Option<String>,
|
||||
}
|
||||
///
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct FindAll {
|
||||
pub search: Option<FindAllSearch>,
|
||||
///
|
||||
pub pagination: Option<bcr::pagination::Pagination>,
|
||||
///
|
||||
pub sorts: Option<Vec<bcr::pagination::Sort>>,
|
||||
}
|
|
@ -108,7 +108,7 @@ impl Composition {
|
|||
member: mm,
|
||||
created_at: m.created_at,
|
||||
updated_at: m.updated_at,
|
||||
}))
|
||||
}));
|
||||
}
|
||||
None => {
|
||||
return Ok(None);
|
||||
|
|
|
@ -106,8 +106,11 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
connection_broker.clone(),
|
||||
queue_broker.clone(),
|
||||
);
|
||||
let betting_service =
|
||||
services::betting::service::Service::new(connection_broker.clone(), queue_broker.clone());
|
||||
let betting_service = services::betting::service::Service::new(
|
||||
connection_broker.clone(),
|
||||
queue_broker.clone(),
|
||||
pool.clone(),
|
||||
);
|
||||
|
||||
let member_event_handler = events::member::event::EventHandler::new(
|
||||
connection_broker.clone(),
|
||||
|
@ -164,6 +167,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
futures::try_join!(
|
||||
vendor_service.subscribe(),
|
||||
game_service.subscribe(),
|
||||
betting_service.subscribe(),
|
||||
// member_service.subscribe(),
|
||||
// member_account_service.subscribe(),
|
||||
// betting_service.subscribe(),
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
pub mod models;
|
||||
pub mod service;
|
||||
|
|
54
src/services/betting/models.rs
Normal file
54
src/services/betting/models.rs
Normal file
|
@ -0,0 +1,54 @@
|
|||
use crate::compositions;
|
||||
use beteran_protobuf_rust as bpr;
|
||||
|
||||
impl From<&compositions::betting::models::BettingHistoryModel>
|
||||
for bpr::models::api::betting::BettingHistoryModel
|
||||
{
|
||||
fn from(d: &compositions::betting::models::BettingHistoryModel) -> Self {
|
||||
let member = Some(bpr::models::member::Member {
|
||||
id: d.member.id.to_string(),
|
||||
site_id: d.member.site_id.to_string(),
|
||||
member_class_id: d.member.member_class_id.to_string(),
|
||||
member_level_id: d.member.member_level_id.to_string(),
|
||||
parent_member_id: d.member.parent_member_id.as_ref().map(|d| d.to_string()),
|
||||
child_member_count: d.member.child_member_count as u64,
|
||||
username: d.member.username.clone(),
|
||||
nickname: d.member.nickname.clone(),
|
||||
mobile_phone_number: d.member.mobile_phone_number.clone(),
|
||||
state: d.member.state as i32,
|
||||
state_changed_at: d.member.state_changed_at.map(|d| d as u64),
|
||||
last_signined_ip: d.member.last_signined_ip.clone(),
|
||||
last_signined_at: d.member.last_signined_at.map(|d| d as u64),
|
||||
created_at: d.member.created_at as u64,
|
||||
updated_at: d.member.updated_at as u64,
|
||||
deleted_at: d.member.deleted_at.map(|d| d as u64),
|
||||
});
|
||||
|
||||
bpr::models::api::betting::BettingHistoryModel {
|
||||
id: d.id.clone(),
|
||||
member,
|
||||
vendor_id: d.vendor_id as u64,
|
||||
vendor_name: d.vendor_name.clone(),
|
||||
game_id: d.game_id as u64,
|
||||
game_name: d.game_name.clone(),
|
||||
game_category: d.game_category.clone(),
|
||||
game_type: d.game_type.clone(),
|
||||
currency: d.currency.clone(),
|
||||
cash: d.cash,
|
||||
before_cash: d.before_cash,
|
||||
after_cash: d.after_cash,
|
||||
key: d.key.clone(),
|
||||
ref_id: d.ref_id.clone(),
|
||||
o_ref_id: d.o_ref_id.clone(),
|
||||
group_key: d.group_key.clone(),
|
||||
is_bonus: d.is_bonus,
|
||||
is_promo: d.is_promo,
|
||||
is_jackpot: d.is_jackpot,
|
||||
site_username: d.site_username.clone(),
|
||||
betting_type: d.betting_type.clone(),
|
||||
category: d.category.clone(),
|
||||
created_at: d.created_at as u64,
|
||||
utc_created_at: d.utc_created_at as u64,
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,7 +1,18 @@
|
|||
use crate::compositions;
|
||||
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<ConnectionManager<PgConnection>>,
|
||||
betting_composition: compositions::betting::composition::Composition,
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for Service {
|
||||
|
@ -12,16 +23,22 @@ impl std::fmt::Debug for Service {
|
|||
|
||||
impl Service {
|
||||
///
|
||||
pub fn new(connection_broker: nats::asynk::Connection, queue_broker: String) -> Service {
|
||||
pub fn new(
|
||||
connection_broker: nats::asynk::Connection,
|
||||
queue_broker: String,
|
||||
pool: Pool<ConnectionManager<PgConnection>>,
|
||||
) -> Service {
|
||||
Service {
|
||||
connection_broker,
|
||||
connection_broker: connection_broker.clone(),
|
||||
queue_broker,
|
||||
pool,
|
||||
betting_composition: compositions::betting::composition::Composition::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn subscribe(&self) -> std::result::Result<(), std::boxed::Box<dyn std::error::Error>> {
|
||||
futures::try_join!(
|
||||
self.list_history(),
|
||||
self.list_betting_history(),
|
||||
self.list_history_for_pragmatic(),
|
||||
self.list_history_for_evolution(),
|
||||
self.statistics(),
|
||||
|
@ -29,7 +46,178 @@ impl Service {
|
|||
.map(|_| ())
|
||||
}
|
||||
|
||||
async fn list_history(&self) -> Result<(), Box<dyn std::error::Error>> {
|
||||
async fn list_betting_history(&self) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let s = self
|
||||
.connection_broker
|
||||
.queue_subscribe(
|
||||
bpr::ss::api::betting::SUBJECT_LIST_BETTING_HISTORY,
|
||||
self.queue_broker.as_str(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
while let Some(message) = s.next().await {
|
||||
if let Err(e) = async {
|
||||
let req = bpr::ss::api::betting::ListBettingHistoryRequest::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 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 = compositions::betting::models::FindAll {
|
||||
search: match request.search {
|
||||
Some(s) => Some(compositions::betting::models::FindAllSearch {
|
||||
member_id: s.member_id,
|
||||
vendor_id: s.vendor_id.map(|v| v as i64),
|
||||
vendor_name: s.vendor_name,
|
||||
vendor_name_like: s.vendor_name_like,
|
||||
game_id: s.game_id.map(|v| v as i64),
|
||||
game_name: s.game_name,
|
||||
game_name_like: s.game_name_like,
|
||||
game_category: s.game_category,
|
||||
game_category_like: s.game_category_like,
|
||||
game_type: s.game_type,
|
||||
game_type_like: s.game_type_like,
|
||||
currency: s.currency,
|
||||
currency_like: s.currency_like,
|
||||
key: s.key,
|
||||
key_like: s.key_like,
|
||||
ref_id: s.ref_id,
|
||||
ref_id_like: s.ref_id_like,
|
||||
o_ref_id: s.o_ref_id,
|
||||
o_ref_id_like: s.o_ref_id_like,
|
||||
group_key: s.group_key,
|
||||
group_key_like: s.group_key_like,
|
||||
is_bonus: s.is_bonus,
|
||||
is_promo: s.is_promo,
|
||||
is_jackpot: s.is_jackpot,
|
||||
site_username: s.site_username,
|
||||
site_username_like: s.site_username_like,
|
||||
betting_type: s.betting_type,
|
||||
betting_type_like: s.betting_type_like,
|
||||
category: s.category,
|
||||
category_like: s.category_like,
|
||||
}),
|
||||
None => None,
|
||||
},
|
||||
pagination: request
|
||||
.pagination
|
||||
.as_ref()
|
||||
.map(bcr::pagination::Pagination::from),
|
||||
sorts: Some(
|
||||
request
|
||||
.sorts
|
||||
.iter()
|
||||
.map(bcr::pagination::Sort::from)
|
||||
.collect(),
|
||||
),
|
||||
};
|
||||
|
||||
let count = self
|
||||
.betting_composition
|
||||
.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
|
||||
.betting_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::api::betting::ListBettingHistoryResponse {
|
||||
error: None,
|
||||
result: Some(
|
||||
bpr::ss::api::betting::list_betting_history_response::Result {
|
||||
betting_history: list
|
||||
.iter()
|
||||
.map(bpr::models::api::betting::BettingHistoryModel::from)
|
||||
.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::api::betting::ListBettingHistoryResponse {
|
||||
error: Some(bpr::protobuf::rpc::Error::from(e)),
|
||||
result: None,
|
||||
}
|
||||
.encode_to_vec(),
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
async fn list_history_for_pragmatic(&self) -> Result<(), Box<dyn std::error::Error>> {
|
||||
|
|
Loading…
Reference in New Issue
Block a user