br_addon/
action.rs

1use crate::request::{ContentType, Method, Request};
2use crate::PLUGIN_TOOLS;
3use crate::{ApiResponse, Tools};
4use br_fields::Field;
5use json::{array, object, JsonValue};
6use std::any::type_name;
7use std::collections::HashMap;
8
9/// 功能接口
10pub trait Action {
11    /// 功能名称
12    fn _name(&self) -> String {
13        type_name::<Self>()
14            .rsplit("::")
15            .next()
16            .unwrap()
17            .to_lowercase()
18    }
19    /// API 名称
20    fn api(&self) -> String {
21        let t = type_name::<Self>().split("::").collect::<Vec<&str>>();
22        let plugin = t[2].to_lowercase();
23        let module = t[3].to_lowercase();
24        let action = t[4].to_lowercase();
25        format!("{plugin}.{module}.{action}")
26    }
27    /// 是否需要密钥
28    fn token(&self) -> bool {
29        true
30    }
31    /// 版本号
32    fn version(&self) -> &'static str {
33        "v1"
34    }
35    /// 作者
36    fn author(&self) -> &'static str {
37        ""
38    }
39    fn sort(&self) -> usize {
40        99
41    }
42    /// 功能标题
43    fn title(&self) -> &'static str;
44    /// 功能描述
45    fn description(&self) -> &'static str {
46        ""
47    }
48    /// 请求地址路径
49    fn path(&self) -> &'static str {
50        ""
51    }
52    /// 请求地址参数
53    fn query(&self) -> JsonValue {
54        object! {}
55    }
56    /// 归属标签
57    fn tags(&self) -> &'static [&'static str] {
58        &[]
59    }
60    fn icon(&self) -> &'static str {
61        ""
62    }
63    /// 是否公开
64    fn public(&self) -> bool {
65        true
66    }
67    /// 是否权限组显示
68    fn auth(&mut self) -> bool {
69        true
70    }
71    /// 接口类型 btn api menu
72    fn interface_type(&mut self) -> InterfaceType {
73        InterfaceType::API
74    }
75    /// 允许的请求类型
76    fn method(&mut self) -> Method {
77        Method::Post
78    }
79    /// 请求类型
80    fn content_type(&mut self) -> ContentType {
81        ContentType::Json
82    }
83    /// 请求body参数
84    fn params(&mut self) -> JsonValue {
85        object! {}
86    }
87    /// 成功响应
88    fn success(&mut self) -> ApiResponse {
89        let mut data = object! {};
90        data["code"] = br_fields::int::Int::new(true, "code", "编号", 10, 0)
91            .example(0.into())
92            .swagger();
93        data["message"] = br_fields::str::Str::new(true, "message", "成功消息", 256, "")
94            .example("成功".into())
95            .swagger();
96        data["data"] = br_fields::text::Json::new(true, "data", "返回数据", object! {}).swagger();
97        data["success"] = br_fields::int::Switch::new(true, "success", "成功状态", true)
98            .example(true.into())
99            .swagger();
100        ApiResponse::success(data, "请求成功")
101    }
102    /// 失败响应
103    fn error(&mut self) -> ApiResponse {
104        let mut data = object! {};
105        data["code"] = br_fields::int::Int::new(true, "code", "编号", 10, 1000)
106            .example(1000.into())
107            .swagger();
108        data["message"] = br_fields::str::Str::new(true, "message", "错误消息", 256, "")
109            .example("失败".into())
110            .swagger();
111        data["data"] = br_fields::text::Json::new(true, "data", "返回数据", object! {}).swagger();
112        data["success"] = br_fields::int::Switch::new(true, "success", "成功状态", false)
113            .example(false.into())
114            .swagger();
115        ApiResponse::error(data, "请求失败")
116    }
117    /// 外部入口
118    fn run(&mut self, mut request: Request) -> Result<ApiResponse, ApiResponse> {
119        if self.method().str().to_lowercase() != request.method.str().to_lowercase() {
120            return Err(ApiResponse::fail(
121                -1,
122                format!(
123                    "Request type error: Actual [{}] Expected [{}]",
124                    request.method.str(),
125                    self.method().str()
126                )
127                .as_str(),
128            ));
129        }
130        let params = self.params().clone();
131        self.check(&mut request.query.clone().into(), self.query().clone())?;
132        self.check(&mut request.body, params)?;
133        let res = self.index(request.clone());
134        match res.success {
135            true => Ok(res),
136            false => Err(res),
137        }
138    }
139    /// 入参验证
140    fn check(&mut self, request: &mut JsonValue, params: JsonValue) -> Result<(), ApiResponse> {
141        let req = request.clone();
142        for (name, _) in req.entries() {
143            if !params.has_key(name) {
144                request.remove(name);
145            }
146        }
147        for (name, field) in params.entries() {
148            let require = field["require"].as_bool().unwrap_or(false);
149            let title = field["title"].as_str().unwrap_or("");
150            if request.has_key(name) {
151                // 判断输入类型
152                match field["mode"].as_str().unwrap() {
153                    "key" => {
154                        if !request[name].is_string() {
155                            return Err(ApiResponse::fail(
156                                900001,
157                                format!(
158                                    "请求参数数据类型错误: 参数 [{}] 数据类型应为[{}]",
159                                    name, field["mode"]
160                                )
161                                .as_str(),
162                            ));
163                        }
164                        if require && request[name].is_empty() {
165                            return Err(ApiResponse::fail(
166                                900014,
167                                format!("请求参数数据类型错误: 参数 [{}] 不能为空", name).as_str(),
168                            ));
169                        }
170                    }
171                    "text" | "table" | "file" => {
172                        if !request[name].is_string() {
173                            return Err(ApiResponse::fail(
174                                900001,
175                                format!(
176                                    "请求参数数据类型错误: 参数 [{}] 数据类型应为[{}]",
177                                    name, field["mode"]
178                                )
179                                .as_str(),
180                            ));
181                        }
182                        if require && request[name].is_empty() {
183                            return Err(ApiResponse::fail(
184                                900002,
185                                format!("{} 必填", title).as_str(),
186                            ));
187                        }
188                    }
189                    "int" => {
190                        if !request[name].is_number() {
191                            return Err(ApiResponse::fail(
192                                900013,
193                                format!(
194                                    "请求参数数据类型错误: 参数 [{}] 数据类型应为[{}]",
195                                    name, field["mode"]
196                                )
197                                .as_str(),
198                            ));
199                        }
200                    }
201                    "float" => {
202                        if !request[name].is_number() {
203                            return Err(ApiResponse::fail(
204                                900023,
205                                format!(
206                                    "请求参数数据类型错误: 参数 [{}] 数据类型应为[{}]",
207                                    name, field["mode"]
208                                )
209                                .as_str(),
210                            ));
211                        }
212                    }
213                    "string" | "code" => {
214                        if !request[name].is_string() {
215                            return Err(ApiResponse::fail(
216                                -1,
217                                format!(
218                                    "请求参数数据类型错误: 参数 [{}] 数据类型应为[{}]",
219                                    name, field["mode"]
220                                )
221                                .as_str(),
222                            ));
223                        }
224                        if require && request[name].is_empty() {
225                            return Err(ApiResponse::fail(
226                                900003,
227                                format!("{} 必填", title).as_str(),
228                            ));
229                        }
230                    }
231                    "switch" => {
232                        if !request[name].is_boolean() {
233                            return Err(ApiResponse::fail(
234                                -1,
235                                format!(
236                                    "请求参数数据类型错误: 参数 [{}] 数据类型应为[{}]",
237                                    name, field["mode"]
238                                )
239                                .as_str(),
240                            ));
241                        }
242                    }
243                    "select" => {
244                        if !request[name].is_array() && !request[name].is_string() {
245                            return Err(ApiResponse::fail(
246                                -1,
247                                format!(
248                                    "请求参数数据类型错误: 参数 [{}] 数据类型应为[{}]",
249                                    name, field["mode"]
250                                )
251                                .as_str(),
252                            ));
253                        }
254                        let option = field["option"]
255                            .members()
256                            .map(|m| m.as_str().unwrap_or(""))
257                            .collect::<Vec<&str>>()
258                            .join(",");
259                        if request[name].is_string()
260                            && !field["option"].contains(request[name].as_str().unwrap_or(""))
261                        {
262                            return Err(ApiResponse::fail(
263                                -1,
264                                format!(
265                                    "请求参数选项错误: 参数 [{}] 数据类型应为[{}]之内",
266                                    name, option
267                                )
268                                .as_str(),
269                            ));
270                        }
271                        if request[name].is_array() {
272                            let res1 = request[name]
273                                .members()
274                                .map(|m| m.as_str().unwrap_or(""))
275                                .collect::<Vec<&str>>();
276                            let diff = res1
277                                .iter()
278                                .filter(|&item| {
279                                    !field["option"]
280                                        .members()
281                                        .map(|m| m.as_str().unwrap_or(""))
282                                        .collect::<Vec<&str>>()
283                                        .contains(item)
284                                })
285                                .collect::<Vec<&&str>>();
286                            if !diff.is_empty() {
287                                return Err(ApiResponse::fail(
288                                    -1,
289                                    format!(
290                                        "请求参数选项错误: 参数 [{}] 数据 {:?} 应为[{:?}]范围之内",
291                                        name, diff, option
292                                    )
293                                    .as_str(),
294                                ));
295                            }
296                        }
297                    }
298                    "radio" => {
299                        if !request[name].is_string() {
300                            return Err(ApiResponse::fail(
301                                -1,
302                                format!(
303                                    "请求参数数据类型错误: 参数 [{}] 数据类型应为[{}] 实际为[{}]",
304                                    name, field["mode"], request[name]
305                                )
306                                .as_str(),
307                            ));
308                        }
309                        let option = field["option"]
310                            .members()
311                            .map(|m| m.as_str().unwrap_or(""))
312                            .collect::<Vec<&str>>()
313                            .join(",");
314                        if request[name].is_string()
315                            && !field["option"].contains(request[name].as_str().unwrap_or(""))
316                        {
317                            return Err(ApiResponse::fail(
318                                -1,
319                                format!(
320                                    "请求参数选项错误: 参数 [{}] 数据 [{}] 应为 [{}] 之一",
321                                    name, request[name], option
322                                )
323                                .as_str(),
324                            ));
325                        }
326                    }
327                    "array" => {
328                        if !request[name].is_array() {
329                            return Err(ApiResponse::fail(
330                                900009,
331                                format!(
332                                    "请求参数数据类型错误: 参数 [{}] 数据类型应为[{}]",
333                                    name, field["mode"]
334                                )
335                                .as_str(),
336                            ));
337                        }
338                        if require && request[name].is_empty() {
339                            return Err(ApiResponse::fail(
340                                900010,
341                                format!("请求参数数据类型错误: 参数 [{}] 不能为空", name).as_str(),
342                            ));
343                        }
344                    }
345                    "object" => {
346                        if !request[name].is_object() {
347                            return Err(ApiResponse::fail(
348                                900009,
349                                format!(
350                                    "请求参数数据类型错误: 参数 [{}] 数据类型应为[{}]",
351                                    name, field["mode"]
352                                )
353                                .as_str(),
354                            ));
355                        }
356                        if require && request[name].is_empty() {
357                            return Err(ApiResponse::fail(
358                                900006,
359                                format!("{} 必填", title).as_str(),
360                            ));
361                        }
362                    }
363                    _ => {
364                        println!("检查未知类型: {}", field["mode"])
365                    }
366                }
367            } else {
368                if require {
369                    return Err(ApiResponse::fail(
370                        900007,
371                        format!("{} 必填", title).as_str(),
372                    ));
373                }
374                request[name] = field["def"].clone();
375            }
376        }
377        Ok(())
378    }
379    /// 内部入口
380    fn index(&mut self, request: Request) -> ApiResponse;
381    fn params_table_select(&mut self, mut params: JsonValue) -> JsonValue {
382        params["page"] = br_fields::int::Int::new(false, "page", "页数", 10, 1)
383            .example(1.into())
384            .field();
385        params["limit"] = br_fields::int::Int::new(false, "limit", "行数", 10, 10)
386            .example(10.into())
387            .field();
388        params["search"] = br_fields::str::Str::new(false, "search", "搜索", 200, "")
389            .example("".into())
390            .field();
391        params["where_or"] = br_fields::text::Array::new(false, "where_or", "查询条件", array![])
392            .example(array![])
393            .field();
394        params["where_and"] = br_fields::text::Array::new(false, "where_and", "查询条件", array![])
395            .example(array![])
396            .field();
397        params["params"] =
398            br_fields::text::Object::new(false, "params", "关联数据参数", object! {})
399                .example(object! {})
400                .field();
401        params
402    }
403    #[cfg(any(feature = "sqlite", feature = "mssql", feature = "mysql"))]
404    fn table_select(
405        &mut self,
406        request: JsonValue,
407        table_name: &str,
408        mut fields: Vec<&str>,
409    ) -> JsonValue {
410        let page = request["page"].as_i32().unwrap_or(1);
411        let limit = request["limit"].as_i32().unwrap_or(10);
412
413        let search = request["search"].as_str().unwrap_or("");
414
415        let where_or = request["where_or"].clone();
416        let where_and = request["where_and"].clone();
417
418        let mut tools = self.tools();
419        let db = tools.db.table(table_name);
420
421        if !search.is_empty() {
422            db.where_and(&fields.join("|"), "like", format!("%{}%", search).into());
423        }
424
425        for (key, value) in where_or.entries() {
426            if value.is_empty() {
427                continue;
428            }
429            if value.is_array() {
430                db.where_or(key, "between", value.clone());
431                db.where_or(key, "in", value.clone());
432            } else if value.is_boolean() {
433                db.where_or(key, "=", value.clone());
434            } else {
435                db.where_or(key, "like", format!("%{}%", value).into());
436            }
437        }
438
439        for value in where_and.members() {
440            db.where_and(
441                value[0].as_str().unwrap(),
442                value[1].as_str().unwrap(),
443                value[2].clone(),
444            );
445        }
446
447        let total = (db.clone().count().as_f64().unwrap() / limit as f64).ceil() as i64;
448        let mut db_list = db.clone();
449
450        fields.push("id");
451        db_list.field(&fields.join(","));
452
453        let mut data = db_list.page(page, limit).select();
454        let mut list = array![];
455        for item in data.members_mut() {
456            let value = item["id"].clone();
457            item.remove("id");
458
459            let label = item
460                .entries()
461                .map(|(_, v)| v.as_str().unwrap())
462                .collect::<Vec<&str>>();
463
464            list.push(object! {
465                value: value,
466                label: label.join(" | ").clone(),
467            })
468            .unwrap();
469        }
470        object! {
471            total:total,
472            data:list,
473        }
474    }
475    /// 菜单表格接收参数
476    fn params_table_menu(&mut self, mut params: JsonValue) -> JsonValue {
477        params["search"] = br_fields::str::Str::new(false, "search", "搜索", 200, "")
478            .example("".into())
479            .field();
480        params["where_or"] = br_fields::text::Array::new(false, "where_or", "查询条件", array![])
481            .example(array![])
482            .field();
483        params["where_and"] = br_fields::text::Array::new(false, "where_and", "查询条件", array![])
484            .example(array![])
485            .field();
486        params
487    }
488    #[cfg(any(feature = "sqlite", feature = "mssql", feature = "mysql"))]
489    fn table_menu(
490        &mut self,
491        request: JsonValue,
492        table_name: &str,
493        label_field: &str,
494        fields: JsonValue,
495
496        hidd_field: Vec<&str>,
497        show_field: Vec<&str>,
498
499        search_fields: Vec<&str>,
500        _filter_fields: Vec<&str>,
501    ) -> JsonValue {
502        let search = request["search"].as_str().unwrap_or("");
503
504        let order = request["order"].clone();
505        let where_or = request["where_or"].clone();
506        let where_and = request["where_and"].clone();
507        let mut columns = array![];
508        let mut search_name = vec![];
509        let mut search_field = vec![];
510        let mut filter_columns = vec![];
511        let mut table_fields = object! {};
512        let mut table_field_json = vec![];
513
514        let mut alls_field = fields.entries().map(|(x, _)| x).collect::<Vec<&str>>();
515        alls_field.retain(|x| !hidd_field.contains(x));
516        if !show_field.is_empty() {
517            alls_field.retain(|x| show_field.contains(x) || *x == "id");
518        }
519
520        for item in alls_field.iter() {
521            let row = &fields[item.clone()];
522            let field = row["field"].to_string();
523            let title = row["title"].to_string();
524            let mode = row["mode"].to_string();
525
526            if search_fields.contains(&field.as_str()) {
527                search_name.push(title);
528                search_field.push(field.clone());
529            }
530            filter_columns.push(self.filter_column(row.clone()));
531            columns.push(self.table_column(row.clone())).unwrap();
532            let mut table_field_info = object! {};
533            match mode.as_str() {
534                "table" => table_field_info = row.clone(),
535                "array" => table_field_json.push(field.clone()),
536                _ => {}
537            }
538            if !table_field_info.is_empty() {
539                table_fields[field.as_str()] = table_field_info;
540            }
541        }
542
543        let mut tools = self.tools();
544        let db = tools.db.table(table_name);
545
546        if !search.is_empty() {
547            db.where_and(
548                &search_field.join("|"),
549                "like",
550                format!("%{}%", search).into(),
551            );
552        }
553
554        for (key, value) in where_or.entries() {
555            if value.is_empty() {
556                continue;
557            }
558            if value.is_array() {
559                db.where_or(key, "between", value.clone());
560                db.where_or(key, "in", value.clone());
561            } else if value.is_boolean() {
562                db.where_or(key, "=", value.clone());
563            } else {
564                db.where_or(key, "like", format!("%{}%", value).into());
565            }
566        }
567
568        for value in where_and.members() {
569            db.where_and(
570                value[0].as_str().unwrap(),
571                value[1].as_str().unwrap(),
572                value[2].clone(),
573            );
574        }
575
576        let mut db_list = db.clone();
577
578        for item in order.members() {
579            db_list.order(item[0].as_str().unwrap(), item[1].as_bool().unwrap());
580        }
581
582        let t = alls_field.join(",");
583        db_list.field(t.as_str());
584
585        if !table_field_json.is_empty() {
586            db_list.json(&table_field_json.join(","));
587        }
588
589        let mut data = db_list.select();
590
591        let mut table_datas = object! {};
592        let mut ids = HashMap::new();
593
594        for item in data.members_mut() {
595            for (field, _) in table_fields.entries() {
596                if table_datas[field].is_empty() {
597                    table_datas[field] = array![];
598                }
599                let _ = table_datas[field].push(item[field].clone());
600            }
601        }
602        for (field, info) in table_fields.entries_mut() {
603            let _ = info["fields"].push("id");
604            let fields_k = info["fields"]
605                .members()
606                .map(|x| x.as_str().unwrap())
607                .collect::<Vec<&str>>();
608            let table_name = info["table"].clone();
609            let mut data_list = self
610                .tools()
611                .db
612                .table(table_name.as_str().unwrap())
613                .where_and("id", "in", table_datas[field].clone())
614                .field(&fields_k.join(","))
615                .select();
616
617            for item in data_list.members_mut() {
618                let id = item["id"].as_str().unwrap_or("").to_string();
619                item.remove("id");
620                let label = item
621                    .entries()
622                    .map(|(_, v)| v.as_str().unwrap())
623                    .collect::<Vec<&str>>();
624                ids.insert(
625                    id.clone(),
626                    object! {
627                        value: id.clone(),
628                        label:label.join(" | ").clone(),
629                    },
630                );
631            }
632        }
633
634        for item in data.members_mut() {
635            for (field, _) in table_fields.entries() {
636                if item[field].is_empty() {
637                    continue;
638                }
639                item[field] = ids[item[field].as_str().unwrap()].clone();
640            }
641        }
642
643        object! {
644            data:data,
645            columns:columns,
646            search_name:search_name.join("/"),
647            filter_columns:filter_columns,
648            label_field:label_field,
649            btn_all:array![],
650            btn_api:array![]
651        }
652    }
653    /// 树型表格接收参数
654    fn params_table_tree(&mut self, mut params: JsonValue) -> JsonValue {
655        params["pid"] = br_fields::str::Str::new(false, "pid", "上级ID", 50, "")
656            .example("".into())
657            .field();
658        params["search"] = br_fields::str::Str::new(false, "search", "搜索", 200, "")
659            .example("".into())
660            .field();
661        params["where_or"] = br_fields::text::Array::new(false, "where_or", "查询条件", array![])
662            .example(array![])
663            .field();
664        params["where_and"] = br_fields::text::Array::new(false, "where_and", "查询条件", array![])
665            .example(array![])
666            .field();
667        params
668    }
669    #[cfg(any(feature = "sqlite", feature = "mssql", feature = "mysql"))]
670    fn table_tree(
671        &mut self,
672        request: JsonValue,
673        table_name: &str,
674        pid_field: &str,
675        label_field: &str,
676        fields: JsonValue,
677        hidd_field: Vec<&str>,
678        show_field: Vec<&str>,
679        search_fields: Vec<&str>,
680        _filter_fields: Vec<&str>,
681    ) -> JsonValue {
682        let search = request["search"].as_str().unwrap_or("");
683
684        let pid = request["pid"].clone();
685
686        let order = request["order"].clone();
687        let where_or = request["where_or"].clone();
688        let where_and = request["where_and"].clone();
689        let mut columns = array![];
690        let mut search_name = vec![];
691        let mut search_field = vec![];
692        let mut filter_columns = vec![];
693        let mut table_field_json = vec![];
694        let mut table_fields = object! {};
695
696        let mut alls_field = fields.entries().map(|(x, _)| x).collect::<Vec<&str>>();
697        alls_field.retain(|x| !hidd_field.contains(x));
698        if !show_field.is_empty() {
699            alls_field.retain(|x| show_field.contains(x) || *x == "id");
700        }
701
702        for item in alls_field.iter() {
703            let row = fields[item.clone()].clone();
704            let field = row["field"].to_string();
705            let title = row["title"].to_string();
706            let mode = row["mode"].to_string();
707
708            if search_fields.contains(&field.as_str()) {
709                search_name.push(title);
710                search_field.push(field.clone());
711            }
712            filter_columns.push(self.filter_column(row.clone()));
713            columns.push(self.table_column(row.clone())).unwrap();
714            let mut table_field_info = object! {};
715            match mode.as_str() {
716                "table" => table_field_info = row.clone(),
717                "array" => table_field_json.push(field.clone()),
718                _ => {}
719            }
720            if !table_field_info.is_empty() {
721                table_fields[field.as_str()] = table_field_info;
722            }
723        }
724
725        let mut tools = self.tools();
726        let db = tools.db.table(table_name);
727        db.where_and(pid_field, "=", pid);
728        if !search.is_empty() {
729            db.where_and(
730                &search_field.join("|"),
731                "like",
732                format!("%{}%", search).into(),
733            );
734        }
735
736        for (key, value) in where_or.entries() {
737            if value.is_empty() {
738                continue;
739            }
740            if value.is_array() {
741                // db.where_or(key, "between", value.clone());
742                db.where_or(key, "in", value.clone());
743            } else if value.is_boolean() {
744                db.where_or(key, "=", value.clone());
745            } else {
746                db.where_or(key, "like", format!("%{}%", value).into());
747            }
748        }
749
750        for value in where_and.members() {
751            db.where_and(
752                value[0].as_str().unwrap(),
753                value[1].as_str().unwrap(),
754                value[2].clone(),
755            );
756        }
757
758        let mut db_list = db.clone();
759
760        for item in order.members() {
761            db_list.order(item[0].as_str().unwrap(), item[1].as_bool().unwrap());
762        }
763        let t = alls_field.join(",");
764        db_list.field(t.as_str());
765        if !table_field_json.is_empty() {
766            db_list.json(&table_field_json.join(","));
767        }
768        let mut data = db_list.select();
769
770        let mut table_datas = object! {};
771        let mut ids = HashMap::new();
772
773        for item in data.members_mut() {
774            for (field, _) in table_fields.entries() {
775                if table_datas[field].is_empty() {
776                    table_datas[field] = array![];
777                }
778                let _ = table_datas[field].push(item[field].clone());
779            }
780        }
781        for (field, info) in table_fields.entries_mut() {
782            let _ = info["fields"].push("id");
783            let fields_k = info["fields"]
784                .members()
785                .map(|x| x.as_str().unwrap())
786                .collect::<Vec<&str>>();
787            let table_name = info["table"].clone();
788            let mut data_list = self
789                .tools()
790                .db
791                .table(table_name.as_str().unwrap())
792                .where_and("id", "in", table_datas[field].clone())
793                .field(&fields_k.join(","))
794                .select();
795
796            for item in data_list.members_mut() {
797                let id = item["id"].as_str().unwrap_or("").to_string();
798                item.remove("id");
799                let label = item
800                    .entries()
801                    .map(|(_, v)| v.as_str().unwrap())
802                    .collect::<Vec<&str>>();
803                ids.insert(
804                    id.clone(),
805                    object! {
806                        value: id.clone(),
807                        label:label.join(" | ").clone(),
808                    },
809                );
810            }
811        }
812
813        let mut list = array![];
814        for item in data.members_mut() {
815            for (field, _) in table_fields.entries() {
816                if item[field].is_empty() {
817                    continue;
818                }
819                item[field] = ids[item[field].as_str().unwrap()].clone();
820            }
821            let _ = list.push(object! {
822                id:item["id"].as_str().unwrap(),
823                label:item[label_field].as_str().unwrap(),
824                data:item.clone(),
825            });
826        }
827
828        object! {
829            data:list,
830            columns:columns,
831            search_name:search_name.join("/"),
832            filter_columns:filter_columns,
833            pid_field:pid_field,
834            btn_all:array![],
835            btn_api:array![]
836        }
837    }
838    /// 表格接收参数
839    fn params_table_list(&mut self, mut params: JsonValue) -> JsonValue {
840        params["page"] = br_fields::int::Int::new(false, "page", "页数", 10, 1)
841            .example(1.into())
842            .field();
843        params["limit"] = br_fields::int::Int::new(false, "limit", "行数", 10, 10)
844            .example(10.into())
845            .field();
846        params["search"] = br_fields::str::Str::new(false, "search", "搜索", 200, "")
847            .example("".into())
848            .field();
849        params["order"] = br_fields::text::Array::new(false, "order", "排序", array![])
850            .example(array![array!["id", false]])
851            .field();
852        params["where_or"] = br_fields::text::Array::new(false, "where_or", "查询条件", array![])
853            .example(array![])
854            .field();
855        params["where_and"] = br_fields::text::Array::new(false, "where_and", "查询条件", array![])
856            .example(array![])
857            .field();
858        params
859    }
860    /// 列表表格渲染
861    /// * table_name 表名
862    /// * fields 全部模型字段集合
863    /// * hidd_field 需要隐藏的字段集合
864    /// * show_field 需要显示的字段集合
865    /// * search_fields 搜索字段集合
866    /// * filter_fields 高级搜索字段集合
867    #[cfg(any(feature = "sqlite", feature = "mssql", feature = "mysql"))]
868    fn table_list(
869        &mut self,
870        request: JsonValue,
871        table_name: &str,
872        fields: JsonValue,
873        hidd_field: Vec<&str>,
874        show_field: Vec<&str>,
875        search_fields: Vec<&str>,
876        filter_fields: Vec<&str>,
877    ) -> JsonValue {
878        let page = request["page"].as_i32().unwrap_or(1);
879        let limit = request["limit"].as_i32().unwrap_or(10);
880        let search = request["search"].as_str().unwrap_or("");
881        let order = request["order"].clone();
882        let where_or = request["where_or"].clone();
883        let where_and = request["where_and"].clone();
884        let mut columns = array![];
885        let mut search_name = vec![];
886        let mut search_field = vec![];
887        let mut filter_columns = vec![];
888
889        let mut table_fields = object! {};
890
891        let mut alls_field = fields.entries().map(|(x, _)| x).collect::<Vec<&str>>();
892        alls_field.retain(|x| !hidd_field.contains(x));
893        if !show_field.is_empty() {
894            alls_field.retain(|x| show_field.contains(x) || *x == "id");
895        }
896
897        for item in alls_field.iter() {
898            let key = item.clone();
899            let field = fields[key]["field"].as_str().unwrap();
900            let title = fields[key]["title"].as_str().unwrap();
901            let mode = fields[key]["mode"].as_str().unwrap();
902
903            if search_fields.contains(&field) {
904                search_name.push(title);
905                search_field.push(field);
906            }
907            if filter_fields.contains(&field) {
908                filter_columns.push(self.filter_column(fields[key].clone()));
909            }
910            columns
911                .push(self.table_column(fields[key].clone()))
912                .unwrap();
913            let table_field_info = if mode == "table" {
914                fields[key].clone()
915            } else {
916                JsonValue::Null
917            };
918            if !table_field_info.is_empty() {
919                table_fields[field] = table_field_info;
920            }
921        }
922
923        let mut tools = self.tools();
924        let db = tools.db.table(table_name);
925
926        if !search.is_empty() {
927            db.where_and(
928                &search_field.join("|"),
929                "like",
930                format!("%{}%", search).into(),
931            );
932        }
933
934        for (key, value) in where_or.entries() {
935            if value.is_empty() {
936                continue;
937            }
938            if value.is_array() {
939                // db.where_or(key, "between", value.clone());
940                db.where_or(key, "in", value.clone());
941            } else if value.is_boolean() {
942                db.where_or(key, "=", value.clone());
943            } else {
944                db.where_or(key, "like", format!("%{}%", value).into());
945            }
946        }
947
948        for value in where_and.members() {
949            db.where_and(
950                value[0].as_str().unwrap(),
951                value[1].as_str().unwrap(),
952                value[2].clone(),
953            );
954        }
955
956        let total = db.clone().count().as_f64().unwrap();
957        // let total = (db.clone().count().as_f64().unwrap() / limit as f64).ceil() as i64;
958        let mut db_list = db.clone();
959
960        for item in order.members() {
961            db_list.order(item[0].as_str().unwrap(), item[1].as_bool().unwrap());
962        }
963
964        let t = alls_field.join(",");
965        db_list.field(t.as_str());
966
967        let mut data = db_list.page(page, limit).select();
968
969        let mut table_datas = object! {};
970        let mut ids = HashMap::new();
971
972        for item in data.members_mut() {
973            if table_fields.is_empty() {
974                continue;
975            }
976            for (field, _) in table_fields.entries() {
977                if table_datas[field].is_empty() {
978                    table_datas[field] = array![];
979                }
980                let _ = table_datas[field].push(item[field].clone());
981            }
982        }
983        for (field, info) in table_fields.entries_mut() {
984            let _ = info["fields"].push("id");
985            let fields_k = info["fields"]
986                .members()
987                .map(|x| x.as_str().unwrap())
988                .collect::<Vec<&str>>();
989            let table_name = info["table"].clone();
990            let mut data_list = self
991                .tools()
992                .db
993                .table(table_name.as_str().unwrap())
994                .where_and("id", "in", table_datas[field].clone())
995                .field(&fields_k.join(","))
996                .select();
997
998            for item in data_list.members_mut() {
999                let id = item["id"].as_str().unwrap_or("").to_string();
1000                item.remove("id");
1001                let label = item
1002                    .entries()
1003                    .map(|(_, v)| v.to_string())
1004                    .collect::<Vec<String>>();
1005                ids.insert(
1006                    id.clone(),
1007                    object! {
1008                        value: id.clone(),
1009                        label:label.join(" | ").clone(),
1010                    },
1011                );
1012            }
1013        }
1014
1015        for item in data.members_mut() {
1016            if table_fields.is_empty() {
1017                continue;
1018            }
1019            for (field, _) in table_fields.entries() {
1020                if item[field].is_empty() {
1021                    continue;
1022                }
1023                let key = item[field].as_str().unwrap_or("");
1024                if key.is_empty() {
1025                    continue;
1026                }
1027                if !ids.contains_key(key) {
1028                    continue;
1029                }
1030                item[field] = ids.get(key).unwrap().clone();
1031            }
1032        }
1033
1034        object! {
1035            total:total,
1036            data:data,
1037            columns:columns,
1038            search_name:search_name.join("/"),
1039            filter_columns:filter_columns,
1040            btn_all:array![],
1041            btn_api:array![],
1042            btn_ids:array![]
1043        }
1044    }
1045    fn table_column(&mut self, field: JsonValue) -> JsonValue {
1046        object! {
1047            name:field["field"].clone(),
1048            label:field["title"].clone(),
1049            align:"center",
1050            field:field["field"].clone(),
1051            sortable:true,
1052            mode:field["mode"].clone(),
1053        }
1054    }
1055    fn filter_column(&mut self, field: JsonValue) -> JsonValue {
1056        object! {
1057            name:field["field"].clone(),
1058            label:field["title"].clone(),
1059            mode:field["mode"].clone(),
1060            option:field["option"].clone(),
1061            api:field["api"].clone(),
1062        }
1063    }
1064    /// 使用工具
1065    fn tools(&mut self) -> Tools {
1066        let tools = PLUGIN_TOOLS.lock().unwrap();
1067        let tools = tools.get("tools").unwrap().clone();
1068        tools
1069    }
1070    /// 按钮信息
1071    /// * cnd 显示条件 vec![vec!["xxx","=","yyy"],vec!["zzz","=","eee"]]
1072    fn btn(&mut self) -> Btn {
1073        let mut btn = Btn::new(self.api().as_str());
1074        btn.fields(self.params().clone());
1075        btn.icon(self.icon());
1076        btn.desc(self.description());
1077        btn.auth(self.auth());
1078        btn.public(self.public());
1079        btn.title(self.title());
1080        btn.btn_type(BtnType::Api);
1081        btn.btn_color(BtnColor::Primary);
1082        btn.path(self.api().clone().replace(".", "/").as_str());
1083        btn
1084    }
1085}
1086#[derive(Debug, Clone)]
1087pub struct Btn {
1088    api: String,
1089    title: String,
1090    desc: String,
1091    auth: bool,
1092    public: bool,
1093    btn_type: BtnType,
1094    color: BtnColor,
1095    icon: String,
1096    cnd: Vec<JsonValue>,
1097    url: String,
1098    path: String,
1099    fields: JsonValue,
1100}
1101impl Btn {
1102    pub fn new(api: &str) -> Self {
1103        Self {
1104            api: api.to_string(),
1105            title: "".to_string(),
1106            desc: "".to_string(),
1107            btn_type: BtnType::Api,
1108            color: BtnColor::Primary,
1109            icon: "".to_string(),
1110            auth: false,
1111            public: false,
1112            cnd: vec![],
1113            url: "".to_string(),
1114            path: "".to_string(),
1115            fields: object! {},
1116        }
1117    }
1118    pub fn path(&mut self, path: &str) -> &mut Self {
1119        self.path = path.to_string();
1120        self
1121    }
1122    pub fn cnd(&mut self, cnd: Vec<JsonValue>) -> &mut Self {
1123        self.cnd = cnd;
1124        self
1125    }
1126    pub fn btn_type(&mut self, btn_type: BtnType) -> &mut Self {
1127        self.btn_type = btn_type;
1128        self
1129    }
1130    pub fn btn_color(&mut self, btn_color: BtnColor) -> &mut Self {
1131        self.color = btn_color;
1132        self
1133    }
1134    pub fn fields(&mut self, fields: JsonValue) -> &mut Self {
1135        self.fields = fields;
1136        self
1137    }
1138    pub fn url(&mut self, url: &str) -> &mut Self {
1139        self.url = url.to_string();
1140        self
1141    }
1142    pub fn title(&mut self, title: &str) -> &mut Self {
1143        self.title = title.to_string();
1144        self
1145    }
1146    pub fn desc(&mut self, desc: &str) -> &mut Self {
1147        self.desc = desc.to_string();
1148        self
1149    }
1150    pub fn public(&mut self, public: bool) -> &mut Self {
1151        self.public = public;
1152        self
1153    }
1154    pub fn auth(&mut self, auth: bool) -> &mut Self {
1155        self.auth = auth;
1156        self
1157    }
1158    pub fn icon(&mut self, icon: &str) -> &mut Self {
1159        self.icon = icon.to_string();
1160        self
1161    }
1162    pub fn json(&mut self) -> JsonValue {
1163        object! {
1164            api:self.api.clone(),
1165            title:self.title.clone(),
1166            desc:self.desc.clone(),
1167            auth:self.auth,
1168            public:self.public,
1169            btn_type:self.btn_type.clone().str(),
1170            color:self.color.clone().str(),
1171            icon:self.icon.clone(),
1172            cnd:self.cnd.clone(),
1173            url:self.url.clone(),
1174            path:self.path.clone(),
1175            fields:self.fields.clone()
1176        }
1177    }
1178}
1179
1180/// 接口类型
1181#[derive(Debug, Clone)]
1182pub enum InterfaceType {
1183    API,
1184    BTN,
1185    MENU,
1186}
1187
1188impl InterfaceType {
1189    pub fn str(self) -> &'static str {
1190        match self {
1191            InterfaceType::API => "api",
1192            InterfaceType::BTN => "btn",
1193            InterfaceType::MENU => "menu",
1194        }
1195    }
1196    pub fn types() -> Vec<&'static str> {
1197        vec!["api", "btn", "menu"]
1198    }
1199}
1200
1201/// 按钮类型
1202#[derive(Debug, Clone)]
1203pub enum BtnType {
1204    /// 表单
1205    Form,
1206    /// 表单下载
1207    FormDownload,
1208    /// 表单自定义
1209    FormCustom,
1210    FormData,
1211    /// 外部跳转
1212    Url,
1213    /// api请求
1214    Api,
1215    /// 下载
1216    Download,
1217    /// 内部跳转
1218    Path,
1219    /// 弹窗-定制页面
1220    DialogCustom,
1221}
1222
1223impl BtnType {
1224    fn str(self) -> &'static str {
1225        match self {
1226            BtnType::Form => "form",
1227            BtnType::FormDownload => "form_download",
1228            BtnType::FormCustom => "form_custom",
1229            BtnType::FormData => "form_data",
1230            BtnType::Api => "api",
1231            BtnType::Download => "download",
1232            BtnType::Url => "url",
1233            BtnType::Path => "path",
1234            BtnType::DialogCustom => "dialog_custom",
1235        }
1236    }
1237}
1238/// 按钮颜色
1239#[derive(Debug, Clone)]
1240pub enum BtnColor {
1241    Primary,
1242    Red,
1243    Blue,
1244    Yellow,
1245    Green,
1246}
1247
1248impl BtnColor {
1249    fn str(self) -> &'static str {
1250        match self {
1251            BtnColor::Primary => "primary",
1252            BtnColor::Red => "negative",
1253            BtnColor::Blue => "info",
1254            BtnColor::Yellow => "warning",
1255            BtnColor::Green => "positive",
1256        }
1257    }
1258}