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