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            if request.has_key(name) {
150                // 判断输入类型
151                match field["mode"].as_str().unwrap() {
152                    "int" => {
153                        if !request[name].is_number() {
154                            return Err(ApiResponse::fail(
155                                -1,
156                                format!(
157                                    "请求参数数据类型错误: 参数 [{}] 数据类型应为[{}]",
158                                    name, field["mode"]
159                                )
160                                .as_str(),
161                            ));
162                        }
163                    }
164                    "string" => {
165                        if !request[name].is_string() {
166                            return Err(ApiResponse::fail(
167                                -1,
168                                format!(
169                                    "请求参数数据类型错误: 参数 [{}] 数据类型应为[{}]",
170                                    name, field["mode"]
171                                )
172                                .as_str(),
173                            ));
174                        }
175                        if require && request[name].is_empty() {
176                            return Err(ApiResponse::fail(
177                                -1,
178                                format!("请求参数数据类型错误: 参数 [{}] 不能为空", name).as_str(),
179                            ));
180                        }
181                    }
182                    "switch" => {
183                        if !request[name].is_boolean() {
184                            return Err(ApiResponse::fail(
185                                -1,
186                                format!(
187                                    "请求参数数据类型错误: 参数 [{}] 数据类型应为[{}]",
188                                    name, field["mode"]
189                                )
190                                .as_str(),
191                            ));
192                        }
193                    }
194                    "select" => {
195                        if !request[name].is_array() && !request[name].is_string() {
196                            return Err(ApiResponse::fail(
197                                -1,
198                                format!(
199                                    "请求参数数据类型错误: 参数 [{}] 数据类型应为[{}]",
200                                    name, field["mode"]
201                                )
202                                .as_str(),
203                            ));
204                        }
205                        let option = field["option"]
206                            .members()
207                            .map(|m| m.as_str().unwrap_or(""))
208                            .collect::<Vec<&str>>()
209                            .join(",");
210                        if request[name].is_string()
211                            && !field["option"].contains(request[name].as_str().unwrap_or(""))
212                        {
213                            return Err(ApiResponse::fail(
214                                -1,
215                                format!(
216                                    "请求参数选项错误: 参数 [{}] 数据类型应为[{}]之内",
217                                    name, option
218                                )
219                                .as_str(),
220                            ));
221                        }
222                        if request[name].is_array() {
223                            let res1 = request[name]
224                                .members()
225                                .map(|m| m.as_str().unwrap_or(""))
226                                .collect::<Vec<&str>>();
227                            let diff = res1
228                                .iter()
229                                .filter(|&item| {
230                                    !field["option"]
231                                        .members()
232                                        .map(|m| m.as_str().unwrap_or(""))
233                                        .collect::<Vec<&str>>()
234                                        .contains(item)
235                                })
236                                .collect::<Vec<&&str>>();
237                            if !diff.is_empty() {
238                                return Err(ApiResponse::fail(
239                                    -1,
240                                    format!(
241                                        "请求参数选项错误: 参数 [{}] 数据 {:?} 应为[{:?}]范围之内",
242                                        name, diff, option
243                                    )
244                                    .as_str(),
245                                ));
246                            }
247                        }
248                    }
249                    "radio" => {
250                        if !request[name].is_string() {
251                            return Err(ApiResponse::fail(
252                                -1,
253                                format!(
254                                    "请求参数数据类型错误: 参数 [{}] 数据类型应为[{}] 实际为[{}]",
255                                    name, field["mode"], request[name]
256                                )
257                                .as_str(),
258                            ));
259                        }
260                        let option = field["option"]
261                            .members()
262                            .map(|m| m.as_str().unwrap_or(""))
263                            .collect::<Vec<&str>>()
264                            .join(",");
265                        if request[name].is_string()
266                            && !field["option"].contains(request[name].as_str().unwrap_or(""))
267                        {
268                            return Err(ApiResponse::fail(
269                                -1,
270                                format!(
271                                    "请求参数选项错误: 参数 [{}] 数据 [{}] 应为 [{}] 之一",
272                                    name, request[name], option
273                                )
274                                .as_str(),
275                            ));
276                        }
277                    }
278                    _ => {
279                        // println!("未知类型: {}", field["mode"])
280                    }
281                }
282            } else {
283                if require {
284                    return Err(ApiResponse::fail(
285                        -1,
286                        format!("请求参数错误: 参数[{}]必填", name).as_str(),
287                    ));
288                }
289                request[name] = field["def"].clone();
290            }
291        }
292        Ok(())
293    }
294    /// 内部入口
295    fn index(&mut self, request: Request) -> ApiResponse;
296    fn params_table_select(&mut self, mut params: JsonValue) -> JsonValue {
297        params["page"] = br_fields::int::Int::new(false, "page", "页数", 10, 1)
298            .example(1.into())
299            .field();
300        params["limit"] = br_fields::int::Int::new(false, "limit", "行数", 10, 10)
301            .example(10.into())
302            .field();
303        params["search"] = br_fields::str::Str::new(false, "search", "搜索", 200, "")
304            .example("".into())
305            .field();
306        params["where_or"] = br_fields::text::Array::new(false, "where_or", "查询条件", array![])
307            .example(array![])
308            .field();
309        params["where_and"] = br_fields::text::Array::new(false, "where_and", "查询条件", array![])
310            .example(array![])
311            .field();
312        params["params"] = br_fields::text::Object::new(false, "params", "关联数据参数", object!{})
313            .example(object!{})
314            .field();
315        params
316    }
317    #[cfg(any(feature = "sqlite", feature = "mssql", feature = "mysql"))]
318    fn table_select(
319        &mut self,
320        request: JsonValue,
321        table_name: &str,
322        mut fields: Vec<&str>,
323    ) -> JsonValue {
324        let page = request["page"].as_i32().unwrap_or(1);
325        let limit = request["limit"].as_i32().unwrap_or(10);
326
327        let search = request["search"].as_str().unwrap_or("");
328
329        let where_or = request["where_or"].clone();
330        let where_and = request["where_and"].clone();
331
332        let mut tools = self.tools();
333        let db = tools.db.table(table_name);
334
335        if !search.is_empty() {
336            db.where_and(&fields.join("|"), "like", format!("%{}%", search).into());
337        }
338
339        for (key, value) in where_or.entries() {
340            if value.is_empty() {
341                continue;
342            }
343            if value.is_array() {
344                db.where_or(key, "between", value.clone());
345                db.where_or(key, "in", value.clone());
346            } else if value.is_boolean() {
347                db.where_or(key, "=", value.clone());
348            } else {
349                db.where_or(key, "like", format!("%{}%", value).into());
350            }
351        }
352
353        for value in where_and.members() {
354            db.where_and(
355                value[0].as_str().unwrap(),
356                value[1].as_str().unwrap(),
357                value[2].clone(),
358            );
359        }
360
361        let total = (db.clone().count().as_f64().unwrap() / limit as f64).ceil() as i64;
362        let mut db_list = db.clone();
363
364        fields.push("id");
365        db_list.field(&fields.join(","));
366
367        let mut data = db_list.page(page, limit).select();
368        let mut list = array![];
369        for item in data.members_mut() {
370            let value = item["id"].clone();
371            item.remove("id");
372
373            let label = item
374                .entries()
375                .map(|(_, v)| v.as_str().unwrap())
376                .collect::<Vec<&str>>();
377
378            list.push(object! {
379                value: value,
380                label: label.join(" | ").clone(),
381            })
382            .unwrap();
383        }
384        object! {
385            total:total,
386            data:list,
387        }
388    }
389    /// 菜单表格接收参数
390    fn params_table_menu(&mut self, mut params: JsonValue) -> JsonValue {
391        params["search"] = br_fields::str::Str::new(false, "search", "搜索", 200, "")
392            .example("".into())
393            .field();
394        params["where_or"] = br_fields::text::Array::new(false, "where_or", "查询条件", array![])
395            .example(array![])
396            .field();
397        params["where_and"] = br_fields::text::Array::new(false, "where_and", "查询条件", array![])
398            .example(array![])
399            .field();
400        params
401    }
402    #[cfg(any(feature = "sqlite", feature = "mssql", feature = "mysql"))]
403    fn table_menu(
404        &mut self,
405        request: JsonValue,
406        table_name: &str,
407        label_field: &str,
408        fields: JsonValue,
409
410        hidd_field: Vec<&str>,
411        show_field: Vec<&str>,
412
413        search_fields: Vec<&str>,
414        _filter_fields: Vec<&str>,
415    ) -> JsonValue {
416        let search = request["search"].as_str().unwrap_or("");
417
418        let order = request["order"].clone();
419        let where_or = request["where_or"].clone();
420        let where_and = request["where_and"].clone();
421        let mut columns = array![];
422        let mut search_name = vec![];
423        let mut search_field = vec![];
424        let mut filter_columns = vec![];
425        let mut table_fields = object! {};
426        let mut table_field_json = vec![];
427
428        let mut alls_field = fields.entries().map(|(x, _)| x).collect::<Vec<&str>>();
429        alls_field.retain(|x| !hidd_field.contains(x));
430        if !show_field.is_empty() {
431            alls_field.retain(|x| show_field.contains(x) || *x == "id");
432        }
433
434        for item in alls_field.iter() {
435            let row = fields[item.clone()].clone();
436            let field = row["field"].to_string();
437            let title = row["title"].to_string();
438            let mode = row["mode"].to_string();
439
440            if search_fields.contains(&field.as_str()) {
441                search_name.push(title);
442                search_field.push(field.clone());
443            }
444            filter_columns.push(self.filter_column(row.clone()));
445            columns.push(self.table_column(row.clone())).unwrap();
446            let mut table_field_info = object! {};
447            match mode.as_str() {
448                "table" => table_field_info = row.clone(),
449                "array" => table_field_json.push(field.clone()),
450                _ => {}
451            }
452            if !table_field_info.is_empty() {
453                table_fields[field.as_str()] = table_field_info;
454            }
455        }
456
457        let mut tools = self.tools();
458        let db = tools.db.table(table_name);
459
460        if !search.is_empty() {
461            db.where_and(
462                &search_field.join("|"),
463                "like",
464                format!("%{}%", search).into(),
465            );
466        }
467
468        for (key, value) in where_or.entries() {
469            if value.is_empty() {
470                continue;
471            }
472            if value.is_array() {
473                 db.where_or(key, "between", value.clone());
474                db.where_or(key, "in", value.clone());
475            } else if value.is_boolean() {
476                db.where_or(key, "=", value.clone());
477            } else {
478                db.where_or(key, "like", format!("%{}%", value).into());
479            }
480        }
481
482        for value in where_and.members() {
483            db.where_and(
484                value[0].as_str().unwrap(),
485                value[1].as_str().unwrap(),
486                value[2].clone(),
487            );
488        }
489
490        let mut db_list = db.clone();
491
492        for item in order.members() {
493            db_list.order(item[0].as_str().unwrap(), item[1].as_bool().unwrap());
494        }
495
496        let t = alls_field.join(",");
497        db_list.field(t.as_str());
498
499        if !table_field_json.is_empty() {
500            db_list.json(&table_field_json.join(","));
501        }
502
503        let mut data = db_list.select();
504
505        let mut table_datas = object! {};
506        let mut ids = HashMap::new();
507
508        for item in data.members_mut() {
509            for (field, _) in table_fields.entries() {
510                if table_datas[field].is_empty() {
511                    table_datas[field] = array![];
512                }
513                let _ = table_datas[field].push(item[field].clone());
514            }
515        }
516        for (field, info) in table_fields.entries_mut() {
517            let _ = info["fields"].push("id");
518            let fields_k = info["fields"]
519                .members()
520                .map(|x| x.as_str().unwrap())
521                .collect::<Vec<&str>>();
522            let table_name = info["table"].clone();
523            let mut data_list = self
524                .tools()
525                .db
526                .table(table_name.as_str().unwrap())
527                .where_and("id", "in", table_datas[field].clone())
528                .field(&fields_k.join(","))
529                .select();
530
531            for item in data_list.members_mut() {
532                let id = item["id"].as_str().unwrap_or("").to_string();
533                item.remove("id");
534                let label = item
535                    .entries()
536                    .map(|(_, v)| v.as_str().unwrap())
537                    .collect::<Vec<&str>>();
538                ids.insert(
539                    id.clone(),
540                    object! {
541                        value: id.clone(),
542                        label:label.join(" | ").clone(),
543                    },
544                );
545            }
546        }
547
548        for item in data.members_mut() {
549            for (field, _) in table_fields.entries() {
550                if item[field].is_empty() {
551                    continue;
552                }
553                item[field] = ids[item[field].as_str().unwrap()].clone();
554            }
555        }
556
557        object! {
558            data:data,
559            columns:columns,
560            search_name:search_name.join("/"),
561            filter_columns:filter_columns,
562            label_field:label_field,
563            btn_all:array![],
564            btn_api:array![]
565        }
566    }
567    /// 树型表格接收参数
568    fn params_table_tree(&mut self, mut params: JsonValue) -> JsonValue {
569        params["pid"] = br_fields::str::Str::new(false, "pid", "上级ID", 50, "")
570            .example("".into())
571            .field();
572        params["search"] = br_fields::str::Str::new(false, "search", "搜索", 200, "")
573            .example("".into())
574            .field();
575        params["where_or"] = br_fields::text::Array::new(false, "where_or", "查询条件", array![])
576            .example(array![])
577            .field();
578        params["where_and"] = br_fields::text::Array::new(false, "where_and", "查询条件", array![])
579            .example(array![])
580            .field();
581        params
582    }
583    #[cfg(any(feature = "sqlite", feature = "mssql", feature = "mysql"))]
584    fn table_tree(
585        &mut self,
586        request: JsonValue,
587        table_name: &str,
588        pid_field: &str,
589        label_field: &str,
590        fields: JsonValue,
591        hidd_field: Vec<&str>,
592        show_field: Vec<&str>,
593        search_fields: Vec<&str>,
594        _filter_fields: Vec<&str>,
595    ) -> JsonValue {
596        let search = request["search"].as_str().unwrap_or("");
597
598        let pid = request["pid"].clone();
599
600        let order = request["order"].clone();
601        let where_or = request["where_or"].clone();
602        let where_and = request["where_and"].clone();
603        let mut columns = array![];
604        let mut search_name = vec![];
605        let mut search_field = vec![];
606        let mut filter_columns = vec![];
607        let mut table_field_json = vec![];
608        let mut table_fields = object! {};
609
610        let mut alls_field = fields.entries().map(|(x, _)| x).collect::<Vec<&str>>();
611        alls_field.retain(|x| !hidd_field.contains(x));
612        if !show_field.is_empty() {
613            alls_field.retain(|x| show_field.contains(x) || *x == "id");
614        }
615
616        for item in alls_field.iter() {
617            let row = fields[item.clone()].clone();
618            let field = row["field"].to_string();
619            let title = row["title"].to_string();
620            let mode = row["mode"].to_string();
621
622            if search_fields.contains(&field.as_str()) {
623                search_name.push(title);
624                search_field.push(field.clone());
625            }
626            filter_columns.push(self.filter_column(row.clone()));
627            columns.push(self.table_column(row.clone())).unwrap();
628            let mut table_field_info = object! {};
629            match mode.as_str() {
630                "table" => table_field_info = row.clone(),
631                "array" => table_field_json.push(field.clone()),
632                _ => {}
633            }
634            if !table_field_info.is_empty() {
635                table_fields[field.as_str()] = table_field_info;
636            }
637        }
638
639        let mut tools = self.tools();
640        let db = tools.db.table(table_name);
641        db.where_and(pid_field, "=", pid);
642        if !search.is_empty() {
643            db.where_and(
644                &search_field.join("|"),
645                "like",
646                format!("%{}%", search).into(),
647            );
648        }
649
650        for (key, value) in where_or.entries() {
651            if value.is_empty() {
652                continue;
653            }
654            if value.is_array() {
655                // db.where_or(key, "between", value.clone());
656                db.where_or(key, "in", value.clone());
657            } else if value.is_boolean() {
658                db.where_or(key, "=", value.clone());
659            } else {
660                db.where_or(key, "like", format!("%{}%", value).into());
661            }
662        }
663
664        for value in where_and.members() {
665            db.where_and(
666                value[0].as_str().unwrap(),
667                value[1].as_str().unwrap(),
668                value[2].clone(),
669            );
670        }
671
672        let mut db_list = db.clone();
673
674        for item in order.members() {
675            db_list.order(item[0].as_str().unwrap(), item[1].as_bool().unwrap());
676        }
677        let t = alls_field.join(",");
678        db_list.field(t.as_str());
679        if !table_field_json.is_empty() {
680            db_list.json(&table_field_json.join(","));
681        }
682        let mut data = db_list.select();
683
684        let mut table_datas = object! {};
685        let mut ids = HashMap::new();
686
687        for item in data.members_mut() {
688            for (field, _) in table_fields.entries() {
689                if table_datas[field].is_empty() {
690                    table_datas[field] = array![];
691                }
692                let _ = table_datas[field].push(item[field].clone());
693            }
694        }
695        for (field, info) in table_fields.entries_mut() {
696            let _ = info["fields"].push("id");
697            let fields_k = info["fields"]
698                .members()
699                .map(|x| x.as_str().unwrap())
700                .collect::<Vec<&str>>();
701            let table_name = info["table"].clone();
702            let mut data_list = self
703                .tools()
704                .db
705                .table(table_name.as_str().unwrap())
706                .where_and("id", "in", table_datas[field].clone())
707                .field(&fields_k.join(","))
708                .select();
709
710            for item in data_list.members_mut() {
711                let id = item["id"].as_str().unwrap_or("").to_string();
712                item.remove("id");
713                let label = item
714                    .entries()
715                    .map(|(_, v)| v.as_str().unwrap())
716                    .collect::<Vec<&str>>();
717                ids.insert(
718                    id.clone(),
719                    object! {
720                        value: id.clone(),
721                        label:label.join(" | ").clone(),
722                    },
723                );
724            }
725        }
726
727        let mut list = array![];
728        for item in data.members_mut() {
729            for (field, _) in table_fields.entries() {
730                if item[field].is_empty() {
731                    continue;
732                }
733                item[field] = ids[item[field].as_str().unwrap()].clone();
734            }
735            let _ = list.push(object! {
736                id:item["id"].as_str().unwrap(),
737                label:item[label_field].as_str().unwrap(),
738                data:item.clone(),
739            });
740        }
741
742        object! {
743            data:list,
744            columns:columns,
745            search_name:search_name.join("/"),
746            filter_columns:filter_columns,
747            pid_field:pid_field,
748            btn_all:array![],
749            btn_api:array![]
750        }
751    }
752    /// 表格接收参数
753    fn params_table_list(&mut self, mut params: JsonValue) -> JsonValue {
754        params["page"] = br_fields::int::Int::new(false, "page", "页数", 10, 1)
755            .example(1.into())
756            .field();
757        params["limit"] = br_fields::int::Int::new(false, "limit", "行数", 10, 10)
758            .example(10.into())
759            .field();
760        params["search"] = br_fields::str::Str::new(false, "search", "搜索", 200, "")
761            .example("".into())
762            .field();
763        params["order"] = br_fields::text::Array::new(false, "order", "排序", array![])
764            .example(array![array!["id", false]])
765            .field();
766        params["where_or"] = br_fields::text::Array::new(false, "where_or", "查询条件", array![])
767            .example(array![])
768            .field();
769        params["where_and"] = br_fields::text::Array::new(false, "where_and", "查询条件", array![])
770            .example(array![])
771            .field();
772        params
773    }
774    /// 列表表格渲染
775    /// * table_name 表名
776    /// * fields 全部模型字段集合
777    /// * hidd_field 需要隐藏的字段集合
778    /// * show_field 需要显示的字段集合
779    /// * search_fields 搜索字段集合
780    /// * filter_fields 高级搜索字段集合
781    #[cfg(any(feature = "sqlite", feature = "mssql", feature = "mysql"))]
782    fn table_list(
783        &mut self,
784        request: JsonValue,
785        table_name: &str,
786        fields: JsonValue,
787        hidd_field: Vec<&str>,
788        show_field: Vec<&str>,
789        search_fields: Vec<&str>,
790        filter_fields: Vec<&str>,
791    ) -> JsonValue {
792        let page = request["page"].as_i32().unwrap_or(1);
793        let limit = request["limit"].as_i32().unwrap_or(10);
794        let search = request["search"].as_str().unwrap_or("");
795        let order = request["order"].clone();
796        let where_or = request["where_or"].clone();
797        let where_and = request["where_and"].clone();
798        let mut columns = array![];
799        let mut search_name = vec![];
800        let mut search_field = vec![];
801        let mut filter_columns = vec![];
802
803        let mut table_fields = object! {};
804
805        let mut alls_field = fields.entries().map(|(x, _)| x).collect::<Vec<&str>>();
806        alls_field.retain(|x| !hidd_field.contains(x));
807        if !show_field.is_empty() {
808            alls_field.retain(|x| show_field.contains(x) || *x == "id");
809        }
810
811        for item in alls_field.iter() {
812            let key = item.clone();
813            let field = fields[key]["field"].as_str().unwrap();
814            let title = fields[key]["title"].as_str().unwrap();
815            let mode = fields[key]["mode"].as_str().unwrap();
816
817            if search_fields.contains(&field) {
818                search_name.push(title);
819                search_field.push(field);
820            }
821            if filter_fields.contains(&field) {
822                filter_columns.push(self.filter_column(fields[key].clone()));
823            }
824            columns
825                .push(self.table_column(fields[key].clone()))
826                .unwrap();
827            let table_field_info = if mode == "table" {
828                fields[key].clone()
829            } else {
830                JsonValue::Null
831            };
832            if !table_field_info.is_empty() {
833                table_fields[field] = table_field_info;
834            }
835        }
836
837        let mut tools = self.tools();
838        let db = tools.db.table(table_name);
839
840        if !search.is_empty() {
841            db.where_and(
842                &search_field.join("|"),
843                "like",
844                format!("%{}%", search).into(),
845            );
846        }
847
848        for (key, value) in where_or.entries() {
849            if value.is_empty() {
850                continue;
851            }
852            if value.is_array() {
853                // db.where_or(key, "between", value.clone());
854                db.where_or(key, "in", value.clone());
855            } else if value.is_boolean() {
856                db.where_or(key, "=", value.clone());
857            } else {
858                db.where_or(key, "like", format!("%{}%", value).into());
859            }
860        }
861
862        for value in where_and.members() {
863            db.where_and(
864                value[0].as_str().unwrap(),
865                value[1].as_str().unwrap(),
866                value[2].clone(),
867            );
868        }
869
870        let total = db.clone().count().as_f64().unwrap();
871        // let total = (db.clone().count().as_f64().unwrap() / limit as f64).ceil() as i64;
872        let mut db_list = db.clone();
873
874        for item in order.members() {
875            db_list.order(item[0].as_str().unwrap(), item[1].as_bool().unwrap());
876        }
877
878        let t = alls_field.join(",");
879        db_list.field(t.as_str());
880
881        let mut data = db_list.page(page, limit).select();
882
883        let mut table_datas = object! {};
884        let mut ids = HashMap::new();
885
886        for item in data.members_mut() {
887            if table_fields.is_empty() {
888                continue;
889            }
890            for (field, _) in table_fields.entries() {
891                if table_datas[field].is_empty() {
892                    table_datas[field] = array![];
893                }
894                let _ = table_datas[field].push(item[field].clone());
895            }
896        }
897        for (field, info) in table_fields.entries_mut() {
898            let _ = info["fields"].push("id");
899            let fields_k = info["fields"]
900                .members()
901                .map(|x| x.as_str().unwrap())
902                .collect::<Vec<&str>>();
903            let table_name = info["table"].clone();
904            let mut data_list = self
905                .tools()
906                .db
907                .table(table_name.as_str().unwrap())
908                .where_and("id", "in", table_datas[field].clone())
909                .field(&fields_k.join(","))
910                .select();
911
912            for item in data_list.members_mut() {
913                let id = item["id"].as_str().unwrap_or("").to_string();
914                item.remove("id");
915                let label = item
916                    .entries()
917                    .map(|(_, v)| v.to_string())
918                    .collect::<Vec<String>>();
919                ids.insert(
920                    id.clone(),
921                    object! {
922                        value: id.clone(),
923                        label:label.join(" | ").clone(),
924                    },
925                );
926            }
927        }
928
929        for item in data.members_mut() {
930            if table_fields.is_empty() {
931                continue;
932            }
933            for (field, _) in table_fields.entries() {
934                if item[field].is_empty() {
935                    continue;
936                }
937                let key = item[field].as_str().unwrap_or("");
938                if key.is_empty() {
939                    continue;
940                }
941                if ids.get(key).is_none() {
942                    continue;
943                }
944                item[field] = ids.get(key).unwrap().clone();
945            }
946        }
947
948        object! {
949            total:total,
950            data:data,
951            columns:columns,
952            search_name:search_name.join("/"),
953            filter_columns:filter_columns,
954            btn_all:array![],
955            btn_api:array![],
956            btn_ids:array![]
957        }
958    }
959    fn table_column(&mut self, field: JsonValue) -> JsonValue {
960        object! {
961            name:field["field"].clone(),
962            label:field["title"].clone(),
963            align:"center",
964            field:field["field"].clone(),
965            sortable:true,
966            mode:field["mode"].clone(),
967        }
968    }
969    fn filter_column(&mut self, field: JsonValue) -> JsonValue {
970        object! {
971            name:field["field"].clone(),
972            label:field["title"].clone(),
973            mode:field["mode"].clone(),
974            option:field["option"].clone(),
975            api:field["api"].clone(),
976        }
977    }
978    /// 使用工具
979    fn tools(&mut self) -> Tools {
980        let tools = PLUGIN_TOOLS.lock().unwrap();
981        let tools = tools.get("tools").unwrap().clone();
982        tools
983    }
984    /// 按钮信息
985    /// * cnd 显示条件 vec![vec!["xxx","=","yyy"],vec!["zzz","=","eee"]]
986    fn btn(&mut self) -> Btn {
987        let mut btn = Btn::new(self.api().as_str());
988        btn.fields(self.params().clone());
989        btn.icon(self.icon());
990        btn.desc(self.description());
991        btn.title(self.title());
992        btn.btn_type(BtnType::Api);
993        btn.btn_color(BtnColor::Primary);
994        btn.path(self.api().clone().replace(".", "/").as_str());
995        btn
996    }
997}
998#[derive(Debug, Clone)]
999pub struct Btn {
1000    api: String,
1001    title: String,
1002    desc: String,
1003    btn_type: BtnType,
1004    color: BtnColor,
1005    icon: String,
1006    cnd: Vec<JsonValue>,
1007    url: String,
1008    path: String,
1009    fields: JsonValue,
1010}
1011impl Btn {
1012    pub fn new(api: &str) -> Self {
1013        Self {
1014            api: api.to_string(),
1015            title: "".to_string(),
1016            desc: "".to_string(),
1017            btn_type: BtnType::Api,
1018            color: BtnColor::Primary,
1019            icon: "".to_string(),
1020            cnd: vec![],
1021            url: "".to_string(),
1022            path: "".to_string(),
1023            fields: object! {},
1024        }
1025    }
1026    pub fn path(&mut self, path: &str) -> &mut Self {
1027        self.path = path.to_string();
1028        self
1029    }
1030    pub fn cnd(&mut self, cnd: Vec<JsonValue>) -> &mut Self {
1031        self.cnd = cnd;
1032        self
1033    }
1034    pub fn btn_type(&mut self, btn_type: BtnType) -> &mut Self {
1035        self.btn_type = btn_type;
1036        self
1037    }
1038    pub fn btn_color(&mut self, btn_color: BtnColor) -> &mut Self {
1039        self.color = btn_color;
1040        self
1041    }
1042    pub fn fields(&mut self, fields: JsonValue) -> &mut Self {
1043        self.fields = fields;
1044        self
1045    }
1046    pub fn url(&mut self, url: &str) -> &mut Self {
1047        self.url = url.to_string();
1048        self
1049    }
1050    pub fn title(&mut self, title: &str) -> &mut Self {
1051        self.title = title.to_string();
1052        self
1053    }
1054    pub fn desc(&mut self, desc: &str) -> &mut Self {
1055        self.desc = desc.to_string();
1056        self
1057    }
1058    pub fn icon(&mut self, icon: &str) -> &mut Self {
1059        self.icon = icon.to_string();
1060        self
1061    }
1062    pub fn json(&mut self) -> JsonValue {
1063        object! {
1064            api:self.api.clone(),
1065            title:self.title.clone(),
1066            desc:self.desc.clone(),
1067            btn_type:self.btn_type.clone().str(),
1068            color:self.color.clone().str(),
1069            icon:self.icon.clone(),
1070            cnd:self.cnd.clone(),
1071            url:self.url.clone(),
1072            path:self.path.clone(),
1073            fields:self.fields.clone()
1074        }
1075    }
1076}
1077
1078/// 接口类型
1079#[derive(Debug, Clone)]
1080pub enum InterfaceType {
1081    API,
1082    BTN,
1083    MENU,
1084}
1085
1086impl InterfaceType {
1087    pub fn str(self) -> &'static str {
1088        match self {
1089            InterfaceType::API => "api",
1090            InterfaceType::BTN => "btn",
1091            InterfaceType::MENU => "menu",
1092        }
1093    }
1094    pub fn types() -> Vec<&'static str> {
1095        vec!["api", "btn", "menu"]
1096    }
1097}
1098
1099/// 按钮类型
1100#[derive(Debug, Clone)]
1101pub enum BtnType {
1102    /// 表单
1103    Form,
1104    /// 表单下载
1105    FormDownload,
1106    /// 表单自定义
1107    FormCustom,
1108    FormData,
1109    /// 外部跳转
1110    Url,
1111    /// api请求
1112    Api,
1113    /// 下载
1114    Download,
1115    /// 内部跳转
1116    Path,
1117    /// 弹窗-定制页面
1118    DialogCustom,
1119}
1120
1121impl BtnType {
1122    fn str(self) -> &'static str {
1123        match self {
1124            BtnType::Form => "form",
1125            BtnType::FormDownload => "form_download",
1126            BtnType::FormCustom => "form_custom",
1127            BtnType::FormData => "form_data",
1128            BtnType::Api => "api",
1129            BtnType::Download => "download",
1130            BtnType::Url => "url",
1131            BtnType::Path => "path",
1132            BtnType::DialogCustom => "dialog_custom",
1133        }
1134    }
1135}
1136/// 按钮颜色
1137#[derive(Debug, Clone)]
1138pub enum BtnColor {
1139    Primary,
1140    Red,
1141    Blue,
1142    Yellow,
1143    Green,
1144}
1145
1146impl BtnColor {
1147    fn str(self) -> &'static str {
1148        match self {
1149            BtnColor::Primary => "primary",
1150            BtnColor::Red => "negative",
1151            BtnColor::Blue => "info",
1152            BtnColor::Yellow => "warning",
1153            BtnColor::Green => "positive",
1154        }
1155    }
1156}