Skip to main content

tdm_server_rust/service/
questionnaire_service.rs

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