This commit is contained in:
parent
8791aee96c
commit
7a64171b96
@ -62,8 +62,10 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_md5() {
|
||||
let input = "hello";
|
||||
// let input = "hello";
|
||||
let input = "joylink0503";
|
||||
let output = md5(input);
|
||||
assert_eq!(output, "5d41402abc4b2a76b9719d911017c592");
|
||||
println!("{}", output);
|
||||
// assert_eq!(output, "5d41402abc4b2a76b9719d911017c592");
|
||||
}
|
||||
}
|
||||
|
@ -29,6 +29,10 @@ fn main() {
|
||||
"common.DataType",
|
||||
"#[derive(sqlx::Type, async_graphql::Enum, serde::Serialize, serde::Deserialize)]",
|
||||
)
|
||||
.type_attribute(
|
||||
"common.LineType",
|
||||
"#[derive(async_graphql::Enum, serde::Serialize, serde::Deserialize)]",
|
||||
)
|
||||
.type_attribute(
|
||||
"common.IscsStyle",
|
||||
"#[derive(async_graphql::Enum, serde::Serialize, serde::Deserialize)]",
|
||||
|
@ -199,6 +199,56 @@ impl DataType {
|
||||
}
|
||||
}
|
||||
}
|
||||
/// 线路类型
|
||||
#[derive(
|
||||
async_graphql::Enum,
|
||||
serde::Serialize,
|
||||
serde::Deserialize,
|
||||
Clone,
|
||||
Copy,
|
||||
Debug,
|
||||
PartialEq,
|
||||
Eq,
|
||||
Hash,
|
||||
PartialOrd,
|
||||
Ord,
|
||||
::prost::Enumeration,
|
||||
)]
|
||||
#[repr(i32)]
|
||||
pub enum LineType {
|
||||
/// 未知
|
||||
Unknown = 0,
|
||||
/// 城市轨道交通
|
||||
Ur = 1,
|
||||
/// 城际轨道交通
|
||||
Ir = 2,
|
||||
/// 市域轨道交通
|
||||
Cr = 3,
|
||||
}
|
||||
impl LineType {
|
||||
/// String value of the enum field names used in the ProtoBuf definition.
|
||||
///
|
||||
/// The values are not transformed in any way and thus are considered stable
|
||||
/// (if the ProtoBuf definition does not change) and safe for programmatic use.
|
||||
pub fn as_str_name(&self) -> &'static str {
|
||||
match self {
|
||||
LineType::Unknown => "LineType_Unknown",
|
||||
LineType::Ur => "LineType_Ur",
|
||||
LineType::Ir => "LineType_Ir",
|
||||
LineType::Cr => "LineType_Cr",
|
||||
}
|
||||
}
|
||||
/// Creates an enum from field names used in the ProtoBuf definition.
|
||||
pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
|
||||
match value {
|
||||
"LineType_Unknown" => Some(Self::Unknown),
|
||||
"LineType_Ur" => Some(Self::Ur),
|
||||
"LineType_Ir" => Some(Self::Ir),
|
||||
"LineType_Cr" => Some(Self::Cr),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
#[derive(
|
||||
async_graphql::Enum,
|
||||
serde::Serialize,
|
||||
|
@ -1,16 +1,28 @@
|
||||
use async_graphql::{InputObject, InputType, OutputType, SimpleObject};
|
||||
use rtsa_db::{common::TableColumn, model::DraftDataColumn};
|
||||
use rtsa_dto::common::IscsStyle;
|
||||
use rtsa_dto::common::{IscsStyle, LineType};
|
||||
use serde::{de::DeserializeOwned, Deserialize, Serialize};
|
||||
use serde_json::Value;
|
||||
|
||||
pub trait DataOptions: InputType + OutputType + Serialize + DeserializeOwned {
|
||||
fn to_data_options_filter_clause(&self) -> String;
|
||||
}
|
||||
|
||||
impl DataOptions for Value {
|
||||
// impl DataOptions for Value {
|
||||
// fn to_data_options_filter_clause(&self) -> String {
|
||||
// format!("{} @> '{}'", DraftDataColumn::Options.name(), self)
|
||||
// }
|
||||
// }
|
||||
|
||||
impl<T> DataOptions for T
|
||||
where
|
||||
T: ?Sized + Serialize + DeserializeOwned + OutputType + InputType,
|
||||
{
|
||||
fn to_data_options_filter_clause(&self) -> String {
|
||||
format!("{} @> '{}'", DraftDataColumn::Options.name(), self)
|
||||
format!(
|
||||
"{} @> '{}'",
|
||||
DraftDataColumn::Options.name(),
|
||||
serde_json::to_string(self).unwrap()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -20,14 +32,14 @@ pub struct IscsDataOptions {
|
||||
pub style: IscsStyle,
|
||||
}
|
||||
|
||||
impl DataOptions for IscsDataOptions {
|
||||
fn to_data_options_filter_clause(&self) -> String {
|
||||
let options_column = DraftDataColumn::Options.name();
|
||||
format!(
|
||||
"{options_column} @> '{}'",
|
||||
serde_json::to_string(self).unwrap()
|
||||
)
|
||||
}
|
||||
#[derive(Debug, Clone, InputObject, SimpleObject, Serialize, Deserialize)]
|
||||
#[graphql(input_name = "LineInfoOptionsInput")]
|
||||
pub struct LineInfoOptions {
|
||||
pub line_type: LineType,
|
||||
/// 城轨线路所属城市
|
||||
pub city: Option<String>,
|
||||
/// 城轨线路编号
|
||||
pub line_code: Option<String>,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -11,7 +11,7 @@ use serde_json::Value;
|
||||
use crate::apis::{PageDto, PageQueryDto};
|
||||
use crate::loader::RtsaDbLoader;
|
||||
|
||||
use super::data_options_def::{DataOptions, IscsDataOptions};
|
||||
use super::data_options_def::{DataOptions, IscsDataOptions, LineInfoOptions};
|
||||
use super::release_data::ReleaseDataId;
|
||||
use super::user::UserId;
|
||||
|
||||
@ -39,6 +39,37 @@ impl DraftDataQuery {
|
||||
.await?;
|
||||
Ok(paging_result.into())
|
||||
}
|
||||
/// 分页查询用户电子地图草稿数据
|
||||
#[graphql(guard = "RoleGuard::new(Role::User)")]
|
||||
async fn user_draft_em_data_paging<'ctx>(
|
||||
&self,
|
||||
ctx: &Context<'ctx>,
|
||||
paging: PageQueryDto,
|
||||
mut query: UserDraftDataFilterDto<LineInfoOptions>,
|
||||
) -> async_graphql::Result<PageDto<DraftEmDataDto>> {
|
||||
let claims = ctx.data::<Jwt>()?.decode()?;
|
||||
query = query.with_data_type_and_user_id(DataType::Em, claims.uid);
|
||||
let db_accessor = ctx.data::<RtsaDbAccessor>()?;
|
||||
let paging_result = db_accessor
|
||||
.paging_query_draft_data(query.into(), paging.into())
|
||||
.await?;
|
||||
Ok(paging_result.into())
|
||||
}
|
||||
/// 分页查询共享的草稿电子地图数据
|
||||
#[graphql(guard = "RoleGuard::new(Role::User)")]
|
||||
async fn shared_draft_em_data_paging<'ctx>(
|
||||
&self,
|
||||
ctx: &Context<'ctx>,
|
||||
paging: PageQueryDto,
|
||||
mut query: DraftDataFilterDto<LineInfoOptions>,
|
||||
) -> async_graphql::Result<PageDto<DraftEmDataDto>> {
|
||||
let db_accessor = ctx.data::<RtsaDbAccessor>()?;
|
||||
query.data_type = Some(DataType::Em);
|
||||
let paging_result = db_accessor
|
||||
.paging_query_draft_data(query.into(), paging.into())
|
||||
.await?;
|
||||
Ok(paging_result.into())
|
||||
}
|
||||
/// 分页查询用户的草稿ISCS数据
|
||||
#[graphql(guard = "RoleGuard::new(Role::User)")]
|
||||
async fn user_draft_iscs_data_paging<'ctx>(
|
||||
@ -48,8 +79,7 @@ impl DraftDataQuery {
|
||||
mut query: UserDraftDataFilterDto<IscsDataOptions>,
|
||||
) -> async_graphql::Result<PageDto<DraftIscsDataDto>> {
|
||||
let claims = ctx.data::<Jwt>()?.decode()?;
|
||||
query.user_id = claims.uid;
|
||||
query.data_type = Some(DataType::Iscs);
|
||||
query = query.with_data_type_and_user_id(DataType::Iscs, claims.uid);
|
||||
let db_accessor = ctx.data::<RtsaDbAccessor>()?;
|
||||
let paging_result = db_accessor
|
||||
.paging_query_draft_data(query.into(), paging.into())
|
||||
@ -98,6 +128,20 @@ impl DraftDataQuery {
|
||||
|
||||
#[Object]
|
||||
impl DraftDataMutation {
|
||||
/// 创建电子地图草稿数据
|
||||
#[graphql(guard = "RoleGuard::new(Role::User)")]
|
||||
async fn create_draft_em_data(
|
||||
&self,
|
||||
ctx: &Context<'_>,
|
||||
mut input: CreateDraftDataDto<LineInfoOptions>,
|
||||
) -> async_graphql::Result<DraftDataDto> {
|
||||
let claims = ctx.data::<Jwt>()?.decode()?;
|
||||
input = input.with_data_type_and_user_id(DataType::Em, claims.uid);
|
||||
let db_accessor = ctx.data::<RtsaDbAccessor>()?;
|
||||
let draft_data = db_accessor.create_draft_data(input.into()).await?;
|
||||
Ok(draft_data.into())
|
||||
}
|
||||
|
||||
/// 创建草稿ISCS数据
|
||||
#[graphql(guard = "RoleGuard::new(Role::User)")]
|
||||
async fn create_draft_iscs_data(
|
||||
@ -194,6 +238,7 @@ impl DraftDataMutation {
|
||||
|
||||
#[derive(Debug, InputObject)]
|
||||
#[graphql(concrete(name = "CreateDraftIscsDto", params(IscsDataOptions)))]
|
||||
#[graphql(concrete(name = "CreateDraftEmDto", params(LineInfoOptions)))]
|
||||
pub struct CreateDraftDataDto<T: DataOptions> {
|
||||
#[graphql(skip)]
|
||||
pub data_type: Option<DataType>,
|
||||
@ -228,6 +273,7 @@ impl<T: DataOptions> From<CreateDraftDataDto<T>> for rtsa_db::CreateDraftData {
|
||||
|
||||
/// 用户的草稿数据查询条件
|
||||
#[derive(Debug, InputObject)]
|
||||
#[graphql(concrete(name = "UserDraftEmDataFilterDto", params(LineInfoOptions)))]
|
||||
#[graphql(concrete(name = "UserDraftIscsDataFilterDto", params(IscsDataOptions)))]
|
||||
pub struct UserDraftDataFilterDto<T: DataOptions> {
|
||||
#[graphql(skip)]
|
||||
@ -239,6 +285,14 @@ pub struct UserDraftDataFilterDto<T: DataOptions> {
|
||||
pub is_shared: Option<bool>,
|
||||
}
|
||||
|
||||
impl<T: DataOptions> UserDraftDataFilterDto<T> {
|
||||
pub fn with_data_type_and_user_id(mut self, data_type: DataType, id: i32) -> Self {
|
||||
self.data_type = Some(data_type);
|
||||
self.user_id = id;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: DataOptions> From<UserDraftDataFilterDto<T>> for rtsa_db::DraftDataQuery {
|
||||
fn from(value: UserDraftDataFilterDto<T>) -> Self {
|
||||
Self {
|
||||
@ -254,6 +308,7 @@ impl<T: DataOptions> From<UserDraftDataFilterDto<T>> for rtsa_db::DraftDataQuery
|
||||
/// 共享的草稿数据查询条件
|
||||
#[derive(Debug, InputObject)]
|
||||
#[graphql(concrete(name = "DraftDataFilterDto", params(Value)))]
|
||||
#[graphql(concrete(name = "SharedDraftEmDataFilterDto", params(LineInfoOptions)))]
|
||||
#[graphql(concrete(name = "SharedDraftIscsDataFilterDto", params(IscsDataOptions)))]
|
||||
|
||||
pub struct DraftDataFilterDto<T: DataOptions> {
|
||||
@ -336,6 +391,26 @@ impl From<rtsa_db::model::DraftDataModel> for DraftDataDto {
|
||||
}
|
||||
}
|
||||
|
||||
/// 草稿电子地图数据
|
||||
#[derive(Debug, SimpleObject)]
|
||||
pub struct DraftEmDataDto {
|
||||
pub draft_data: DraftDataDto,
|
||||
pub options: Option<LineInfoOptions>,
|
||||
}
|
||||
|
||||
impl From<rtsa_db::model::DraftDataModel> for DraftEmDataDto {
|
||||
fn from(value: rtsa_db::model::DraftDataModel) -> Self {
|
||||
Self {
|
||||
options: value
|
||||
.options
|
||||
.clone()
|
||||
.map(|o| serde_json::from_value(o).unwrap()),
|
||||
draft_data: value.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// ISCS草稿数据
|
||||
#[derive(Debug, SimpleObject)]
|
||||
pub struct DraftIscsDataDto {
|
||||
pub draft_data: DraftDataDto,
|
||||
|
@ -67,6 +67,7 @@ impl From<PageQueryDto> for rtsa_db::common::PageQuery {
|
||||
#[derive(Debug, SimpleObject)]
|
||||
#[graphql(concrete(name = "UserPageDto", params(user::UserDto)))]
|
||||
#[graphql(concrete(name = "DraftDataPageDto", params(draft_data::DraftDataDto)))]
|
||||
#[graphql(concrete(name = "DraftEmDataPageDto", params(draft_data::DraftEmDataDto)))]
|
||||
#[graphql(concrete(name = "DraftIscsDataPageDto", params(draft_data::DraftIscsDataDto)))]
|
||||
#[graphql(concrete(name = "ReleaseDataPageDto", params(release_data::ReleaseDataDto)))]
|
||||
#[graphql(concrete(
|
||||
|
@ -72,6 +72,13 @@ mod tests {
|
||||
assert_eq!(org.name, DEFAULT_ORG_NAME);
|
||||
assert_eq!(org.creator_id, user.id);
|
||||
|
||||
let user = db_accessor
|
||||
.query_user_login(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
|
||||
.await?;
|
||||
assert_eq!(user.username, ADMIN_USER_NAME);
|
||||
assert_eq!(user.nickname, ADMIN_USER_NAME);
|
||||
assert_eq!(user.roles, json!([Role::Admin]));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
use async_graphql::Guard;
|
||||
use rtsa_db::prelude::*;
|
||||
use rtsa_dto::common::Role;
|
||||
use rtsa_log::tracing::{info, warn};
|
||||
use rtsa_log::tracing::{error, info, warn};
|
||||
use serde_json::json;
|
||||
|
||||
mod jwt_auth;
|
||||
@ -113,9 +113,24 @@ pub(crate) async fn handle_login(
|
||||
))
|
||||
}
|
||||
}
|
||||
_ => Err(BusinessError::AuthError(
|
||||
DbAccessError::PasswordNotMatch => {
|
||||
warn!(
|
||||
"密码不匹配: username={}, password={}, org_id={}",
|
||||
user_login_dto.username, user_login_dto.password, org_id
|
||||
);
|
||||
Err(BusinessError::AuthError(
|
||||
"用户不存在或密码不正确".to_string(),
|
||||
)),
|
||||
))
|
||||
}
|
||||
_ => {
|
||||
error!(
|
||||
"查询用户登录验证错误: username={}, org_id={}, error={:?}",
|
||||
user_login_dto.username, org_id, e
|
||||
);
|
||||
Err(BusinessError::AuthError(
|
||||
"用户不存在或密码不正确".to_string(),
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 867c075833ffbe64b0291db921adddc9d5d5a7a3
|
||||
Subproject commit a30bf52339620075e8d666be363eb3d93d532656
|
Loading…
Reference in New Issue
Block a user