feat: add gacha credits

This commit is contained in:
Maulana Sodiqin
2025-05-22 00:31:36 +07:00
parent 465cbee2c3
commit 9878279660
31 changed files with 252 additions and 127 deletions
-22
View File
@@ -1,22 +0,0 @@
use axum::{
Router,
routing::{get, post},
};
pub mod gacha_claim_controller;
pub mod gacha_claim_dto;
pub mod gacha_claim_repository;
pub mod gacha_claim_schema;
pub mod gacha_claim_service;
pub use gacha_claim_controller::*;
pub use gacha_claim_dto::*;
pub use gacha_claim_repository::*;
pub use gacha_claim_schema::*;
pub use gacha_claim_service::*;
pub fn gacha_claim_router() -> Router {
Router::new()
.route("/create", post(post_create_gacha_claim))
.route("/detail/{id}", get(get_detail_gacha_claim))
}
@@ -46,9 +46,7 @@ impl GachaClaimSchema {
),
user: make_thing(&ResourceEnum::Users.to_string(), &dto.user_id),
item: make_thing(&ResourceEnum::GachaItems.to_string(), &dto.item_id),
is_deleted: false,
created_at: Some(get_iso_date()),
updated_at: Some(get_iso_date()),
..Default::default()
}
}
+22
View File
@@ -0,0 +1,22 @@
use axum::{
Router,
routing::{get, post},
};
pub mod gacha_claims_controller;
pub mod gacha_claims_dto;
pub mod gacha_claims_repository;
pub mod gacha_claims_schema;
pub mod gacha_claims_service;
pub use gacha_claims_controller::*;
pub use gacha_claims_dto::*;
pub use gacha_claims_repository::*;
pub use gacha_claims_schema::*;
pub use gacha_claims_service::*;
pub fn gacha_claim_router() -> Router {
Router::new()
.route("/create", post(post_create_gacha_claim))
.route("/detail/{id}", get(get_detail_gacha_claim))
}
@@ -0,0 +1,7 @@
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct GachaCreditRequestDto {
pub user_id: String,
pub amount: i32,
}
@@ -0,0 +1,82 @@
use super::{GachaCreditRequestDto, GachaCreditSchema};
use crate::{AppState, ResourceEnum};
use anyhow::{Result, bail};
use imphnen_iam::make_thing;
use surrealdb::Uuid;
pub struct GachaCreditRepository<'a> {
state: &'a AppState,
}
impl<'a> GachaCreditRepository<'a> {
pub fn new(state: &'a AppState) -> Self {
Self { state }
}
pub async fn query_by_user_id(
&self,
user_id: String,
) -> Result<Option<GachaCreditSchema>> {
let db = &self.state.surrealdb_ws;
let sql = format!(
"SELECT * FROM {} WHERE user = {}:⟨$user_id⟩ AND is_deleted = false LIMIT 1",
ResourceEnum::GachaCredits.to_string(),
ResourceEnum::Users.to_string()
);
let result: Vec<GachaCreditSchema> =
db.query(sql).bind(("user_id", user_id)).await?.take(0)?;
Ok(result.into_iter().next())
}
pub async fn query_consume_credit(&self, user_id: String) -> Result<()> {
let db = &self.state.surrealdb_ws;
let credit_opt = self.query_by_user_id(user_id).await?;
let Some(mut credit) = credit_opt else {
return Ok(());
};
if credit.available_rolls <= 0 {
bail!("No extra roll credits remaining");
}
credit.available_rolls -= 1;
let _: Option<GachaCreditSchema> = db
.update((
&ResourceEnum::GachaCredits.to_string(),
credit.id.id.to_raw(),
))
.merge(credit)
.await?;
Ok(())
}
pub async fn query_add_credit(
&self,
payload: GachaCreditRequestDto,
) -> Result<()> {
let db = &self.state.surrealdb_ws;
if let Some(mut credit) = self.query_by_user_id(payload.user_id.clone()).await? {
credit.available_rolls += payload.amount;
let _: Option<GachaCreditSchema> = db
.update((
&ResourceEnum::GachaCredits.to_string(),
credit.id.id.to_raw(),
))
.merge(credit)
.await?;
} else {
let data = GachaCreditSchema::from(&GachaCreditSchema {
id: make_thing(
&ResourceEnum::GachaCredits.to_string(),
&Uuid::new_v4().to_string(),
),
user: make_thing(&ResourceEnum::Users.to_string(), &payload.user_id),
available_rolls: payload.amount,
..Default::default()
});
let _: Option<GachaCreditSchema> = db
.create(&ResourceEnum::GachaCredits.to_string())
.content(data)
.await?;
}
Ok(())
}
}
@@ -0,0 +1,39 @@
use imphnen_iam::get_iso_date;
use serde::{Deserialize, Serialize};
use surrealdb::sql::Thing;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct GachaCreditSchema {
pub id: Thing,
pub user: Thing,
pub available_rolls: i32,
pub is_deleted: bool,
pub created_at: Option<String>,
pub updated_at: Option<String>,
}
impl Default for GachaCreditSchema {
fn default() -> Self {
GachaCreditSchema {
id: Thing::from(("app_gacha_credits", "uuid")),
user: Thing::from(("app_users", "uuid")),
available_rolls: 0,
is_deleted: false,
created_at: Some(get_iso_date()),
updated_at: Some(get_iso_date()),
}
}
}
impl GachaCreditSchema {
pub fn from(&self) -> Self {
Self {
id: self.id.clone(),
user: self.user.clone(),
available_rolls: self.available_rolls,
is_deleted: false,
created_at: Some(get_iso_date()),
updated_at: Some(get_iso_date()),
}
}
}
@@ -0,0 +1,7 @@
pub mod gacha_credits_dto;
pub mod gacha_credits_repository;
pub mod gacha_credits_schema;
pub use gacha_credits_dto::*;
pub use gacha_credits_repository::*;
pub use gacha_credits_schema::*;
@@ -1,8 +1,6 @@
use crate::{
AppState, MessageResponseDto, MetaRequestDto, ResponseListSuccessDto,
ResponseSuccessDto,
gacha_item_dto::{GachaItemDto, GachaItemRequestDto},
gacha_item_service::GachaItemService,
AppState, GachaItemDto, GachaItemRequestDto, GachaItemService, MessageResponseDto,
MetaRequestDto, ResponseListSuccessDto, ResponseSuccessDto,
};
use axum::{
Extension, Json,
@@ -40,9 +40,7 @@ impl GachaItemSchema {
),
name: dto.name,
image_url: dto.image_url,
is_deleted: false,
created_at: Some(get_iso_date()),
updated_at: Some(get_iso_date()),
..Default::default()
}
}
}
@@ -3,17 +3,17 @@ use axum::{
routing::{delete, get, post, put},
};
pub mod gacha_item_controller;
pub mod gacha_item_dto;
pub mod gacha_item_repository;
pub mod gacha_item_schema;
pub mod gacha_item_service;
pub mod gacha_items_controller;
pub mod gacha_items_dto;
pub mod gacha_items_repository;
pub mod gacha_items_schema;
pub mod gacha_items_service;
pub use gacha_item_controller::*;
pub use gacha_item_dto::*;
pub use gacha_item_repository::*;
pub use gacha_item_schema::*;
pub use gacha_item_service::*;
pub use gacha_items_controller::*;
pub use gacha_items_dto::*;
pub use gacha_items_repository::*;
pub use gacha_items_schema::*;
pub use gacha_items_service::*;
pub fn gacha_item_router() -> Router {
Router::new()
-22
View File
@@ -1,22 +0,0 @@
pub mod gacha_roll_controller;
pub mod gacha_roll_dto;
pub mod gacha_roll_repository;
pub mod gacha_roll_schema;
pub mod gacha_roll_service;
use axum::{
Router,
routing::{get, post},
};
pub use gacha_roll_controller::*;
pub use gacha_roll_dto::*;
pub use gacha_roll_repository::*;
pub use gacha_roll_schema::*;
pub use gacha_roll_service::*;
pub fn gacha_roll_router() -> Router {
Router::new()
.route("/create", post(post_create_gacha_roll))
.route("/execute", post(post_execute_gacha_roll))
.route("/detail/{id}", get(get_detail_gacha_roll))
}
@@ -1,7 +1,6 @@
use crate::{
AppState, MessageResponseDto, ResponseSuccessDto,
gacha_roll_dto::{GachaRollItemDto, GachaRollRequestDto},
gacha_roll_service::GachaRollService,
AppState, GachaRollItemDto, GachaRollRequestDto, GachaRollService,
MessageResponseDto, ResponseSuccessDto,
};
use axum::{
Extension, Json, extract::Path, http::HeaderMap, response::IntoResponse,
@@ -46,9 +46,7 @@ impl GachaRollSchema {
item: make_thing(&ResourceEnum::GachaItems.to_string(), &dto.item_id),
weight: dto.weight,
quantity: dto.quantity,
is_deleted: false,
created_at: Some(get_iso_date()),
updated_at: Some(get_iso_date()),
..Default::default()
}
}
}
+22
View File
@@ -0,0 +1,22 @@
pub mod gacha_rolls_controller;
pub mod gacha_rolls_dto;
pub mod gacha_rolls_repository;
pub mod gacha_rolls_schema;
pub mod gacha_rolls_service;
use axum::{
Router,
routing::{get, post},
};
pub use gacha_rolls_controller::*;
pub use gacha_rolls_dto::*;
pub use gacha_rolls_repository::*;
pub use gacha_rolls_schema::*;
pub use gacha_rolls_service::*;
pub fn gacha_roll_router() -> Router {
Router::new()
.route("/create", post(post_create_gacha_roll))
.route("/execute", post(post_execute_gacha_roll))
.route("/detail/{id}", get(get_detail_gacha_roll))
}
+8 -6
View File
@@ -1,12 +1,14 @@
use axum::Router;
pub mod gacha_claim;
pub mod gacha_item;
pub mod gacha_roll;
pub mod gacha_claims;
pub mod gacha_credits;
pub mod gacha_items;
pub mod gacha_rolls;
pub use gacha_claim::*;
pub use gacha_item::*;
pub use gacha_roll::*;
pub use gacha_claims::*;
pub use gacha_credits::*;
pub use gacha_items::*;
pub use gacha_rolls::*;
pub fn gacha_router() -> Router {
Router::new()