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