Skip to main content

openlark_workflow/v1/task/
create.rs

1//! 创建任务(v1)
2//!
3//! docPath: https://open.feishu.cn/document/server-docs/docs/task-v1/task/create
4
5use openlark_core::{
6    api::{ApiRequest, ApiResponseTrait, ResponseFormat},
7    config::Config,
8    validate_required, SDKResult,
9};
10use serde::{Deserialize, Serialize};
11use std::sync::Arc;
12
13/// 创建任务请求体(v1)
14#[derive(Debug, Clone, Serialize, Default)]
15pub struct CreateTaskBodyV1 {
16    /// 任务标题
17    pub summary: String,
18
19    /// 任务描述
20    #[serde(skip_serializing_if = "Option::is_none")]
21    pub description: Option<String>,
22
23    /// 任务开始时间
24    #[serde(skip_serializing_if = "Option::is_none")]
25    pub start: Option<String>,
26
27    /// 任务截止时间
28    #[serde(skip_serializing_if = "Option::is_none")]
29    pub due: Option<String>,
30
31    /// 任务优先级(1-5)
32    #[serde(skip_serializing_if = "Option::is_none")]
33    pub priority: Option<i32>,
34}
35
36/// 创建任务响应(v1)
37#[derive(Debug, Clone, Deserialize)]
38pub struct CreateTaskResponseV1 {
39    /// 任务 GUID
40    pub task_guid: String,
41
42    /// 任务标题
43    pub summary: String,
44}
45
46/// 创建任务请求(v1)
47#[derive(Debug, Clone)]
48pub struct CreateTaskRequestV1 {
49    config: Arc<Config>,
50    body: CreateTaskBodyV1,
51}
52
53impl CreateTaskRequestV1 {
54    pub fn new(config: Arc<Config>) -> Self {
55        Self {
56            config,
57            body: CreateTaskBodyV1::default(),
58        }
59    }
60
61    /// 设置任务标题
62    pub fn summary(mut self, summary: impl Into<String>) -> Self {
63        self.body.summary = summary.into();
64        self
65    }
66
67    /// 设置任务描述
68    pub fn description(mut self, description: impl Into<String>) -> Self {
69        self.body.description = Some(description.into());
70        self
71    }
72
73    /// 设置任务开始时间
74    pub fn start(mut self, start: impl Into<String>) -> Self {
75        self.body.start = Some(start.into());
76        self
77    }
78
79    /// 设置任务截止时间
80    pub fn due(mut self, due: impl Into<String>) -> Self {
81        self.body.due = Some(due.into());
82        self
83    }
84
85    /// 设置任务优先级(1-5)
86    pub fn priority(mut self, priority: i32) -> Self {
87        self.body.priority = Some(priority);
88        self
89    }
90
91    /// 执行请求
92    pub async fn execute(self) -> SDKResult<CreateTaskResponseV1> {
93        self.execute_with_options(openlark_core::req_option::RequestOption::default())
94            .await
95    }
96
97    /// 执行请求(带选项)
98    pub async fn execute_with_options(
99        self,
100        option: openlark_core::req_option::RequestOption,
101    ) -> SDKResult<CreateTaskResponseV1> {
102        validate_required!(self.body.summary.trim(), "任务标题不能为空");
103
104        let api_endpoint = crate::common::api_endpoints::TaskApiV1::TaskCreate;
105        let mut request = ApiRequest::<CreateTaskResponseV1>::post(api_endpoint.to_url());
106
107        let body_json = serde_json::to_value(&self.body).map_err(|e| {
108            openlark_core::error::validation_error("序列化请求体失败", e.to_string().as_str())
109        })?;
110
111        request = request.body(body_json);
112
113        let response =
114            openlark_core::http::Transport::request(request, &self.config, Some(option)).await?;
115        response.data.ok_or_else(|| {
116            openlark_core::error::validation_error("响应数据为空", "服务器没有返回有效的数据")
117        })
118    }
119}
120
121impl ApiResponseTrait for CreateTaskResponseV1 {
122    fn data_format() -> ResponseFormat {
123        ResponseFormat::Data
124    }
125}
126
127#[cfg(test)]
128#[allow(unused_imports)]
129mod tests {
130    use std::sync::Arc;
131
132    use super::*;
133
134    #[test]
135    fn test_create_task_v1_builder() {
136        let config = Arc::new(
137            openlark_core::config::Config::builder()
138                .app_id("test")
139                .app_secret("test")
140                .build(),
141        );
142
143        let request = CreateTaskRequestV1::new(config)
144            .summary("测试任务")
145            .description("任务描述")
146            .priority(3);
147
148        assert_eq!(request.body.summary, "测试任务");
149        assert_eq!(request.body.description, Some("任务描述".to_string()));
150        assert_eq!(request.body.priority, Some(3));
151    }
152
153    #[test]
154    fn test_task_api_v1_url() {
155        let endpoint = crate::common::api_endpoints::TaskApiV1::TaskCreate;
156        assert_eq!(endpoint.to_url(), "/open-apis/task/v1/tasks");
157    }
158}