feat(ws-org): add org_id scoping across ws entities
Add org_id fields and migrations for course, section, lianxi, piyue, and jihua/daka data paths, and enforce organization-scoped filtering in ws service queries. Made-with: Cursor
This commit is contained in:
+51
-15
@@ -71,6 +71,9 @@ pub async fn raw_create_course(
|
||||
let user_id = hty_token
|
||||
.hty_id
|
||||
.ok_or_else(|| anyhow!("hty_id is required"))?;
|
||||
let current_org_id = hty_token
|
||||
.current_org_id
|
||||
.ok_or_else(|| anyhow!("current_org_id is required"))?;
|
||||
|
||||
let req_course = in_req_course.clone();
|
||||
if req_course.course_type.is_none() || req_course.course_name.is_none() {
|
||||
@@ -89,6 +92,7 @@ pub async fn raw_create_course(
|
||||
created_by: Some(user_id.clone()),
|
||||
created_at: Some(current_local_datetime()),
|
||||
is_delete: Some(false),
|
||||
org_id: Some(current_org_id),
|
||||
};
|
||||
Course::create(&in_course, extract_conn(fetch_db_conn(&db_pool)?).deref_mut())?
|
||||
.to_req(extract_conn(fetch_db_conn(&db_pool)?).deref_mut())
|
||||
@@ -272,6 +276,7 @@ pub fn convert_course_sections_to_req_course_sections_for_jihua_daka_scenario(
|
||||
updated_by: c_course_section.updated_by.clone(),
|
||||
updated_by_realname: None,
|
||||
teachers: c_course_section.teachers.clone(),
|
||||
org_id: c_course_section.org_id.clone(),
|
||||
};
|
||||
|
||||
Ok(out_section)
|
||||
@@ -407,6 +412,7 @@ reason: Some("scenario must be DAKA or JIHUA".into()),
|
||||
resources: out_resources,
|
||||
course_category_key: c_course_section.course_category_key,
|
||||
course_category_name: c_course_section.course_category_name,
|
||||
org_id: c_course_section.org_id.clone(),
|
||||
};
|
||||
|
||||
Ok(out_section)
|
||||
@@ -669,6 +675,9 @@ pub async fn raw_create_course_section(
|
||||
) -> anyhow::Result<ReqCourseSection> {
|
||||
let token = HtyToken::from_jwt(auth.clone().deref())?;
|
||||
let user_id = token.hty_id.ok_or_else(|| anyhow!("hty_id is required"))?;
|
||||
let current_org_id = token
|
||||
.current_org_id
|
||||
.ok_or_else(|| anyhow!("current_org_id is required"))?;
|
||||
|
||||
let mut in_section = CourseSection::from(&req_course_section)?;
|
||||
|
||||
@@ -684,6 +693,7 @@ pub async fn raw_create_course_section(
|
||||
in_section.created_by = user_id.clone();
|
||||
in_section.updated_at = Some(current_local_datetime());
|
||||
in_section.updated_by = Some(user_id.clone());
|
||||
in_section.org_id = Some(current_org_id);
|
||||
|
||||
if let Some(course_id) = &some_in_course_id {
|
||||
let inner_course =
|
||||
@@ -754,11 +764,12 @@ pub async fn raw_create_course_section(
|
||||
|
||||
pub async fn update_piyue(
|
||||
_root: HtySudoerTokenHeader,
|
||||
auth: AuthorizationHeader,
|
||||
State(db_pool): State<Arc<DbState>>,
|
||||
Json(in_piyue): Json<ReqPiyue>,
|
||||
) -> Json<HtyResponse<String>> {
|
||||
debug!("update_piyue -> starts");
|
||||
match raw_update_piyue(&in_piyue, db_pool).await {
|
||||
match raw_update_piyue(&auth, &in_piyue, db_pool).await {
|
||||
Ok(ok) => {
|
||||
debug!("update_piyue -> success to update piyue, e: {}", ok);
|
||||
wrap_json_ok_resp(ok)
|
||||
@@ -771,10 +782,14 @@ pub async fn update_piyue(
|
||||
}
|
||||
|
||||
pub async fn raw_update_piyue(
|
||||
auth: &AuthorizationHeader,
|
||||
req_piyue: &ReqPiyue,
|
||||
db_pool: Arc<DbState>,
|
||||
) -> anyhow::Result<String> {
|
||||
let c_piyue = req_piyue.clone();
|
||||
let current_org_id = jwt_decode_token(&(*auth).clone())?
|
||||
.current_org_id
|
||||
.ok_or_else(|| anyhow!("current_org_id is required"))?;
|
||||
|
||||
let in_piyue = Piyue {
|
||||
id: c_piyue.id.ok_or_else(|| anyhow!("id is required"))?,
|
||||
@@ -788,6 +803,7 @@ pub async fn raw_update_piyue(
|
||||
rating: c_piyue.rating,
|
||||
created_at: c_piyue.created_at,
|
||||
is_delete: c_piyue.is_delete,
|
||||
org_id: Some(current_org_id.clone()),
|
||||
};
|
||||
|
||||
let req_piyue_infos = req_piyue
|
||||
@@ -811,6 +827,7 @@ pub async fn raw_update_piyue(
|
||||
serial: c_each_piyue_info.serial,
|
||||
created_at: c_each_piyue_info.created_at,
|
||||
is_delete: c_each_piyue_info.is_delete,
|
||||
org_id: Some(current_org_id.clone()),
|
||||
})
|
||||
})
|
||||
.collect();
|
||||
@@ -1364,11 +1381,12 @@ pub async fn create_piyue(
|
||||
|
||||
// deprecated
|
||||
pub async fn raw_create_piyue(
|
||||
_root: HtySudoerTokenHeader,
|
||||
root: HtySudoerTokenHeader,
|
||||
_host: HtyHostHeader,
|
||||
req_piyue: &ReqPiyue,
|
||||
db_pool: Arc<DbState>,
|
||||
) -> anyhow::Result<String> {
|
||||
let current_org_id = required_current_org_id_from_token_str(&root.0)?;
|
||||
let req_piyue_copy = req_piyue.clone();
|
||||
let the_lianxi_id = req_piyue_copy
|
||||
.lianxi_id
|
||||
@@ -1384,6 +1402,7 @@ pub async fn raw_create_piyue(
|
||||
rating: req_piyue_copy.rating,
|
||||
created_at: Some(current_local_datetime()),
|
||||
is_delete: Some(false),
|
||||
org_id: Some(current_org_id.clone()),
|
||||
};
|
||||
|
||||
let res_piyue = Piyue::create(
|
||||
@@ -1391,8 +1410,9 @@ pub async fn raw_create_piyue(
|
||||
extract_conn(fetch_db_conn(&db_pool)?).deref_mut(),
|
||||
)?;
|
||||
|
||||
let mut the_lianxi = Lianxi::find_by_id(
|
||||
let mut the_lianxi = Lianxi::find_by_id_in_org(
|
||||
&the_lianxi_id,
|
||||
¤t_org_id,
|
||||
extract_conn(fetch_db_conn(&db_pool)?).deref_mut(),
|
||||
)?;
|
||||
the_lianxi.has_piyue = Some(true);
|
||||
@@ -1460,6 +1480,7 @@ pub async fn raw_create_piyue(
|
||||
serial: c_req_piyue_info.serial.clone(),
|
||||
created_at: Some(current_local_datetime()),
|
||||
is_delete: Some(false),
|
||||
org_id: Some(current_org_id.clone()),
|
||||
};
|
||||
|
||||
let resp_piyue_info = PiyueInfo::create(&piyue_info, conn)?;
|
||||
@@ -1528,11 +1549,12 @@ pub async fn create_piyue2(
|
||||
}
|
||||
|
||||
pub fn raw_create_piyue2(
|
||||
_root: HtySudoerTokenHeader,
|
||||
root: HtySudoerTokenHeader,
|
||||
_host: HtyHostHeader,
|
||||
req_piyue: &ReqPiyue2,
|
||||
db_pool: Arc<DbState>,
|
||||
) -> anyhow::Result<String> {
|
||||
let current_org_id = required_current_org_id_from_token_str(&root.0)?;
|
||||
let req_piyue_copy = req_piyue.clone();
|
||||
|
||||
debug!("raw_create_piyue2 -> req_piyue {:?}", req_piyue);
|
||||
@@ -1543,8 +1565,9 @@ pub fn raw_create_piyue2(
|
||||
.ok_or_else(|| anyhow!("lianxi_id is required"))?;
|
||||
|
||||
// https://github.com/alchemy-studio/huiwing/issues/1290
|
||||
let some_existing_piyue = Piyue::find_first_by_lianxi_id(
|
||||
let some_existing_piyue = Piyue::find_first_by_lianxi_id_in_org(
|
||||
&the_lianxi_id.clone(),
|
||||
¤t_org_id,
|
||||
extract_conn(fetch_db_conn(&db_pool)?).deref_mut(),
|
||||
)?;
|
||||
|
||||
@@ -1568,6 +1591,7 @@ pub fn raw_create_piyue2(
|
||||
rating: req_piyue_copy.rating.clone(),
|
||||
created_at: Some(current_local_datetime()),
|
||||
is_delete: Some(false),
|
||||
org_id: Some(current_org_id.clone()),
|
||||
};
|
||||
|
||||
debug!("raw_create_piyue2 -> in_piyue {:?}", in_piyue);
|
||||
@@ -1577,8 +1601,9 @@ pub fn raw_create_piyue2(
|
||||
extract_conn(fetch_db_conn(&db_pool)?).deref_mut(),
|
||||
)?;
|
||||
|
||||
let mut the_lianxi = Lianxi::find_by_id(
|
||||
let mut the_lianxi = Lianxi::find_by_id_in_org(
|
||||
&the_lianxi_id,
|
||||
¤t_org_id,
|
||||
extract_conn(fetch_db_conn(&db_pool)?).deref_mut(),
|
||||
)?;
|
||||
the_lianxi.has_piyue = Some(true);
|
||||
@@ -2029,6 +2054,7 @@ pub async fn raw_update_course(
|
||||
created_by: token.hty_id,
|
||||
created_at: Some(current_local_datetime()),
|
||||
is_delete: req_course.is_delete.clone(),
|
||||
org_id: token.current_org_id.clone(),
|
||||
};
|
||||
|
||||
let updated_course = Course::update(
|
||||
@@ -2392,6 +2418,7 @@ pub async fn raw_find_course_by_id(
|
||||
created_at: resp_course.created_at,
|
||||
task: None,
|
||||
is_delete: resp_course.is_delete,
|
||||
org_id: resp_course.org_id,
|
||||
};
|
||||
|
||||
Ok(req_course)
|
||||
@@ -3812,12 +3839,11 @@ pub async fn raw_find_all_courses(
|
||||
auth: &AuthorizationHeader,
|
||||
db_pool: Arc<DbState>,
|
||||
) -> anyhow::Result<Vec<ReqCourseWithSections>> {
|
||||
let current_user = jwt_decode_token(&(*auth).clone())?
|
||||
.hty_id
|
||||
.ok_or_else(|| anyhow!("hty_id is required"))?;
|
||||
|
||||
let courses = Course::find_all_active_by_created_by(
|
||||
¤t_user,
|
||||
let current_org_id = jwt_decode_token(&(*auth).clone())?
|
||||
.current_org_id
|
||||
.ok_or_else(|| anyhow!("current_org_id is required"))?;
|
||||
let courses = Course::find_all_course_in_org(
|
||||
¤t_org_id,
|
||||
extract_conn(fetch_db_conn(&db_pool)?).deref_mut(),
|
||||
)?;
|
||||
|
||||
@@ -3832,6 +3858,7 @@ pub async fn raw_find_all_courses(
|
||||
created_at: course_item.created_at.clone(),
|
||||
task: None,
|
||||
is_delete: course_item.is_delete.clone(),
|
||||
org_id: course_item.org_id.clone(),
|
||||
})
|
||||
.collect();
|
||||
Ok(result)
|
||||
@@ -3840,10 +3867,11 @@ pub async fn raw_find_all_courses(
|
||||
// #[get("/find_all_course_sections")]
|
||||
pub async fn find_all_course_sections(
|
||||
_root: HtySudoerTokenHeader,
|
||||
auth: AuthorizationHeader,
|
||||
State(db_pool): State<Arc<DbState>>,
|
||||
) -> Json<HtyResponse<Vec<ReqCourseSection>>> {
|
||||
debug!("find_all_course_sections -> starts");
|
||||
match raw_find_all_course_sections(db_pool).await {
|
||||
match raw_find_all_course_sections(&auth, db_pool).await {
|
||||
Ok(sections) => wrap_json_ok_resp(sections),
|
||||
Err(e) => {
|
||||
error!(
|
||||
@@ -3856,10 +3884,16 @@ pub async fn find_all_course_sections(
|
||||
}
|
||||
|
||||
pub async fn raw_find_all_course_sections(
|
||||
auth: &AuthorizationHeader,
|
||||
db_pool: Arc<DbState>,
|
||||
) -> anyhow::Result<Vec<ReqCourseSection>> {
|
||||
let sections =
|
||||
CourseSection::find_all_active_sections(extract_conn(fetch_db_conn(&db_pool)?).deref_mut())?;
|
||||
let current_org_id = jwt_decode_token(&(*auth).clone())?
|
||||
.current_org_id
|
||||
.ok_or_else(|| anyhow!("current_org_id is required"))?;
|
||||
let sections = CourseSection::find_all_active_sections_in_org(
|
||||
¤t_org_id,
|
||||
extract_conn(fetch_db_conn(&db_pool)?).deref_mut(),
|
||||
)?;
|
||||
let any_req_sections: Vec<anyhow::Result<ReqCourseSection>> = sections
|
||||
.iter()
|
||||
.map(|section| {
|
||||
@@ -3912,6 +3946,7 @@ pub async fn raw_find_all_course_sections(
|
||||
updated_by: section.updated_by.clone(),
|
||||
updated_by_realname: None,
|
||||
teachers: section.teachers.clone(),
|
||||
org_id: section.org_id.clone(),
|
||||
})
|
||||
})
|
||||
.collect();
|
||||
@@ -4218,6 +4253,7 @@ pub async fn raw_find_all_course_sections_by_created_by_with_page(
|
||||
updated_by: section.updated_by.clone(),
|
||||
updated_by_realname: None,
|
||||
teachers: section.teachers.clone(),
|
||||
org_id: section.org_id.clone(),
|
||||
})
|
||||
})
|
||||
.collect();
|
||||
|
||||
+73
-17
@@ -14,6 +14,7 @@ use htycommons::common::{
|
||||
HtyErrCode, HtyResponse,
|
||||
};
|
||||
use htycommons::db::{exec_read_write_task, extract_conn, fetch_db_conn, DbState};
|
||||
use htycommons::jwt::jwt_decode_token;
|
||||
use htycommons::uuid;
|
||||
use htycommons::web::{
|
||||
wrap_json_anyhow_err, wrap_json_ok_resp, AuthorizationHeader, HtyHostHeader,
|
||||
@@ -30,6 +31,12 @@ use std::ops::DerefMut;
|
||||
use std::sync::Arc;
|
||||
use tracing::{debug, error};
|
||||
|
||||
fn required_current_org_id_from_sudoer_token_str(token_str: &String) -> anyhow::Result<String> {
|
||||
jwt_decode_token(token_str)?
|
||||
.current_org_id
|
||||
.ok_or_else(|| anyhow!("current_org_id is required"))
|
||||
}
|
||||
|
||||
pub async fn create_daka(
|
||||
root: HtySudoerTokenHeader,
|
||||
host: HtyHostHeader,
|
||||
@@ -54,6 +61,9 @@ pub async fn raw_create_daka(
|
||||
db_pool: Arc<DbState>,
|
||||
in_req_daka: &ReqDakaWithCourseSectionIds,
|
||||
) -> anyhow::Result<String> {
|
||||
let current_org_id = jwt_decode_token(&(*_token).clone())?
|
||||
.current_org_id
|
||||
.ok_or_else(|| anyhow!("current_org_id is required"))?;
|
||||
let req_daka = in_req_daka.clone();
|
||||
if req_daka.start_date.is_none()
|
||||
|| req_daka.duration_days.is_none()
|
||||
@@ -120,6 +130,7 @@ pub async fn raw_create_daka(
|
||||
students: req_daka.students.clone(),
|
||||
course_sections: req_daka.course_sections.clone(),
|
||||
is_yanqi: req_daka.is_yanqi.clone(),
|
||||
org_id: Some(current_org_id),
|
||||
};
|
||||
|
||||
let mut params = HashMap::new();
|
||||
@@ -168,6 +179,7 @@ pub fn raw_create_daka_tx(
|
||||
course_section_id: in_section_id,
|
||||
meta: Some(meta_data.clone()),
|
||||
is_delete: false,
|
||||
org_id: result_daka.org_id.clone(),
|
||||
};
|
||||
debug!("START CREATE DAKA QUMU SECTION -> {:?}", §ion);
|
||||
let created_section = DakaCourseSection::create(§ion, conn)?;
|
||||
@@ -220,8 +232,12 @@ pub async fn raw_find_daka_by_id2(
|
||||
db_pool: Arc<DbState>,
|
||||
) -> anyhow::Result<ReqDakaWithCourseSections2> {
|
||||
debug!("raw_find_daka_by_id2 -> {:?}", id);
|
||||
|
||||
let daka = Daka::find_by_id(&id, extract_conn(fetch_db_conn(&db_pool)?).deref_mut())?;
|
||||
let current_org_id = required_current_org_id_from_sudoer_token_str(&root.0)?;
|
||||
let daka = Daka::find_by_id_in_org(
|
||||
&id,
|
||||
¤t_org_id,
|
||||
extract_conn(fetch_db_conn(&db_pool)?).deref_mut(),
|
||||
)?;
|
||||
|
||||
debug!("raw_find_daka_by_id2 -> daka: {:?}", id);
|
||||
|
||||
@@ -262,11 +278,17 @@ pub async fn raw_find_daka_by_id2(
|
||||
let any_relations: Vec<anyhow::Result<ReqDakaCourseSection>> = the_course_sections
|
||||
.iter()
|
||||
.map(|course_section| {
|
||||
let in_jihua_course_section = DakaCourseSection::find_by_daka_id_and_course_section_id(
|
||||
&daka.id,
|
||||
&course_section.id,
|
||||
extract_conn(fetch_db_conn(&db_pool)?).deref_mut(),
|
||||
)?;
|
||||
let daka_org_id = daka
|
||||
.org_id
|
||||
.as_ref()
|
||||
.ok_or_else(|| anyhow!("daka.org_id is required"))?;
|
||||
let in_jihua_course_section =
|
||||
DakaCourseSection::find_by_daka_id_and_course_section_id_in_org(
|
||||
&daka.id,
|
||||
&course_section.id,
|
||||
daka_org_id,
|
||||
extract_conn(fetch_db_conn(&db_pool)?).deref_mut(),
|
||||
)?;
|
||||
Ok(ReqDakaCourseSection {
|
||||
id: Some(in_jihua_course_section.id.clone()),
|
||||
daka_id: None,
|
||||
@@ -348,7 +370,12 @@ pub async fn raw_find_daka_by_id(
|
||||
id: &String,
|
||||
db_pool: Arc<DbState>,
|
||||
) -> anyhow::Result<ReqDakaWithCourseSections> {
|
||||
let daka = Daka::find_by_id(&id, extract_conn(fetch_db_conn(&db_pool)?).deref_mut())?;
|
||||
let current_org_id = required_current_org_id_from_sudoer_token_str(&root.0)?;
|
||||
let daka = Daka::find_by_id_in_org(
|
||||
&id,
|
||||
¤t_org_id,
|
||||
extract_conn(fetch_db_conn(&db_pool)?).deref_mut(),
|
||||
)?;
|
||||
|
||||
let all_lianxis =
|
||||
daka.find_active_belonging_lianxis(extract_conn(fetch_db_conn(&db_pool)?).deref_mut())?;
|
||||
@@ -368,11 +395,17 @@ pub async fn raw_find_daka_by_id(
|
||||
let any_relations: Vec<anyhow::Result<ReqDakaCourseSection>> = the_course_sections
|
||||
.iter()
|
||||
.map(|course_section| {
|
||||
let in_jihua_course_section = DakaCourseSection::find_by_daka_id_and_course_section_id(
|
||||
&daka.id,
|
||||
&course_section.id,
|
||||
extract_conn(fetch_db_conn(&db_pool)?).deref_mut(),
|
||||
)?;
|
||||
let daka_org_id = daka
|
||||
.org_id
|
||||
.as_ref()
|
||||
.ok_or_else(|| anyhow!("daka.org_id is required"))?;
|
||||
let in_jihua_course_section =
|
||||
DakaCourseSection::find_by_daka_id_and_course_section_id_in_org(
|
||||
&daka.id,
|
||||
&course_section.id,
|
||||
daka_org_id,
|
||||
extract_conn(fetch_db_conn(&db_pool)?).deref_mut(),
|
||||
)?;
|
||||
Ok(ReqDakaCourseSection {
|
||||
id: Some(in_jihua_course_section.id.clone()),
|
||||
daka_id: None,
|
||||
@@ -471,6 +504,9 @@ pub async fn raw_update_daka(
|
||||
db_pool: Arc<DbState>,
|
||||
in_req_daka: &ReqDakaWithCourseSectionIds,
|
||||
) -> anyhow::Result<String> {
|
||||
let current_org_id = jwt_decode_token(&(*_token).clone())?
|
||||
.current_org_id
|
||||
.ok_or_else(|| anyhow!("current_org_id is required"))?;
|
||||
let the_req_daka = in_req_daka.clone();
|
||||
let id_daka = the_req_daka
|
||||
.clone()
|
||||
@@ -534,6 +570,7 @@ pub async fn raw_update_daka(
|
||||
db_daka.updated_at = c_req_daka.updated_at.clone();
|
||||
db_daka.course_sections = c_req_daka.course_sections.clone();
|
||||
db_daka.is_yanqi = c_req_daka.is_yanqi.clone();
|
||||
db_daka.org_id = Some(current_org_id.clone());
|
||||
|
||||
debug!("raw_update_daka -> update_daka -> {:?}", &db_daka);
|
||||
|
||||
@@ -596,9 +633,14 @@ pub fn raw_update_daka_course_section_relations(
|
||||
|
||||
// 首先做第一步
|
||||
// todo: 改为逻辑删除后,这里会重复查出来`已删除`关系,后续优化。
|
||||
let current_org_id = in_daka
|
||||
.org_id
|
||||
.clone()
|
||||
.ok_or_else(|| anyhow!("daka.org_id is required"))?;
|
||||
let mut to_delete_relation_ids: Vec<String> = Vec::new();
|
||||
// 查找这个daka的所有course_section_ids,然后跟传入的做比对,把不存在于传入数据的ids放入`to_delete_relation_ids`,然后逻辑删除.
|
||||
let existing_daka_course_sections = DakaCourseSection::find_by_daka_id(daka_id, conn)?;
|
||||
let existing_daka_course_sections =
|
||||
DakaCourseSection::find_by_daka_id_in_org(daka_id, ¤t_org_id, conn)?;
|
||||
debug!(
|
||||
"raw_update_daka_course_section_relations -> existing_daka_course_sections -> {:?}",
|
||||
&existing_daka_course_sections
|
||||
@@ -627,9 +669,10 @@ pub fn raw_update_daka_course_section_relations(
|
||||
|
||||
// 然后做第二步
|
||||
for in_course_section_id in in_course_section_ids.clone() {
|
||||
match DakaCourseSection::find_by_daka_id_and_course_section_id(
|
||||
match DakaCourseSection::find_by_daka_id_and_course_section_id_in_org(
|
||||
&in_daka.id,
|
||||
&in_course_section_id,
|
||||
¤t_org_id,
|
||||
conn,
|
||||
) {
|
||||
Ok(rel) => {
|
||||
@@ -657,6 +700,7 @@ pub fn raw_update_daka_course_section_relations(
|
||||
course_section_id: in_course_section_id.clone(),
|
||||
meta: None,
|
||||
is_delete: false,
|
||||
org_id: in_daka.org_id.clone(),
|
||||
};
|
||||
debug!("raw_update_daka_course_section_relations -> ADDING THIS RELATION -> {:?}", & to_add_rel);
|
||||
let _ = DakaCourseSection::create(&to_add_rel, conn)?;
|
||||
@@ -674,12 +718,12 @@ pub fn raw_update_daka_course_section_relations(
|
||||
}
|
||||
|
||||
pub async fn delete_daka_by_id(
|
||||
_root: HtySudoerTokenHeader,
|
||||
root: HtySudoerTokenHeader,
|
||||
Path(id_delete): Path<String>,
|
||||
State(db_pool): State<Arc<DbState>>,
|
||||
) -> Json<HtyResponse<()>> {
|
||||
debug!("delete_daka_by_id -> start here");
|
||||
match raw_delete_daka_by_id(&id_delete, db_pool).await {
|
||||
match raw_delete_daka_by_id(&root, &id_delete, db_pool).await {
|
||||
Ok(ok) => wrap_json_ok_resp(ok),
|
||||
Err(e) => {
|
||||
error!("delete_daka_by_id -> failed to delete daka, e: {}", e);
|
||||
@@ -689,9 +733,16 @@ pub async fn delete_daka_by_id(
|
||||
}
|
||||
|
||||
pub async fn raw_delete_daka_by_id(
|
||||
root: &HtySudoerTokenHeader,
|
||||
id_delete: &String,
|
||||
db_pool: Arc<DbState>,
|
||||
) -> anyhow::Result<()> {
|
||||
let current_org_id = required_current_org_id_from_sudoer_token_str(&root.0)?;
|
||||
let _ = Daka::find_by_id_in_org(
|
||||
id_delete,
|
||||
¤t_org_id,
|
||||
extract_conn(fetch_db_conn(&db_pool)?).deref_mut(),
|
||||
)?;
|
||||
// 逻辑删除 daka
|
||||
let _ = Daka::logic_delete_by_id(
|
||||
id_delete,
|
||||
@@ -778,6 +829,7 @@ pub async fn raw_find_dakas_with_sections_by_user_id(
|
||||
) -> anyhow::Result<(Vec<ReqDakaWithCourseSections>, i64, i64)> {
|
||||
debug!("raw_find_dakas_with_sections_by_user_id -> START");
|
||||
debug!("raw_find_dakas_with_sections_by_user_id -> teacher_id: {:?} / student_id: {:?} / scope: {:?}", teacher_id, student_id, scope);
|
||||
let current_org_id = required_current_org_id_from_sudoer_token_str(&_root.0)?;
|
||||
|
||||
if (teacher_id.is_some() && student_id.is_some())
|
||||
|| (teacher_id.is_none() && student_id.is_none())
|
||||
@@ -799,6 +851,7 @@ pub async fn raw_find_dakas_with_sections_by_user_id(
|
||||
teacher_id
|
||||
.as_ref()
|
||||
.ok_or_else(|| anyhow!("teacher_id is required"))?,
|
||||
¤t_org_id,
|
||||
page,
|
||||
page_size,
|
||||
extract_conn(fetch_db_conn(&db_pool)?).deref_mut(),
|
||||
@@ -809,6 +862,7 @@ pub async fn raw_find_dakas_with_sections_by_user_id(
|
||||
teacher_id
|
||||
.as_ref()
|
||||
.ok_or_else(|| anyhow!("teacher_id is required"))?,
|
||||
¤t_org_id,
|
||||
page,
|
||||
page_size,
|
||||
start_from,
|
||||
@@ -821,6 +875,7 @@ pub async fn raw_find_dakas_with_sections_by_user_id(
|
||||
teacher_id
|
||||
.as_ref()
|
||||
.ok_or_else(|| anyhow!("teacher_id is required"))?,
|
||||
¤t_org_id,
|
||||
page,
|
||||
page_size,
|
||||
extract_conn(fetch_db_conn(&db_pool)?).deref_mut(),
|
||||
@@ -850,6 +905,7 @@ pub async fn raw_find_dakas_with_sections_by_user_id(
|
||||
|
||||
dakas_with_pages = Daka::find_active_dakas_by_student_id_with_pagination(
|
||||
&id_student,
|
||||
¤t_org_id,
|
||||
page,
|
||||
page_size,
|
||||
extract_conn(fetch_db_conn(&db_pool)?).deref_mut(),
|
||||
|
||||
+68
-17
@@ -12,6 +12,7 @@ use htycommons::common::{
|
||||
HtyErr, HtyErrCode, HtyResponse,
|
||||
};
|
||||
use htycommons::db::{exec_read_write_task, extract_conn, fetch_db_conn, DbState};
|
||||
use htycommons::jwt::jwt_decode_token;
|
||||
use htycommons::uuid;
|
||||
use htycommons::web::{
|
||||
wrap_json_anyhow_err, wrap_json_ok_resp, AuthorizationHeader, HtyHostHeader,
|
||||
@@ -28,6 +29,12 @@ use std::ops::DerefMut;
|
||||
use std::sync::Arc;
|
||||
use tracing::{debug, error};
|
||||
|
||||
fn required_current_org_id_from_sudoer_token_str(token_str: &String) -> anyhow::Result<String> {
|
||||
jwt_decode_token(token_str)?
|
||||
.current_org_id
|
||||
.ok_or_else(|| anyhow!("current_org_id is required"))
|
||||
}
|
||||
|
||||
pub async fn raw_find_jihuas_by_course_section_id(
|
||||
id: String,
|
||||
db_pool: Arc<DbState>,
|
||||
@@ -121,7 +128,12 @@ async fn raw_find_jihua_by_id2(
|
||||
id: &String,
|
||||
db_pool: Arc<DbState>,
|
||||
) -> anyhow::Result<ReqJihua2> {
|
||||
let jihua = Jihua::find_by_id(&id, extract_conn(fetch_db_conn(&db_pool)?).deref_mut())?;
|
||||
let current_org_id = required_current_org_id_from_sudoer_token_str(&root.0)?;
|
||||
let jihua = Jihua::find_by_id_in_org(
|
||||
&id,
|
||||
¤t_org_id,
|
||||
extract_conn(fetch_db_conn(&db_pool)?).deref_mut(),
|
||||
)?;
|
||||
debug!("raw_find_jihua_by_id2 -> {:?}", &jihua);
|
||||
|
||||
// unimplemented!()
|
||||
@@ -148,11 +160,17 @@ async fn raw_find_jihua_by_id2(
|
||||
let any_relations: Vec<anyhow::Result<ReqJihuaCourseSection>> = the_course_sections
|
||||
.iter()
|
||||
.map(|course_section| {
|
||||
let in_jihua_course_section = JihuaCourseSection::find_by_jihua_id_and_course_section_id(
|
||||
&jihua.id,
|
||||
&course_section.id,
|
||||
extract_conn(fetch_db_conn(&db_pool)?).deref_mut(),
|
||||
)?;
|
||||
let jihua_org_id = jihua
|
||||
.org_id
|
||||
.as_ref()
|
||||
.ok_or_else(|| anyhow!("jihua.org_id is required"))?;
|
||||
let in_jihua_course_section =
|
||||
JihuaCourseSection::find_by_jihua_id_and_course_section_id_in_org(
|
||||
&jihua.id,
|
||||
&course_section.id,
|
||||
jihua_org_id,
|
||||
extract_conn(fetch_db_conn(&db_pool)?).deref_mut(),
|
||||
)?;
|
||||
|
||||
Ok(ReqJihuaCourseSection {
|
||||
id: Some(in_jihua_course_section.id.clone()),
|
||||
@@ -204,7 +222,12 @@ async fn raw_find_jihua_by_id(
|
||||
id: &String,
|
||||
db_pool: Arc<DbState>,
|
||||
) -> anyhow::Result<ReqJihua> {
|
||||
let jihua = Jihua::find_by_id(&id, extract_conn(fetch_db_conn(&db_pool)?).deref_mut())?;
|
||||
let current_org_id = required_current_org_id_from_sudoer_token_str(&root.0)?;
|
||||
let jihua = Jihua::find_by_id_in_org(
|
||||
&id,
|
||||
¤t_org_id,
|
||||
extract_conn(fetch_db_conn(&db_pool)?).deref_mut(),
|
||||
)?;
|
||||
debug!("raw_find_jihua_by_id -> {:?}", &jihua);
|
||||
|
||||
// fix: 改为使用数据库字段
|
||||
@@ -229,11 +252,17 @@ async fn raw_find_jihua_by_id(
|
||||
let any_relations: Vec<anyhow::Result<ReqJihuaCourseSection>> = the_course_sections
|
||||
.iter()
|
||||
.map(|course_section| {
|
||||
let in_jihua_course_section = JihuaCourseSection::find_by_jihua_id_and_course_section_id(
|
||||
&jihua.id,
|
||||
&course_section.id,
|
||||
extract_conn(fetch_db_conn(&db_pool)?).deref_mut(),
|
||||
)?;
|
||||
let jihua_org_id = jihua
|
||||
.org_id
|
||||
.as_ref()
|
||||
.ok_or_else(|| anyhow!("jihua.org_id is required"))?;
|
||||
let in_jihua_course_section =
|
||||
JihuaCourseSection::find_by_jihua_id_and_course_section_id_in_org(
|
||||
&jihua.id,
|
||||
&course_section.id,
|
||||
jihua_org_id,
|
||||
extract_conn(fetch_db_conn(&db_pool)?).deref_mut(),
|
||||
)?;
|
||||
|
||||
Ok(ReqJihuaCourseSection {
|
||||
id: Some(in_jihua_course_section.id.clone()),
|
||||
@@ -312,6 +341,9 @@ pub async fn raw_create_jihua(
|
||||
db_pool: Arc<DbState>,
|
||||
in_req_jihua: &ReqJihuaWithCourseSectionIds,
|
||||
) -> anyhow::Result<ReqJihua> {
|
||||
let current_org_id = jwt_decode_token(&(*_token).clone())?
|
||||
.current_org_id
|
||||
.ok_or_else(|| anyhow!("current_org_id is required"))?;
|
||||
let req_jihua = in_req_jihua.clone();
|
||||
let insert_jihua = Jihua {
|
||||
id: uuid(),
|
||||
@@ -339,6 +371,7 @@ pub async fn raw_create_jihua(
|
||||
course_sections: req_jihua.course_sections.clone(),
|
||||
created_by: req_jihua.created_by.clone(),
|
||||
created_at: Some(current_local_datetime()),
|
||||
org_id: Some(current_org_id),
|
||||
};
|
||||
|
||||
debug!("raw_create_jihua -> insert_jihua: {:?}", insert_jihua);
|
||||
@@ -401,6 +434,7 @@ pub fn raw_create_jihua_tx(
|
||||
meta: Some(meta_data.clone()),
|
||||
created_at: Some(current_local_datetime()),
|
||||
is_delete: Some(false),
|
||||
org_id: result_jihua.org_id.clone(),
|
||||
};
|
||||
debug!("START CREATE JIHUA QUMU SECTION -> {:?}", §ion);
|
||||
let created_section = JihuaCourseSection::create(§ion, conn)?;
|
||||
@@ -412,12 +446,12 @@ pub fn raw_create_jihua_tx(
|
||||
}
|
||||
|
||||
pub async fn delete_jihua_by_id(
|
||||
_root: HtySudoerTokenHeader,
|
||||
root: HtySudoerTokenHeader,
|
||||
Path(id_delete): Path<String>,
|
||||
State(db_pool): State<Arc<DbState>>,
|
||||
) -> Json<HtyResponse<Jihua>> {
|
||||
debug!("delete_jihua_by_id -> start here");
|
||||
match raw_delete_jihua_by_id(&id_delete, db_pool).await {
|
||||
match raw_delete_jihua_by_id(&root, &id_delete, db_pool).await {
|
||||
Ok(ok) => wrap_json_ok_resp(ok),
|
||||
Err(e) => {
|
||||
error!("delete_jihua_by_id -> failed to delete jihua, e: {}", e);
|
||||
@@ -427,9 +461,11 @@ pub async fn delete_jihua_by_id(
|
||||
}
|
||||
|
||||
pub async fn raw_delete_jihua_by_id(
|
||||
root: &HtySudoerTokenHeader,
|
||||
id_delete: &String,
|
||||
db_pool: Arc<DbState>,
|
||||
) -> anyhow::Result<Jihua> {
|
||||
let current_org_id = required_current_org_id_from_sudoer_token_str(&root.0)?;
|
||||
// 因为是逻辑删除,这里就不检查了。
|
||||
// let jihua_course_sections = JihuaCourseSection::find_by_jihua_id(id_delete, extract_conn(fetch_db_conn(&db_pool)?).deref_mut())?;
|
||||
//
|
||||
@@ -457,8 +493,9 @@ pub async fn raw_delete_jihua_by_id(
|
||||
// let _ = Jihua::update(&child_jihua, extract_conn(fetch_db_conn(&db_pool)?).deref_mut())?;
|
||||
|
||||
// 需要做的逻辑是把parent jihua的`is_yanqi`给改为`false`
|
||||
let to_delete_jihua = Jihua::find_by_id(
|
||||
let to_delete_jihua = Jihua::find_by_id_in_org(
|
||||
id_delete,
|
||||
¤t_org_id,
|
||||
extract_conn(fetch_db_conn(&db_pool)?).deref_mut(),
|
||||
)?;
|
||||
|
||||
@@ -503,6 +540,9 @@ pub async fn raw_update_jihua(
|
||||
db_pool: Arc<DbState>,
|
||||
in_req_jihua: &ReqJihuaWithCourseSectionIds,
|
||||
) -> anyhow::Result<ReqJihua> {
|
||||
let current_org_id = jwt_decode_token(&(*_token).clone())?
|
||||
.current_org_id
|
||||
.ok_or_else(|| anyhow!("current_org_id is required"))?;
|
||||
let the_req_jihua = in_req_jihua.clone();
|
||||
if the_req_jihua.id.is_none()
|
||||
|| the_req_jihua.start_date.is_none()
|
||||
@@ -579,6 +619,7 @@ pub async fn raw_update_jihua(
|
||||
course_sections: c_req_jihua.course_sections.clone(),
|
||||
created_by: c_req_jihua.created_by.clone(),
|
||||
created_at: c_req_jihua.created_at.clone(),
|
||||
org_id: Some(current_org_id.clone()),
|
||||
};
|
||||
|
||||
debug!("raw_update_jihua -> update_jihua -> {:?}", &update_jihua);
|
||||
@@ -675,6 +716,10 @@ pub fn raw_update_jihua_course_section_relations(
|
||||
.ok_or_else(|| anyhow!("course_section_ids is required"))?; // 这些是传入给我们要保留/添加的关系.
|
||||
|
||||
let mut resp_jihua = in_jihua.to_req(); // 返回数据
|
||||
let current_org_id = in_jihua
|
||||
.org_id
|
||||
.clone()
|
||||
.ok_or_else(|| anyhow!("jihua.org_id is required"))?;
|
||||
|
||||
// *更新逻辑*
|
||||
// 1.把不存在于传入的`in_course_section_ids`,且已有的关系数据删掉(逻辑删除)。
|
||||
@@ -684,7 +729,8 @@ pub fn raw_update_jihua_course_section_relations(
|
||||
// todo: 改为逻辑删除后,这里会重复查出来`已删除`关系,后续优化。
|
||||
let mut to_delete_relation_ids: Vec<String> = Vec::new();
|
||||
// 查找这个jihua的所有course_section_ids,然后跟传入的做比对,把不存在于传入数据的ids放入`to_delete_relation_ids`,然后逻辑删除.
|
||||
let existing_jihua_course_sections = JihuaCourseSection::find_by_jihua_id(jihua_id, conn)?;
|
||||
let existing_jihua_course_sections =
|
||||
JihuaCourseSection::find_by_jihua_id_in_org(jihua_id, ¤t_org_id, conn)?;
|
||||
debug!(
|
||||
"raw_update_jihua_course_section_relations -> existing_jihua_course_sections -> {:?}",
|
||||
&existing_jihua_course_sections
|
||||
@@ -713,9 +759,10 @@ pub fn raw_update_jihua_course_section_relations(
|
||||
|
||||
// 然后做第二步
|
||||
for in_course_section_id in in_course_section_ids.clone() {
|
||||
match JihuaCourseSection::find_by_jihua_id_and_course_section_id(
|
||||
match JihuaCourseSection::find_by_jihua_id_and_course_section_id_in_org(
|
||||
&in_jihua.id,
|
||||
&in_course_section_id,
|
||||
¤t_org_id,
|
||||
conn,
|
||||
) {
|
||||
Ok(rel) => {
|
||||
@@ -744,6 +791,7 @@ pub fn raw_update_jihua_course_section_relations(
|
||||
meta: None,
|
||||
created_at: Some(current_local_datetime()),
|
||||
is_delete: Some(false),
|
||||
org_id: in_jihua.org_id.clone(),
|
||||
};
|
||||
debug!("raw_update_jihua_course_section_relations -> ADDING THIS RELATION -> {:?}", & to_add_rel);
|
||||
let _ = JihuaCourseSection::create(&to_add_rel, conn)?;
|
||||
@@ -879,6 +927,7 @@ pub async fn raw_find_jihuas_with_sections_by_user_id(
|
||||
db_pool: Arc<DbState>,
|
||||
) -> anyhow::Result<(Vec<ReqJihua>, i64, i64)> {
|
||||
debug!("raw_find_jihuas_with_sections_by_user_id -> START");
|
||||
let current_org_id = required_current_org_id_from_sudoer_token_str(&root.0)?;
|
||||
|
||||
if (teacher_id.is_some() && student_id.is_some())
|
||||
|| (teacher_id.is_none() && student_id.is_none())
|
||||
@@ -898,6 +947,7 @@ pub async fn raw_find_jihuas_with_sections_by_user_id(
|
||||
if let Some(t_id) = &teacher_id {
|
||||
jihuas_with_pages = Jihua::find_active_jihuas_by_teacher_id_with_pagination(
|
||||
t_id,
|
||||
¤t_org_id,
|
||||
page,
|
||||
page_size,
|
||||
start_from,
|
||||
@@ -911,6 +961,7 @@ pub async fn raw_find_jihuas_with_sections_by_user_id(
|
||||
student_id
|
||||
.as_ref()
|
||||
.ok_or_else(|| anyhow!("student_id is required"))?,
|
||||
¤t_org_id,
|
||||
page,
|
||||
page_size,
|
||||
start_from,
|
||||
|
||||
+18
-4
@@ -4,6 +4,7 @@ use axum::Json;
|
||||
use axum_macros::debug_handler;
|
||||
use htycommons::common::{current_local_datetime, HtyErr, HtyErrCode, HtyResponse};
|
||||
use htycommons::db::{extract_conn, fetch_db_conn, DbState};
|
||||
use htycommons::jwt::jwt_decode_token;
|
||||
use htycommons::uuid;
|
||||
use htycommons::web::{
|
||||
wrap_json_anyhow_err, wrap_json_ok_resp, HtyHostHeader, HtySudoerTokenHeader,
|
||||
@@ -16,6 +17,12 @@ use std::ops::DerefMut;
|
||||
use std::sync::Arc;
|
||||
use tracing::{debug, error};
|
||||
|
||||
fn required_current_org_id_from_sudoer_token_str(token_str: &String) -> anyhow::Result<String> {
|
||||
jwt_decode_token(token_str)?
|
||||
.current_org_id
|
||||
.ok_or_else(|| anyhow!("current_org_id is required"))
|
||||
}
|
||||
|
||||
pub fn count_lianxi_and_piyue_on_the_fly(all_lianxis: &Vec<Lianxi>) -> (i32, i32) {
|
||||
let count_lianxi = all_lianxis.clone().len() as i32;
|
||||
let not_piyue_count = all_lianxis
|
||||
@@ -53,10 +60,11 @@ pub async fn create_lianxi(
|
||||
|
||||
pub async fn raw_create_lianxi(
|
||||
_host: &HtyHostHeader,
|
||||
_root: &HtySudoerTokenHeader,
|
||||
root: &HtySudoerTokenHeader,
|
||||
in_req_lianxi: &ReqLianxi,
|
||||
db_pool: Arc<DbState>,
|
||||
) -> anyhow::Result<String> {
|
||||
let current_org_id = required_current_org_id_from_sudoer_token_str(&root.0)?;
|
||||
let req_lianxi = in_req_lianxi.clone();
|
||||
|
||||
let mut in_jihua_course_section_id = None;
|
||||
@@ -88,6 +96,7 @@ pub async fn raw_create_lianxi(
|
||||
is_delete: Some(false),
|
||||
created_by: req_lianxi.created_by.clone(),
|
||||
creator_name: req_lianxi.creator_name.clone(),
|
||||
org_id: Some(current_org_id),
|
||||
};
|
||||
|
||||
let res = Lianxi::create(
|
||||
@@ -159,10 +168,11 @@ pub async fn create_lianxi2(
|
||||
|
||||
pub async fn raw_create_lianxi2(
|
||||
_host: &HtyHostHeader,
|
||||
_root: &HtySudoerTokenHeader,
|
||||
root: &HtySudoerTokenHeader,
|
||||
in_req_lianxi: &ReqLianxi2,
|
||||
db_pool: Arc<DbState>,
|
||||
) -> anyhow::Result<String> {
|
||||
let current_org_id = required_current_org_id_from_sudoer_token_str(&root.0)?;
|
||||
let req_lianxi = in_req_lianxi.clone();
|
||||
|
||||
let mut in_jihua_course_section_id = None;
|
||||
@@ -196,6 +206,7 @@ pub async fn raw_create_lianxi2(
|
||||
is_delete: Some(false),
|
||||
created_by: req_lianxi.created_by.clone(),
|
||||
creator_name: req_lianxi.creator_name.clone(),
|
||||
org_id: Some(current_org_id),
|
||||
};
|
||||
|
||||
let some_in_ref_resources = req_lianxi.ref_resources.clone();
|
||||
@@ -429,12 +440,12 @@ pub async fn raw_delete_lianxi_by_id2(
|
||||
|
||||
// deprecated. NO USE
|
||||
pub async fn update_lianxi_by_id(
|
||||
_root: HtySudoerTokenHeader,
|
||||
root: HtySudoerTokenHeader,
|
||||
State(db_pool): State<Arc<DbState>>,
|
||||
Json(in_lianxi): Json<ReqLianxi>,
|
||||
) -> Json<HtyResponse<String>> {
|
||||
debug!("update_lianxi_by_id -> start here");
|
||||
match raw_update_lianxi_by_id(&in_lianxi, db_pool).await {
|
||||
match raw_update_lianxi_by_id(&root, &in_lianxi, db_pool).await {
|
||||
Ok(ok) => {
|
||||
debug!("update_lianxi_by_id -> success to update lianxi {}", ok);
|
||||
wrap_json_ok_resp(ok)
|
||||
@@ -447,9 +458,11 @@ pub async fn update_lianxi_by_id(
|
||||
}
|
||||
|
||||
pub async fn raw_update_lianxi_by_id(
|
||||
root: &HtySudoerTokenHeader,
|
||||
in_req_lianxi: &ReqLianxi,
|
||||
db_pool: Arc<DbState>,
|
||||
) -> anyhow::Result<String> {
|
||||
let current_org_id = required_current_org_id_from_sudoer_token_str(&root.0)?;
|
||||
let req_lianxi = in_req_lianxi.clone();
|
||||
if req_lianxi.jihua_course_section_id.is_none() && req_lianxi.daka_course_section_id.is_none() {
|
||||
return Err(anyhow!(HtyErr {
|
||||
@@ -502,6 +515,7 @@ pub async fn raw_update_lianxi_by_id(
|
||||
is_delete: req_lianxi.is_delete,
|
||||
created_by: req_lianxi.created_by,
|
||||
creator_name: req_lianxi.creator_name,
|
||||
org_id: Some(current_org_id),
|
||||
};
|
||||
let res = Lianxi::update(
|
||||
&update_lianxi,
|
||||
|
||||
Reference in New Issue
Block a user