open_lark/service/cloud_docs/comments/
get.rs

1use reqwest::Method;
2use serde::{Deserialize, Serialize};
3
4use crate::{
5    core::{
6        api_req::ApiRequest,
7        api_resp::{ApiResponseTrait, BaseResponse, ResponseFormat},
8        config::Config,
9        constants::AccessTokenType,
10        http::Transport,
11        req_option::RequestOption,
12        SDKResult,
13    },
14    impl_executable_builder_owned,
15};
16
17use super::list::Comment;
18
19/// 获取全文评论请求
20#[derive(Debug, Serialize, Default, Clone)]
21pub struct GetCommentRequest {
22    #[serde(skip)]
23    api_request: ApiRequest,
24    /// 文档token
25    #[serde(skip)]
26    file_token: String,
27    /// 文档类型:doc、docx、sheet、bitable
28    #[serde(skip)]
29    file_type: String,
30    /// 评论ID
31    #[serde(skip)]
32    comment_id: String,
33    /// 用户ID类型
34    #[serde(skip_serializing_if = "Option::is_none")]
35    user_id_type: Option<String>,
36}
37
38impl GetCommentRequest {
39    pub fn builder() -> GetCommentRequestBuilder {
40        GetCommentRequestBuilder::default()
41    }
42
43    pub fn new(
44        file_token: impl ToString,
45        file_type: impl ToString,
46        comment_id: impl ToString,
47    ) -> Self {
48        Self {
49            file_token: file_token.to_string(),
50            file_type: file_type.to_string(),
51            comment_id: comment_id.to_string(),
52            ..Default::default()
53        }
54    }
55}
56
57#[derive(Default)]
58pub struct GetCommentRequestBuilder {
59    request: GetCommentRequest,
60}
61
62impl GetCommentRequestBuilder {
63    /// 文档token
64    pub fn file_token(mut self, file_token: impl ToString) -> Self {
65        self.request.file_token = file_token.to_string();
66        self
67    }
68
69    /// 文档类型
70    pub fn file_type(mut self, file_type: impl ToString) -> Self {
71        self.request.file_type = file_type.to_string();
72        self
73    }
74
75    /// 设置为文档类型
76    pub fn with_doc_type(mut self) -> Self {
77        self.request.file_type = "doc".to_string();
78        self
79    }
80
81    /// 设置为docx类型
82    pub fn with_docx_type(mut self) -> Self {
83        self.request.file_type = "docx".to_string();
84        self
85    }
86
87    /// 设置为电子表格类型
88    pub fn with_sheet_type(mut self) -> Self {
89        self.request.file_type = "sheet".to_string();
90        self
91    }
92
93    /// 设置为多维表格类型
94    pub fn with_bitable_type(mut self) -> Self {
95        self.request.file_type = "bitable".to_string();
96        self
97    }
98
99    /// 评论ID
100    pub fn comment_id(mut self, comment_id: impl ToString) -> Self {
101        self.request.comment_id = comment_id.to_string();
102        self
103    }
104
105    /// 用户ID类型
106    pub fn user_id_type(mut self, user_id_type: impl ToString) -> Self {
107        self.request.user_id_type = Some(user_id_type.to_string());
108        self
109    }
110
111    /// 使用OpenID
112    pub fn with_open_id(mut self) -> Self {
113        self.request.user_id_type = Some("open_id".to_string());
114        self
115    }
116
117    /// 使用UserID
118    pub fn with_user_id(mut self) -> Self {
119        self.request.user_id_type = Some("user_id".to_string());
120        self
121    }
122
123    /// 使用UnionID
124    pub fn with_union_id(mut self) -> Self {
125        self.request.user_id_type = Some("union_id".to_string());
126        self
127    }
128
129    pub fn build(mut self) -> GetCommentRequest {
130        self.request.api_request.body = serde_json::to_vec(&self.request).unwrap();
131        self.request
132    }
133}
134
135// 应用ExecutableBuilder trait到GetCommentRequestBuilder
136impl_executable_builder_owned!(
137    GetCommentRequestBuilder,
138    super::CommentsService,
139    GetCommentRequest,
140    BaseResponse<GetCommentResponse>,
141    get
142);
143
144/// 获取全文评论响应
145#[derive(Debug, Deserialize)]
146pub struct GetCommentResponse {
147    /// 评论信息
148    pub comment: Comment,
149}
150
151impl ApiResponseTrait for GetCommentResponse {
152    fn data_format() -> ResponseFormat {
153        ResponseFormat::Data
154    }
155}
156
157/// 获取全文评论
158pub async fn get_comment(
159    request: GetCommentRequest,
160    config: &Config,
161    option: Option<RequestOption>,
162) -> SDKResult<BaseResponse<GetCommentResponse>> {
163    let mut api_req = request.api_request;
164    api_req.http_method = Method::GET;
165    api_req.api_path = format!(
166        "/open-apis/comment/v1/comments/{}?file_type={}&file_token={}",
167        request.comment_id, request.file_type, request.file_token
168    );
169
170    // 添加用户ID类型查询参数
171    if let Some(user_id_type) = request.user_id_type {
172        api_req.api_path = format!("{}&user_id_type={}", api_req.api_path, user_id_type);
173    }
174
175    api_req.supported_access_token_types = vec![AccessTokenType::Tenant, AccessTokenType::User];
176
177    let api_resp = Transport::request(api_req, config, option).await?;
178    Ok(api_resp)
179}
180
181impl GetCommentResponse {
182    /// 获取评论ID
183    pub fn comment_id(&self) -> &str {
184        &self.comment.comment_id
185    }
186
187    /// 获取用户ID
188    pub fn user_id(&self) -> &str {
189        &self.comment.user_id
190    }
191
192    /// 是否已解决
193    pub fn is_solved(&self) -> bool {
194        self.comment.is_solved
195    }
196
197    /// 是否为全文评论
198    pub fn is_whole_comment(&self) -> bool {
199        self.comment.is_whole.unwrap_or(false)
200    }
201
202    /// 是否有回复
203    pub fn has_replies(&self) -> bool {
204        self.comment.has_replies()
205    }
206
207    /// 获取回复数量
208    pub fn reply_count(&self) -> usize {
209        self.comment.reply_count()
210    }
211
212    /// 获取评论的文本内容
213    pub fn get_text_content(&self) -> String {
214        self.comment.get_text_content()
215    }
216
217    /// 获取创建时间
218    pub fn create_time(&self) -> i64 {
219        self.comment.create_time
220    }
221
222    /// 获取更新时间
223    pub fn update_time(&self) -> i64 {
224        self.comment.update_time
225    }
226
227    /// 获取解决时间
228    pub fn solved_time(&self) -> Option<i64> {
229        self.comment.solved_time
230    }
231
232    /// 获取解决者用户ID
233    pub fn solver_user_id(&self) -> Option<&str> {
234        self.comment.solver_user_id.as_deref()
235    }
236
237    /// 获取引用内容
238    pub fn quote(&self) -> Option<&str> {
239        self.comment.quote.as_deref()
240    }
241
242    /// 获取详细信息摘要
243    pub fn summary(&self) -> String {
244        format!(
245            "评论ID: {}, 用户: {}, 状态: {}, 回复数: {}, 创建时间: {}",
246            self.comment_id(),
247            self.user_id(),
248            if self.is_solved() {
249                "已解决"
250            } else {
251                "未解决"
252            },
253            self.reply_count(),
254            self.create_time()
255        )
256    }
257}
258
259#[cfg(test)]
260mod tests {
261    use super::*;
262
263    #[test]
264    fn test_get_comment_request_builder() {
265        let request = GetCommentRequest::builder()
266            .file_token("doccnxxxxxx")
267            .with_doc_type()
268            .comment_id("comment123")
269            .with_open_id()
270            .build();
271
272        assert_eq!(request.file_token, "doccnxxxxxx");
273        assert_eq!(request.file_type, "doc");
274        assert_eq!(request.comment_id, "comment123");
275        assert_eq!(request.user_id_type, Some("open_id".to_string()));
276    }
277
278    #[test]
279    fn test_get_comment_new() {
280        let request = GetCommentRequest::new("doccnxxxxxx", "doc", "comment123");
281        assert_eq!(request.file_token, "doccnxxxxxx");
282        assert_eq!(request.file_type, "doc");
283        assert_eq!(request.comment_id, "comment123");
284    }
285}