feat: gacha roll, user auth
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
hard_tabs = true
|
hard_tabs = true
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
max_width = 85
|
max_width = 85
|
||||||
|
tab_spaces = 2
|
||||||
|
|||||||
@@ -29,8 +29,15 @@ pub struct AuthRegisterRequestDto {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize, ToSchema)]
|
#[derive(Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||||
pub struct AuthQueryByEmailResponse {
|
pub struct AuthActiveInactiveRequestDto {
|
||||||
|
pub is_active: bool,
|
||||||
|
pub email: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||||
|
pub struct AuthQueryByEmailResponseDto {
|
||||||
pub email: String,
|
pub email: String,
|
||||||
pub fullname: String,
|
pub fullname: String,
|
||||||
pub password: String,
|
pub password: String,
|
||||||
|
pub is_active: bool,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
use crate::{common_response, extract_email, AppState};
|
use super::AuthRepository;
|
||||||
|
use crate::{
|
||||||
|
common_response, extract_email, v1::users_schema::UsersSchema, AppState,
|
||||||
|
};
|
||||||
use axum::{
|
use axum::{
|
||||||
extract::Request, http::StatusCode, middleware::Next, response::Response,
|
extract::Request, http::StatusCode, middleware::Next, response::Response,
|
||||||
Extension,
|
Extension,
|
||||||
};
|
};
|
||||||
use std::convert::Infallible;
|
use std::convert::Infallible;
|
||||||
|
|
||||||
use super::{AuthQueryByEmailResponse, AuthRepository};
|
|
||||||
|
|
||||||
pub async fn auth_middleware(
|
pub async fn auth_middleware(
|
||||||
Extension(state): Extension<AppState>,
|
Extension(state): Extension<AppState>,
|
||||||
mut req: Request,
|
mut req: Request,
|
||||||
@@ -26,16 +27,15 @@ pub async fn auth_middleware(
|
|||||||
|
|
||||||
let repository = AuthRepository::new(&state);
|
let repository = AuthRepository::new(&state);
|
||||||
|
|
||||||
let user: Option<AuthQueryByEmailResponse> =
|
let user: Option<UsersSchema> = match repository.query_user_by_email(email).await {
|
||||||
match repository.query_user_by_email(email).await {
|
Ok(user) => Some(user),
|
||||||
Ok(user) => Some(user),
|
Err(err) => {
|
||||||
Err(err) => {
|
return Ok(common_response(
|
||||||
return Ok(common_response(
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
StatusCode::INTERNAL_SERVER_ERROR,
|
&err.to_string(),
|
||||||
&format!("DB error: {}", err),
|
))
|
||||||
))
|
}
|
||||||
}
|
};
|
||||||
};
|
|
||||||
|
|
||||||
if user.is_none() {
|
if user.is_none() {
|
||||||
return Ok(common_response(
|
return Ok(common_response(
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
use crate::{v1::UsersItemDto, AppState, RedisKeyEnum, ResourceEnum};
|
use super::{AuthActiveInactiveRequestDto, AuthRegisterRequestDto};
|
||||||
|
use crate::{
|
||||||
|
v1::{users_schema::UsersSchema, UsersItemDto},
|
||||||
|
AppState, RedisKeyEnum, ResourceEnum,
|
||||||
|
};
|
||||||
use anyhow::{bail, Result};
|
use anyhow::{bail, Result};
|
||||||
use redis::Commands;
|
use redis::Commands;
|
||||||
|
|
||||||
use super::{AuthQueryByEmailResponse, AuthRegisterRequestDto};
|
|
||||||
|
|
||||||
pub struct AuthRepository<'a> {
|
pub struct AuthRepository<'a> {
|
||||||
state: &'a AppState,
|
state: &'a AppState,
|
||||||
}
|
}
|
||||||
@@ -33,26 +35,19 @@ impl<'a> AuthRepository<'a> {
|
|||||||
pub fn query_get_stored_user(&self, email: String) -> Result<UsersItemDto> {
|
pub fn query_get_stored_user(&self, email: String) -> Result<UsersItemDto> {
|
||||||
let redis_key = format!("{}:{}", RedisKeyEnum::User, email);
|
let redis_key = format!("{}:{}", RedisKeyEnum::User, email);
|
||||||
let mut conn = self.state.redisdb.get_connection()?;
|
let mut conn = self.state.redisdb.get_connection()?;
|
||||||
|
|
||||||
let data: Option<String> = conn.get(&redis_key)?;
|
let data: Option<String> = conn.get(&redis_key)?;
|
||||||
|
|
||||||
match data {
|
match data {
|
||||||
Some(user_json) => {
|
Some(user_json) => {
|
||||||
let user: UsersItemDto = serde_json::from_str(&user_json)?;
|
let user: UsersItemDto = serde_json::from_str(&user_json)?;
|
||||||
Ok(user)
|
Ok(user)
|
||||||
}
|
}
|
||||||
None => bail!("No stored user data found for email"),
|
None => bail!("No stored user data found"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn query_user_by_email(
|
pub async fn query_user_by_email(&self, email: String) -> Result<UsersSchema> {
|
||||||
&self,
|
|
||||||
email: String,
|
|
||||||
) -> Result<AuthQueryByEmailResponse> {
|
|
||||||
let db = &self.state.surrealdb;
|
let db = &self.state.surrealdb;
|
||||||
|
|
||||||
let result = db.select((ResourceEnum::Users.to_string(), email)).await?;
|
let result = db.select((ResourceEnum::Users.to_string(), email)).await?;
|
||||||
|
|
||||||
match result {
|
match result {
|
||||||
Some(response) => Ok(response),
|
Some(response) => Ok(response),
|
||||||
None => bail!("User not found"),
|
None => bail!("User not found"),
|
||||||
@@ -64,15 +59,28 @@ impl<'a> AuthRepository<'a> {
|
|||||||
data: AuthRegisterRequestDto,
|
data: AuthRegisterRequestDto,
|
||||||
) -> Result<String> {
|
) -> Result<String> {
|
||||||
let db = &self.state.surrealdb;
|
let db = &self.state.surrealdb;
|
||||||
|
|
||||||
let record: Option<UsersItemDto> = db
|
let record: Option<UsersItemDto> = db
|
||||||
.create((ResourceEnum::Users.to_string(), &data.email))
|
.create((ResourceEnum::Users.to_string(), &data.email))
|
||||||
.content(data)
|
.content(data)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
match record {
|
match record {
|
||||||
Some(_) => Ok("Success create user".into()),
|
Some(_) => Ok("Success create user".into()),
|
||||||
None => bail!("Failed to create user"),
|
None => bail!("Failed to create user"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn query_active_inactive_user(
|
||||||
|
&self,
|
||||||
|
data: AuthActiveInactiveRequestDto,
|
||||||
|
) -> Result<String> {
|
||||||
|
let db = &self.state.surrealdb;
|
||||||
|
let record: Option<UsersItemDto> = db
|
||||||
|
.update((ResourceEnum::Users.to_string(), &data.email))
|
||||||
|
.content(data)
|
||||||
|
.await?;
|
||||||
|
match record {
|
||||||
|
Some(_) => Ok("Success update user".into()),
|
||||||
|
None => bail!("Failed to update user"),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,8 +6,7 @@ use super::{
|
|||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
common_response, encode_access_token, encode_refresh_token, hash_password,
|
common_response, encode_access_token, encode_refresh_token, hash_password,
|
||||||
success_response, v1::UsersItemDto, verify_password, AppState,
|
success_response, v1::UsersItemDto, verify_password, AppState, ResponseSuccessDto,
|
||||||
ResponseSuccessDto,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct AuthService;
|
pub struct AuthService;
|
||||||
@@ -21,14 +20,10 @@ impl AuthService {
|
|||||||
match repository.query_user_by_email(payload.email.clone()).await {
|
match repository.query_user_by_email(payload.email.clone()).await {
|
||||||
Ok(user) => {
|
Ok(user) => {
|
||||||
let is_password_correct =
|
let is_password_correct =
|
||||||
verify_password(&payload.password, &user.password)
|
verify_password(&payload.password, &user.password).unwrap_or(false);
|
||||||
.unwrap_or(false);
|
|
||||||
|
|
||||||
if is_password_correct {
|
if is_password_correct {
|
||||||
common_response(
|
common_response(StatusCode::BAD_REQUEST, "Email or password not correct");
|
||||||
StatusCode::BAD_REQUEST,
|
|
||||||
"Email or password not correct",
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let access_token = encode_access_token(payload.email.clone());
|
let access_token = encode_access_token(payload.email.clone());
|
||||||
@@ -39,6 +34,7 @@ impl AuthService {
|
|||||||
user: UsersItemDto {
|
user: UsersItemDto {
|
||||||
fullname: user.fullname.clone(),
|
fullname: user.fullname.clone(),
|
||||||
email: user.email.clone(),
|
email: user.email.clone(),
|
||||||
|
is_active: user.is_active.clone(),
|
||||||
},
|
},
|
||||||
token: TokenDto {
|
token: TokenDto {
|
||||||
access_token: access_token.unwrap(),
|
access_token: access_token.unwrap(),
|
||||||
@@ -55,10 +51,7 @@ impl AuthService {
|
|||||||
})
|
})
|
||||||
.is_ok()
|
.is_ok()
|
||||||
{
|
{
|
||||||
return common_response(
|
return common_response(StatusCode::BAD_REQUEST, "Failed to store data");
|
||||||
StatusCode::BAD_REQUEST,
|
|
||||||
"Failed to store data",
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
success_response(response)
|
success_response(response)
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
v1::{auth, AuthLoginRequestDto, AuthLoginResponsetDto},
|
v1::{
|
||||||
|
auth, gacha, AuthLoginRequestDto, AuthLoginResponsetDto,
|
||||||
|
GachaCreateClaimRequestDto, GachaCreateItemRequestDto,
|
||||||
|
GachaCreateRollRequestDto,
|
||||||
|
},
|
||||||
MessageResponseDto, MetaRequestDto, MetaResponseDto, ResponseSuccessDto,
|
MessageResponseDto, MetaRequestDto, MetaResponseDto, ResponseSuccessDto,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -12,17 +16,22 @@ use utoipa::{
|
|||||||
#[openapi(
|
#[openapi(
|
||||||
paths(
|
paths(
|
||||||
auth::auth_controller::post_login,
|
auth::auth_controller::post_login,
|
||||||
auth::auth_controller::post_register
|
auth::auth_controller::post_register,
|
||||||
|
gacha::gacha_controller::post_create_gacha_claim,
|
||||||
|
gacha::gacha_controller::post_create_gacha_item,
|
||||||
|
gacha::gacha_controller::post_create_gacha_roll,
|
||||||
),
|
),
|
||||||
components(
|
components(
|
||||||
schemas(
|
schemas(
|
||||||
MetaRequestDto,
|
MetaRequestDto,
|
||||||
MetaResponseDto,
|
MetaResponseDto,
|
||||||
MessageResponseDto,
|
MessageResponseDto,
|
||||||
|
|
||||||
AuthLoginRequestDto,
|
AuthLoginRequestDto,
|
||||||
AuthLoginResponsetDto,
|
AuthLoginResponsetDto,
|
||||||
ResponseSuccessDto<AuthLoginResponsetDto>,
|
ResponseSuccessDto<AuthLoginResponsetDto>,
|
||||||
|
GachaCreateClaimRequestDto,
|
||||||
|
GachaCreateItemRequestDto,
|
||||||
|
GachaCreateRollRequestDto
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
info(
|
info(
|
||||||
|
|||||||
@@ -1,23 +1,23 @@
|
|||||||
use super::{GachaClaimRequestDto, GachaService};
|
use super::{GachaCreateClaimRequestDto, GachaCreateRollRequestDto, GachaService};
|
||||||
use crate::{v1::GachaCreateItemRequestDto, AppState, MessageResponseDto};
|
use crate::{v1::GachaCreateItemRequestDto, AppState, MessageResponseDto};
|
||||||
use axum::{http::HeaderMap, response::IntoResponse, Extension, Json};
|
use axum::{http::HeaderMap, response::IntoResponse, Extension, Json};
|
||||||
|
|
||||||
#[utoipa::path(
|
#[utoipa::path(
|
||||||
post,
|
post,
|
||||||
path = "/v1/gacha/create/claims",
|
path = "/v1/gacha/create/claims",
|
||||||
request_body = GachaClaimRequestDto,
|
request_body = GachaCreateClaimRequestDto,
|
||||||
responses(
|
responses(
|
||||||
(status = 200, description = "Create gacha claims successful", body = MessageResponseDto),
|
(status = 200, description = "Create gacha claims successful", body = MessageResponseDto),
|
||||||
(status = 401, description = "Create gacha claims failed", body = MessageResponseDto)
|
(status = 401, description = "Create gacha claims failed", body = MessageResponseDto)
|
||||||
),
|
),
|
||||||
tag = "Gacha"
|
tag = "Gacha"
|
||||||
)]
|
)]
|
||||||
pub async fn post_create_gacha_claims(
|
pub async fn post_create_gacha_claim(
|
||||||
header: HeaderMap,
|
header: HeaderMap,
|
||||||
Extension(state): Extension<AppState>,
|
Extension(state): Extension<AppState>,
|
||||||
Json(payload): Json<GachaClaimRequestDto>,
|
Json(payload): Json<GachaCreateClaimRequestDto>,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
GachaService::mutation_create_gacha_claims(payload, &state, header).await
|
GachaService::mutation_create_gacha_claim(payload, &state, header).await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[utoipa::path(
|
#[utoipa::path(
|
||||||
@@ -36,3 +36,20 @@ pub async fn post_create_gacha_item(
|
|||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
GachaService::mutation_create_gacha_item(payload, &state).await
|
GachaService::mutation_create_gacha_item(payload, &state).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[utoipa::path(
|
||||||
|
post,
|
||||||
|
path = "/v1/gacha/create/roll",
|
||||||
|
request_body = GachaCreateRollRequestDto,
|
||||||
|
responses(
|
||||||
|
(status = 200, description = "Create gacha roll successful", body = MessageResponseDto),
|
||||||
|
(status = 401, description = "Create gacha roll failed", body = MessageResponseDto)
|
||||||
|
),
|
||||||
|
tag = "Gacha"
|
||||||
|
)]
|
||||||
|
pub async fn post_create_gacha_roll(
|
||||||
|
Extension(state): Extension<AppState>,
|
||||||
|
Json(payload): Json<GachaCreateRollRequestDto>,
|
||||||
|
) -> impl IntoResponse {
|
||||||
|
GachaService::mutation_create_gacha_roll(payload, &state).await
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ use utoipa::ToSchema;
|
|||||||
use crate::v1::UsersItemDto;
|
use crate::v1::UsersItemDto;
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize, ToSchema)]
|
#[derive(Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||||
pub struct GachaClaimRequestDto {
|
pub struct GachaCreateClaimRequestDto {
|
||||||
pub transaction_number: String,
|
pub transaction_number: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -16,7 +16,7 @@ pub struct GachaCreateItemRequestDto {
|
|||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize, ToSchema)]
|
#[derive(Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||||
pub struct GachaCreateRollRequestDto {
|
pub struct GachaCreateRollRequestDto {
|
||||||
pub item_id: String,
|
pub item_name: String,
|
||||||
pub weight: String,
|
pub weight: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -31,3 +31,8 @@ pub struct GachaClaimResponseDto {
|
|||||||
pub transaction_number: String,
|
pub transaction_number: String,
|
||||||
pub user: UsersItemDto,
|
pub user: UsersItemDto,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||||
|
pub struct GachaRollResponseDto {
|
||||||
|
pub item: GachaItemResponseDto,
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
use super::{
|
use super::{
|
||||||
GachaClaimRequestDto, GachaClaimResponseDto, GachaCreateItemRequestDto,
|
GachaClaimResponseDto, GachaClaimSchema, GachaCreateClaimRequestDto,
|
||||||
GachaItemSchema, GachaSchema,
|
GachaCreateItemRequestDto, GachaCreateRollRequestDto, GachaItemResponseDto,
|
||||||
|
GachaItemSchema, GachaRollSchema,
|
||||||
};
|
};
|
||||||
use crate::{v1::AuthRepository, AppState, ResourceEnum};
|
use crate::{v1::AuthRepository, AppState, ResourceEnum};
|
||||||
use anyhow::{bail, Result};
|
use anyhow::{bail, Result};
|
||||||
@@ -15,25 +16,41 @@ impl<'a> GachaRepository<'a> {
|
|||||||
Self { state }
|
Self { state }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn query_gacha_by_transaction_number(
|
pub async fn query_gacha_claim_by_transaction_number(
|
||||||
&self,
|
&self,
|
||||||
transaction_number: String,
|
transaction_number: String,
|
||||||
) -> Result<GachaClaimResponseDto> {
|
) -> Result<GachaClaimResponseDto> {
|
||||||
let db = &self.state.surrealdb;
|
let db = &self.state.surrealdb;
|
||||||
|
|
||||||
let result = db
|
let result = db
|
||||||
.select((ResourceEnum::Gacha.to_string(), transaction_number))
|
.select((ResourceEnum::GachaClaims.to_string(), transaction_number))
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
match result {
|
match result {
|
||||||
Some(response) => Ok(response),
|
Some(response) => Ok(response),
|
||||||
None => bail!("Gacha not found"),
|
None => bail!("Gacha claim not found"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn query_create_gacha_claims(
|
pub async fn query_gacha_item_by_name(
|
||||||
&self,
|
&self,
|
||||||
data: GachaClaimRequestDto,
|
name: String,
|
||||||
|
) -> Result<GachaItemResponseDto> {
|
||||||
|
let db = &self.state.surrealdb;
|
||||||
|
|
||||||
|
let result = db
|
||||||
|
.select((ResourceEnum::GachaItems.to_string(), name))
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
match result {
|
||||||
|
Some(response) => Ok(response),
|
||||||
|
None => bail!("Gacha item not found"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn query_create_gacha_claim(
|
||||||
|
&self,
|
||||||
|
data: GachaCreateClaimRequestDto,
|
||||||
email: String,
|
email: String,
|
||||||
) -> Result<String> {
|
) -> Result<String> {
|
||||||
let auth_repository = AuthRepository::new(self.state);
|
let auth_repository = AuthRepository::new(self.state);
|
||||||
@@ -44,12 +61,12 @@ impl<'a> GachaRepository<'a> {
|
|||||||
let user_thing =
|
let user_thing =
|
||||||
Thing::from((ResourceEnum::Users.to_string(), Id::String(user.email)));
|
Thing::from((ResourceEnum::Users.to_string(), Id::String(user.email)));
|
||||||
|
|
||||||
let record: Option<GachaSchema> = db
|
let record: Option<GachaClaimSchema> = db
|
||||||
.create((
|
.create((
|
||||||
ResourceEnum::GachaClaims.to_string(),
|
ResourceEnum::GachaClaims.to_string(),
|
||||||
&data.transaction_number,
|
&data.transaction_number,
|
||||||
))
|
))
|
||||||
.content(GachaSchema {
|
.content(GachaClaimSchema {
|
||||||
transaction_number: data.transaction_number.clone(),
|
transaction_number: data.transaction_number.clone(),
|
||||||
user: user_thing,
|
user: user_thing,
|
||||||
})
|
})
|
||||||
@@ -68,7 +85,7 @@ impl<'a> GachaRepository<'a> {
|
|||||||
let db = &self.state.surrealdb;
|
let db = &self.state.surrealdb;
|
||||||
|
|
||||||
let record: Option<GachaItemSchema> = db
|
let record: Option<GachaItemSchema> = db
|
||||||
.create((ResourceEnum::Gacha.to_string(), data.item_name.clone()))
|
.create((ResourceEnum::GachaItems.to_string(), data.item_name.clone()))
|
||||||
.content(GachaItemSchema {
|
.content(GachaItemSchema {
|
||||||
item_name: data.item_name.clone(),
|
item_name: data.item_name.clone(),
|
||||||
item_image: data.item_image.clone(),
|
item_image: data.item_image.clone(),
|
||||||
@@ -77,27 +94,31 @@ impl<'a> GachaRepository<'a> {
|
|||||||
|
|
||||||
match record {
|
match record {
|
||||||
Some(_) => Ok("Gacha item successfully created".to_string()),
|
Some(_) => Ok("Gacha item successfully created".to_string()),
|
||||||
None => bail!("Failed to create gacha item record"),
|
None => bail!("Failed to create gacha item"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn query_create_gacha_roll(
|
pub async fn query_create_gacha_roll(
|
||||||
&self,
|
&self,
|
||||||
data: GachaCreateItemRequestDto,
|
data: GachaCreateRollRequestDto,
|
||||||
) -> Result<String> {
|
) -> Result<String> {
|
||||||
let db = &self.state.surrealdb;
|
let db = &self.state.surrealdb;
|
||||||
|
let item_thing = Thing::from((
|
||||||
|
ResourceEnum::GachaItems.to_string(),
|
||||||
|
Id::String(data.item_name.clone()),
|
||||||
|
));
|
||||||
|
|
||||||
let record: Option<GachaItemSchema> = db
|
let record: Option<GachaRollSchema> = db
|
||||||
.create((ResourceEnum::Gacha.to_string(), data.item_name.clone()))
|
.create((ResourceEnum::GachaRolls.to_string(), data.item_name.clone()))
|
||||||
.content(GachaItemSchema {
|
.content(GachaRollSchema {
|
||||||
item_name: data.item_name.clone(),
|
weight: data.weight.clone(),
|
||||||
item_image: data.item_image.clone(),
|
item: item_thing,
|
||||||
})
|
})
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
match record {
|
match record {
|
||||||
Some(_) => Ok("Gacha item successfully created".to_string()),
|
Some(_) => Ok("Gacha roll successfully created".to_string()),
|
||||||
None => bail!("Failed to create gacha item record"),
|
None => bail!("Failed to create gacha roll"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,11 +2,17 @@ use serde::{Deserialize, Serialize};
|
|||||||
use surrealdb::sql::Thing;
|
use surrealdb::sql::Thing;
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
pub struct GachaSchema {
|
pub struct GachaClaimSchema {
|
||||||
pub transaction_number: String,
|
pub transaction_number: String,
|
||||||
pub user: Thing,
|
pub user: Thing,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
|
pub struct GachaRollSchema {
|
||||||
|
pub weight: String,
|
||||||
|
pub item: Thing,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
pub struct GachaItemSchema {
|
pub struct GachaItemSchema {
|
||||||
pub item_image: String,
|
pub item_image: String,
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
use super::{GachaClaimRequestDto, GachaCreateItemRequestDto, GachaRepository};
|
use super::{
|
||||||
|
GachaCreateClaimRequestDto, GachaCreateItemRequestDto, GachaCreateRollRequestDto,
|
||||||
|
GachaRepository,
|
||||||
|
};
|
||||||
use crate::{common_response, extract_email, AppState};
|
use crate::{common_response, extract_email, AppState};
|
||||||
use axum::{
|
use axum::{
|
||||||
http::{HeaderMap, StatusCode},
|
http::{HeaderMap, StatusCode},
|
||||||
@@ -8,8 +11,8 @@ use axum::{
|
|||||||
pub struct GachaService;
|
pub struct GachaService;
|
||||||
|
|
||||||
impl GachaService {
|
impl GachaService {
|
||||||
pub async fn mutation_create_gacha_claims(
|
pub async fn mutation_create_gacha_claim(
|
||||||
payload: GachaClaimRequestDto,
|
payload: GachaCreateClaimRequestDto,
|
||||||
state: &AppState,
|
state: &AppState,
|
||||||
header: HeaderMap,
|
header: HeaderMap,
|
||||||
) -> Response {
|
) -> Response {
|
||||||
@@ -25,7 +28,7 @@ impl GachaService {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
match repository.query_create_gacha_claims(payload, email).await {
|
match repository.query_create_gacha_claim(payload, email).await {
|
||||||
Ok(msg) => common_response(StatusCode::CREATED, &msg),
|
Ok(msg) => common_response(StatusCode::CREATED, &msg),
|
||||||
Err(err) => common_response(StatusCode::BAD_REQUEST, &err.to_string()),
|
Err(err) => common_response(StatusCode::BAD_REQUEST, &err.to_string()),
|
||||||
}
|
}
|
||||||
@@ -42,4 +45,16 @@ impl GachaService {
|
|||||||
Err(err) => common_response(StatusCode::BAD_REQUEST, &err.to_string()),
|
Err(err) => common_response(StatusCode::BAD_REQUEST, &err.to_string()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn mutation_create_gacha_roll(
|
||||||
|
payload: GachaCreateRollRequestDto,
|
||||||
|
state: &AppState,
|
||||||
|
) -> Response {
|
||||||
|
let repository = GachaRepository::new(state);
|
||||||
|
|
||||||
|
match repository.query_create_gacha_roll(payload).await {
|
||||||
|
Ok(msg) => common_response(StatusCode::CREATED, &msg),
|
||||||
|
Err(err) => common_response(StatusCode::BAD_REQUEST, &err.to_string()),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,11 +14,15 @@ pub use gacha_service::*;
|
|||||||
pub fn gacha_router() -> Router {
|
pub fn gacha_router() -> Router {
|
||||||
Router::new()
|
Router::new()
|
||||||
.route(
|
.route(
|
||||||
"/create/claims",
|
"/create/claim",
|
||||||
post(gacha_controller::post_create_gacha_claims),
|
post(gacha_controller::post_create_gacha_claim),
|
||||||
)
|
)
|
||||||
.route(
|
.route(
|
||||||
"/create/item",
|
"/create/item",
|
||||||
post(gacha_controller::post_create_gacha_item),
|
post(gacha_controller::post_create_gacha_item),
|
||||||
)
|
)
|
||||||
|
.route(
|
||||||
|
"/create/roll",
|
||||||
|
post(gacha_controller::post_create_gacha_roll),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,4 +5,5 @@ use utoipa::ToSchema;
|
|||||||
pub struct UsersItemDto {
|
pub struct UsersItemDto {
|
||||||
pub email: String,
|
pub email: String,
|
||||||
pub fullname: String,
|
pub fullname: String,
|
||||||
|
pub is_active: bool,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,4 +6,5 @@ pub struct UsersSchema {
|
|||||||
pub email: String,
|
pub email: String,
|
||||||
pub fullname: String,
|
pub fullname: String,
|
||||||
pub password: String,
|
pub password: String,
|
||||||
|
pub is_active: bool,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,8 +13,7 @@ pub mod error {
|
|||||||
|
|
||||||
impl IntoResponse for Error {
|
impl IntoResponse for Error {
|
||||||
fn into_response(self) -> Response {
|
fn into_response(self) -> Response {
|
||||||
(StatusCode::INTERNAL_SERVER_ERROR, Json(self.to_string()))
|
(StatusCode::INTERNAL_SERVER_ERROR, Json(self.to_string())).into_response()
|
||||||
.into_response()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -47,16 +47,13 @@ impl Env {
|
|||||||
.unwrap_or_else(|_| "no-reply@example.com".to_string()),
|
.unwrap_or_else(|_| "no-reply@example.com".to_string()),
|
||||||
smtp_password: env::var("SMTP_PASSWORD")
|
smtp_password: env::var("SMTP_PASSWORD")
|
||||||
.unwrap_or_else(|_| "default_smtp_password".to_string()),
|
.unwrap_or_else(|_| "default_smtp_password".to_string()),
|
||||||
smtp_name: env::var("SMTP_NAME")
|
smtp_name: env::var("SMTP_NAME").unwrap_or_else(|_| "MyApp SMTP".to_string()),
|
||||||
.unwrap_or_else(|_| "MyApp SMTP".to_string()),
|
|
||||||
smtp_host: env::var("SMTP_HOST")
|
smtp_host: env::var("SMTP_HOST")
|
||||||
.unwrap_or_else(|_| "smtp.gmail.com".to_string()),
|
.unwrap_or_else(|_| "smtp.gmail.com".to_string()),
|
||||||
redisdb_url: env::var("REDISDB_URL")
|
redisdb_url: env::var("REDISDB_URL")
|
||||||
.unwrap_or_else(|_| "localhost".to_string()),
|
.unwrap_or_else(|_| "localhost".to_string()),
|
||||||
fe_url: env::var("FE_URL")
|
fe_url: env::var("FE_URL").unwrap_or_else(|_| "http://localhost".to_string()),
|
||||||
.unwrap_or_else(|_| "http://localhost".to_string()),
|
rust_env: env::var("RUST_ENV").unwrap_or_else(|_| "development".to_string()),
|
||||||
rust_env: env::var("RUST_ENV")
|
|
||||||
.unwrap_or_else(|_| "development".to_string()),
|
|
||||||
minio_endpoint: env::var("MINIO_ENDPOINT")
|
minio_endpoint: env::var("MINIO_ENDPOINT")
|
||||||
.unwrap_or_else(|_| "http://localhost:9000".to_string()),
|
.unwrap_or_else(|_| "http://localhost:9000".to_string()),
|
||||||
minio_bucket_name: env::var("MINIO_BUCKET_NAME")
|
minio_bucket_name: env::var("MINIO_BUCKET_NAME")
|
||||||
|
|||||||
@@ -2,11 +2,13 @@ use std::fmt;
|
|||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub enum ResourceEnum {
|
pub enum ResourceEnum {
|
||||||
Gacha,
|
GachaItems,
|
||||||
GachaClaims,
|
GachaClaims,
|
||||||
|
GachaRolls,
|
||||||
Users,
|
Users,
|
||||||
Roles,
|
Roles,
|
||||||
Permissions,
|
Permissions,
|
||||||
|
RolesPermissions,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for ResourceEnum {
|
impl fmt::Display for ResourceEnum {
|
||||||
@@ -15,8 +17,10 @@ impl fmt::Display for ResourceEnum {
|
|||||||
ResourceEnum::Users => "app_users",
|
ResourceEnum::Users => "app_users",
|
||||||
ResourceEnum::Roles => "app_roles",
|
ResourceEnum::Roles => "app_roles",
|
||||||
ResourceEnum::Permissions => "app_permissions",
|
ResourceEnum::Permissions => "app_permissions",
|
||||||
ResourceEnum::Gacha => "app_gacha",
|
ResourceEnum::RolesPermissions => "app_roles_permissions",
|
||||||
|
ResourceEnum::GachaItems => "app_gacha_items",
|
||||||
ResourceEnum::GachaClaims => "app_gacha_claims",
|
ResourceEnum::GachaClaims => "app_gacha_claims",
|
||||||
|
ResourceEnum::GachaRolls => "app_gacha_rolls",
|
||||||
};
|
};
|
||||||
write!(f, "{}", str)
|
write!(f, "{}", str)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user