Skip to main content

br_addon/
tables.rs

1use br_db::Db;
2use br_fields::Field;
3use json::{array, object, JsonValue};
4use std::collections::HashMap;
5
6#[allow(clippy::too_many_arguments)]
7#[cfg(any(
8    feature = "sqlite",
9    feature = "mssql",
10    feature = "mysql",
11    feature = "pgsql"
12))]
13pub struct Tables {
14    /// 主数据表名称
15    main_table: String,
16    /// 数据库
17    db: Db,
18    /// 记录总数量
19    total: i64,
20    /// 字段数据
21    fields: Vec<JsonValue>,
22    /// 连表查询
23    join_params: Vec<Vec<String>>,
24    /// 字段值集合
25    fields_keys: Vec<String>,
26    /// 联表字段
27    join_fields: Vec<String>,
28    /// 隐藏字段
29    hide_fields: Vec<String>,
30    /// 显示字段
31    show_fields: Vec<String>,
32    /// 合计字段
33    total_fields: Vec<String>,
34    /// 数据
35    data: JsonValue,
36    /// 页数
37    page: usize,
38    /// 总页数
39    pages: i64,
40    /// 每页数量
41    limit: usize,
42    /// 搜索内容
43    search: String,
44    /// 搜索字段
45    search_fields: Vec<String>,
46    /// 搜索框名称
47    search_name: String,
48    /// 可以编辑字段
49    edit_fields: Vec<String>,
50    /// 排序
51    /// array![array!["id",false]]
52    order: JsonValue,
53    /// 过滤条件
54    /// array![array!["id","=","*"]]
55    where_and: JsonValue,
56    /// 过滤条件
57    /// array![array!["id","=","*"]]
58    where_or: JsonValue,
59    /// 过滤字段
60    filter_fields: Vec<String>,
61    /// 表单关联字段
62    table_fields: Vec<String>,
63    /// 表单关联多选字段
64    table_multiple_fields: Vec<String>,
65    /// 树形关联字段
66    tree_fields: Vec<String>,
67    /// JSON字段
68    json_fields: Vec<String>,
69    /// 地图字段
70    location_fields: Vec<String>,
71    /// 显示的主键
72    primary_key: String,
73    /// 选中值
74    value: Vec<String>,
75    /// 树形pid
76    pid_id: String,
77    /// 字段索引缓存(field name → field metadata)
78    all_fields_map: JsonValue,
79}
80impl Tables {
81    pub fn params_table(mut params: JsonValue) -> JsonValue {
82        params["page"] = br_fields::int::Int::new(false, "page", "页数", 10, 1)
83            .example(1.into())
84            .field();
85        params["limit"] = br_fields::int::Int::new(false, "limit", "行数", 10, 10)
86            .example(10.into())
87            .field();
88        params["order"] = br_fields::text::Array::new(false, "order", "排序", array![]).field();
89        params["search"] = br_fields::str::Str::new(false, "search", "搜索", 200, "")
90            .example("".into())
91            .field();
92        params["where_or"] = br_fields::text::Array::new(false, "where_or", "查询条件", array![])
93            .example(array![])
94            .field();
95        params["where_and"] = br_fields::text::Array::new(false, "where_and", "查询条件", array![])
96            .example(array![])
97            .field();
98        params["params"] =
99            br_fields::text::Object::new(false, "params", "关联数据参数", object! {})
100                .describe("如果是表单就是表单里的其他字段")
101                .example(object! {})
102                .field();
103        params
104    }
105    pub fn params_table_tree(mut params: JsonValue) -> JsonValue {
106        params["pid"] = br_fields::str::Str::new(false, "pid", "上级ID", 50, "")
107            .example("".into())
108            .field();
109        Tables::params_table_select(params)
110    }
111    pub fn params_table_select(mut params: JsonValue) -> JsonValue {
112        params["value"] = br_fields::text::Array::new(false, "value", "已选中值", array![]).field();
113        params["primary_key"] =
114            br_fields::str::Str::new(false, "primary_key", "显示内容的字段", 50, "id").field();
115        Tables::params_table(params)
116    }
117    pub fn params_table_select_tree(mut params: JsonValue) -> JsonValue {
118        params["pid"] = br_fields::str::Str::new(false, "pid", "上级ID", 20, "")
119            .example("".into())
120            .field();
121        params["value"] = br_fields::text::Array::new(false, "value", "已选中值", array![]).field();
122        Tables::params_table(params)
123    }
124    pub fn new(db: Db) -> Self {
125        Self {
126            main_table: "".to_string(),
127            db,
128            total: 0,
129            fields: vec![],
130            join_params: vec![],
131            fields_keys: vec![],
132            data: array![],
133            page: 1,
134            pages: 0,
135            limit: 10,
136            search: "".to_string(),
137            search_fields: vec![],
138            search_name: "".to_string(),
139            edit_fields: vec![],
140            order: array![],
141            where_and: array![],
142            where_or: array![],
143            filter_fields: vec![],
144            table_fields: vec![],
145            table_multiple_fields: vec![],
146            tree_fields: vec![],
147            json_fields: vec![],
148            location_fields: vec![],
149            primary_key: "".to_string(),
150            value: vec![],
151            join_fields: vec![],
152            hide_fields: vec![],
153            show_fields: vec![],
154            total_fields: vec![],
155            pid_id: "".to_string(),
156            all_fields_map: object! {},
157        }
158    }
159    pub fn main_table_fields(
160        &mut self,
161        table: &str,
162        fields: JsonValue,
163        hide_fields: Vec<&str>,
164        show_fields: Vec<&str>,
165    ) -> &mut Self {
166        self.main_table = table.to_string();
167        self.hide_fields = hide_fields.iter().map(|s| s.to_string()).collect();
168        self.show_fields = show_fields.iter().map(|s| s.to_string()).collect();
169        self.fields = fields
170            .entries()
171            .map(|(_, x)| x.clone())
172            .collect::<Vec<JsonValue>>();
173        self
174    }
175    pub fn join_fields(&mut self, table: &str, mut fields: JsonValue, index: isize) -> &mut Self {
176        for (field, item) in fields.entries_mut() {
177            if self.main_table != table {
178                item["field"] = format!("{table}_{field}").into();
179                item["field_table"] = table.into();
180                item["field_table_field"] = field.into();
181            }
182
183            match index {
184                x if x > -1 => {
185                    // 插入
186                    self.fields.insert(x as usize, item.clone());
187                }
188                _ => {
189                    // 尾部添加
190                    self.fields.push(item.clone());
191                }
192            }
193            self.join_fields.push(format!("{table}.{field}"));
194        }
195        self
196    }
197    pub fn fields(&mut self, fields: JsonValue) -> &mut Self {
198        self.fields = fields
199            .entries()
200            .map(|(_, x)| x.clone())
201            .collect::<Vec<JsonValue>>();
202        self
203    }
204    pub fn hide_fields(&mut self, hide_fields: Vec<&str>) -> &mut Self {
205        self.hide_fields = hide_fields.iter().map(|s| s.to_string()).collect();
206        self
207    }
208    pub fn show_fields(&mut self, show_fields: Vec<&str>) -> &mut Self {
209        self.show_fields = show_fields.iter().map(|s| s.to_string()).collect();
210        self
211    }
212    pub fn total_fields(&mut self, fields: Vec<&str>) -> &mut Self {
213        self.total_fields = fields.iter().map(|s| s.to_string()).collect();
214        self
215    }
216    fn set_fields(&mut self, field: &str, mode: &str) {
217        match mode {
218            "table" => self.table_fields.push(field.to_string()),
219            "table_multiple" => {
220                self.table_multiple_fields.push(field.to_string());
221                self.json_fields.push(field.to_string());
222            }
223            "tree" => self.tree_fields.push(field.to_string()),
224            "object" | "array" | "polygon" | "select" | "location_address" => {
225                self.json_fields.push(field.to_string())
226            }
227            "location" => self.location_fields.push(field.to_string()),
228            _ => {}
229        }
230    }
231    pub fn join_table(
232        &mut self,
233        main_table: &str,
234        main_field: &str,
235        join_table: &str,
236        join_field: &str,
237    ) -> &mut Self {
238        self.join_params.push(vec![
239            main_table.to_string(),
240            main_field.to_string(),
241            join_table.to_string(),
242            join_field.to_string(),
243        ]);
244        self
245    }
246    pub fn main_select_fields(&mut self, table: &str, mut show_fields: Vec<&str>) -> &mut Self {
247        self.main_table = table.to_string();
248        show_fields.insert(0, "id");
249        self.fields_keys = show_fields.into_iter().map(|x| x.to_string()).collect();
250        self.search_fields = self.fields_keys.clone();
251        self
252    }
253
254    pub fn edit_fields(&mut self, fields: Vec<&str>) -> &mut Self {
255        self.edit_fields = fields.iter().map(|s| s.to_string()).collect();
256        self
257    }
258    pub fn search_fields(&mut self, fields: Vec<&str>) -> &mut Self {
259        let mut search_name = vec![];
260        let all_fields = self
261            .fields
262            .iter()
263            .map(|x| (x["field"].to_string(), x.clone()))
264            .collect::<HashMap<String, JsonValue>>();
265        for key in fields.clone() {
266            if let Some(field_info) = all_fields.get(key) {
267                self.search_fields.push(key.to_string());
268                search_name.push(field_info["title"].to_string());
269            }
270        }
271        self.search_name = search_name.join("/");
272        self
273    }
274    /// 条件过滤
275    pub fn filter_fields(&mut self, fields: Vec<&str>) -> &mut Self {
276        let all_fields = self
277            .fields
278            .iter()
279            .map(|x| (x["field"].to_string(), x.clone()))
280            .collect::<HashMap<String, JsonValue>>();
281        for key in fields.clone() {
282            if all_fields.contains_key(key) {
283                self.filter_fields.push(key.to_string());
284            } else {
285                log::warn!(
286                    "filter_fields: unknown field '{}' in table '{}'",
287                    key,
288                    self.main_table
289                );
290            }
291        }
292        self
293    }
294    /// 请求参数
295    pub fn params(&mut self, request: JsonValue) -> &mut Self {
296        if request.has_key("page") {
297            self.page = request["page"].as_usize().unwrap_or(1);
298        }
299        if request.has_key("limit") {
300            self.limit = request["limit"].as_usize().unwrap_or(10);
301        }
302        if request.has_key("where_and") {
303            self.where_and = request["where_and"].clone();
304        }
305        if request.has_key("where_or") {
306            self.where_or = request["where_or"].clone();
307        }
308
309        if request.has_key("pid") {
310            self.pid_id = if let Some(s) = request["pid"].as_str() {
311                s.to_string()
312            } else if request["pid"].is_number() {
313                request["pid"].to_string()
314            } else {
315                String::new()
316            };
317        }
318
319        if request.has_key("order") {
320            for item in request["order"].members() {
321                let _ = self.order.push(item.clone());
322            }
323        }
324        if request.has_key("search") {
325            self.search = request["search"].as_str().unwrap_or("").to_string();
326        }
327        if request.has_key("primary_key") {
328            self.primary_key = request["primary_key"].as_str().unwrap_or("").to_string();
329        }
330        if request.has_key("value") {
331            self.value = request["value"]
332                .members()
333                .map(|x| x.as_str().unwrap_or("").to_string())
334                .filter(|x| !x.is_empty())
335                .collect();
336        }
337        self
338    }
339
340    fn db_search(&mut self) {
341        if !self.search.is_empty() {
342            let mut t = vec![];
343            for value in self.search_fields.clone() {
344                let field = self.all_fields_map[value.as_str()].clone();
345                if field.has_key("field_table") {
346                    t.push(format!(
347                        "{}.{}",
348                        field["field_table"].clone(),
349                        field["field_table_field"].clone()
350                    ));
351                } else {
352                    t.push(value);
353                }
354            }
355            self.db
356                .where_and(&t.join("|"), "like", format!("%{}%", self.search).into());
357        }
358    }
359    fn db_where(&mut self) {
360        for value in self.where_or.members() {
361            let field = self.all_fields_map[value[0].to_string()].clone();
362            if field.has_key("field_table") {
363                self.db.where_or(
364                    format!(
365                        "{}.{}",
366                        field["field_table"].clone(),
367                        field["field_table_field"].clone()
368                    )
369                    .as_str(),
370                    value[1].as_str().unwrap_or("="),
371                    value[2].clone(),
372                );
373            } else {
374                self.db.where_or(
375                    value[0].as_str().unwrap_or_default(),
376                    value[1].as_str().unwrap_or("="),
377                    value[2].clone(),
378                );
379            }
380        }
381        for value in self.where_and.members() {
382            let field_name = value[0].as_str().unwrap_or_default();
383            let field = self.all_fields_map[field_name].clone();
384
385            // table_multiple 字段是 JSON 数组 TEXT 列,用 LIKE + where_or 匹配
386            if self.table_multiple_fields.contains(&field_name.to_string()) {
387                let filter_ids: Vec<String> = if value[2].is_array() {
388                    value[2]
389                        .members()
390                        .filter_map(|v| {
391                            let s = v.as_str().unwrap_or("");
392                            if s.is_empty() {
393                                None
394                            } else {
395                                Some(s.to_string())
396                            }
397                        })
398                        .collect()
399                } else {
400                    let s = value[2].as_str().unwrap_or("");
401                    s.split(',')
402                        .map(|x| x.trim().to_string())
403                        .filter(|x| !x.is_empty())
404                        .collect()
405                };
406                if filter_ids.is_empty() {
407                    continue;
408                }
409                for id in &filter_ids {
410                    self.db
411                        .where_or(field_name, "like", format!("%{}%", id).into());
412                }
413                continue;
414            }
415
416            if field.has_key("field_table") {
417                self.db.where_and(
418                    format!(
419                        "{}.{}",
420                        field["field_table"].clone(),
421                        field["field_table_field"].clone()
422                    )
423                    .as_str(),
424                    value[1].as_str().unwrap_or("="),
425                    value[2].clone(),
426                );
427            } else {
428                self.db.where_and(
429                    value[0].as_str().unwrap_or_default(),
430                    value[1].as_str().unwrap_or("="),
431                    value[2].clone(),
432                );
433            }
434        }
435    }
436    fn db_order(&mut self) {
437        for item in self.order.members() {
438            let field = self.all_fields_map[item[0].to_string()].clone();
439            if field.has_key("field_table") {
440                self.db.order(
441                    format!(
442                        "{}.{}",
443                        field["field_table"].clone(),
444                        field["field_table_field"].clone()
445                    )
446                    .as_str(),
447                    item[1].as_bool().unwrap_or(false),
448                );
449            } else {
450                self.db.order(
451                    format!("{}.{}", self.main_table, item[0]).as_str(),
452                    item[1].as_bool().unwrap_or(false),
453                );
454            }
455        }
456    }
457    fn db_fields(&mut self) {
458        let mut all_fields = object! {};
459        let _ = self
460            .fields
461            .iter()
462            .map(|x| all_fields.insert(x["field"].as_str().unwrap_or_default(), x.clone()))
463            .collect::<Vec<_>>();
464
465        if !self.hide_fields.is_empty() {
466            for field in self.hide_fields.clone() {
467                if all_fields.has_key(&field) {
468                    all_fields.remove(&field);
469                    continue;
470                }
471            }
472        }
473
474        if !self.show_fields.is_empty() {
475            self.show_fields.insert(0, "id".to_string());
476            let mut f = object! {};
477            for field in self.show_fields.clone() {
478                if all_fields.has_key(&field) {
479                    let _ = f.insert(&field.clone(), all_fields[field].clone());
480                }
481            }
482            all_fields = f;
483        }
484
485        for (field, item) in all_fields.entries() {
486            let mode = item["mode"].to_string();
487            self.set_fields(field, mode.as_str());
488        }
489
490        self.fields = all_fields
491            .entries()
492            .map(|(_, x)| x.clone())
493            .collect::<Vec<JsonValue>>();
494
495        self.all_fields_map = all_fields;
496
497        if !self.fields_keys.is_empty() {
498            self.db.field(self.fields_keys.join(",").as_str());
499        }
500        if !self.json_fields.is_empty() {
501            self.db.json(self.json_fields.join(",").as_str());
502        }
503        if !self.location_fields.is_empty() {
504            self.db.location(self.location_fields.join(",").as_str());
505        }
506    }
507    fn db_join(&mut self) {
508        if !self.join_fields.is_empty() {
509            self.db
510                .join_fields(self.join_fields.iter().map(|x| x.as_str()).collect());
511        }
512        for item in self.join_params.iter() {
513            self.db.join(&item[0], &item[1], &item[2], &item[3]);
514        }
515    }
516    fn db_total(&mut self) {
517        self.total = self.db.clone().count().as_i64().unwrap_or(0);
518        self.pages = if self.limit > 0 {
519            (self.total + self.limit as i64 - 1) / self.limit as i64
520        } else {
521            0
522        };
523    }
524    fn resolve_table_field_batch(&mut self, field: &str) -> JsonValue {
525        let field_info = self.all_fields_map[field].clone();
526        let mut info = field_info.clone();
527        let _ = info["fields"].push("id");
528        let fields_k = info["fields"]
529            .members()
530            .map(|x| x.as_str().unwrap_or_default())
531            .collect::<Vec<&str>>();
532        let table_name = info["table"].as_str().unwrap_or_default().to_string();
533        let field_str = fields_k.join(",");
534
535        let mut ids: Vec<String> = vec![];
536        for item in self.data.members() {
537            let key = item[field].as_str().unwrap_or("");
538            if !key.is_empty() && !ids.contains(&key.to_string()) {
539                ids.push(key.to_string());
540            }
541        }
542
543        let mut lookup = object! {};
544        if ids.is_empty() {
545            return lookup;
546        }
547
548        let rows = self
549            .db
550            .table(&table_name)
551            .where_and("id", "in", ids.into())
552            .field(&field_str)
553            .select();
554        for mut row in rows.members().cloned() {
555            let id = row["id"]
556                .as_str()
557                .map(|s| s.to_string())
558                .unwrap_or_else(|| row["id"].to_string());
559            row.remove("id");
560            let label = row
561                .entries()
562                .map(|(_, v)| {
563                    v.as_str()
564                        .map(|s| s.to_string())
565                        .unwrap_or_else(|| v.to_string())
566                })
567                .collect::<Vec<String>>();
568            lookup[id.as_str()] = object! {
569                value: id.clone(),
570                label: label.join(" | ").clone(),
571            };
572        }
573        lookup
574    }
575
576    fn resolve_table_multiple_field_batch(&mut self, field: &str) -> JsonValue {
577        let field_info = self.all_fields_map[field].clone();
578        let mut info = field_info.clone();
579        let _ = info["fields"].push("id");
580        let fields_k = info["fields"]
581            .members()
582            .map(|x| x.as_str().unwrap_or_default())
583            .collect::<Vec<&str>>();
584        let table_name = info["table"].as_str().unwrap_or_default().to_string();
585        let field_str = fields_k.join(",");
586
587        let mut ids: Vec<String> = vec![];
588        for item in self.data.members() {
589            let arr = &item[field];
590            if arr.is_array() {
591                for id_val in arr.members() {
592                    let key = id_val.as_str().unwrap_or("");
593                    if !key.is_empty() && !ids.contains(&key.to_string()) {
594                        ids.push(key.to_string());
595                    }
596                }
597            }
598        }
599
600        let mut lookup = object! {};
601        if ids.is_empty() {
602            return lookup;
603        }
604
605        let rows = self
606            .db
607            .table(&table_name)
608            .where_and("id", "in", ids.into())
609            .field(&field_str)
610            .select();
611        for mut row in rows.members().cloned() {
612            let id = row["id"]
613                .as_str()
614                .map(|s| s.to_string())
615                .unwrap_or_else(|| row["id"].to_string());
616            row.remove("id");
617            let label = row
618                .entries()
619                .map(|(_, v)| {
620                    v.as_str()
621                        .map(|s| s.to_string())
622                        .unwrap_or_else(|| v.to_string())
623                })
624                .collect::<Vec<String>>();
625            lookup[id.as_str()] = object! {
626                value: id.clone(),
627                label: label.join(" | ").clone(),
628            };
629        }
630        lookup
631    }
632
633    fn resolve_tree_field(&mut self, field: &str, table_data: &mut JsonValue, key: &str) {
634        if table_data[field].has_key(key) {
635            return;
636        }
637        let field_info = self.all_fields_map[field].clone();
638        let mut info = field_info.clone();
639        let pid_field = info["pid_field"].clone().to_string();
640        let _ = info["fields"].push("id");
641        let _ = info["fields"].push(pid_field.clone());
642        let fields_k = info["fields"]
643            .members()
644            .map(|x| x.as_str().unwrap_or_default())
645            .collect::<Vec<&str>>();
646        let table_name = info["table"].as_str().unwrap_or_default().to_string();
647        let field_str = fields_k.join(",");
648
649        let mut find = self
650            .db
651            .table(&table_name)
652            .where_and("id", "=", key.into())
653            .field(&field_str)
654            .find();
655        let mut pid = find[pid_field.clone()]
656            .as_str()
657            .map(|s| s.to_string())
658            .unwrap_or_else(|| find[pid_field.clone()].to_string());
659        let mut name_list = vec![];
660        let id = find["id"]
661            .as_str()
662            .map(|s| s.to_string())
663            .unwrap_or_else(|| find["id"].to_string());
664        find.remove("id");
665        find.remove(&pid_field);
666        let label = find
667            .entries()
668            .map(|(_, v)| {
669                v.as_str()
670                    .map(|s| s.to_string())
671                    .unwrap_or_else(|| v.to_string())
672            })
673            .collect::<Vec<String>>();
674        name_list.push(label.join(" | ").clone());
675        loop {
676            if pid.is_empty() {
677                break;
678            }
679            let mut t = self
680                .db
681                .table(&table_name)
682                .where_and("id", "=", pid.clone().into())
683                .field(&field_str)
684                .find();
685            pid = t[pid_field.clone()]
686                .as_str()
687                .map(|s| s.to_string())
688                .unwrap_or_else(|| t[pid_field.clone()].to_string());
689            t.remove("id");
690            t.remove(&pid_field);
691            let label = t
692                .entries()
693                .map(|(_, v)| {
694                    v.as_str()
695                        .map(|s| s.to_string())
696                        .unwrap_or_else(|| v.to_string())
697                })
698                .collect::<Vec<String>>();
699            name_list.push(label.join(" | ").clone());
700        }
701        name_list.reverse();
702        if !table_data.has_key(field) {
703            table_data[field] = object! {};
704        }
705        table_data[field][key] = object! {
706            value: id.clone(),
707            label: name_list.join("/").clone(),
708        };
709    }
710
711    fn db_table(&mut self) {
712        let mut table_lookups: HashMap<String, JsonValue> = HashMap::new();
713        for field in self.table_fields.clone() {
714            table_lookups.insert(field.clone(), self.resolve_table_field_batch(&field));
715        }
716
717        let mut multiple_lookups: HashMap<String, JsonValue> = HashMap::new();
718        for field in self.table_multiple_fields.clone() {
719            multiple_lookups.insert(
720                field.clone(),
721                self.resolve_table_multiple_field_batch(&field),
722            );
723        }
724
725        let mut tree_data = object! {};
726        let tree_fields = self.tree_fields.clone();
727        let mut tree_keys: Vec<(String, String)> = vec![];
728        for item in self.data.members() {
729            for field in tree_fields.iter() {
730                let key = item[field].as_str().unwrap_or("");
731                if !key.is_empty() {
732                    tree_keys.push((field.clone(), key.to_string()));
733                }
734            }
735        }
736        for (field, key) in tree_keys {
737            self.resolve_tree_field(&field, &mut tree_data, &key);
738        }
739
740        for item in self.data.members_mut() {
741            for field in self.table_fields.iter() {
742                let key = item[field].as_str().unwrap_or("");
743                if key.is_empty() {
744                    continue;
745                }
746                if let Some(lookup) = table_lookups.get(field.as_str()) {
747                    if lookup.has_key(key) {
748                        item[field] = lookup[key].clone();
749                    }
750                }
751            }
752            for field in tree_fields.iter() {
753                let key = item[field].as_str().unwrap_or("");
754                if key.is_empty() {
755                    continue;
756                }
757                if tree_data.has_key(field) && tree_data[field].has_key(key) {
758                    item[field] = tree_data[field][key].clone();
759                }
760            }
761            for field in self.table_multiple_fields.iter() {
762                let ids = item[field].clone();
763                if !ids.is_array() || ids.is_empty() {
764                    item[field] = array![];
765                    continue;
766                }
767                let mut result = array![];
768                if let Some(lookup) = multiple_lookups.get(field.as_str()) {
769                    for id_val in ids.members() {
770                        let key = id_val.as_str().unwrap_or("");
771                        if !key.is_empty() && lookup.has_key(key) {
772                            let _ = result.push(lookup[key].clone());
773                        }
774                    }
775                }
776                item[field] = result;
777            }
778        }
779    }
780    fn db_table_tree(&mut self, pid_field: &str) {
781        let mut table_lookups: HashMap<String, JsonValue> = HashMap::new();
782        for field in self.table_fields.clone() {
783            table_lookups.insert(field.clone(), self.resolve_table_field_batch(&field));
784        }
785
786        let mut multiple_lookups: HashMap<String, JsonValue> = HashMap::new();
787        for field in self.table_multiple_fields.clone() {
788            multiple_lookups.insert(
789                field.clone(),
790                self.resolve_table_multiple_field_batch(&field),
791            );
792        }
793
794        let mut tree_data = object! {};
795        let tree_fields = self.tree_fields.clone();
796        let mut tree_keys: Vec<(String, String)> = vec![];
797        for item in self.data.members() {
798            for field in tree_fields.iter() {
799                let key = item[field].as_str().unwrap_or("");
800                if !key.is_empty() {
801                    tree_keys.push((field.clone(), key.to_string()));
802                }
803            }
804        }
805        for (field, key) in tree_keys {
806            self.resolve_tree_field(&field, &mut tree_data, &key);
807        }
808
809        for item in self.data.members_mut() {
810            let children = self
811                .db
812                .table(&self.main_table)
813                .where_and(pid_field, "=", item["id"].clone())
814                .count();
815            if children.is_empty() {
816                item["isLeaf"] = true.into();
817            }
818
819            for field in self.table_fields.iter() {
820                let key = item[field].as_str().unwrap_or("");
821                if key.is_empty() {
822                    continue;
823                }
824                if let Some(lookup) = table_lookups.get(field.as_str()) {
825                    if lookup.has_key(key) {
826                        item[field] = lookup[key].clone();
827                    }
828                }
829            }
830            for field in tree_fields.iter() {
831                let key = item[field].as_str().unwrap_or("");
832                if key.is_empty() {
833                    continue;
834                }
835                if tree_data.has_key(field) && tree_data[field].has_key(key) {
836                    item[field] = tree_data[field][key].clone();
837                }
838            }
839            for field in self.table_multiple_fields.iter() {
840                let ids = item[field].clone();
841                if !ids.is_array() || ids.is_empty() {
842                    item[field] = array![];
843                    continue;
844                }
845                let mut result = array![];
846                if let Some(lookup) = multiple_lookups.get(field.as_str()) {
847                    for id_val in ids.members() {
848                        let key = id_val.as_str().unwrap_or("");
849                        if !key.is_empty() && lookup.has_key(key) {
850                            let _ = result.push(lookup[key].clone());
851                        }
852                    }
853                }
854                item[field] = result;
855            }
856        }
857    }
858    fn columns(&mut self) -> JsonValue {
859        let mut all_fields = self.all_fields_map.clone();
860
861        for (_, item) in all_fields.entries_mut() {
862            item["name"] = item["field"].clone();
863            item["align"] = "center".into();
864            item["label"] = item["title"].clone();
865
866            if item["field"].as_str().unwrap_or("") != "id" {
867                item["sortable"] = true.into();
868            }
869            item["dataIndex"] = item["field"].clone();
870            item["slotName"] = item["field"].clone();
871            item["titleSlotName"] = item["field"].clone();
872            match item["mode"].as_str().unwrap_or_default() {
873                "string" | "text" => {
874                    item["ellipsis"] = true.into();
875                    item["tooltip"] = true.into();
876                }
877                "key" => {
878                    item["width"] = 280.into();
879                    item["ellipsis"] = true.into();
880                }
881                _ => {}
882            }
883        }
884        all_fields
885    }
886    pub fn get_table(&mut self) -> JsonValue {
887        self.db.table(&self.main_table);
888        self.db_fields();
889        self.db_search();
890        self.db_where();
891        self.db_join();
892        self.db_total();
893        self.db_order();
894        self.db.page(self.page as i32, self.limit as i32);
895
896        self.data = self.db.select();
897        self.db_table();
898
899        object! {
900            "pages"=>self.pages,
901            "total"=>self.total,
902            "data"=>self.data.clone(),
903            "columns"=>self.columns(),
904            "filter_fields"=>self.filter_fields.clone(),
905            "search_name"=>self.search_name.clone(),
906            "total_fields"=>self.total_fields.clone(),
907            "btn_all"=>array![],
908            "btn_api"=>array![],
909            "btn_ids"=>array![]
910        }
911    }
912    pub fn get_table_menu(&mut self, label_field: &str) -> JsonValue {
913        self.db.table(&self.main_table);
914        self.db_fields();
915        self.db_search();
916        self.db_where();
917        self.db_join();
918        self.db_total();
919        self.db_order();
920        self.db.page(self.page as i32, self.limit as i32);
921
922        self.data = self.db.select();
923        self.db_table();
924
925        object! {
926            "pages"=>self.pages,
927            "total"=>self.total,
928            "data"=>self.data.clone(),
929            "columns"=>self.columns(),
930            "filter_fields"=>self.filter_fields.clone(),
931            "search_name"=>self.search_name.clone(),
932            "total_fields"=>self.total_fields.clone(),
933            "btn_all"=>array![],
934            "btn_api"=>array![],
935            "btn_ids"=>array![],
936            "label_field"=>label_field
937        }
938    }
939
940    pub fn get_tree(&mut self, pid_field: &str) -> JsonValue {
941        self.db.table(&self.main_table);
942        if self.search.is_empty() || !self.pid_id.is_empty() {
943            self.db
944                .where_and(pid_field, "=", self.pid_id.clone().into());
945        }
946        self.db_fields();
947        self.db_search();
948        self.db_where();
949        self.db_join();
950        self.db_total();
951        self.db_order();
952        if self.pid_id.is_empty() {
953            self.db.page(self.page as i32, self.limit as i32);
954        } else {
955            self.db.page(1, 1000);
956        }
957
958        self.data = self.db.select();
959        self.db_table_tree(pid_field);
960
961        object! {
962            "pages"=>self.pages,
963            "total"=>self.total,
964            "data"=>self.data.clone(),
965            "columns"=>self.columns(),
966            "filter_fields"=>self.filter_fields.clone(),
967            "search_name"=>self.search_name.clone(),
968            "total_fields"=>self.total_fields.clone(),
969            "btn_all"=>array![],
970            "btn_api"=>array![],
971            "btn_ids"=>array![]
972        }
973    }
974    pub fn get_table_edit(&mut self) -> JsonValue {
975        self.db.table(&self.main_table);
976        self.db_fields();
977        self.db_search();
978        self.db_where();
979        self.db_total();
980        self.db_order();
981        self.db.page(self.page as i32, self.limit as i32);
982        self.db_join();
983        self.data = self.db.select();
984
985        object! {
986            "pages"=>self.pages,
987            "total"=>self.total,
988            "data"=>self.data.clone(),
989            "columns"=>self.columns(),
990            "edit_fields"=>self.edit_fields.clone(),
991        }
992    }
993    pub fn get_table_select(&mut self) -> JsonValue {
994        self.db.table(&self.main_table);
995        if !self.primary_key.eq("id") {
996            self.fields_keys.remove(0);
997        }
998        if !self.value.is_empty() && self.search.is_empty() {
999            let _ = self
1000                .where_or
1001                .push(array![self.primary_key.clone(), "in", self.value.clone()]);
1002            let _ = self
1003                .where_or
1004                .push(array![self.primary_key.clone(), "isnot", "NULL"]);
1005            let _ = self.order.push(array![
1006                format!(
1007                    "{} in ('{}')",
1008                    self.primary_key.clone(),
1009                    self.value.join("','")
1010                ),
1011                true
1012            ]);
1013        }
1014        self.db_fields();
1015        self.db_search();
1016        self.db_where();
1017        self.db_join();
1018        self.db_total();
1019        self.db_order();
1020        self.db.page(self.page as i32, self.limit as i32);
1021
1022        let mut list = self.db.select();
1023
1024        for item in list.members_mut() {
1025            let value = item[self.primary_key.clone()].clone();
1026            if self.primary_key.eq("id") {
1027                item.remove(&self.primary_key.clone());
1028            }
1029            let label = item
1030                .entries()
1031                .map(|(_, v)| v.to_string())
1032                .collect::<Vec<String>>();
1033            let _ = self.data.push(object! {
1034                value: value,
1035                label: label.join(" | ").clone(),
1036            });
1037        }
1038
1039        object! {
1040            "pages"=>self.pages,
1041            "total"=>self.total,
1042            "data"=>self.data.clone(),
1043        }
1044    }
1045    pub fn get_table_select_tree(&mut self, pid_field: &str, label_field: &str) -> JsonValue {
1046        self.fields_keys.push(pid_field.to_string());
1047        self.db.table(&self.main_table);
1048        self.db
1049            .where_and(pid_field, "=", self.pid_id.clone().into());
1050
1051        self.db_fields();
1052        self.db_search();
1053        self.db_where();
1054        self.db_join();
1055        self.db_order();
1056        self.db.page(1, 1000);
1057
1058        self.data = self.db.select();
1059
1060        for item in self.data.members_mut() {
1061            let children = self
1062                .db
1063                .table(&self.main_table)
1064                .where_and(pid_field, "=", item["id"].clone())
1065                .count();
1066            if children.is_empty() {
1067                item["lazy"] = false.into();
1068                item["isLeaf"] = true.into();
1069            } else {
1070                item["lazy"] = true.into();
1071            }
1072        }
1073
1074        if self.pid_id.is_empty() {
1075            for id in self.value.clone() {
1076                let mut list = vec![];
1077                let mut find = self
1078                    .db
1079                    .table(&self.main_table)
1080                    .where_and("id", "=", id.into())
1081                    .field(self.fields_keys.join(",").as_str())
1082                    .find();
1083                loop {
1084                    let pid = find[pid_field].to_string();
1085                    if pid.is_empty() {
1086                        break;
1087                    }
1088                    find = self
1089                        .db
1090                        .table(&self.main_table)
1091                        .where_and("id", "=", pid.into())
1092                        .field(self.fields_keys.join(",").as_str())
1093                        .find();
1094                    list.insert(0, find.clone());
1095                }
1096                let data = &mut self.data.clone();
1097                self.tree_data(data, list.into(), 0, pid_field);
1098                self.data = data.clone();
1099            }
1100        }
1101        object! {
1102            "data"=> self.data.clone(),
1103            "label_field"=>label_field.to_string(),
1104            "pid_field"=>pid_field.to_string(),
1105        }
1106    }
1107    fn tree_data(&mut self, data: &mut JsonValue, list: JsonValue, index: usize, pid_field: &str) {
1108        let id = list[index]["id"].clone();
1109        for item in data.members_mut() {
1110            let children = self
1111                .db
1112                .table(&self.main_table)
1113                .where_and(pid_field, "=", item["id"].clone())
1114                .field(self.fields_keys.join(",").as_str())
1115                .select();
1116            if children.is_empty() {
1117                item["isLeaf"] = true.into();
1118            }
1119            if id == item["id"] && !children.is_empty() {
1120                item["children"] = children;
1121                self.tree_data(&mut item["children"], list.clone(), index + 1, pid_field);
1122            }
1123        }
1124    }
1125}