Skip to main content

tdm_server_rust/service/
questionnaire_service.rs

1//! 接稿意愿问卷服务 (Questionnaire Service)
2//!
3//! 组员提交/更新接稿偏好问卷,支持按岗位/意愿/篇幅等多维筛选。
4
5use crate::{
6    app::AppState, entity::questionnaire::Questionnaire, error::ApiResult,
7    repository::questionnaire_repo::QuestionnaireRepository,
8};
9
10/// 问卷服务
11pub struct QuestionnaireService;
12
13impl QuestionnaireService {
14    /// 条件列表查询
15    #[tracing::instrument(skip_all, level = "debug")]
16    pub async fn list_all(
17        state: &AppState,
18        post_id: Option<i32>,
19        willingness: Option<i32>,
20        length: Option<String>,
21        frequency: Option<i32>,
22        member_id: Option<i32>,
23    ) -> ApiResult<Vec<Questionnaire>> {
24        let repo = QuestionnaireRepository::new(state.db.clone());
25        let w = willingness.map(|v| v as i16);
26        let f = frequency.map(|v| v as i16);
27        let list = if let Some(pid) = post_id {
28            repo.list_by_post(pid, w, length.as_deref(), f, member_id)
29                .await?
30        } else {
31            repo.list_all(w, length.as_deref(), f, member_id).await?
32        };
33        let member_ids: Vec<i32> = list.iter().filter_map(|q| q.member_id).collect();
34        let assigned_times = repo.select_last_assigned_times(&member_ids).await?;
35        let mut result = Vec::with_capacity(list.len());
36        for mut q in list {
37            if let Some(mid) = q.member_id {
38                q.last_assigned_time = assigned_times.get(&mid).copied();
39            }
40            result.push(q);
41        }
42        Ok(result)
43    }
44
45    /// 按组员 ID 查询问卷
46    #[tracing::instrument(skip_all, level = "debug")]
47    pub async fn get_by_member_id(
48        state: &AppState,
49        member_id: i32,
50    ) -> ApiResult<Option<Questionnaire>> {
51        let repo = QuestionnaireRepository::new(state.db.clone());
52        let mut q = repo.get_by_member_id(member_id).await?;
53        if let Some(ref mut item) = q {
54            item.last_assigned_time = repo.select_last_assigned_time(member_id).await?;
55        }
56        Ok(q)
57    }
58
59    /// 提交或更新问卷
60    #[tracing::instrument(skip_all, level = "debug")]
61    pub async fn submit(
62        state: &AppState,
63        member_id: i32,
64        mut questionnaire: Questionnaire,
65    ) -> ApiResult<Questionnaire> {
66        let repo = QuestionnaireRepository::new(state.db.clone());
67        questionnaire.member_id = Some(member_id);
68        if let Some(existing) = repo.get_by_member_id(member_id).await? {
69            questionnaire.id = existing.id;
70            repo.update(&questionnaire).await?;
71        } else {
72            let id = repo.insert(&questionnaire).await?;
73            questionnaire.id = Some(id);
74        }
75        questionnaire.last_assigned_time = repo.select_last_assigned_time(member_id).await?;
76        Ok(questionnaire)
77    }
78}