feat: finishing gacha feature
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
use crate::{ResourceEnum, make_thing};
|
||||
use crate::{GachaRollQueryDto, ResourceEnum, make_thing};
|
||||
use imphnen_iam::get_iso_date;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use surrealdb::{Uuid, sql::Thing};
|
||||
|
||||
@@ -30,8 +31,8 @@ impl Default for GachaClaimSchema {
|
||||
&Uuid::new_v4().to_string(),
|
||||
),
|
||||
is_deleted: false,
|
||||
created_at: None,
|
||||
updated_at: None,
|
||||
created_at: Some(get_iso_date()),
|
||||
updated_at: Some(get_iso_date()),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -46,8 +47,20 @@ 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: None,
|
||||
updated_at: None,
|
||||
created_at: Some(get_iso_date()),
|
||||
updated_at: Some(get_iso_date()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn roll(roll: GachaRollQueryDto, user_id: Thing) -> Self {
|
||||
Self {
|
||||
id: make_thing(
|
||||
&ResourceEnum::GachaClaims.to_string(),
|
||||
&Uuid::new_v4().to_string(),
|
||||
),
|
||||
user: user_id,
|
||||
item: roll.item.id.clone(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,7 +88,7 @@ pub async fn post_execute_gacha_roll(
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(_) => GachaRollService::execute_roll_once(&state).await,
|
||||
Ok(_) => GachaRollService::execute_roll_once(headers, &state).await,
|
||||
Err(response) => response,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@ use validator::Validate;
|
||||
pub struct GachaRollRequestDto {
|
||||
#[validate(length(min = 1, message = "Item ID must not be empty"))]
|
||||
pub item_id: String,
|
||||
#[validate(range(min = 1, message = "Weight must be greater than zero"))]
|
||||
pub weight: f32,
|
||||
#[validate(range(min = 1, message = "Quantity must be at least 1"))]
|
||||
pub quantity: i32,
|
||||
@@ -18,7 +17,7 @@ pub struct GachaRollRequestDto {
|
||||
pub struct GachaRollItemDto {
|
||||
pub id: String,
|
||||
pub item: GachaItemDto,
|
||||
pub weight: String,
|
||||
pub weight: f32,
|
||||
pub quantity: i32,
|
||||
pub is_deleted: bool,
|
||||
pub created_at: Option<String>,
|
||||
@@ -30,7 +29,7 @@ impl GachaRollItemDto {
|
||||
Self {
|
||||
id: dto.id.id.to_raw(),
|
||||
item: GachaItemDto::from(dto.item.clone()),
|
||||
weight: dto.weight.to_string(),
|
||||
weight: dto.weight.clone(),
|
||||
quantity: dto.quantity,
|
||||
is_deleted: dto.is_deleted,
|
||||
created_at: dto.created_at.clone(),
|
||||
|
||||
@@ -2,6 +2,7 @@ use super::GachaRollQueryDto;
|
||||
use super::GachaRollSchema;
|
||||
use crate::{AppState, DetailQueryBuilder, ResourceEnum};
|
||||
use anyhow::{Result, bail};
|
||||
use imphnen_iam::ListQueryBuilder;
|
||||
use rand::prelude::*;
|
||||
use rand::rng;
|
||||
use rand_distr::weighted::WeightedIndex;
|
||||
@@ -50,12 +51,10 @@ impl<'a> GachaRollRepository<'a> {
|
||||
|
||||
pub async fn query_all_active_rolls(&self) -> Result<Vec<GachaRollQueryDto>> {
|
||||
let db = &self.state.surrealdb_ws;
|
||||
let sql = DetailQueryBuilder::new(ResourceEnum::GachaRolls.to_string())
|
||||
.with_where("is_deleted")
|
||||
.where_value("false")
|
||||
let builder = ListQueryBuilder::new(ResourceEnum::GachaRolls.to_string())
|
||||
.with_select_fields(vec!["*"])
|
||||
.with_fetch("item")
|
||||
.build();
|
||||
.with_fetch(Some(vec!["item"]));
|
||||
let sql = builder.build();
|
||||
let result: Vec<GachaRollQueryDto> = db.query(sql).await?.take(0)?;
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
use crate::{
|
||||
AppState, GachaRollItemDto, GachaRollRepository, GachaRollRequestDto,
|
||||
GachaRollSchema, ResponseSuccessDto, common_response, success_response,
|
||||
validate_request,
|
||||
AppState, GachaClaimRepository, GachaClaimSchema, GachaRollItemDto,
|
||||
GachaRollRepository, GachaRollRequestDto, GachaRollSchema, ResponseSuccessDto,
|
||||
common_response, success_response, validate_request,
|
||||
};
|
||||
use axum::http::StatusCode;
|
||||
use axum::http::{HeaderMap, StatusCode};
|
||||
use axum::response::Response;
|
||||
use imphnen_iam::{UsersRepository, extract_email};
|
||||
|
||||
pub struct GachaRollService;
|
||||
|
||||
@@ -34,13 +35,29 @@ impl GachaRollService {
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn execute_roll_once(state: &AppState) -> Response {
|
||||
pub async fn execute_roll_once(headers: HeaderMap, state: &AppState) -> Response {
|
||||
let repo = GachaRollRepository::new(state);
|
||||
let repo_claim = GachaClaimRepository::new(state);
|
||||
let repo_user = UsersRepository::new(state);
|
||||
let Some(email) = extract_email(&headers) else {
|
||||
return common_response(StatusCode::UNAUTHORIZED, "Unauthorized");
|
||||
};
|
||||
let Ok(user) = repo_user.query_user_by_email(email.to_string()).await else {
|
||||
return common_response(StatusCode::NOT_FOUND, "User not found");
|
||||
};
|
||||
match repo.query_all_active_rolls().await {
|
||||
Ok(rolls) => match GachaRollRepository::roll_once(&rolls) {
|
||||
Some(roll) => success_response(ResponseSuccessDto {
|
||||
data: GachaRollItemDto::from(&roll),
|
||||
}),
|
||||
Some(roll) => {
|
||||
let claim = GachaClaimSchema::roll(roll.clone(), user.id);
|
||||
match repo_claim.query_create_gacha_claim(claim).await {
|
||||
Ok(_) => success_response(ResponseSuccessDto {
|
||||
data: GachaRollItemDto::from(&roll),
|
||||
}),
|
||||
Err(e) => {
|
||||
common_response(StatusCode::INTERNAL_SERVER_ERROR, &e.to_string())
|
||||
}
|
||||
}
|
||||
}
|
||||
None => common_response(StatusCode::NOT_FOUND, "No rollable item available"),
|
||||
},
|
||||
Err(e) => common_response(StatusCode::INTERNAL_SERVER_ERROR, &e.to_string()),
|
||||
|
||||
Reference in New Issue
Block a user