Skip to main content

tdm_server_rust/repository/
evaluation_repo.rs

1//! 评价数据访问层 (Evaluation Repository)
2//!
3//! 封装 `evaluation` 表的增删改查(SeaORM)。
4
5use crate::db::DbConn;
6use crate::entity::evaluation::Evaluation;
7use crate::sea_entity::evaluation;
8use chrono::{DateTime, Utc};
9use sea_orm::{
10    ActiveModelTrait, ColumnTrait, DatabaseConnection, EntityTrait, QueryFilter, QueryOrder, Set,
11};
12use sqlx::postgres::PgPool;
13
14/// 评价仓储
15pub struct EvaluationRepository {
16    /// SeaORM 数据库连接
17    db: DbConn,
18}
19
20impl EvaluationRepository {
21    /// 从 `PgPool` 构造
22    pub fn new(pool: PgPool) -> Self {
23        Self {
24            db: crate::db::from_sqlx_pool(pool),
25        }
26    }
27
28    /// 从 `DatabaseConnection` 构造
29    pub fn from_db(db: DatabaseConnection) -> Self {
30        Self { db }
31    }
32
33    /// 新增评价
34    #[tracing::instrument(skip_all, level = "debug")]
35    pub async fn insert(&self, eval: &Evaluation) -> crate::error::ApiResult<i64> {
36        let member_id = eval
37            .member_id
38            .ok_or_else(|| crate::error::AppError::business("member_id 不能为空"))?
39            as i64;
40        let evaluator_id = eval
41            .evaluator_id
42            .ok_or_else(|| crate::error::AppError::business("evaluator_id 不能为空"))?
43            as i64;
44        let target = eval
45            .target
46            .as_deref()
47            .ok_or_else(|| crate::error::AppError::business("target 不能为空"))?;
48        let evaluator = eval
49            .evaluator
50            .as_deref()
51            .ok_or_else(|| crate::error::AppError::business("evaluator 不能为空"))?;
52        let now = chrono::Utc::now().naive_utc();
53        let model = evaluation::ActiveModel {
54            member_id: Set(member_id),
55            target: Set(target.to_string()),
56            evaluator_id: Set(evaluator_id),
57            evaluator: Set(evaluator.to_string()),
58            role_type: Set(eval.role_type),
59            content: Set(eval.content.clone()),
60            evaluation_time: Set(now),
61            created_at: Set(now),
62            updated_at: Set(now),
63            ..Default::default()
64        };
65        let inserted = model.insert(&self.db).await?;
66        Ok(inserted.id)
67    }
68
69    /// 按 ID 查询评价
70    #[tracing::instrument(skip_all, level = "debug")]
71    pub async fn get_by_id(&self, id: i64) -> crate::error::ApiResult<Option<Evaluation>> {
72        let row = evaluation::Entity::find_by_id(id).one(&self.db).await?;
73        Ok(row.map(model_to_evaluation))
74    }
75
76    /// 条件筛选评价列表
77    #[tracing::instrument(skip_all, level = "debug")]
78    pub async fn select_by_filter(
79        &self,
80        member_id: Option<i32>,
81        evaluator_id: Option<i32>,
82        start_time: Option<DateTime<Utc>>,
83        end_time: Option<DateTime<Utc>>,
84    ) -> crate::error::ApiResult<Vec<Evaluation>> {
85        let mut q = evaluation::Entity::find();
86        if let Some(v) = member_id {
87            q = q.filter(evaluation::Column::MemberId.eq(v as i64));
88        }
89        if let Some(v) = evaluator_id {
90            q = q.filter(evaluation::Column::EvaluatorId.eq(v as i64));
91        }
92        if let Some(v) = start_time {
93            q = q.filter(evaluation::Column::EvaluationTime.gte(v.naive_utc()));
94        }
95        if let Some(v) = end_time {
96            q = q.filter(evaluation::Column::EvaluationTime.lte(v.naive_utc()));
97        }
98        let rows = q
99            .order_by_desc(evaluation::Column::EvaluationTime)
100            .all(&self.db)
101            .await?;
102        Ok(rows.into_iter().map(model_to_evaluation).collect())
103    }
104
105    /// 更新评价
106    #[tracing::instrument(skip_all, level = "debug")]
107    pub async fn update(&self, eval: &Evaluation) -> crate::error::ApiResult<()> {
108        let id = eval
109            .id
110            .ok_or_else(|| crate::error::AppError::business("id 不能为空"))?;
111        let member_id = eval
112            .member_id
113            .ok_or_else(|| crate::error::AppError::business("member_id 不能为空"))?
114            as i64;
115        let target = eval
116            .target
117            .as_deref()
118            .ok_or_else(|| crate::error::AppError::business("target 不能为空"))?;
119        let model = evaluation::ActiveModel {
120            id: Set(id),
121            member_id: Set(member_id),
122            target: Set(target.to_string()),
123            role_type: Set(eval.role_type),
124            content: Set(eval.content.clone()),
125            updated_at: Set(chrono::Utc::now().naive_utc()),
126            ..Default::default()
127        };
128        model.update(&self.db).await?;
129        Ok(())
130    }
131
132    /// 按 ID 删除评价
133    #[tracing::instrument(skip_all, level = "debug")]
134    pub async fn delete_by_id(&self, id: i64) -> crate::error::ApiResult<()> {
135        evaluation::Entity::delete_by_id(id).exec(&self.db).await?;
136        Ok(())
137    }
138}
139
140/// SeaORM Model 映射为评价 DTO
141fn model_to_evaluation(m: evaluation::Model) -> Evaluation {
142    Evaluation {
143        id: Some(m.id),
144        member_id: Some(m.member_id as i32),
145        target: Some(m.target),
146        evaluator_id: Some(m.evaluator_id as i32),
147        evaluator: Some(m.evaluator),
148        role_type: m.role_type,
149        content: m.content,
150        evaluation_time: Some(m.evaluation_time.and_utc()),
151        created_at: Some(m.created_at.and_utc()),
152        updated_at: Some(m.updated_at.and_utc()),
153    }
154}