open_lark/card/components/interactive_components/
select_person.rs

1use serde::{Deserialize, Serialize};
2
3use crate::card::components::{
4    content_components::plain_text::PlainText, interactive_components::input::InputConfirm,
5};
6
7/// 人员选择-单选
8#[derive(Debug, Serialize, Deserialize)]
9pub struct SelectPerson {
10    /// 组件的标签。人员选择-单选组件取固定值 select_person。
11    tag: String,
12    /// 组件边框样式。可选值:
13    ///
14    /// default:带边框样式
15    /// text:不带边框的纯文本样式
16    #[serde(skip_serializing_if = "Option::is_none")]
17    r#type: Option<String>,
18    /// 单选组件的内容是否必选。当组件内嵌在表单容器中时,该属性可用。其它情况将报错或不生效。
19    /// 可取值:
20    ///
21    /// - true:单选组件必选。当用户点击表单容器的“提交”时,未填写单选组件,
22    ///   则前端提示“有必填项未填写”,不会向开发者的服务端发起回传请求。
23    /// - false:单选组件选填。当用户点击表单容器的“提交”时,未填写单选组件,
24    ///   仍提交表单容器中的数据。
25    #[serde(skip_serializing_if = "Option::is_none")]
26    required: Option<bool>,
27    /// 是否禁用该单选组件。该属性仅支持飞书 V7.4 及以上版本的客户端。可选值:
28    ///
29    /// true:禁用单选组件组件
30    /// false:单选组件组件保持可用状态
31    #[serde(skip_serializing_if = "Option::is_none")]
32    disabled: Option<bool>,
33    /// 人员选择组件内的占位文本。
34    #[serde(skip_serializing_if = "Option::is_none")]
35    placeholder: Option<PlainText>,
36    /// 人员选择组件的宽度。支持以下枚举值:
37    ///
38    /// - default:默认宽度
39    /// - fill:卡片最大支持宽度
40    /// - [100,∞)px:自定义宽度。超出卡片宽度时将按最大支持宽度展示
41    #[serde(skip_serializing_if = "Option::is_none")]
42    width: Option<String>,
43    /// 选项值配置。按选项数组的顺序展示选项内容。
44    #[serde(skip_serializing_if = "Option::is_none")]
45    options: Option<Vec<SelectPersonOption>>,
46    /// 二次确认弹窗配置。指在用户提交时弹出二次确认弹窗提示;只有用户点击确认后,
47    /// 才提交输入的内容。该字段默认提供了确认和取消按钮,你只需要配置弹窗的标题与内容即可。
48    ///
49    /// 注意:confirm 字段仅在用户点击包含提交属性的按钮时才会触发二次确认弹窗。
50    #[serde(skip_serializing_if = "Option::is_none")]
51    confirm: Option<InputConfirm>,
52}
53
54impl Default for SelectPerson {
55    fn default() -> Self {
56        Self {
57            tag: "select_person".to_string(),
58            r#type: None,
59            required: None,
60            disabled: None,
61            placeholder: None,
62            width: None,
63            options: None,
64            confirm: None,
65        }
66    }
67}
68
69impl SelectPerson {
70    pub fn new() -> Self {
71        Self::default()
72    }
73
74    pub fn r#type(mut self, r#type: &str) -> Self {
75        self.r#type = Some(r#type.to_string());
76        self
77    }
78
79    pub fn required(mut self, required: bool) -> Self {
80        self.required = Some(required);
81        self
82    }
83
84    pub fn disabled(mut self, disabled: bool) -> Self {
85        self.disabled = Some(disabled);
86        self
87    }
88
89    pub fn placeholder(mut self, placeholder: PlainText) -> Self {
90        self.placeholder = Some(placeholder);
91        self
92    }
93
94    pub fn width(mut self, width: &str) -> Self {
95        self.width = Some(width.to_string());
96        self
97    }
98
99    pub fn options(mut self, options: Vec<SelectPersonOption>) -> Self {
100        self.options = Some(options);
101        self
102    }
103
104    pub fn confirm(mut self, confirm: InputConfirm) -> Self {
105        self.confirm = Some(confirm);
106        self
107    }
108}
109
110/// 选项的配置。
111#[derive(Debug, Serialize, Deserialize)]
112pub struct SelectPersonOption {
113    /// 选项配置,仅支持添加候选用户的 open_id。
114    value: String,
115}
116
117impl SelectPersonOption {
118    pub fn new(value: &str) -> Self {
119        Self {
120            value: value.to_string(),
121        }
122    }
123}
124
125#[cfg(test)]
126mod test {
127    use serde_json::json;
128
129    use super::*;
130
131    #[test]
132    fn test_select_person() {
133        let select_person = SelectPerson::new()
134            .r#type("text")
135            .required(true)
136            .disabled(false)
137            .placeholder(PlainText::text("默认提示文本"))
138            .width("default")
139            .options(vec![
140                SelectPersonOption::new("ou_48d0958ee4b2ab3eaf0b5f6c968xxxxx"),
141                SelectPersonOption::new("ou_f9d24af786a14340721288cda6axxxxx"),
142            ])
143            .confirm(InputConfirm::new("弹窗标题", "弹窗正文文案"));
144
145        let json = json!({
146          "tag": "select_person", // 组件的标签
147          "type": "text", // 组件边框样式。默认值为 default。
148          "required":true, // 选项是否必填。
149          "disabled":false, // 选项是否禁用。
150          "placeholder": {
151            // 人员选择组件内的占位文本
152            "tag": "plain_text",
153            "content": "默认提示文本"
154          },
155          "width": "default",  // 下拉选择组件的宽度
156          "options": [
157            // 选项配置,仅支持添加候选用户的 open_id。
158            {
159              "value": "ou_48d0958ee4b2ab3eaf0b5f6c968xxxxx" // 候选用户的 open_id
160            },
161            {
162              "value": "ou_f9d24af786a14340721288cda6axxxxx" // 候选用户的 open_id
163            }
164          ],
165          "confirm": {
166            // 二次确认弹窗配置
167            "title": {
168              "tag": "plain_text",
169              "content": "弹窗标题"
170            },
171            "text": {
172              "tag": "plain_text",
173              "content": "弹窗正文文案"
174            }
175          }
176        });
177
178        assert_eq!(serde_json::to_value(&select_person).unwrap(), json);
179    }
180}