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