br_addon/
action.rs

1use crate::request::{ContentType, Method, Request};
2use crate::{CONFIG, GLOBAL_DATA, PLUGIN_TOOLS};
3use crate::{ApiResponse, Tools};
4use br_fields::Field;
5use json::{array, object, JsonValue};
6use std::any::type_name;
7use std::collections::HashMap;
8use crate::tables::Tables;
9
10/// 功能接口
11pub trait Action {
12    /// 功能名称
13    fn _name(&self) -> String {
14        type_name::<Self>().rsplit("::").next().unwrap().to_lowercase()
15    }
16    /// 模块名称
17    fn module_name(&self) -> String {
18        let t = type_name::<Self>().split("::").collect::<Vec<&str>>();
19        let plugin = t[2].to_lowercase();
20        let module = t[3].to_lowercase();
21        format!("{plugin}.{module}")
22    }
23    /// 插件名称
24    fn addon_name(&self) -> String {
25        let t = type_name::<Self>().split("::").collect::<Vec<&str>>();
26        t[2].to_lowercase()
27    }
28    /// API 名称
29    fn api(&self) -> String {
30        let t = type_name::<Self>().split("::").collect::<Vec<&str>>();
31        let plugin = t[2].to_lowercase();
32        let module = t[3].to_lowercase();
33        let action = t[4].to_lowercase();
34        format!("{plugin}.{module}.{action}")
35    }
36    /// 是否需要密钥
37    fn token(&self) -> bool {
38        true
39    }
40
41    fn sort(&self) -> usize {
42        99
43    }
44    /// 功能标题
45    fn title(&self) -> &'static str;
46    /// 功能描述
47    fn description(&self) -> &'static str {
48        ""
49    }
50    /// 请求地址路径
51    fn path(&self) -> &'static str {
52        ""
53    }
54    /// 请求地址参数
55    fn query(&self) -> JsonValue {
56        object! {}
57    }
58    /// 标签范围
59    fn tags(&self) -> &'static [&'static str] {
60        &[]
61    }
62    fn icon(&self) -> &'static str {
63        ""
64    }
65    /// 是否公开
66    fn public(&self) -> bool {
67        true
68    }
69    /// 是否权限组显示
70    fn auth(&self) -> bool {
71        true
72    }
73    /// 接口类型 btn api menu
74    fn interface_type(&self) -> InterfaceType {
75        InterfaceType::API
76    }
77    /// 允许的请求类型
78    fn method(&mut self) -> Method {
79        Method::Post
80    }
81    /// 请求类型
82    fn content_type(&mut self) -> ContentType {
83        ContentType::Json
84    }
85    /// 是否检查参数
86    fn params_check(&mut self) -> bool {
87        true
88    }
89    /// 请求body参数
90    fn params(&mut self) -> JsonValue {
91        object! {}
92    }
93    /// 成功响应
94    fn success(&mut self) -> ApiResponse {
95        let mut data = object! {};
96        data["code"] = br_fields::int::Int::new(true, "code", "编号", 10, 0).example(0.into()).swagger();
97        data["message"] = br_fields::str::Str::new(true, "message", "成功消息", 256, "").example("成功".into()).swagger();
98        data["data"] = br_fields::text::Json::new(true, "data", "返回数据", object! {}).swagger();
99        data["success"] = br_fields::int::Switch::new(true, "success", "成功状态", true).example(true.into()).swagger();
100        data["timestamp"] = br_fields::datetime::Timestamp::new(true, "timestamp", "时间戳", 0, 0.0).swagger();
101        ApiResponse::success(data, "请求成功")
102    }
103    /// 失败响应
104    fn error(&mut self) -> ApiResponse {
105        let mut data = object! {};
106        data["code"] = br_fields::int::Int::new(true, "code", "编号", 10, 1000).example(1000.into()).swagger();
107        data["message"] = br_fields::str::Str::new(true, "message", "错误消息", 256, "").example("失败".into()).swagger();
108        data["data"] = br_fields::text::Json::new(true, "data", "返回数据", object! {}).swagger();
109        data["success"] = br_fields::int::Switch::new(true, "success", "成功状态", false).example(false.into()).swagger();
110        data["timestamp"] = br_fields::datetime::Timestamp::new(true, "timestamp", "时间戳", 0, 0.0).swagger();
111        ApiResponse::error(data, "请求失败")
112    }
113    /// 外部入口
114    fn run(&mut self, mut request: Request) -> Result<ApiResponse, ApiResponse> {
115        if self.public() && !self.method().str().is_empty() && self.method().str().to_lowercase() != request.method.str().to_lowercase() {
116            return Err(ApiResponse::fail(
117                -1,
118                format!(
119                    "Request type error: Actual [{}] Expected [{}]",
120                    request.method.str(),
121                    self.method().str()
122                ).as_str(),
123            ));
124        }
125        let params = self.params().clone();
126        if self.params_check() {
127            self.check(&mut request.query.clone(), self.query().clone())?;
128            self.check(&mut request.body, params)?;
129        }
130        let res = self.index(request.clone());
131        match res.success {
132            true => Ok(res),
133            false => Err(res),
134        }
135    }
136    /// 入参验证
137    fn check(&mut self, request: &mut JsonValue, params: JsonValue) -> Result<(), ApiResponse> {
138        let req = request.clone();
139        for (name, _) in req.entries() {
140            if !params.has_key(name) {
141                request.remove(name);
142            }
143        }
144        for (name, field) in params.entries() {
145            let require = field["require"].as_bool().unwrap_or(false);
146            let title = field["title"].as_str().unwrap_or("");
147            if request.has_key(name) {
148                // 判断输入类型
149                match field["mode"].as_str().unwrap() {
150                    "key" => {
151                        if !request[name].is_string() {
152                            return Err(ApiResponse::fail(
153                                900_001,
154                                format!(
155                                    "请求参数数据类型错误: 参数 [{}] 数据类型应为[{}]",
156                                    name, field["mode"]
157                                ).as_str(),
158                            ));
159                        }
160                        if require && request[name].is_empty() {
161                            return Err(ApiResponse::fail(
162                                900014,
163                                format!("请求参数数据类型错误: 参数 [{name}] 不能为空").as_str(),
164                            ));
165                        }
166                    }
167                    "text" | "table" | "tree" => {
168                        if !request[name].is_string() {
169                            return Err(ApiResponse::fail(
170                                900002,
171                                format!(
172                                    "请求参数数据类型错误: 参数 [{}] 数据类型应为[{}]",
173                                    name, field["mode"]
174                                ).as_str(),
175                            ));
176                        }
177                        if require && request[name].is_empty() {
178                            return Err(ApiResponse::fail(
179                                900002,
180                                format!("{title} 必填").as_str(),
181                            ));
182                        }
183                    }
184                    "file" => {
185                        if !request[name].is_array() && !request[name].is_string() {
186                            return Err(ApiResponse::fail(
187                                900003,
188                                format!("参数 [{}] 数据类型应为[{}]", name, field["mode"]).as_str(),
189                            ));
190                        }
191                        if require && request[name].is_empty() {
192                            return Err(ApiResponse::fail(
193                                900002,
194                                format!("{title} 必填").as_str(),
195                            ));
196                        }
197                    }
198                    "int" => {
199                        if require && request[name].to_string().is_empty() {
200                            return Err(ApiResponse::fail(
201                                900_002,
202                                format!("{title} 必填").as_str(),
203                            ));
204                        }
205                        if !request[name].to_string().is_empty() {
206                            match request[name].to_string().parse::<i64>() {
207                                Ok(_) => {}
208                                Err(_) => {
209                                    return Err(ApiResponse::fail(
210                                        900013,
211                                        format!(
212                                            "请求参数数据类型错误: 参数 [{}] 数据类型应为[{}]",
213                                            name, field["mode"]
214                                        ).as_str(),
215                                    ));
216                                }
217                            }
218                        }
219                    }
220                    "timestamp" => {
221                        if require && request[name].to_string().is_empty() {
222                            return Err(ApiResponse::fail(
223                                900002,
224                                format!("{title} 必填").as_str(),
225                            ));
226                        }
227                        if !request[name].to_string().is_empty() {
228                            if request[name].is_array() && request[name].len() == 2 {
229                                // 如果是数组,遍历每个元素
230                                for item in request[name].members() {
231                                    match item.to_string().parse::<f64>() {
232                                        Ok(_) => {}
233                                        Err(_) => {
234                                            return Err(ApiResponse::fail(
235                                                900_013,
236                                                format!(
237                                                    "请求参数数据类型错误: 参数 [{}] 数据类型应为[{}]",
238                                                    name, field["mode"]
239                                                ).as_str(),
240                                            ));
241                                        }
242                                    }
243                                }
244                            } else {
245                                match request[name].to_string().parse::<f64>() {
246                                    Ok(_) => {}
247                                    Err(_) => {
248                                        return Err(ApiResponse::fail(
249                                            900013,
250                                            format!(
251                                                "请求参数数据类型错误: 参数 [{}] 数据类型应为[{}]",
252                                                name, field["mode"]
253                                            ).as_str(),
254                                        ));
255                                    }
256                                }
257                            }
258                        }
259                    }
260                    "float" => {
261                        if require && request[name].to_string().is_empty() {
262                            return Err(ApiResponse::fail(
263                                900002,
264                                format!("{title} 必填").as_str(),
265                            ));
266                        }
267                        if !request[name].to_string().is_empty() {
268                            match request[name].to_string().parse::<f64>() {
269                                Ok(_) => {}
270                                Err(_) => {
271                                    return Err(ApiResponse::fail(
272                                        900023,
273                                        format!(
274                                            "请求参数数据类型错误: 参数 [{}] 数据类型应为[{}]",
275                                            name, field["mode"]
276                                        ).as_str(),
277                                    ));
278                                }
279                            }
280                        }
281                    }
282                    "string" | "time" | "code" | "pass" | "email" | "location" | "color" | "date" | "barcode" | "datetime" | "editor" | "tel" => {
283                        if !request[name].is_string() {
284                            return Err(ApiResponse::fail(
285                                -1,
286                                format!(
287                                    "请求参数数据类型错误: 参数 [{}] 数据类型应为[{}]",
288                                    name, field["mode"]
289                                ).as_str(),
290                            ));
291                        }
292                        if require && request[name].is_empty() {
293                            return Err(ApiResponse::fail(
294                                900004,
295                                format!("{title} 必填").as_str(),
296                            ));
297                        }
298                    }
299                    "dict" => {
300                        if require && request[name].is_empty() {
301                            return Err(ApiResponse::fail(
302                                900005,
303                                format!("{title} 必填").as_str(),
304                            ));
305                        }
306                    }
307                    "switch" => {
308                        match request[name].to_string().parse::<bool>() {
309                            Ok(e) => {
310                                request[name] = e.into();
311                            }
312                            Err(_) => {
313                                return Err(ApiResponse::fail(
314                                    -1,
315                                    format!("请求参数数据类型错误: 参数 [{name}] 数据类型应为[{}]", field["mode"]).as_str(),
316                                ));
317                            }
318                        }
319                    }
320                    "select" => {
321                        if !request[name].is_array() && !request[name].is_string() {
322                            return Err(ApiResponse::fail(
323                                -1,
324                                format!(
325                                    "请求参数数据类型错误: 参数 [{}] 数据类型应为[{}]",
326                                    name, field["mode"]
327                                ).as_str(),
328                            ));
329                        }
330                        let value = if request[name].is_array() {
331                            request[name].members().map(|m| m.to_string()).collect::<Vec<String>>()
332                        } else {
333                            request[name].to_string().split(",").map(|x| x.to_string()).collect::<Vec<String>>()
334                        };
335                        let option = field["option"].members().map(|m| m.as_str().unwrap_or("")).collect::<Vec<&str>>();
336
337                        let require = field["require"].as_bool().unwrap();
338                        for item in value.clone() {
339                            if !option.contains(&&*item.clone()) && (item.is_empty() && require) {
340                                let option = field["option"].members().map(|m| m.as_str().unwrap_or("")).collect::<Vec<&str>>().join(",");
341                                return Err(ApiResponse::fail(-1, format!("请求参数选项错误: 参数 [{item}] 数据类型应为[{option}]之内").as_str()));
342                            }
343                        }
344                        request[name] = value.into();
345                    }
346                    "radio" => {
347                        if !request[name].is_string() {
348                            return Err(ApiResponse::fail(
349                                -1,
350                                format!(
351                                    "请求参数数据类型错误: 参数 [{}] 数据类型应为[{}] 实际为[{}]",
352                                    name, field["mode"], request[name]
353                                ).as_str(),
354                            ));
355                        }
356                        let option = field["option"].members().map(|m| m.as_str().unwrap_or("")).collect::<Vec<&str>>().join(",");
357                        if request[name].is_string() && !field["option"].contains(request[name].as_str().unwrap_or(""))
358                        {
359                            return Err(ApiResponse::fail(
360                                -1,
361                                format!(
362                                    "请求参数选项错误: 参数 [{}] 数据 [{}] 应为 [{}] 之一",
363                                    name, request[name], option
364                                ).as_str(),
365                            ));
366                        }
367                    }
368                    "array" | "polygon" => {
369                        if !request[name].is_array() {
370                            return Err(ApiResponse::fail(
371                                900_009,
372                                format!(
373                                    "请求参数数据类型错误: 参数 [{}] 数据类型应为[{}]",
374                                    name, field["mode"]
375                                ).as_str(),
376                            ));
377                        }
378                        if require && request[name].is_empty() {
379                            return Err(ApiResponse::fail(
380                                900010,
381                                format!("请求参数数据类型错误: 参数 [{name}] 不能为空").as_str(),
382                            ));
383                        }
384                    }
385                    "object" => {
386                        if !request[name].is_object() {
387                            return Err(ApiResponse::fail(
388                                900009,
389                                format!(
390                                    "请求参数数据类型错误: 参数 [{}] 数据类型应为[{}]",
391                                    name, field["mode"]
392                                ).as_str(),
393                            ));
394                        }
395                        if require && request[name].is_empty() {
396                            return Err(ApiResponse::fail(
397                                900006,
398                                format!("{title} 必填").as_str(),
399                            ));
400                        }
401                    }
402                    _ => {
403                        println!("检查未知类型: {}", field["mode"])
404                    }
405                }
406            } else {
407                if require {
408                    return Err(ApiResponse::fail(
409                        900007,
410                        format!("{title} 必填").as_str(),
411                    ));
412                }
413                request[name] = field["def"].clone();
414            }
415        }
416        Ok(())
417    }
418    /// 内部入口
419    fn index(&mut self, request: Request) -> ApiResponse;
420    /// 表单查询
421    fn params_table_select(&mut self, mut params: JsonValue) -> JsonValue {
422        params["page"] = br_fields::int::Int::new(false, "page", "页数", 10, 1).example(1.into()).field();
423        params["limit"] = br_fields::int::Int::new(false, "limit", "行数", 10, 10).example(10.into()).field();
424        params["search"] = br_fields::str::Str::new(false, "search", "搜索", 200, "").example("".into()).field();
425        params["where_or"] = br_fields::text::Array::new(false, "where_or", "查询条件", array![]).example(array![]).field();
426        params["where_and"] = br_fields::text::Array::new(false, "where_and", "查询条件", array![]).example(array![]).field();
427        params["params"] = br_fields::text::Object::new(false, "params", "关联数据参数", object! {}).example(object! {}).field();
428        params["field"] = br_fields::str::Str::new(false, "field", "显示字段", 50, "id").example("id".into()).field();
429        params
430    }
431    #[cfg(any(feature = "sqlite", feature = "mssql", feature = "mysql", feature = "pgsql"))]
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() / f64::from(limit)).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.entries().map(|(_, v)| v.to_string()).collect::<Vec<String>>();
489
490            list.push(object! {
491                value: value,
492                label: label.join(" | ").clone(),
493            }).unwrap();
494        }
495        object! {
496            total:total,
497            data:list,
498        }
499    }
500    /// 树形查询
501    fn params_table_tree_select(&mut self, mut params: JsonValue) -> JsonValue {
502        params["ids"] = br_fields::text::Array::new(false, "ids", "加载已选中数据", array![]).field();
503        params["search"] = br_fields::str::Str::new(false, "search", "搜索", 200, "").example("".into()).field();
504        params["pid"] = br_fields::str::Str::new(false, "pid", "上级ID", 20, "").example("".into()).field();
505        params["where_or"] = br_fields::text::Array::new(false, "where_or", "查询条件", array![]).example(array![]).field();
506        params["where_and"] = br_fields::text::Array::new(false, "where_and", "查询条件", array![]).example(array![]).field();
507        params["params"] = br_fields::text::Object::new(false, "params", "关联数据参数", object! {}).example(object! {}).field();
508        params
509    }
510    #[cfg(any(feature = "sqlite", feature = "mssql", feature = "mysql", feature = "pgsql"))]
511    fn table_tree_select(
512        &mut self,
513        request: JsonValue,
514        table_name: &str,
515        pid_field: &str,
516        label_field: &str,
517        fields: Vec<&str>,
518    ) -> JsonValue {
519        let ids = request["ids"].clone();
520        let search = request["search"].as_str().unwrap_or("");
521        let pid_id = request["pid"].as_str().unwrap_or("id");
522
523        let where_or = request["where_or"].clone();
524        let where_and = request["where_and"].clone();
525
526        let mut tools = self.tools();
527        let db = tools.db.table(table_name);
528
529        db.where_and(pid_field, "=", pid_id.into());
530
531        if !search.is_empty() {
532            db.where_and("id", "in", search.into());
533        }
534
535        for (key, value) in where_or.entries() {
536            if value.is_empty() {
537                continue;
538            }
539            if value.is_array() {
540                db.where_or(key, "between", value.clone());
541                db.where_or(key, "in", value.clone());
542            } else if value.is_boolean() {
543                db.where_or(key, "=", value.clone());
544            } else {
545                db.where_or(key, "like", format!("%{value}%").into());
546            }
547        }
548
549        for value in where_and.members() {
550            db.where_and(
551                value[0].as_str().unwrap(),
552                value[1].as_str().unwrap(),
553                value[2].clone(),
554            );
555        }
556
557        db.field(format!("id,{},{}", pid_field, fields.join(",")).as_str());
558
559        let mut data = db.select();
560        for item in data.members_mut() {
561            let children = self.tools().db.table(table_name).where_and(pid_field, "=", item["id"].clone()).select();
562            if children.is_empty() {
563                item["lazy"] = false.into();
564            } else {
565                item["lazy"] = true.into();
566            }
567        }
568
569        let ids_list = if ids.is_empty() {
570            vec![]
571        } else {
572            let list = self.tools().db.table(table_name).where_and("id", "in", ids).field(format!("id,{},{}", pid_field, fields.join(",")).as_str()).select();
573            let mut t = vec![];
574            for item in list.members() {
575                let mut v = vec![];
576                let mut pid = item[pid_field].to_string();
577                v.push(item[label_field].to_string());
578                loop {
579                    if pid.is_empty() {
580                        break;
581                    }
582                    let find = self.tools().db.table(table_name).where_and("id", "=", pid.into()).field(format!("id,{},{}", pid_field, fields.join(",")).as_str()).find();
583                    pid = find[pid_field].to_string();
584                    v.push(find[label_field].to_string());
585                }
586                v.reverse();
587                t.push(object! {
588                    id:item["id"].clone(),
589                    label:v.join("/"),
590                });
591            }
592            t
593        };
594
595
596        object! {
597            data:data,
598            label_field:label_field,
599            pid_field:pid_field,
600            ids:ids_list.clone()
601
602        }
603    }
604    /// 菜单表格接收参数
605    fn params_table_menu(&mut self, mut params: JsonValue) -> JsonValue {
606        params["search"] = br_fields::str::Str::new(false, "search", "搜索", 200, "").example("".into()).field();
607        params["where_or"] = br_fields::text::Array::new(false, "where_or", "查询条件", array![]).example(array![]).field();
608        params["where_and"] = br_fields::text::Array::new(false, "where_and", "查询条件", array![]).example(array![]).field();
609        params
610    }
611    #[allow(clippy::too_many_arguments)]
612    #[cfg(any(feature = "sqlite", feature = "mssql", feature = "mysql", feature = "pgsql"))]
613    fn table_menu(
614        &mut self,
615        request: JsonValue,
616        table_name: &str,
617        label_field: &str,
618        fields: JsonValue,
619
620        hidd_field: Vec<&str>,
621        show_field: Vec<&str>,
622        search_fields: Vec<&str>,
623    ) -> JsonValue {
624        let search = request["search"].as_str().unwrap_or("");
625        
626        let order = request["order"].clone();
627        let where_or = request["where_or"].clone();
628        let where_and = request["where_and"].clone();
629        let mut columns = array![];
630        let mut search_name = vec![];
631        let mut search_field = vec![];
632        let mut filter_columns = vec![];
633        let mut table_fields = object! {};
634        let mut table_field_json = vec![];
635
636        let mut alls_field = fields.entries().map(|(x, _)| x).collect::<Vec<&str>>();
637        alls_field.retain(|x| !hidd_field.contains(x));
638        if !show_field.is_empty() {
639            alls_field.retain(|x| show_field.contains(x) || *x == "id");
640        }
641
642        for item in alls_field.iter() {
643            let row = &fields[item.to_string()];
644            let field = row["field"].to_string();
645            let title = row["title"].to_string();
646            let mode = row["mode"].to_string();
647
648            if search_fields.contains(&field.as_str()) {
649                search_name.push(title);
650                search_field.push(field.clone());
651            }
652            filter_columns.push(self.filter_column(row.clone()));
653            columns.push(self.table_column(row.clone())).unwrap();
654            let mut table_field_info = object! {};
655            match mode.as_str() {
656                "table" => table_field_info = row.clone(),
657                "array" => table_field_json.push(field.clone()),
658                _ => {}
659            }
660            if !table_field_info.is_empty() {
661                table_fields[field.as_str()] = table_field_info;
662            }
663        }
664
665        let mut tools = self.tools();
666        let db = tools.db.table(table_name);
667
668        if !search.is_empty() {
669            db.where_and(
670                &search_field.join("|"),
671                "like",
672                format!("%{search}%").into(),
673            );
674        }
675
676        for (key, value) in where_or.entries() {
677            if value.is_empty() {
678                continue;
679            }
680            if value.is_array() {
681                db.where_or(key, "between", value.clone());
682                db.where_or(key, "in", value.clone());
683            } else if value.is_boolean() {
684                db.where_or(key, "=", value.clone());
685            } else {
686                db.where_or(key, "like", format!("%{value}%").into());
687            }
688        }
689
690        for value in where_and.members() {
691            db.where_and(
692                value[0].as_str().unwrap(),
693                value[1].as_str().unwrap(),
694                value[2].clone(),
695            );
696        }
697
698        let mut db_list = db.clone();
699
700        for item in order.members() {
701            db_list.order(item[0].as_str().unwrap(), item[1].as_bool().unwrap());
702        }
703
704        let t = alls_field.join(",");
705        db_list.field(t.as_str());
706
707        if !table_field_json.is_empty() {
708            db_list.json(&table_field_json.join(","));
709        }
710
711        let mut data = db_list.select();
712
713        let mut table_datas = object! {};
714        let mut ids = HashMap::new();
715
716        for item in data.members_mut() {
717            for (field, _) in table_fields.entries() {
718                if table_datas[field].is_empty() {
719                    table_datas[field] = array![];
720                }
721                let _ = table_datas[field].push(item[field].clone());
722            }
723        }
724        for (field, info) in table_fields.entries_mut() {
725            let _ = info["fields"].push("id");
726            let fields_k = info["fields"].members().map(|x| x.as_str().unwrap()).collect::<Vec<&str>>();
727            let table_name = info["table"].clone();
728            let mut data_list = self.tools().db.table(table_name.as_str().unwrap()).where_and("id", "in", table_datas[field].clone()).field(&fields_k.join(",")).select();
729
730            for item in data_list.members_mut() {
731                let id = item["id"].as_str().unwrap_or("").to_string();
732                item.remove("id");
733                let label = item.entries().map(|(_, v)| v.as_str().unwrap()).collect::<Vec<&str>>();
734                ids.insert(
735                    id.clone(),
736                    object! {
737                        value: id.clone(),
738                        label:label.join(" | ").clone(),
739                    },
740                );
741            }
742        }
743
744        for item in data.members_mut() {
745            for (field, _) in table_fields.entries() {
746                if item[field].is_empty() {
747                    continue;
748                }
749                item[field] = ids[item[field].as_str().unwrap()].clone();
750            }
751        }
752
753        object! {
754            data:data,
755            columns:columns,
756            search_name:search_name.join("/"),
757            label_field:label_field,
758            btn_all:array![],
759            btn_api:array![],
760            btn_ids:array![],
761        }
762    }
763    /// 树型表格接收参数
764    fn params_table_tree(&mut self, mut params: JsonValue) -> JsonValue {
765        params["pid"] = br_fields::str::Str::new(false, "pid", "上级ID", 50, "").example("".into()).field();
766        params["search"] = br_fields::str::Str::new(false, "search", "搜索", 200, "").example("".into()).field();
767        params["order"] = br_fields::text::Array::new(false, "order", "排序", array![]).example(array![array!["id", false]]).field();
768        params["where_or"] = br_fields::text::Array::new(false, "where_or", "查询条件", array![]).example(array![]).field();
769        params["where_and"] = br_fields::text::Array::new(false, "where_and", "查询条件", array![]).example(array![]).field();
770        params
771    }
772    #[allow(clippy::too_many_arguments)]
773    #[cfg(any(feature = "sqlite", feature = "mssql", feature = "mysql", feature = "pgsql"))]
774    fn table_tree(
775        &mut self,
776        request: JsonValue,
777        table_name: &str,
778        pid_field: &str,
779        label_field: &str,
780        fields: JsonValue,
781        hidd_field: Vec<&str>,
782        show_field: Vec<&str>,
783        search_fields: Vec<&str>,
784        _filter_fields: Vec<&str>,
785    ) -> JsonValue {
786        let search = request["search"].as_str().unwrap_or("");
787
788        let pid = request["pid"].clone();
789
790        let order = request["order"].clone();
791        let where_or = request["where_or"].clone();
792        let where_and = request["where_and"].clone();
793        let mut columns = array![];
794        let mut search_name = vec![];
795        let mut search_field = vec![];
796        let mut filter_columns = vec![];
797        let mut table_field_json = vec![];
798        let mut table_fields = object! {};
799
800        let mut alls_field = fields.entries().map(|(x, _)| x).collect::<Vec<&str>>();
801        alls_field.retain(|x| !hidd_field.contains(x));
802        if !show_field.is_empty() {
803            alls_field.retain(|x| show_field.contains(x) || *x == "id");
804        }
805
806        for item in alls_field.iter() {
807            let row = fields[item.to_string()].clone();
808            let field = row["field"].to_string();
809            let title = row["title"].to_string();
810            let mode = row["mode"].to_string();
811
812            if search_fields.contains(&field.as_str()) {
813                search_name.push(title);
814                search_field.push(field.clone());
815            }
816            filter_columns.push(self.filter_column(row.clone()));
817            columns.push(self.table_column(row.clone())).unwrap();
818            let mut table_field_info = object! {};
819            match mode.as_str() {
820                "table" => table_field_info = row.clone(),
821                "array" => table_field_json.push(field.clone()),
822                _ => {}
823            }
824            if !table_field_info.is_empty() {
825                table_fields[field.as_str()] = table_field_info;
826            }
827        }
828
829        let mut tools = self.tools();
830        let db = tools.db.table(table_name);
831        db.where_and(pid_field, "=", pid);
832        if !search.is_empty() {
833            db.where_and(
834                &search_field.join("|"),
835                "like",
836                format!("%{search}%").into(),
837            );
838        }
839
840        for (key, value) in where_or.entries() {
841            if value.is_empty() {
842                continue;
843            }
844            if value.is_array() {
845                // db.where_or(key, "between", value.clone());
846                db.where_or(key, "in", value.clone());
847            } else if value.is_boolean() {
848                db.where_or(key, "=", value.clone());
849            } else {
850                db.where_or(key, "like", format!("%{value}%").into());
851            }
852        }
853
854        for value in where_and.members() {
855            db.where_and(
856                value[0].as_str().unwrap(),
857                value[1].as_str().unwrap(),
858                value[2].clone(),
859            );
860        }
861
862        let mut db_list = db.clone();
863
864        for item in order.members() {
865            db_list.order(item[0].as_str().unwrap(), item[1].as_bool().unwrap());
866        }
867        let t = alls_field.join(",");
868        db_list.field(t.as_str());
869        if !table_field_json.is_empty() {
870            db_list.json(&table_field_json.join(","));
871        }
872        let mut data = db_list.select();
873
874        let mut table_datas = object! {};
875        let mut ids = HashMap::new();
876
877        for item in data.members_mut() {
878            for (field, _) in table_fields.entries() {
879                if table_datas[field].is_empty() {
880                    table_datas[field] = array![];
881                }
882                let _ = table_datas[field].push(item[field].clone());
883            }
884        }
885        for (field, info) in table_fields.entries_mut() {
886            let _ = info["fields"].push("id");
887            let fields_k = info["fields"].members().map(|x| x.as_str().unwrap()).collect::<Vec<&str>>();
888            let table_name = info["table"].clone();
889            let mut data_list = self.tools().db.table(table_name.as_str().unwrap()).where_and("id", "in", table_datas[field].clone()).field(&fields_k.join(",")).select();
890
891            for item in data_list.members_mut() {
892                let id = item["id"].as_str().unwrap_or("").to_string();
893                item.remove("id");
894                let label = item.entries().map(|(_, v)| v.as_str().unwrap()).collect::<Vec<&str>>();
895                ids.insert(
896                    id.clone(),
897                    object! {
898                        value: id.clone(),
899                        label:label.join(" | ").clone(),
900                    },
901                );
902            }
903        }
904
905        let mut list = array![];
906        for item in data.members_mut() {
907            for (field, _) in table_fields.entries() {
908                if item[field].is_empty() {
909                    continue;
910                }
911                item[field] = ids[item[field].as_str().unwrap()].clone();
912            }
913            let _ = list.push(object! {
914                id:item["id"].as_str().unwrap(),
915                code:item["code"].as_str().unwrap(),
916                label:item[label_field].as_str().unwrap(),
917                data:item.clone(),
918            });
919        }
920
921        object! {
922            data:list,
923            columns:columns,
924            search_name:search_name.join("/"),
925            filter_columns:filter_columns,
926            pid_field:pid_field,
927            btn_all:array![],
928            btn_api:array![]
929        }
930    }
931
932    #[allow(clippy::too_many_arguments)]
933    #[cfg(any(feature = "sqlite", feature = "mssql", feature = "mysql", feature = "pgsql"))]
934    /// 树形表单
935    fn tree(&mut self, request: JsonValue, table_name: &str, pid_field: &str, label: &str, fields: JsonValue, hidd_field: Vec<&str>, show_field: Vec<&str>, search_fields: Vec<&str>, _filter_fields: Vec<&str>) -> JsonValue {
936        let search = request["search"].as_str().unwrap_or("");
937
938        let pid = request["pid"].clone();
939        let order = request["order"].clone();
940        let where_or = request["where_or"].clone();
941        let where_and = request["where_and"].clone();
942        let mut columns = array![];
943        let mut search_name = vec![];
944        let mut search_field = vec![];
945        let mut filter_columns = vec![];
946        let mut table_field_json = vec![];
947        let mut table_fields = object! {};
948
949        let mut alls_field = fields.entries().map(|(x, _)| x).collect::<Vec<&str>>();
950        alls_field.retain(|x| !hidd_field.contains(x));
951        if !show_field.is_empty() {
952            alls_field.retain(|x| show_field.contains(x) || *x == "id");
953        }
954
955        for item in alls_field.iter() {
956            let row = fields[item.to_string()].clone();
957            let field = row["field"].to_string();
958            let title = row["title"].to_string();
959            let mode = row["mode"].to_string();
960
961            if search_fields.contains(&field.as_str()) {
962                search_name.push(title);
963                search_field.push(field.clone());
964            }
965            filter_columns.push(self.filter_column(row.clone()));
966            columns.push(self.table_column(row.clone())).unwrap();
967            let mut table_field_info = object! {};
968            match mode.as_str() {
969                "table" => table_field_info = row.clone(),
970                "array" => table_field_json.push(field.clone()),
971                _ => {}
972            }
973            if !table_field_info.is_empty() {
974                table_fields[field.as_str()] = table_field_info;
975            }
976        }
977
978        let mut tools = self.tools();
979        let db = tools.db.table(table_name);
980        db.where_and(pid_field, "=", pid);
981        if !search.is_empty() {
982            db.where_and(
983                &search_field.join("|"),
984                "like",
985                format!("%{search}%").into(),
986            );
987        }
988
989        for (key, value) in where_or.entries() {
990            if value.is_empty() {
991                continue;
992            }
993            if value.is_array() {
994                db.where_or(key, "in", value.clone());
995            } else if value.is_boolean() {
996                db.where_or(key, "=", value.clone());
997            } else {
998                db.where_or(key, "like", format!("%{value}%").into());
999            }
1000        }
1001
1002        for value in where_and.members() {
1003            db.where_and(
1004                value[0].as_str().unwrap(),
1005                value[1].as_str().unwrap(),
1006                value[2].clone(),
1007            );
1008        }
1009
1010        let mut db_list = db.clone();
1011
1012        for item in order.members() {
1013            db_list.order(item[0].as_str().unwrap(), item[1].as_bool().unwrap());
1014        }
1015        let t = alls_field.join(",");
1016        db_list.field(t.as_str());
1017        if !table_field_json.is_empty() {
1018            db_list.json(&table_field_json.join(","));
1019        }
1020        let mut data = db_list.select();
1021
1022        let mut table_datas = object! {};
1023        let mut ids = HashMap::new();
1024
1025        for item in data.members_mut() {
1026            for (field, _) in table_fields.entries() {
1027                if table_datas[field].is_empty() {
1028                    table_datas[field] = array![];
1029                }
1030                let _ = table_datas[field].push(item[field].clone());
1031            }
1032        }
1033        for (field, info) in table_fields.entries_mut() {
1034            let _ = info["fields"].push("id");
1035            let fields_k = info["fields"].members().map(|x| x.as_str().unwrap()).collect::<Vec<&str>>();
1036            let table_name = info["table"].clone();
1037            let mut data_list = self.tools().db.table(table_name.as_str().unwrap()).where_and("id", "in", table_datas[field].clone()).field(&fields_k.join(",")).select();
1038
1039            for item in data_list.members_mut() {
1040                let id = item["id"].as_str().unwrap_or("").to_string();
1041                item.remove("id");
1042                let label = item.entries().map(|(_, v)| v.as_str().unwrap()).collect::<Vec<&str>>();
1043                ids.insert(
1044                    id.clone(),
1045                    object! {
1046                        value: id.clone(),
1047                        label:label.join(" | ").clone(),
1048                    },
1049                );
1050            }
1051        }
1052
1053        for item in data.members_mut() {
1054            for (field, _) in table_fields.entries() {
1055                if item[field].is_empty() {
1056                    continue;
1057                }
1058                item[field] = ids[item[field].as_str().unwrap()].clone();
1059            }
1060            //item["children"] = self.tools().db.table(table_name).where_and(pid_field, "=", item["id"].clone()).select();
1061        }
1062
1063        object! {
1064            data:data,
1065            columns:columns,
1066            search_name:search_name.join("/"),
1067            label:label,
1068            btn_all:array![],
1069            btn_api:array![],
1070            btn_ids:array![]
1071        }
1072    }
1073
1074    /// 表格接收参数
1075    fn params_table_list(&mut self, mut params: JsonValue) -> JsonValue {
1076        params["page"] = br_fields::int::Int::new(false, "page", "页数", 10, 1).example(1.into()).field();
1077        params["limit"] = br_fields::int::Int::new(false, "limit", "行数", 10, 10).example(10.into()).field();
1078        params["search"] = br_fields::str::Str::new(false, "search", "搜索", 200, "").example("".into()).field();
1079        params["order"] = br_fields::text::Array::new(false, "order", "排序", array![]).example(array![array!["id", false]]).field();
1080        params["where_or"] = br_fields::text::Array::new(false, "where_or", "查询条件", array![]).example(array![]).field();
1081        params["where_and"] = br_fields::text::Array::new(false, "where_and", "查询条件", array![]).example(array![]).field();
1082        params["field"] = br_fields::str::Str::new(false, "field", "显示字段", 20, "id").example("id".into()).field();
1083        params
1084    }
1085    /// 列表表格渲染
1086    /// * table_name 表名
1087    /// * fields 全部模型字段集合
1088    /// * hidd_field 需要隐藏的字段集合
1089    /// * show_field 需要显示的字段集合
1090    /// * search_fields 搜索字段集合
1091    /// * filter_fields 高级搜索字段集合
1092    #[allow(clippy::too_many_arguments)]
1093    #[cfg(any(feature = "sqlite", feature = "mssql", feature = "mysql", feature = "pgsql"))]
1094    fn table_list(
1095        &mut self,
1096        request: JsonValue,
1097        table_name: &str,
1098        fields: JsonValue,
1099        hidd_field: Vec<&str>,
1100        show_field: Vec<&str>,
1101        search_fields: Vec<&str>,
1102        filter_fields: Vec<&str>,
1103    ) -> JsonValue {
1104        let page = request["page"].as_i32().unwrap_or(1);
1105        let limit = request["limit"].as_i32().unwrap_or(10);
1106        let search = request["search"].as_str().unwrap_or("");
1107        let order = request["order"].clone();
1108        let where_or = request["where_or"].clone();
1109        let where_and = request["where_and"].clone();
1110        let mut columns = array![];
1111        let mut search_name = vec![];
1112        let mut search_field = vec![];
1113        let mut filter_columns = vec![];
1114
1115        // 表单关联字段
1116        let mut table_fields = object! {};
1117        // 树形关联字段
1118        let mut tree_fields = object! {};
1119
1120        // 需要处理为json格式的字段
1121        let mut json_fields = vec![];
1122
1123        let mut alls_field = fields.entries().map(|(x, _)| x).collect::<Vec<&str>>();
1124        alls_field.retain(|x| !hidd_field.contains(x));
1125        if !show_field.is_empty() {
1126            alls_field.retain(|x| show_field.contains(x) || *x == "id");
1127        }
1128
1129        for item in alls_field.iter() {
1130            let key = item.to_string();
1131            let field = fields[key.clone()]["field"].as_str().unwrap();
1132            let title = fields[key.clone()]["title"].as_str().unwrap();
1133            let mode = fields[key.clone()]["mode"].as_str().unwrap();
1134
1135            if search_fields.contains(&field) {
1136                search_name.push(title);
1137                search_field.push(field);
1138            }
1139            if filter_fields.contains(&field) {
1140                filter_columns.push(self.filter_column(fields[key.clone()].clone()));
1141            }
1142            columns.push(self.table_column(fields[key.clone()].clone())).unwrap();
1143
1144            match mode {
1145                "table" => {
1146                    let table_field_info = if mode == "table" {
1147                        fields[key.clone()].clone()
1148                    } else {
1149                        JsonValue::Null
1150                    };
1151                    if !table_field_info.is_empty() {
1152                        table_fields[field] = table_field_info;
1153                    }
1154                }
1155                "tree" => {
1156                    let table_field_info = if mode == "tree" {
1157                        fields[key.clone()].clone()
1158                    } else {
1159                        JsonValue::Null
1160                    };
1161                    if !table_field_info.is_empty() {
1162                        tree_fields[field] = table_field_info;
1163                    }
1164                }
1165                "object" | "array" | "polygon" => {
1166                    json_fields.push(field);
1167                }
1168                _ => {}
1169            }
1170        }
1171
1172        let mut tools = self.tools();
1173        let db = tools.db.table(table_name);
1174
1175        if !search.is_empty() {
1176            db.where_and(
1177                &search_field.join("|"),
1178                "like",
1179                format!("%{search}%").into(),
1180            );
1181        }
1182
1183        for (key, value) in where_or.entries() {
1184            if value.is_empty() {
1185                continue;
1186            }
1187            if value.is_array() {
1188                db.where_or(key, "in", value.clone());
1189            } else if value.is_boolean() {
1190                db.where_or(key, "=", value.clone());
1191            } else {
1192                db.where_or(key, "like", format!("%{value}%").into());
1193            }
1194        }
1195
1196        for value in where_and.members() {
1197            db.where_and(
1198                value[0].as_str().unwrap(),
1199                value[1].as_str().unwrap(),
1200                value[2].clone(),
1201            );
1202        }
1203
1204        let total = db.clone().count().as_f64().unwrap();
1205        let mut db_list = db.clone();
1206
1207        for item in order.members() {
1208            db_list.order(item[0].as_str().unwrap(), item[1].as_bool().unwrap());
1209        }
1210
1211        let t = alls_field.join(",");
1212        db_list.field(t.as_str());
1213        let mut data = db_list.page(page, limit).json(&json_fields.join(",")).select();
1214
1215        let mut table_data = object! {};
1216
1217        for item in data.members_mut() {
1218            if !table_fields.is_empty() {
1219                for (field, field_info) in table_fields.entries() {
1220                    if item[field].is_empty() {
1221                        continue;
1222                    }
1223                    let key = item[field].as_str().unwrap_or("");
1224                    if key.is_empty() {
1225                        continue;
1226                    }
1227                    if !table_data.has_key(field) {
1228                        table_data[field] = object! {};
1229                    }
1230                    if !table_data[field].has_key(key) {
1231                        let mut info = field_info.clone();
1232                        let _ = info["fields"].push("id");
1233                        let fields_k = info["fields"].members().map(|x| x.as_str().unwrap()).collect::<Vec<&str>>();
1234                        let mut find = self.tools().db.table(info["table"].as_str().unwrap()).where_and("id", "=", key.into()).field(&fields_k.join(",")).find();
1235                        let id = find["id"].to_string();
1236                        find.remove("id");
1237                        let label = find.entries().map(|(_, v)| v.to_string()).collect::<Vec<String>>();
1238                        table_data[field][key] = object! {
1239                                value: id.clone(),
1240                                label:label.join(" | ").clone(),
1241                        };
1242                    }
1243                    item[field] = table_data[field][key].clone();
1244                }
1245            }
1246            if !tree_fields.is_empty() {
1247                for (field, field_info) in tree_fields.entries() {
1248                    if item[field].is_empty() {
1249                        continue;
1250                    }
1251                    let key = item[field].as_str().unwrap_or("");
1252                    if key.is_empty() {
1253                        continue;
1254                    }
1255                    if !table_data.has_key(field) {
1256                        table_data[field] = object! {};
1257                    }
1258                    if !table_data[field].has_key(key) {
1259                        let mut info = field_info.clone();
1260                        let pid_field = info["pid_field"].clone().to_string();
1261                        let _ = info["fields"].push("id");
1262                        let _ = info["fields"].push(pid_field.clone());
1263                        let fields_k = info["fields"].members().map(|x| x.as_str().unwrap()).collect::<Vec<&str>>();
1264                        let mut find = self.tools().db.table(info["table"].as_str().unwrap()).where_and("id", "=", key.into()).field(&fields_k.join(",")).find();
1265                        let mut pid = find[pid_field.clone()].to_string();
1266                        let mut name_list = vec![];
1267                        let id = find["id"].to_string();
1268                        find.remove("id");
1269                        find.remove(&pid_field);
1270                        let label = find.entries().map(|(_, v)| v.to_string()).collect::<Vec<String>>();
1271                        name_list.push(label.join(" | ").clone());
1272                        loop {
1273                            if pid.is_empty() {
1274                                break;
1275                            }
1276                            let mut t = self.tools().db.table(info["table"].as_str().unwrap()).where_and("id", "=", pid.clone().into()).field(&fields_k.join(",")).find();
1277                            pid = t[pid_field.clone()].to_string();
1278                            t.remove("id");
1279                            t.remove(&pid_field);
1280                            let label = t.entries().map(|(_, v)| v.to_string()).collect::<Vec<String>>();
1281                            name_list.push(label.join(" | ").clone());
1282                        }
1283                        name_list.reverse();
1284                        table_data[field][key] = object! {
1285                                value: id.clone(),
1286                                label:name_list.join("/").clone(),
1287                        };
1288                    }
1289                    item[field] = table_data[field][key].clone();
1290                }
1291            }
1292        }
1293
1294        object! {
1295            total:total,
1296            data:data,
1297            columns:columns,
1298            search_name:search_name.join("/"),
1299            filter_columns:filter_columns,
1300            btn_all:array![],
1301            btn_api:array![],
1302            btn_ids:array![]
1303        }
1304    }
1305    /// 列表表格渲染
1306    /// * table_name 表名
1307    /// * fields 全部模型字段集合
1308    /// * hidd_field 需要隐藏的字段集合
1309    /// * show_field 需要显示的字段集合
1310    /// * search_fields 搜索字段集合
1311    /// * filter_fields 高级搜索字段集合
1312    #[allow(clippy::too_many_arguments)]
1313    #[cfg(any(feature = "sqlite", feature = "mssql", feature = "mysql", feature = "pgsql"))]
1314    fn table_edit_list(
1315        &mut self,
1316        request: JsonValue,
1317        table_name: &str,
1318        fields: JsonValue,
1319        hidd_field: Vec<&str>,
1320        show_field: Vec<&str>,
1321        search_fields: Vec<&str>,
1322        edit_fields: Vec<&str>,
1323    ) -> JsonValue {
1324        let page = request["page"].as_i32().unwrap_or(1);
1325        let limit = request["limit"].as_i32().unwrap_or(10);
1326        let search = request["search"].as_str().unwrap_or("");
1327        let order = request["order"].clone();
1328        let where_or = request["where_or"].clone();
1329        let where_and = request["where_and"].clone();
1330        let mut columns = array![];
1331        let mut search_name = vec![];
1332        let mut search_field = vec![];
1333        let mut edit_columns = vec![];
1334
1335        // 表单关联字段
1336        let mut table_fields = object! {};
1337        // 树形关联字段
1338        let mut tree_fields = object! {};
1339
1340        // 需要处理为json格式的字段
1341        let mut json_fields = vec![];
1342
1343        let mut alls_field = fields.entries().map(|(x, _)| x).collect::<Vec<&str>>();
1344        alls_field.retain(|x| !hidd_field.contains(x));
1345        if !show_field.is_empty() {
1346            alls_field.retain(|x| show_field.contains(x) || *x == "id");
1347        }
1348
1349        for item in alls_field.iter() {
1350            let key = item.to_string();
1351            let field = fields[key.clone()]["field"].as_str().unwrap();
1352            let title = fields[key.clone()]["title"].as_str().unwrap();
1353            let mode = fields[key.clone()]["mode"].as_str().unwrap();
1354
1355            if search_fields.contains(&field) {
1356                search_name.push(title);
1357                search_field.push(field);
1358            }
1359            if edit_fields.contains(&field) {
1360                edit_columns.push(self.filter_column(fields[key.clone()].clone()));
1361            }
1362            columns.push(self.table_column(fields[key.clone()].clone())).unwrap();
1363
1364            match mode {
1365                "table" => {
1366                    let table_field_info = if mode == "table" {
1367                        fields[key.clone()].clone()
1368                    } else {
1369                        JsonValue::Null
1370                    };
1371                    if !table_field_info.is_empty() {
1372                        table_fields[field] = table_field_info;
1373                    }
1374                }
1375                "tree" => {
1376                    let table_field_info = if mode == "tree" {
1377                        fields[key.clone()].clone()
1378                    } else {
1379                        JsonValue::Null
1380                    };
1381                    if !table_field_info.is_empty() {
1382                        tree_fields[field] = table_field_info;
1383                    }
1384                }
1385                "object" | "array" | "polygon" => {
1386                    json_fields.push(field);
1387                }
1388                _ => {}
1389            }
1390        }
1391
1392        let mut tools = self.tools();
1393        let db = tools.db.table(table_name);
1394
1395        if !search.is_empty() {
1396            db.where_and(
1397                &search_field.join("|"),
1398                "like",
1399                format!("%{search}%").into(),
1400            );
1401        }
1402
1403        for (key, value) in where_or.entries() {
1404            if value.is_empty() {
1405                continue;
1406            }
1407            if value.is_array() {
1408                db.where_or(key, "in", value.clone());
1409            } else if value.is_boolean() {
1410                db.where_or(key, "=", value.clone());
1411            } else {
1412                db.where_or(key, "like", format!("%{value}%").into());
1413            }
1414        }
1415
1416        for value in where_and.members() {
1417            db.where_and(
1418                value[0].as_str().unwrap(),
1419                value[1].as_str().unwrap(),
1420                value[2].clone(),
1421            );
1422        }
1423
1424        let total = db.clone().count().as_f64().unwrap();
1425        let mut db_list = db.clone();
1426
1427        for item in order.members() {
1428            db_list.order(item[0].as_str().unwrap(), item[1].as_bool().unwrap());
1429        }
1430
1431        let t = alls_field.join(",");
1432        db_list.field(t.as_str());
1433        let mut data = db_list.page(page, limit).json(&json_fields.join(",")).select();
1434
1435        let mut table_data = object! {};
1436
1437        for item in data.members_mut() {
1438            if !table_fields.is_empty() {
1439                for (field, field_info) in table_fields.entries() {
1440                    if item[field].is_empty() {
1441                        continue;
1442                    }
1443                    let key = item[field].as_str().unwrap_or("");
1444                    if key.is_empty() {
1445                        continue;
1446                    }
1447                    if !table_data.has_key(field) {
1448                        table_data[field] = object! {};
1449                    }
1450                    if !table_data[field].has_key(key) {
1451                        let mut info = field_info.clone();
1452                        let _ = info["fields"].push("id");
1453                        let fields_k = info["fields"].members().map(|x| x.as_str().unwrap()).collect::<Vec<&str>>();
1454                        let mut find = self.tools().db.table(info["table"].as_str().unwrap()).where_and("id", "=", key.into()).field(&fields_k.join(",")).find();
1455                        let id = find["id"].to_string();
1456                        find.remove("id");
1457                        let label = find.entries().map(|(_, v)| v.to_string()).collect::<Vec<String>>();
1458                        table_data[field][key] = object! {
1459                                value: id.clone(),
1460                                label:label.join(" | ").clone(),
1461                        };
1462                    }
1463                    item[field] = table_data[field][key].clone();
1464                }
1465            }
1466            if !tree_fields.is_empty() {
1467                for (field, field_info) in tree_fields.entries() {
1468                    if item[field].is_empty() {
1469                        continue;
1470                    }
1471                    let key = item[field].as_str().unwrap_or("");
1472                    if key.is_empty() {
1473                        continue;
1474                    }
1475                    if !table_data.has_key(field) {
1476                        table_data[field] = object! {};
1477                    }
1478                    if !table_data[field].has_key(key) {
1479                        let mut info = field_info.clone();
1480                        let pid_field = info["pid_field"].clone().to_string();
1481                        let _ = info["fields"].push("id");
1482                        let _ = info["fields"].push(pid_field.clone());
1483                        let fields_k = info["fields"].members().map(|x| x.as_str().unwrap()).collect::<Vec<&str>>();
1484                        let mut find = self.tools().db.table(info["table"].as_str().unwrap()).where_and("id", "=", key.into()).field(&fields_k.join(",")).find();
1485                        let mut pid = find[pid_field.clone()].to_string();
1486                        let mut name_list = vec![];
1487                        let id = find["id"].to_string();
1488                        find.remove("id");
1489                        find.remove(&pid_field);
1490                        let label = find.entries().map(|(_, v)| v.to_string()).collect::<Vec<String>>();
1491                        name_list.push(label.join(" | ").clone());
1492                        loop {
1493                            if pid.is_empty() {
1494                                break;
1495                            }
1496                            let mut t = self.tools().db.table(info["table"].as_str().unwrap()).where_and("id", "=", pid.clone().into()).field(&fields_k.join(",")).find();
1497                            pid = t[pid_field.clone()].to_string();
1498                            t.remove("id");
1499                            t.remove(&pid_field);
1500                            let label = t.entries().map(|(_, v)| v.to_string()).collect::<Vec<String>>();
1501                            name_list.push(label.join(" | ").clone());
1502                        }
1503                        name_list.reverse();
1504                        table_data[field][key] = object! {
1505                                value: id.clone(),
1506                                label:name_list.join("/").clone(),
1507                        };
1508                    }
1509                    item[field] = table_data[field][key].clone();
1510                }
1511            }
1512        }
1513
1514        object! {
1515            total:total,
1516            data:data,
1517            columns:columns,
1518            search_name:search_name.join("/"),
1519            edit_columns:edit_columns
1520        }
1521    }
1522    #[allow(clippy::too_many_arguments)]
1523    #[cfg(any(feature = "sqlite", feature = "mssql", feature = "mysql", feature = "pgsql"))]
1524    fn table(&mut self) -> Tables {
1525        Tables::new(self.tools().db.clone())
1526    }
1527    fn table_column(&mut self, field: JsonValue) -> JsonValue {
1528        object! {
1529            name:field["field"].clone(),
1530            label:field["title"].clone(),
1531            align:"center",
1532            field:field["field"].clone(),
1533            sortable:true,
1534            mode:field["mode"].clone(),
1535            dec:field["dec"].clone(),
1536            fields:field["fields"].clone()
1537        }
1538    }
1539    fn filter_column(&mut self, field: JsonValue) -> JsonValue {
1540        object! {
1541            name:field["field"].clone(),
1542            label:field["title"].clone(),
1543            mode:field["mode"].clone(),
1544            option:field["option"].clone(),
1545            api:field["api"].clone(),
1546            fields:field["fields"].clone()
1547        }
1548    }
1549    /// 使用工具
1550    fn tools(&mut self) -> Tools {
1551        let tools = PLUGIN_TOOLS.lock().unwrap();
1552        let tools = tools.get("tools").unwrap().clone();
1553        tools
1554    }
1555    /// 使用配置
1556    fn config(&mut self, name: &str) -> JsonValue {
1557        if CONFIG.lock().unwrap().get(name).is_none() {
1558            object! {}
1559        } else {
1560            CONFIG.lock().unwrap().get(name).unwrap().clone()
1561        }
1562    }
1563    /// 按钮信息
1564    /// * cnd 显示条件 vec![vec!["xxx","=","yyy"],vec!["zzz","=","eee"]]
1565    fn btn(&mut self) -> Btn {
1566        let mut btn = Btn::new(self.api().as_str());
1567        btn.fields(self.params().clone());
1568        btn.tags(self.tags());
1569        btn.icon(self.icon());
1570        btn.desc(self.description());
1571        btn.auth(self.auth());
1572        btn.public(self.public());
1573        btn.title(self.title());
1574        btn.btn_type(BtnType::Api);
1575        btn.btn_color(BtnColor::Primary);
1576        btn.path(self.api().clone().replace(".", "/").as_str());
1577        btn.pass(false);
1578        btn.addon();
1579        btn
1580    }
1581    /// 设置全局变量
1582    fn set_global_data(&mut self, key: &str, value: JsonValue) {
1583        GLOBAL_DATA.with(|data| {
1584            data.borrow_mut()[key] = value;
1585        });
1586    }
1587    /// 获取全局变量数据
1588    fn get_global_data(&mut self) -> JsonValue {
1589        GLOBAL_DATA.with(|data| {
1590            data.borrow().clone()
1591        })
1592    }
1593    /// 获取全局变量指定字段数据
1594    fn get_global_data_key(&mut self, key: &str) -> JsonValue {
1595        GLOBAL_DATA.with(|data| {
1596            data.borrow()[key].clone()
1597        })
1598    }
1599}
1600#[derive(Debug, Clone)]
1601pub struct Btn {
1602    api: String,
1603    title: String,
1604    desc: String,
1605    tags: &'static [&'static str],
1606    auth: bool,
1607    public: bool,
1608    btn_type: BtnType,
1609    color: BtnColor,
1610    icon: String,
1611    cnd: Vec<JsonValue>,
1612    url: String,
1613    path: String,
1614    fields: JsonValue,
1615    addon: String,
1616    /// 是否需要密码
1617    pass: bool,
1618}
1619impl Btn {
1620    pub fn new(api: &str) -> Self {
1621        Self {
1622            api: api.to_string(),
1623            title: "".to_string(),
1624            desc: "".to_string(),
1625            btn_type: BtnType::Api,
1626            color: BtnColor::Primary,
1627            icon: "".to_string(),
1628            auth: false,
1629            public: false,
1630            cnd: vec![],
1631            url: "".to_string(),
1632            path: "".to_string(),
1633            fields: object! {},
1634            tags: &[],
1635            pass: false,
1636            addon: "".to_string(),
1637        }
1638    }
1639
1640    pub fn addon(&mut self) -> &mut Self {
1641        self.addon = self.api.split('.').nth(0).unwrap().to_string();
1642        self
1643    }
1644    pub fn path(&mut self, path: &str) -> &mut Self {
1645        self.path = path.to_string();
1646        self
1647    }
1648    pub fn cnd(&mut self, cnd: Vec<JsonValue>) -> &mut Self {
1649        self.cnd = cnd;
1650        self
1651    }
1652    pub fn btn_type(&mut self, btn_type: BtnType) -> &mut Self {
1653        self.btn_type = btn_type;
1654        self
1655    }
1656    pub fn btn_color(&mut self, btn_color: BtnColor) -> &mut Self {
1657        self.color = btn_color;
1658        self
1659    }
1660    pub fn fields(&mut self, fields: JsonValue) -> &mut Self {
1661        self.fields = fields;
1662        self
1663    }
1664    pub fn pass(&mut self, pass: bool) -> &mut Self {
1665        self.pass = pass;
1666        self
1667    }
1668    pub fn url(&mut self, url: &str) -> &mut Self {
1669        self.url = url.to_string();
1670        self
1671    }
1672    pub fn title(&mut self, title: &str) -> &mut Self {
1673        self.title = title.to_string();
1674        self
1675    }
1676    pub fn desc(&mut self, desc: &str) -> &mut Self {
1677        self.desc = desc.to_string();
1678        self
1679    }
1680    pub fn tags(&mut self, tags: &'static [&'static str]) -> &mut Self {
1681        self.tags = tags;
1682        self
1683    }
1684    pub fn public(&mut self, public: bool) -> &mut Self {
1685        self.public = public;
1686        self
1687    }
1688    pub fn auth(&mut self, auth: bool) -> &mut Self {
1689        self.auth = auth;
1690        self
1691    }
1692    pub fn icon(&mut self, icon: &str) -> &mut Self {
1693        self.icon = icon.to_string();
1694        self
1695    }
1696    pub fn json(&mut self) -> JsonValue {
1697        object! {
1698            addon:self.addon.to_string() ,
1699            api:self.api.clone(),
1700            title:self.title.clone(),
1701            desc:self.desc.clone(),
1702            auth:self.auth,
1703            public:self.public,
1704            btn_type:self.btn_type.clone().str(),
1705            color:self.color.clone().str(),
1706            icon:self.icon.clone(),
1707            cnd:self.cnd.clone(),
1708            url:self.url.clone(),
1709            path:self.path.clone(),
1710            fields:self.fields.clone(),
1711            tags:self.tags,
1712            pass:self.pass,
1713        }
1714    }
1715}
1716
1717/// 接口类型
1718#[derive(Debug, Clone)]
1719pub enum InterfaceType {
1720    API,
1721    BTN,
1722    MENU,
1723}
1724
1725impl InterfaceType {
1726    pub fn str(&self) -> &'static str {
1727        match self {
1728            InterfaceType::API => "api",
1729            InterfaceType::BTN => "btn",
1730            InterfaceType::MENU => "menu",
1731        }
1732    }
1733    pub fn types() -> Vec<&'static str> {
1734        vec!["api", "btn", "menu"]
1735    }
1736}
1737
1738/// 按钮类型
1739#[derive(Debug, Clone)]
1740pub enum BtnType {
1741    /// 表单
1742    Form,
1743    /// 表单下载
1744    FormDownload,
1745    /// 表单自定义
1746    FormCustom,
1747    FormData,
1748    /// 外部跳转
1749    Url,
1750    /// api请求
1751    Api,
1752    /// 下载
1753    Download,
1754    /// 内部跳转
1755    Path,
1756    /// 弹窗-定制页面
1757    DialogCustom,
1758    /// 表单->API->弹出自定义窗口
1759    FormApiDialogCustom,
1760    /// 预览
1761    Preview,
1762}
1763
1764impl BtnType {
1765    fn str(self) -> &'static str {
1766        match self {
1767            BtnType::Form => "form",
1768            BtnType::FormDownload => "form_download",
1769            BtnType::FormCustom => "form_custom",
1770            BtnType::FormData => "form_data",
1771            BtnType::Api => "api",
1772            BtnType::Download => "download",
1773            BtnType::Url => "url",
1774            BtnType::Path => "path",
1775            BtnType::DialogCustom => "dialog_custom",
1776            BtnType::FormApiDialogCustom => "form_api_dialog_custom",
1777            BtnType::Preview => "preview",
1778        }
1779    }
1780}
1781/// 按钮颜色
1782#[derive(Debug, Clone)]
1783pub enum BtnColor {
1784    Primary,
1785    Red,
1786    Blue,
1787    Yellow,
1788    Green,
1789}
1790
1791impl BtnColor {
1792    fn str(self) -> &'static str {
1793        match self {
1794            BtnColor::Primary => "primary",
1795            BtnColor::Red => "negative",
1796            BtnColor::Blue => "info",
1797            BtnColor::Yellow => "warning",
1798            BtnColor::Green => "positive",
1799        }
1800    }
1801}
1802
1803
1804pub struct Dashboard {
1805    /// 名称
1806    title: String,
1807    /// 数据
1808    data: JsonValue,
1809    /// 显示样式
1810    model: DashboardModel,
1811    /// 渲染样式
1812    class: String,
1813    /// 图标
1814    icon: String,
1815    /// 描述
1816    desc: String,
1817    ///数据请求接口
1818    api: String,
1819    ///用户选项,同时也是api接收的参数
1820    options: JsonValue,
1821}
1822impl Dashboard {
1823    pub fn new(title: &str) -> Dashboard {
1824        Dashboard {
1825            title: title.to_string(),
1826            data: JsonValue::Null,
1827            model: DashboardModel::Number,
1828            class: "col-4".to_string(),
1829            icon: "".to_string(),
1830            desc: "".to_string(),
1831            api: "".to_string(),
1832            options: JsonValue::Null,
1833        }
1834    }
1835    pub fn options(&mut self, options: JsonValue) -> &mut Self {
1836        self.options = options;
1837        self
1838    }
1839    pub fn api(&mut self, api: &str) -> &mut Self {
1840        self.api = api.to_string();
1841        self
1842    }
1843    pub fn data(&mut self, data: JsonValue) -> &mut Self {
1844        self.data = data;
1845        self
1846    }
1847    pub fn class(&mut self, name: &str) -> &mut Self {
1848        self.class = name.to_string();
1849        self
1850    }
1851    pub fn icon(&mut self, name: &str) -> &mut Self {
1852        self.icon = name.to_string();
1853        self
1854    }
1855    pub fn model(&mut self, dashboard_model: DashboardModel) -> &mut Self {
1856        self.model = dashboard_model;
1857        self
1858    }
1859    pub fn desc(&mut self, desc: &str) -> &mut Self {
1860        self.desc = desc.to_string();
1861        self
1862    }
1863    pub fn json(&self) -> JsonValue {
1864        object! {
1865            title: self.title.clone(),
1866            data: self.data.clone(),
1867            class: self.class.clone(),
1868            icon: self.icon.clone(),
1869            model: self.model.str(),
1870            desc: self.desc.clone(),
1871            api: self.api.clone(),
1872            options:self.options.clone(),
1873        }
1874    }
1875}
1876
1877pub enum DashboardModel {
1878    /// 数字
1879    Number,
1880    /// 柱状图
1881    EchartsBar,
1882    /// 堆叠柱状图
1883    EchartsStackedBar,
1884    /// 动态排序的柱状图
1885    EchartsBarRace,
1886    /// 饼图
1887    EchartsPie,
1888    /// 中空饼图
1889    EchartsDoughnut,
1890    /// 堆叠折线图
1891    EchartsStackedLine,
1892    /// 面积填充的堆叠折线图
1893    EchartsStackedLineArea,
1894    /// 地图
1895    EchartsGeoGraph,
1896}
1897
1898impl DashboardModel {
1899    pub fn str(&self) -> &'static str {
1900        match self {
1901            Self::Number => "number",
1902            Self::EchartsBar => "echarts-bar",
1903            Self::EchartsStackedBar => "echarts-stacked_bar",
1904            Self::EchartsBarRace => "echarts-bar_race",
1905            Self::EchartsPie => "echarts-pie",
1906            Self::EchartsDoughnut => "echarts-doughnut",
1907            Self::EchartsStackedLine => "echarts-stacked_line",
1908            Self::EchartsStackedLineArea => "echarts-stacked_line_area",
1909            Self::EchartsGeoGraph => "echarts-geo_graph",
1910        }
1911    }
1912}