Skip to main content

openlark_workflow/v1/task/
complete.rs

1//! 完成任务(v1)
2//!
3//! docPath: https://open.feishu.cn/document/server-docs/docs/task-v1/task/complete
4
5use openlark_core::{
6    api::{ApiRequest, ApiResponseTrait, ResponseFormat},
7    config::Config,
8    SDKResult,
9};
10use serde::{Deserialize, Serialize};
11use std::sync::Arc;
12
13/// 完成任务请求体(v1)
14#[derive(Debug, Clone, Serialize, Default)]
15pub struct CompleteTaskBodyV1 {
16    /// 完成时间(可选)
17    #[serde(skip_serializing_if = "Option::is_none")]
18    pub completed_at: Option<String>,
19}
20
21/// 完成任务响应(v1)
22#[derive(Debug, Clone, Deserialize)]
23pub struct CompleteTaskResponseV1 {
24    /// 任务 ID
25    pub id: String,
26    /// 任务标题
27    pub summary: String,
28    /// 任务是否完成
29    pub is_completed: bool,
30    /// 完成时间
31    #[serde(default)]
32    pub completed_at: Option<String>,
33}
34
35/// 完成任务请求(v1)
36#[derive(Debug, Clone)]
37pub struct CompleteTaskRequestV1 {
38    config: Arc<Config>,
39    task_id: String,
40    body: CompleteTaskBodyV1,
41}
42
43impl CompleteTaskRequestV1 {
44    pub fn new(config: Arc<Config>, task_id: impl Into<String>) -> Self {
45        Self {
46            config,
47            task_id: task_id.into(),
48            body: CompleteTaskBodyV1::default(),
49        }
50    }
51
52    /// 设置完成时间
53    pub fn completed_at(mut self, completed_at: impl Into<String>) -> Self {
54        self.body.completed_at = Some(completed_at.into());
55        self
56    }
57
58    /// 执行请求
59    pub async fn execute(self) -> SDKResult<CompleteTaskResponseV1> {
60        self.execute_with_options(openlark_core::req_option::RequestOption::default())
61            .await
62    }
63
64    /// 执行请求(带选项)
65    pub async fn execute_with_options(
66        self,
67        option: openlark_core::req_option::RequestOption,
68    ) -> SDKResult<CompleteTaskResponseV1> {
69        let api_endpoint = crate::common::api_endpoints::TaskApiV1::TaskComplete(self.task_id);
70        let mut request = ApiRequest::<CompleteTaskResponseV1>::post(api_endpoint.to_url());
71
72        let body_json = serde_json::to_value(&self.body).map_err(|e| {
73            openlark_core::error::validation_error("序列化请求体失败", e.to_string().as_str())
74        })?;
75
76        request = request.body(body_json);
77
78        let response =
79            openlark_core::http::Transport::request(request, &self.config, Some(option)).await?;
80        response.data.ok_or_else(|| {
81            openlark_core::error::validation_error("响应数据为空", "服务器没有返回有效的数据")
82        })
83    }
84}
85
86impl ApiResponseTrait for CompleteTaskResponseV1 {
87    fn data_format() -> ResponseFormat {
88        ResponseFormat::Data
89    }
90}
91
92#[cfg(test)]
93#[allow(unused_imports)]
94mod tests {
95    use std::sync::Arc;
96
97    use super::*;
98
99    #[test]
100    fn test_complete_task_v1_builder() {
101        let config = Arc::new(
102            openlark_core::config::Config::builder()
103                .app_id("test")
104                .app_secret("test")
105                .build(),
106        );
107
108        let request =
109            CompleteTaskRequestV1::new(config, "test_task_id").completed_at("2024-01-15T10:00:00Z");
110
111        assert_eq!(request.task_id, "test_task_id");
112        assert_eq!(
113            request.body.completed_at,
114            Some("2024-01-15T10:00:00Z".to_string())
115        );
116    }
117
118    #[test]
119    fn test_task_api_v1_complete_url() {
120        let endpoint =
121            crate::common::api_endpoints::TaskApiV1::TaskComplete("task_123".to_string());
122        assert_eq!(
123            endpoint.to_url(),
124            "/open-apis/task/v1/tasks/task_123/complete"
125        );
126    }
127}