open_lark/card/components/interactive_components/
picker_time.rs

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