open_lark/service/cloud_docs/bitable/v1/app_table_view/
create.rs

1use reqwest::Method;
2use serde::{Deserialize, Serialize};
3
4use crate::{
5    core::{
6        api_req::ApiRequest,
7        api_resp::{ApiResponseTrait, BaseResponse, ResponseFormat},
8        constants::AccessTokenType,
9        endpoints::cloud_docs::*,
10        http::Transport,
11        req_option::RequestOption,
12        SDKResult,
13    },
14    impl_executable_builder_owned,
15};
16
17use super::AppTableViewService;
18
19impl AppTableViewService {
20    /// 新增视图
21    pub async fn create(
22        &self,
23        request: CreateViewRequest,
24        option: Option<RequestOption>,
25    ) -> SDKResult<BaseResponse<CreateViewResponse>> {
26        let mut api_req = request.api_request;
27        api_req.http_method = Method::POST;
28        api_req.api_path = BITABLE_V1_VIEW_CREATE
29            .replace("{app_token}", &request.app_token)
30            .replace("{table_id}", &request.table_id);
31        api_req.supported_access_token_types = vec![AccessTokenType::Tenant, AccessTokenType::User];
32        api_req.body = serde_json::to_vec(&CreateViewRequestBody { view: request.view })?;
33
34        let api_resp = Transport::request(api_req, &self.config, option).await?;
35        Ok(api_resp)
36    }
37}
38
39/// 新增视图请求
40#[derive(Debug, Default)]
41pub struct CreateViewRequest {
42    api_request: ApiRequest,
43    /// 多维表格的 app_token
44    app_token: String,
45    /// 数据表的 table_id
46    table_id: String,
47    /// 视图信息
48    view: ViewData,
49}
50
51impl CreateViewRequest {
52    pub fn builder() -> CreateViewRequestBuilder {
53        CreateViewRequestBuilder::default()
54    }
55
56    /// 创建新增视图请求
57    pub fn new(app_token: impl ToString, table_id: impl ToString, view: ViewData) -> Self {
58        Self {
59            api_request: ApiRequest::default(),
60            app_token: app_token.to_string(),
61            table_id: table_id.to_string(),
62            view,
63        }
64    }
65}
66
67#[derive(Default)]
68pub struct CreateViewRequestBuilder {
69    request: CreateViewRequest,
70}
71
72impl CreateViewRequestBuilder {
73    /// 多维表格的 app_token
74    pub fn app_token(mut self, app_token: impl ToString) -> Self {
75        self.request.app_token = app_token.to_string();
76        self
77    }
78
79    /// 数据表的 table_id
80    pub fn table_id(mut self, table_id: impl ToString) -> Self {
81        self.request.table_id = table_id.to_string();
82        self
83    }
84
85    /// 视图信息
86    pub fn view(mut self, view: ViewData) -> Self {
87        self.request.view = view;
88        self
89    }
90
91    pub fn build(self) -> CreateViewRequest {
92        self.request
93    }
94}
95
96impl_executable_builder_owned!(
97    CreateViewRequestBuilder,
98    super::AppTableViewService,
99    CreateViewRequest,
100    BaseResponse<CreateViewResponse>,
101    create
102);
103
104/// 视图数据
105#[derive(Debug, Clone, Default, Serialize, Deserialize)]
106pub struct ViewData {
107    /// 视图名称
108    pub view_name: String,
109    /// 视图类型,可选值:grid (表格视图)、kanban (看板视图)、gallery (画册视图)、gantt (甘特视图)
110    #[serde(skip_serializing_if = "Option::is_none")]
111    pub view_type: Option<String>,
112    /// 视图的自定义属性,当前支持的视图自定义属性参考视图类型
113    #[serde(skip_serializing_if = "Option::is_none")]
114    pub property: Option<serde_json::Value>,
115}
116
117impl ViewData {
118    /// 创建视图数据
119    pub fn new(view_name: impl ToString) -> Self {
120        Self {
121            view_name: view_name.to_string(),
122            view_type: None,
123            property: None,
124        }
125    }
126
127    /// 创建表格视图
128    pub fn grid_view(view_name: impl ToString) -> Self {
129        Self {
130            view_name: view_name.to_string(),
131            view_type: Some("grid".to_string()),
132            property: None,
133        }
134    }
135
136    /// 创建看板视图
137    pub fn kanban_view(view_name: impl ToString) -> Self {
138        Self {
139            view_name: view_name.to_string(),
140            view_type: Some("kanban".to_string()),
141            property: None,
142        }
143    }
144
145    /// 创建画册视图
146    pub fn gallery_view(view_name: impl ToString) -> Self {
147        Self {
148            view_name: view_name.to_string(),
149            view_type: Some("gallery".to_string()),
150            property: None,
151        }
152    }
153
154    /// 创建甘特视图
155    pub fn gantt_view(view_name: impl ToString) -> Self {
156        Self {
157            view_name: view_name.to_string(),
158            view_type: Some("gantt".to_string()),
159            property: None,
160        }
161    }
162
163    /// 设置视图类型
164    pub fn with_view_type(mut self, view_type: impl ToString) -> Self {
165        self.view_type = Some(view_type.to_string());
166        self
167    }
168
169    /// 设置视图属性
170    pub fn with_property(mut self, property: serde_json::Value) -> Self {
171        self.property = Some(property);
172        self
173    }
174}
175
176#[derive(Serialize)]
177struct CreateViewRequestBody {
178    view: ViewData,
179}
180
181#[derive(Deserialize, Debug)]
182pub struct CreateViewResponse {
183    /// 视图 ID
184    pub view_id: String,
185}
186
187impl ApiResponseTrait for CreateViewResponse {
188    fn data_format() -> ResponseFormat {
189        ResponseFormat::Data
190    }
191}
192
193#[cfg(test)]
194#[allow(unused_variables, unused_unsafe)]
195mod tests {
196    use super::*;
197    use serde_json::json;
198
199    #[test]
200    fn test_create_view_request() {
201        let view = ViewData::grid_view("测试表格视图");
202        let request = CreateViewRequest::builder()
203            .app_token("bascnmBA*****yGehy8")
204            .table_id("tblsRc9GRRXKqhvW")
205            .view(view)
206            .build();
207
208        assert_eq!(request.app_token, "bascnmBA*****yGehy8");
209        assert_eq!(request.table_id, "tblsRc9GRRXKqhvW");
210        assert_eq!(request.view.view_name, "测试表格视图");
211        assert_eq!(request.view.view_type, Some("grid".to_string()));
212    }
213
214    #[test]
215    fn test_view_data_types() {
216        let grid_view = ViewData::grid_view("表格视图");
217        assert_eq!(grid_view.view_type, Some("grid".to_string()));
218
219        let kanban_view = ViewData::kanban_view("看板视图");
220        assert_eq!(kanban_view.view_type, Some("kanban".to_string()));
221
222        let gallery_view = ViewData::gallery_view("画册视图");
223        assert_eq!(gallery_view.view_type, Some("gallery".to_string()));
224
225        let gantt_view = ViewData::gantt_view("甘特视图");
226        assert_eq!(gantt_view.view_type, Some("gantt".to_string()));
227    }
228
229    #[test]
230    fn test_view_data_with_property() {
231        let view = ViewData::new("自定义视图")
232            .with_view_type("grid")
233            .with_property(json!({
234                "filter_info": {
235                    "conditions": []
236                }
237            }));
238
239        assert_eq!(view.view_name, "自定义视图");
240        assert_eq!(view.view_type, Some("grid".to_string()));
241        assert!(view.property.is_some());
242    }
243}