br_addon/
tables.rs

1use br_db::Db;
2use br_fields::Field;
3use json::{array, object, JsonValue};
4
5#[allow(clippy::too_many_arguments)]
6#[cfg(any(feature = "sqlite", feature = "mssql", feature = "mysql", feature = "pgsql"))]
7pub struct Tables {
8    /// 主数据表名称
9    main_table: String,
10    /// 子表名称
11    join_table: String,
12    /// 数据库
13    db: Db,
14    /// 记录总数量
15    total: f64,
16    /// 字段数据
17    fields: JsonValue,
18    /// 连表查询
19    join_params: Vec<Vec<String>>,
20    /// 字段值集合
21    fields_keys: Vec<String>,
22    /// 数据
23    data: JsonValue,
24    /// 页数
25    page: usize,
26    /// 总页数
27    pages: i64,
28    /// 每页数量
29    limit: usize,
30    /// 搜索内容
31    search: String,
32    /// 搜索字段
33    search_fields: Vec<String>,
34    /// 搜索框名称
35    search_name: String,
36    /// 可以编辑字段
37    edit_fields: Vec<String>,
38    /// 排序
39    /// array![array!["id",false]]
40    order: JsonValue,
41    /// 过滤条件
42    /// array![array!["id","=","*"]]
43    where_and: JsonValue,
44    /// 过滤条件
45    /// array![array!["id","=","*"]]
46    where_or: JsonValue,
47    /// 过滤字段
48    filter_fields: Vec<String>,
49    /// 表单关联字段
50    table_fields: Vec<String>,
51    /// 树形关联字段
52    tree_fields: Vec<String>,
53    /// JSON字段
54    json_fields: Vec<String>,
55    /// 地图字段
56    location_fields: Vec<String>,
57    /// 选中值的字段
58    value_field: String,
59    /// 选中值
60    value: String,
61}
62impl Tables {
63    fn params_table(mut params: JsonValue) -> JsonValue {
64        params["page"] = br_fields::int::Int::new(false, "page", "页数", 10, 1).example(1.into()).field();
65        params["limit"] = br_fields::int::Int::new(false, "limit", "行数", 10, 10).example(10.into()).field();
66        params["order"] = br_fields::text::Array::new(false, "order", "排序", array![]).field();
67        params["search"] = br_fields::str::Str::new(false, "search", "搜索", 200, "").example("".into()).field();
68        params["where_or"] = br_fields::text::Array::new(false, "where_or", "查询条件", array![]).example(array![]).field();
69        params["where_and"] = br_fields::text::Array::new(false, "where_and", "查询条件", array![]).example(array![]).field();
70        params["params"] = br_fields::text::Object::new(false, "params", "关联数据参数", object! {}).describe("如果是表单就是表单里的其他字段").example(object! {}).field();
71        params
72    }
73    pub fn params_table_tree(mut params: JsonValue) -> JsonValue {
74        params["pid"] = br_fields::str::Str::new(false, "pid", "上级ID", 50, "").example("".into()).field();
75        Tables::params_table(params)
76    }
77    pub fn params_table_select(params: JsonValue) -> JsonValue {
78        Tables::params_table(params)
79    }
80    pub fn params_dict_select(mut params: JsonValue) -> JsonValue {
81        params["value"] = br_fields::text::Text::new(false, "value", "选中值", "").field();
82        params["field"] = br_fields::str::Str::new(true, "field", "值的字段", 200, "").field();
83        Tables::params_table(params)
84    }
85    pub fn new(db: Db) -> Self {
86        Self {
87            main_table: "".to_string(),
88            join_table: "".to_string(),
89            db,
90            total: 0.0,
91            fields: object! {},
92            join_params: vec![],
93            fields_keys: vec![],
94            data: array![],
95            page: 1,
96            pages: 0,
97            limit: 10,
98            search: "".to_string(),
99            search_fields: vec![],
100            search_name: "".to_string(),
101            edit_fields: vec![],
102            order: array![],
103            where_and: array![],
104            where_or: array![],
105            filter_fields: vec![],
106            table_fields: vec![],
107            tree_fields: vec![],
108            json_fields: vec![],
109            location_fields: vec![],
110            value_field: "".to_string(),
111            value: "".to_string(),
112        }
113    }
114
115    pub fn main_table_fields(&mut self, table: &str, mut fields: JsonValue, hidd_fields: Vec<&str>, mut show_fields: Vec<&str>) -> &mut Self {
116        self.main_table = table.to_string();
117        for item in hidd_fields {
118            if fields.has_key(item) {
119                fields.remove(item);
120                continue;
121            }
122        }
123        if !show_fields.is_empty() {
124            show_fields.insert(0, "id");
125            let mut f = object! {};
126            for key in show_fields {
127                if fields.has_key(key) {
128                    f[key] = fields[key].clone();
129                }
130            }
131            fields = f;
132        }
133        self.fields = fields.clone();
134        for (field, item) in self.fields.entries() {
135            self.fields_keys.push(field.to_string());
136            match item["mode"].as_str().unwrap() {
137                "table" => self.table_fields.push(field.to_string()),
138                "tree" => self.tree_fields.push(field.to_string()),
139                "object" | "array" | "polygon" => self.json_fields.push(field.to_string()),
140                "location" => self.location_fields.push(field.to_string()),
141                _ => {}
142            }
143        }
144        self
145    }
146    pub fn join_table_fields(&mut self, table: &str, mut fields: JsonValue, main_field: &str, join_field: &str) -> &mut Self {
147        self.join_table = table.to_string();
148
149        let mut field = vec![];
150        for (key, item) in fields.entries_mut() {
151            item["field"] = format!("{table}_{key}").into();
152            field.push(format!("{key} as {table}_{key}"));
153            self.fields[format!("{table}_{key}").as_str()] = item.clone();
154        }
155        self.join_params.push(vec![table.to_string(), main_field.to_string(), join_field.to_string(), field.join(",")]);
156        self
157    }
158    pub fn edit_fields(&mut self, fields: Vec<&str>) -> &mut Self {
159        self.edit_fields = fields.iter().map(|s| s.to_string()).collect();
160        self
161    }
162    pub fn search_fields(&mut self, fields: Vec<&str>) -> &mut Self {
163        let mut search_name = vec![];
164        for key in fields.clone() {
165            if self.fields.has_key(key) {
166                self.search_fields.push(key.to_string());
167                search_name.push(self.fields[key]["title"].to_string());
168            }
169        }
170        self.search_name = search_name.join("/");
171        self
172    }
173    /// 条件过滤
174    pub fn filter_fields(&mut self, fields: Vec<&str>) -> &mut Self {
175        for key in fields.clone() {
176            if self.fields.has_key(key) {
177                self.filter_fields.push(key.to_string());
178            }
179        }
180        self
181    }
182    /// 请求参数
183    pub fn params(&mut self, request: JsonValue) -> &mut Self {
184        if request.has_key("page") {
185            self.page = request["page"].as_usize().unwrap();
186        }
187        if request.has_key("limit") {
188            self.limit = request["limit"].as_usize().unwrap();
189        }
190        if request.has_key("where_and") {
191            self.where_and = request["where_and"].clone();
192        }
193        if request.has_key("where_or") {
194            self.where_or = request["where_or"].clone();
195        }
196        if request.has_key("search") {
197            self.search = request["search"].to_string();
198        }
199        if request.has_key("field") {
200            self.value_field = request["field"].to_string();
201        }
202        if request.has_key("value") {
203            self.value = request["value"].to_string();
204        }
205        self
206    }
207
208    fn db_search(&mut self) {
209        if !self.search.is_empty() {
210            self.db.where_and(&self.search_fields.join("|"), "like", format!("%{}%", self.search).into());
211        }
212    }
213    fn db_where(&mut self) {
214        for (key, value) in self.where_or.entries() {
215            if value.is_empty() {
216                continue;
217            }
218            if value.is_array() {
219                self.db.where_or(key, "in", value.clone());
220            } else if value.is_boolean() {
221                self.db.where_or(key, "=", value.clone());
222            } else {
223                self.db.where_or(key, "like", format!("%{value}%").into());
224            }
225        }
226        for value in self.where_and.members() {
227            self.db.where_and(
228                value[0].as_str().unwrap(),
229                value[1].as_str().unwrap(),
230                value[2].clone(),
231            );
232        }
233        for item in self.order.members() {
234            self.db.order(item[0].as_str().unwrap(), item[1].as_bool().unwrap());
235        }
236    }
237    fn db_fields(&mut self) {
238        self.db.field(self.fields_keys.join(",").as_str());
239        if !self.json_fields.is_empty() {
240            self.db.json(self.json_fields.join(",").as_str());
241        }
242        if !self.location_fields.is_empty() {
243            self.db.location(self.location_fields.join(",").as_str());
244        }
245    }
246    fn db_join(&mut self) {
247        for item in self.join_params.iter() {
248            self.db.join(&item[0], &item[1], &item[2]).field(&item[3]);
249        }
250    }
251    fn db_total(&mut self) {
252        self.total = self.db.clone().count().as_f64().unwrap();
253        self.pages = (self.total / (self.limit as f64)).ceil() as i64;
254    }
255    fn db_table(&mut self) {
256        let mut table_data = object! {};
257        for item in self.data.members_mut() {
258            for field in self.table_fields.iter() {
259                let key = item[field].as_str().unwrap_or("");
260                if key.is_empty() {
261                    continue;
262                }
263                let field_info = self.fields[field].clone();
264
265                if !table_data.has_key(field) {
266                    table_data[field] = object! {};
267                }
268                if !table_data[field].has_key(key) {
269                    let mut info = field_info.clone();
270                    let _ = info["fields"].push("id");
271                    let fields_k = info["fields"].members().map(|x| x.as_str().unwrap()).collect::<Vec<&str>>();
272                    let mut find = self.db.table(info["table"].as_str().unwrap()).where_and("id", "=", key.into()).field(&fields_k.join(",")).find();
273                    let id = find["id"].to_string();
274                    find.remove("id");
275                    let label = find.entries().map(|(_, v)| v.to_string()).collect::<Vec<String>>();
276                    table_data[field][key] = object! {
277                                value: id.clone(),
278                                label:label.join(" | ").clone(),
279                    };
280                }
281                item[field] = table_data[field][key].clone();
282            }
283            for field in self.tree_fields.iter() {
284                let key = item[field].as_str().unwrap_or("");
285                if key.is_empty() {
286                    continue;
287                }
288                let field_info = self.fields[field].clone();
289                if !table_data.has_key(field) {
290                    table_data[field] = object! {};
291                }
292                if !table_data[field].has_key(key) {
293                    let mut info = field_info.clone();
294                    let pid_field = info["pid_field"].clone().to_string();
295                    let _ = info["fields"].push("id");
296                    let _ = info["fields"].push(pid_field.clone());
297                    let fields_k = info["fields"].members().map(|x| x.as_str().unwrap()).collect::<Vec<&str>>();
298                    let mut find = self.db.table(info["table"].as_str().unwrap()).where_and("id", "=", key.into()).field(&fields_k.join(",")).find();
299                    let mut pid = find[pid_field.clone()].to_string();
300                    let mut name_list = vec![];
301                    let id = find["id"].to_string();
302                    find.remove("id");
303                    find.remove(&pid_field);
304                    let label = find.entries().map(|(_, v)| v.to_string()).collect::<Vec<String>>();
305                    name_list.push(label.join(" | ").clone());
306                    loop {
307                        if pid.is_empty() {
308                            break;
309                        }
310                        let mut t = self.db.table(info["table"].as_str().unwrap()).where_and("id", "=", pid.clone().into()).field(&fields_k.join(",")).find();
311                        pid = t[pid_field.clone()].to_string();
312                        t.remove("id");
313                        t.remove(&pid_field);
314                        let label = t.entries().map(|(_, v)| v.to_string()).collect::<Vec<String>>();
315                        name_list.push(label.join(" | ").clone());
316                    }
317                    name_list.reverse();
318                    table_data[field][key] = object! {
319                                value: id.clone(),
320                                label:name_list.join("/").clone(),
321                        };
322                }
323                item[field] = table_data[field][key].clone();
324            }
325        }
326    }
327    fn q_columns(&mut self) -> JsonValue {
328        let mut columns = object! {};
329        for (key, item) in self.fields.entries() {
330            columns[key] = item.clone();
331            columns[key]["name"] = item["field"].clone();
332            columns[key]["align"] = "center".into();
333            columns[key]["label"] = item["title"].clone();
334            columns[key]["field"] = item["field"].clone();
335            columns[key]["version"] = 1.into();
336            if item["mode"].as_str().unwrap() == "string" {}
337        }
338        columns
339    }
340    pub fn get_table(&mut self) -> JsonValue {
341        self.db.table(&self.main_table);
342        self.db_search();
343        self.db_where();
344        self.db_total();
345        self.db_fields();
346        self.db.page(self.page as i32, self.limit as i32);
347        self.db_join();
348        self.data = self.db.select();
349        self.db_table();
350
351        object! {
352            "pages"=>self.pages,
353            "total"=>self.total,
354            "data"=>self.data.clone(),
355            "columns"=>self.q_columns(),
356            "filter_fields"=>self.filter_fields.clone(),
357            "search_name"=>self.search_name.clone(),
358            "btn_all"=>array![],
359            "btn_api"=>array![],
360            "btn_ids"=>array![]
361        }
362    }
363    fn a_columns(&mut self) -> JsonValue {
364        let mut columns = object! {};
365        for (key, item) in self.fields.entries() {
366            columns[key] = item.clone();
367            columns[key]["dataIndex"] = item["field"].clone();
368            columns[key]["align"] = "center".into();
369            columns[key]["slotName"] = item["field"].clone();
370            columns[key]["titleSlotName"] = item["field"].clone();
371            if item["mode"].as_str().unwrap() == "string" {}
372            //columns[key]["width"] = 50.into();
373
374            //columns[key]["minWidth"] = 50.into();
375            //columns[key]["fixed"] = "left".into();
376        }
377        columns
378    }
379    pub fn get_table_edit(&mut self) -> JsonValue {
380        self.db.table(&self.main_table);
381        self.db_search();
382        self.db_where();
383        self.db_total();
384        self.db_fields();
385        self.db.page(self.page as i32, self.limit as i32);
386        self.db_join();
387        self.data = self.db.select();
388
389        object! {
390            "pages"=>self.pages,
391            "total"=>self.total,
392            "data"=>self.data.clone(),
393            "columns"=>self.a_columns(),
394            "edit_fields"=>self.edit_fields.clone(),
395        }
396    }
397    pub fn get_table_select(&mut self) -> JsonValue {
398        self.db.table(&self.main_table);
399        self.db_search();
400        self.db_where();
401        self.db_total();
402        self.db_fields();
403        self.db.page(self.page as i32, self.limit as i32);
404        self.db_join();
405        self.data = self.db.select();
406
407
408        object! {
409            "pages"=>self.pages,
410            "total"=>self.total,
411            "data"=>self.data.clone(),
412        }
413    }
414    pub fn get_table_dict_select(&mut self) -> JsonValue {
415        self.db.table(&self.main_table);
416        self.fields_keys.remove(0);
417        if !self.value.is_empty() {
418            let _ = self.where_or.push(array![self.value_field.clone(),"in",self.value.clone()]);
419        }
420
421        self.db_search();
422        self.db_where();
423        self.db_total();
424        self.db_fields();
425        self.db.page(self.page as i32, self.limit as i32);
426        self.db_join();
427        let mut list = self.db.select();
428
429        for item in list.members_mut() {
430            let value = item[self.value_field.clone()].clone();
431            let label = item.entries().map(|(_, v)| v.to_string()).collect::<Vec<String>>();
432            self.data.push(object! {
433                value: value,
434                label: label.join(" | ").clone(),
435            }).unwrap();
436        }
437        object! {
438            "pages"=>self.pages,
439            "total"=>self.total,
440            "data"=>self.data.clone(),
441        }
442    }
443}