Skip to main content

openlark_platform/app_engine/apaas/v1/user_task/
rollback.rs

1//! 退回人工任务
2//!
3//! 文档: <https://open.feishu.cn/document/apaas-v1/flow/user-task/rollback>
4//! docPath: <https://open.feishu.cn/document/apaas-v1/flow/user-task/rollback>
5
6use openlark_core::{
7    SDKResult,
8    api::{ApiRequest, ApiResponseTrait, ResponseFormat},
9    config::Config,
10    http::Transport,
11    req_option::RequestOption,
12};
13use serde::{Deserialize, Serialize};
14
15/// 退回人工任务 Builder
16#[derive(Debug, Clone)]
17pub struct RollbackTaskRequestBuilder {
18    config: Config,
19    /// 任务 ID
20    task_id: String,
21    /// 退回节点 ID
22    node_id: String,
23    /// 退回原因
24    reason: Option<String>,
25}
26
27impl RollbackTaskRequestBuilder {
28    /// 创建新的 Builder
29    pub fn new(config: Config, task_id: impl Into<String>, node_id: impl Into<String>) -> Self {
30        Self {
31            config,
32            task_id: task_id.into(),
33            node_id: node_id.into(),
34            reason: None,
35        }
36    }
37
38    /// 设置退回原因
39    pub fn reason(mut self, reason: impl Into<String>) -> Self {
40        self.reason = Some(reason.into());
41        self
42    }
43
44    /// 执行请求
45    pub async fn execute(self) -> SDKResult<RollbackTaskResponse> {
46        self.execute_with_options(RequestOption::default()).await
47    }
48
49    /// 使用选项执行请求
50    pub async fn execute_with_options(
51        self,
52        option: RequestOption,
53    ) -> SDKResult<RollbackTaskResponse> {
54        let url = format!("/open-apis/apaas/v1/user_tasks/{}/rollback", self.task_id);
55
56        let request = RollbackTaskRequest {
57            node_id: self.node_id,
58            reason: self.reason,
59        };
60
61        let req: ApiRequest<RollbackTaskResponse> =
62            ApiRequest::post(&url).body(serde_json::to_value(&request)?);
63        Transport::request_typed(req, &self.config, Some(option), "Operation").await
64    }
65}
66
67/// 退回请求
68#[derive(Debug, Clone, Deserialize, Serialize)]
69struct RollbackTaskRequest {
70    /// 退回节点 ID
71    #[serde(rename = "node_id")]
72    node_id: String,
73    /// 退回原因
74    #[serde(rename = "reason", skip_serializing_if = "Option::is_none")]
75    reason: Option<String>,
76}
77
78/// 退回响应
79#[derive(Debug, Clone, Deserialize, Serialize)]
80pub struct RollbackTaskResponse {
81    /// 任务 ID
82    #[serde(rename = "task_id")]
83    pub task_id: String,
84    /// 退回结果
85    #[serde(rename = "result")]
86    pub result: bool,
87    /// 结果消息
88    #[serde(rename = "message")]
89    pub message: String,
90}
91
92impl ApiResponseTrait for RollbackTaskResponse {
93    fn data_format() -> ResponseFormat {
94        ResponseFormat::Data
95    }
96}
97
98/// 旧名兼容别名(将在 v1.0 移除)
99#[deprecated(note = "renamed to RollbackTaskRequestBuilder, will be removed in v1.0 (#271)")]
100pub type RollbackTaskBuilder = RollbackTaskRequestBuilder;
101
102#[cfg(test)]
103mod tests {
104    use super::*;
105
106    /// 端到端:POST .../user_tasks/{id}/rollback → 强类型 RollbackTaskResponse。
107    #[tokio::test]
108    async fn test_rollback_user_task_returns_data_on_success() {
109        use serde_json::json;
110        use wiremock::MockServer;
111        use wiremock::matchers::{method, path};
112        use wiremock::{Mock, ResponseTemplate};
113
114        let server = MockServer::start().await;
115        Mock::given(method("POST"))
116            .and(path("/open-apis/apaas/v1/user_tasks/task_001/rollback"))
117            .respond_with(ResponseTemplate::new(200).set_body_json(json!({
118                "code": 0,
119                "msg": "success",
120                "data": {
121                    "task_id": "task_001",
122                    "result": true,
123                    "message": "退回成功"
124                }
125            })))
126            .mount(&server)
127            .await;
128
129        let config = Config::builder()
130            .app_id("ci_app_id")
131            .app_secret("ci_app_secret")
132            .base_url(server.uri())
133            .enable_token_cache(false)
134            .build();
135
136        let resp = RollbackTaskRequestBuilder::new(config, "task_001", "node_1")
137            .reason("信息需补充")
138            .execute()
139            .await
140            .expect("退回人工任务应成功");
141        assert_eq!(resp.task_id, "task_001");
142        assert!(resp.result);
143        assert_eq!(resp.message, "退回成功");
144
145        let received = server.received_requests().await.unwrap_or_default();
146        assert_eq!(received.len(), 1);
147        assert_eq!(
148            received[0].url.path(),
149            "/open-apis/apaas/v1/user_tasks/task_001/rollback"
150        );
151    }
152}