1use crate::request::{ContentType, Method, Request};
2use crate::PLUGIN_TOOLS;
3use crate::{ApiResponse, Tools};
4use br_fields::Field;
5use json::{array, object, JsonValue};
6use std::any::type_name;
7use std::collections::HashMap;
8
9pub trait Action {
11 fn _name(&self) -> String {
13 type_name::<Self>()
14 .rsplit("::")
15 .next()
16 .unwrap()
17 .to_lowercase()
18 }
19 fn api(&self) -> String {
21 let t = type_name::<Self>().split("::").collect::<Vec<&str>>();
22 let plugin = t[2].to_lowercase();
23 let module = t[3].to_lowercase();
24 let action = t[4].to_lowercase();
25 format!("{plugin}.{module}.{action}")
26 }
27 fn token(&self) -> bool {
29 true
30 }
31 fn version(&self) -> &'static str {
33 "v1"
34 }
35 fn author(&self) -> &'static str {
37 ""
38 }
39 fn sort(&self) -> usize {
40 99
41 }
42 fn title(&self) -> &'static str;
44 fn description(&self) -> &'static str {
46 ""
47 }
48 fn path(&self) -> &'static str {
50 ""
51 }
52 fn query(&self) -> JsonValue {
54 object! {}
55 }
56 fn tags(&self) -> &'static [&'static str] {
58 &[]
59 }
60 fn icon(&self) -> &'static str {
61 ""
62 }
63 fn public(&self) -> bool {
65 true
66 }
67 fn auth(&mut self) -> bool {
69 true
70 }
71 fn interface_type(&mut self) -> InterfaceType {
73 InterfaceType::API
74 }
75 fn method(&mut self) -> Method {
77 Method::Post
78 }
79 fn content_type(&mut self) -> ContentType {
81 ContentType::Json
82 }
83 fn params(&mut self) -> JsonValue {
85 object! {}
86 }
87 fn success(&mut self) -> ApiResponse {
89 let mut data = object! {};
90 data["code"] = br_fields::int::Int::new(true, "code", "编号", 10, 0)
91 .example(0.into())
92 .swagger();
93 data["message"] = br_fields::str::Str::new(true, "message", "成功消息", 256, "")
94 .example("成功".into())
95 .swagger();
96 data["data"] = br_fields::text::Json::new(true, "data", "返回数据", object! {}).swagger();
97 data["success"] = br_fields::int::Switch::new(true, "success", "成功状态", true)
98 .example(true.into())
99 .swagger();
100 ApiResponse::success(data, "请求成功")
101 }
102 fn error(&mut self) -> ApiResponse {
104 let mut data = object! {};
105 data["code"] = br_fields::int::Int::new(true, "code", "编号", 10, 1000)
106 .example(1000.into())
107 .swagger();
108 data["message"] = br_fields::str::Str::new(true, "message", "错误消息", 256, "")
109 .example("失败".into())
110 .swagger();
111 data["data"] = br_fields::text::Json::new(true, "data", "返回数据", object! {}).swagger();
112 data["success"] = br_fields::int::Switch::new(true, "success", "成功状态", false)
113 .example(false.into())
114 .swagger();
115 ApiResponse::error(data, "请求失败")
116 }
117 fn run(&mut self, mut request: Request) -> Result<ApiResponse, ApiResponse> {
119 if self.method().str().to_lowercase() != request.method.str().to_lowercase() {
120 return Err(ApiResponse::fail(
121 -1,
122 format!(
123 "Request type error: Actual [{}] Expected [{}]",
124 request.method.str(),
125 self.method().str()
126 )
127 .as_str(),
128 ));
129 }
130 let params=self.params().clone();
131 self.check(&mut request.query.clone().into(),self.query().clone())?;
132 self.check(&mut request.body,params)?;
133 let res = self.index(request.clone());
134 match res.success {
135 true => Ok(res),
136 false => Err(res),
137 }
138 }
139 fn check(&mut self, request: &mut JsonValue,params:JsonValue) -> Result<(), ApiResponse> {
141 let req = request.clone();
142 for (name, _) in req.entries() {
143 if !params.has_key(name) {
144 request.remove(name);
145 }
146 }
147 for (name, field) in params.entries() {
148 let require = field["require"].as_bool().unwrap_or(false);
149 if request.has_key(name) {
150 match field["mode"].as_str().unwrap() {
152 "int" => {
153 if !request[name].is_number() {
154 return Err(ApiResponse::fail(
155 -1,
156 format!(
157 "请求参数数据类型错误: 参数 [{}] 数据类型应为[{}]",
158 name, field["mode"]
159 )
160 .as_str(),
161 ));
162 }
163 }
164 "string" => {
165 if !request[name].is_string() {
166 return Err(ApiResponse::fail(
167 -1,
168 format!(
169 "请求参数数据类型错误: 参数 [{}] 数据类型应为[{}]",
170 name, field["mode"]
171 )
172 .as_str(),
173 ));
174 }
175 if require && request[name].is_empty() {
176 return Err(ApiResponse::fail(
177 -1,
178 format!("请求参数数据类型错误: 参数 [{}] 不能为空", name).as_str(),
179 ));
180 }
181 }
182 "switch" => {
183 if !request[name].is_boolean() {
184 return Err(ApiResponse::fail(
185 -1,
186 format!(
187 "请求参数数据类型错误: 参数 [{}] 数据类型应为[{}]",
188 name, field["mode"]
189 )
190 .as_str(),
191 ));
192 }
193 }
194 "select" => {
195 if !request[name].is_array() && !request[name].is_string() {
196 return Err(ApiResponse::fail(
197 -1,
198 format!(
199 "请求参数数据类型错误: 参数 [{}] 数据类型应为[{}]",
200 name, field["mode"]
201 )
202 .as_str(),
203 ));
204 }
205 let option = field["option"]
206 .members()
207 .map(|m| m.as_str().unwrap_or(""))
208 .collect::<Vec<&str>>()
209 .join(",");
210 if request[name].is_string()
211 && !field["option"].contains(request[name].as_str().unwrap_or(""))
212 {
213 return Err(ApiResponse::fail(
214 -1,
215 format!(
216 "请求参数选项错误: 参数 [{}] 数据类型应为[{}]之内",
217 name, option
218 )
219 .as_str(),
220 ));
221 }
222 if request[name].is_array() {
223 let res1 = request[name]
224 .members()
225 .map(|m| m.as_str().unwrap_or(""))
226 .collect::<Vec<&str>>();
227 let diff = res1
228 .iter()
229 .filter(|&item| {
230 !field["option"]
231 .members()
232 .map(|m| m.as_str().unwrap_or(""))
233 .collect::<Vec<&str>>()
234 .contains(item)
235 })
236 .collect::<Vec<&&str>>();
237 if !diff.is_empty() {
238 return Err(ApiResponse::fail(
239 -1,
240 format!(
241 "请求参数选项错误: 参数 [{}] 数据 {:?} 应为[{:?}]范围之内",
242 name, diff, option
243 )
244 .as_str(),
245 ));
246 }
247 }
248 }
249 "radio" => {
250 if !request[name].is_string() {
251 return Err(ApiResponse::fail(
252 -1,
253 format!(
254 "请求参数数据类型错误: 参数 [{}] 数据类型应为[{}] 实际为[{}]",
255 name, field["mode"], request[name]
256 )
257 .as_str(),
258 ));
259 }
260 let option = field["option"]
261 .members()
262 .map(|m| m.as_str().unwrap_or(""))
263 .collect::<Vec<&str>>()
264 .join(",");
265 if request[name].is_string()
266 && !field["option"].contains(request[name].as_str().unwrap_or(""))
267 {
268 return Err(ApiResponse::fail(
269 -1,
270 format!(
271 "请求参数选项错误: 参数 [{}] 数据 [{}] 应为 [{}] 之一",
272 name, request[name], option
273 )
274 .as_str(),
275 ));
276 }
277 }
278 _ => {
279 }
281 }
282 } else {
283 if require {
284 return Err(ApiResponse::fail(
285 -1,
286 format!("请求参数错误: 参数[{}]必填", name).as_str(),
287 ));
288 }
289 request[name] = field["def"].clone();
290 }
291 }
292 Ok(())
293 }
294 fn index(&mut self, request: Request) -> ApiResponse;
296 fn params_table_select(&mut self, mut params: JsonValue) -> JsonValue {
297 params["page"] = br_fields::int::Int::new(false, "page", "页数", 10, 1)
298 .example(1.into())
299 .field();
300 params["limit"] = br_fields::int::Int::new(false, "limit", "行数", 10, 10)
301 .example(10.into())
302 .field();
303 params["search"] = br_fields::str::Str::new(false, "search", "搜索", 200, "")
304 .example("".into())
305 .field();
306 params["where_or"] = br_fields::text::Array::new(false, "where_or", "查询条件", array![])
307 .example(array![])
308 .field();
309 params["where_and"] = br_fields::text::Array::new(false, "where_and", "查询条件", array![])
310 .example(array![])
311 .field();
312 params["params"] = br_fields::text::Object::new(false, "params", "关联数据参数", object!{})
313 .example(object!{})
314 .field();
315 params
316 }
317 #[cfg(any(feature = "sqlite", feature = "mssql", feature = "mysql"))]
318 fn table_select(
319 &mut self,
320 request: JsonValue,
321 table_name: &str,
322 mut fields: Vec<&str>,
323 ) -> JsonValue {
324 let page = request["page"].as_i32().unwrap_or(1);
325 let limit = request["limit"].as_i32().unwrap_or(10);
326
327 let search = request["search"].as_str().unwrap_or("");
328
329 let where_or = request["where_or"].clone();
330 let where_and = request["where_and"].clone();
331
332 let mut tools = self.tools();
333 let db = tools.db.table(table_name);
334
335 if !search.is_empty() {
336 db.where_and(&fields.join("|"), "like", format!("%{}%", search).into());
337 }
338
339 for (key, value) in where_or.entries() {
340 if value.is_empty() {
341 continue;
342 }
343 if value.is_array() {
344 db.where_or(key, "between", value.clone());
345 db.where_or(key, "in", value.clone());
346 } else if value.is_boolean() {
347 db.where_or(key, "=", value.clone());
348 } else {
349 db.where_or(key, "like", format!("%{}%", value).into());
350 }
351 }
352
353 for value in where_and.members() {
354 db.where_and(
355 value[0].as_str().unwrap(),
356 value[1].as_str().unwrap(),
357 value[2].clone(),
358 );
359 }
360
361 let total = (db.clone().count().as_f64().unwrap() / limit as f64).ceil() as i64;
362 let mut db_list = db.clone();
363
364 fields.push("id");
365 db_list.field(&fields.join(","));
366
367 let mut data = db_list.page(page, limit).select();
368 let mut list = array![];
369 for item in data.members_mut() {
370 let value = item["id"].clone();
371 item.remove("id");
372
373 let label = item
374 .entries()
375 .map(|(_, v)| v.as_str().unwrap())
376 .collect::<Vec<&str>>();
377
378 list.push(object! {
379 value: value,
380 label: label.join(" | ").clone(),
381 })
382 .unwrap();
383 }
384 object! {
385 total:total,
386 data:list,
387 }
388 }
389 fn params_table_menu(&mut self, mut params: JsonValue) -> JsonValue {
391 params["search"] = br_fields::str::Str::new(false, "search", "搜索", 200, "")
392 .example("".into())
393 .field();
394 params["where_or"] = br_fields::text::Array::new(false, "where_or", "查询条件", array![])
395 .example(array![])
396 .field();
397 params["where_and"] = br_fields::text::Array::new(false, "where_and", "查询条件", array![])
398 .example(array![])
399 .field();
400 params
401 }
402 #[cfg(any(feature = "sqlite", feature = "mssql", feature = "mysql"))]
403 fn table_menu(
404 &mut self,
405 request: JsonValue,
406 table_name: &str,
407 label_field: &str,
408 fields: JsonValue,
409
410 hidd_field: Vec<&str>,
411 show_field: Vec<&str>,
412
413 search_fields: Vec<&str>,
414 _filter_fields: Vec<&str>,
415 ) -> JsonValue {
416 let search = request["search"].as_str().unwrap_or("");
417
418 let order = request["order"].clone();
419 let where_or = request["where_or"].clone();
420 let where_and = request["where_and"].clone();
421 let mut columns = array![];
422 let mut search_name = vec![];
423 let mut search_field = vec![];
424 let mut filter_columns = vec![];
425 let mut table_fields = object! {};
426 let mut table_field_json = vec![];
427
428 let mut alls_field = fields.entries().map(|(x, _)| x).collect::<Vec<&str>>();
429 alls_field.retain(|x| !hidd_field.contains(x));
430 if !show_field.is_empty() {
431 alls_field.retain(|x| show_field.contains(x) || *x == "id");
432 }
433
434 for item in alls_field.iter() {
435 let row = fields[item.clone()].clone();
436 let field = row["field"].to_string();
437 let title = row["title"].to_string();
438 let mode = row["mode"].to_string();
439
440 if search_fields.contains(&field.as_str()) {
441 search_name.push(title);
442 search_field.push(field.clone());
443 }
444 filter_columns.push(self.filter_column(row.clone()));
445 columns.push(self.table_column(row.clone())).unwrap();
446 let mut table_field_info = object! {};
447 match mode.as_str() {
448 "table" => table_field_info = row.clone(),
449 "array" => table_field_json.push(field.clone()),
450 _ => {}
451 }
452 if !table_field_info.is_empty() {
453 table_fields[field.as_str()] = table_field_info;
454 }
455 }
456
457 let mut tools = self.tools();
458 let db = tools.db.table(table_name);
459
460 if !search.is_empty() {
461 db.where_and(
462 &search_field.join("|"),
463 "like",
464 format!("%{}%", search).into(),
465 );
466 }
467
468 for (key, value) in where_or.entries() {
469 if value.is_empty() {
470 continue;
471 }
472 if value.is_array() {
473 db.where_or(key, "between", value.clone());
474 db.where_or(key, "in", value.clone());
475 } else if value.is_boolean() {
476 db.where_or(key, "=", value.clone());
477 } else {
478 db.where_or(key, "like", format!("%{}%", value).into());
479 }
480 }
481
482 for value in where_and.members() {
483 db.where_and(
484 value[0].as_str().unwrap(),
485 value[1].as_str().unwrap(),
486 value[2].clone(),
487 );
488 }
489
490 let mut db_list = db.clone();
491
492 for item in order.members() {
493 db_list.order(item[0].as_str().unwrap(), item[1].as_bool().unwrap());
494 }
495
496 let t = alls_field.join(",");
497 db_list.field(t.as_str());
498
499 if !table_field_json.is_empty() {
500 db_list.json(&table_field_json.join(","));
501 }
502
503 let mut data = db_list.select();
504
505 let mut table_datas = object! {};
506 let mut ids = HashMap::new();
507
508 for item in data.members_mut() {
509 for (field, _) in table_fields.entries() {
510 if table_datas[field].is_empty() {
511 table_datas[field] = array![];
512 }
513 let _ = table_datas[field].push(item[field].clone());
514 }
515 }
516 for (field, info) in table_fields.entries_mut() {
517 let _ = info["fields"].push("id");
518 let fields_k = info["fields"]
519 .members()
520 .map(|x| x.as_str().unwrap())
521 .collect::<Vec<&str>>();
522 let table_name = info["table"].clone();
523 let mut data_list = self
524 .tools()
525 .db
526 .table(table_name.as_str().unwrap())
527 .where_and("id", "in", table_datas[field].clone())
528 .field(&fields_k.join(","))
529 .select();
530
531 for item in data_list.members_mut() {
532 let id = item["id"].as_str().unwrap_or("").to_string();
533 item.remove("id");
534 let label = item
535 .entries()
536 .map(|(_, v)| v.as_str().unwrap())
537 .collect::<Vec<&str>>();
538 ids.insert(
539 id.clone(),
540 object! {
541 value: id.clone(),
542 label:label.join(" | ").clone(),
543 },
544 );
545 }
546 }
547
548 for item in data.members_mut() {
549 for (field, _) in table_fields.entries() {
550 if item[field].is_empty() {
551 continue;
552 }
553 item[field] = ids[item[field].as_str().unwrap()].clone();
554 }
555 }
556
557 object! {
558 data:data,
559 columns:columns,
560 search_name:search_name.join("/"),
561 filter_columns:filter_columns,
562 label_field:label_field,
563 btn_all:array![],
564 btn_api:array![]
565 }
566 }
567 fn params_table_tree(&mut self, mut params: JsonValue) -> JsonValue {
569 params["pid"] = br_fields::str::Str::new(false, "pid", "上级ID", 50, "")
570 .example("".into())
571 .field();
572 params["search"] = br_fields::str::Str::new(false, "search", "搜索", 200, "")
573 .example("".into())
574 .field();
575 params["where_or"] = br_fields::text::Array::new(false, "where_or", "查询条件", array![])
576 .example(array![])
577 .field();
578 params["where_and"] = br_fields::text::Array::new(false, "where_and", "查询条件", array![])
579 .example(array![])
580 .field();
581 params
582 }
583 #[cfg(any(feature = "sqlite", feature = "mssql", feature = "mysql"))]
584 fn table_tree(
585 &mut self,
586 request: JsonValue,
587 table_name: &str,
588 pid_field: &str,
589 label_field: &str,
590 fields: JsonValue,
591 hidd_field: Vec<&str>,
592 show_field: Vec<&str>,
593 search_fields: Vec<&str>,
594 _filter_fields: Vec<&str>,
595 ) -> JsonValue {
596 let search = request["search"].as_str().unwrap_or("");
597
598 let pid = request["pid"].clone();
599
600 let order = request["order"].clone();
601 let where_or = request["where_or"].clone();
602 let where_and = request["where_and"].clone();
603 let mut columns = array![];
604 let mut search_name = vec![];
605 let mut search_field = vec![];
606 let mut filter_columns = vec![];
607 let mut table_field_json = vec![];
608 let mut table_fields = object! {};
609
610 let mut alls_field = fields.entries().map(|(x, _)| x).collect::<Vec<&str>>();
611 alls_field.retain(|x| !hidd_field.contains(x));
612 if !show_field.is_empty() {
613 alls_field.retain(|x| show_field.contains(x) || *x == "id");
614 }
615
616 for item in alls_field.iter() {
617 let row = fields[item.clone()].clone();
618 let field = row["field"].to_string();
619 let title = row["title"].to_string();
620 let mode = row["mode"].to_string();
621
622 if search_fields.contains(&field.as_str()) {
623 search_name.push(title);
624 search_field.push(field.clone());
625 }
626 filter_columns.push(self.filter_column(row.clone()));
627 columns.push(self.table_column(row.clone())).unwrap();
628 let mut table_field_info = object! {};
629 match mode.as_str() {
630 "table" => table_field_info = row.clone(),
631 "array" => table_field_json.push(field.clone()),
632 _ => {}
633 }
634 if !table_field_info.is_empty() {
635 table_fields[field.as_str()] = table_field_info;
636 }
637 }
638
639 let mut tools = self.tools();
640 let db = tools.db.table(table_name);
641 db.where_and(pid_field, "=", pid);
642 if !search.is_empty() {
643 db.where_and(
644 &search_field.join("|"),
645 "like",
646 format!("%{}%", search).into(),
647 );
648 }
649
650 for (key, value) in where_or.entries() {
651 if value.is_empty() {
652 continue;
653 }
654 if value.is_array() {
655 db.where_or(key, "in", value.clone());
657 } else if value.is_boolean() {
658 db.where_or(key, "=", value.clone());
659 } else {
660 db.where_or(key, "like", format!("%{}%", value).into());
661 }
662 }
663
664 for value in where_and.members() {
665 db.where_and(
666 value[0].as_str().unwrap(),
667 value[1].as_str().unwrap(),
668 value[2].clone(),
669 );
670 }
671
672 let mut db_list = db.clone();
673
674 for item in order.members() {
675 db_list.order(item[0].as_str().unwrap(), item[1].as_bool().unwrap());
676 }
677 let t = alls_field.join(",");
678 db_list.field(t.as_str());
679 if !table_field_json.is_empty() {
680 db_list.json(&table_field_json.join(","));
681 }
682 let mut data = db_list.select();
683
684 let mut table_datas = object! {};
685 let mut ids = HashMap::new();
686
687 for item in data.members_mut() {
688 for (field, _) in table_fields.entries() {
689 if table_datas[field].is_empty() {
690 table_datas[field] = array![];
691 }
692 let _ = table_datas[field].push(item[field].clone());
693 }
694 }
695 for (field, info) in table_fields.entries_mut() {
696 let _ = info["fields"].push("id");
697 let fields_k = info["fields"]
698 .members()
699 .map(|x| x.as_str().unwrap())
700 .collect::<Vec<&str>>();
701 let table_name = info["table"].clone();
702 let mut data_list = self
703 .tools()
704 .db
705 .table(table_name.as_str().unwrap())
706 .where_and("id", "in", table_datas[field].clone())
707 .field(&fields_k.join(","))
708 .select();
709
710 for item in data_list.members_mut() {
711 let id = item["id"].as_str().unwrap_or("").to_string();
712 item.remove("id");
713 let label = item
714 .entries()
715 .map(|(_, v)| v.as_str().unwrap())
716 .collect::<Vec<&str>>();
717 ids.insert(
718 id.clone(),
719 object! {
720 value: id.clone(),
721 label:label.join(" | ").clone(),
722 },
723 );
724 }
725 }
726
727 let mut list = array![];
728 for item in data.members_mut() {
729 for (field, _) in table_fields.entries() {
730 if item[field].is_empty() {
731 continue;
732 }
733 item[field] = ids[item[field].as_str().unwrap()].clone();
734 }
735 let _ = list.push(object! {
736 id:item["id"].as_str().unwrap(),
737 label:item[label_field].as_str().unwrap(),
738 data:item.clone(),
739 });
740 }
741
742 object! {
743 data:list,
744 columns:columns,
745 search_name:search_name.join("/"),
746 filter_columns:filter_columns,
747 pid_field:pid_field,
748 btn_all:array![],
749 btn_api:array![]
750 }
751 }
752 fn params_table_list(&mut self, mut params: JsonValue) -> JsonValue {
754 params["page"] = br_fields::int::Int::new(false, "page", "页数", 10, 1)
755 .example(1.into())
756 .field();
757 params["limit"] = br_fields::int::Int::new(false, "limit", "行数", 10, 10)
758 .example(10.into())
759 .field();
760 params["search"] = br_fields::str::Str::new(false, "search", "搜索", 200, "")
761 .example("".into())
762 .field();
763 params["order"] = br_fields::text::Array::new(false, "order", "排序", array![])
764 .example(array![array!["id", false]])
765 .field();
766 params["where_or"] = br_fields::text::Array::new(false, "where_or", "查询条件", array![])
767 .example(array![])
768 .field();
769 params["where_and"] = br_fields::text::Array::new(false, "where_and", "查询条件", array![])
770 .example(array![])
771 .field();
772 params
773 }
774 #[cfg(any(feature = "sqlite", feature = "mssql", feature = "mysql"))]
782 fn table_list(
783 &mut self,
784 request: JsonValue,
785 table_name: &str,
786 fields: JsonValue,
787 hidd_field: Vec<&str>,
788 show_field: Vec<&str>,
789 search_fields: Vec<&str>,
790 filter_fields: Vec<&str>,
791 ) -> JsonValue {
792 let page = request["page"].as_i32().unwrap_or(1);
793 let limit = request["limit"].as_i32().unwrap_or(10);
794 let search = request["search"].as_str().unwrap_or("");
795 let order = request["order"].clone();
796 let where_or = request["where_or"].clone();
797 let where_and = request["where_and"].clone();
798 let mut columns = array![];
799 let mut search_name = vec![];
800 let mut search_field = vec![];
801 let mut filter_columns = vec![];
802
803 let mut table_fields = object! {};
804
805 let mut alls_field = fields.entries().map(|(x, _)| x).collect::<Vec<&str>>();
806 alls_field.retain(|x| !hidd_field.contains(x));
807 if !show_field.is_empty() {
808 alls_field.retain(|x| show_field.contains(x) || *x == "id");
809 }
810
811 for item in alls_field.iter() {
812 let key = item.clone();
813 let field = fields[key]["field"].as_str().unwrap();
814 let title = fields[key]["title"].as_str().unwrap();
815 let mode = fields[key]["mode"].as_str().unwrap();
816
817 if search_fields.contains(&field) {
818 search_name.push(title);
819 search_field.push(field);
820 }
821 if filter_fields.contains(&field) {
822 filter_columns.push(self.filter_column(fields[key].clone()));
823 }
824 columns
825 .push(self.table_column(fields[key].clone()))
826 .unwrap();
827 let table_field_info = if mode == "table" {
828 fields[key].clone()
829 } else {
830 JsonValue::Null
831 };
832 if !table_field_info.is_empty() {
833 table_fields[field] = table_field_info;
834 }
835 }
836
837 let mut tools = self.tools();
838 let db = tools.db.table(table_name);
839
840 if !search.is_empty() {
841 db.where_and(
842 &search_field.join("|"),
843 "like",
844 format!("%{}%", search).into(),
845 );
846 }
847
848 for (key, value) in where_or.entries() {
849 if value.is_empty() {
850 continue;
851 }
852 if value.is_array() {
853 db.where_or(key, "in", value.clone());
855 } else if value.is_boolean() {
856 db.where_or(key, "=", value.clone());
857 } else {
858 db.where_or(key, "like", format!("%{}%", value).into());
859 }
860 }
861
862 for value in where_and.members() {
863 db.where_and(
864 value[0].as_str().unwrap(),
865 value[1].as_str().unwrap(),
866 value[2].clone(),
867 );
868 }
869
870 let total = db.clone().count().as_f64().unwrap();
871 let mut db_list = db.clone();
873
874 for item in order.members() {
875 db_list.order(item[0].as_str().unwrap(), item[1].as_bool().unwrap());
876 }
877
878 let t = alls_field.join(",");
879 db_list.field(t.as_str());
880
881 let mut data = db_list.page(page, limit).select();
882
883 let mut table_datas = object! {};
884 let mut ids = HashMap::new();
885
886 for item in data.members_mut() {
887 if table_fields.is_empty() {
888 continue;
889 }
890 for (field, _) in table_fields.entries() {
891 if table_datas[field].is_empty() {
892 table_datas[field] = array![];
893 }
894 let _ = table_datas[field].push(item[field].clone());
895 }
896 }
897 for (field, info) in table_fields.entries_mut() {
898 let _ = info["fields"].push("id");
899 let fields_k = info["fields"]
900 .members()
901 .map(|x| x.as_str().unwrap())
902 .collect::<Vec<&str>>();
903 let table_name = info["table"].clone();
904 let mut data_list = self
905 .tools()
906 .db
907 .table(table_name.as_str().unwrap())
908 .where_and("id", "in", table_datas[field].clone())
909 .field(&fields_k.join(","))
910 .select();
911
912 for item in data_list.members_mut() {
913 let id = item["id"].as_str().unwrap_or("").to_string();
914 item.remove("id");
915 let label = item
916 .entries()
917 .map(|(_, v)| v.to_string())
918 .collect::<Vec<String>>();
919 ids.insert(
920 id.clone(),
921 object! {
922 value: id.clone(),
923 label:label.join(" | ").clone(),
924 },
925 );
926 }
927 }
928
929 for item in data.members_mut() {
930 if table_fields.is_empty() {
931 continue;
932 }
933 for (field, _) in table_fields.entries() {
934 if item[field].is_empty() {
935 continue;
936 }
937 let key = item[field].as_str().unwrap_or("");
938 if key.is_empty() {
939 continue;
940 }
941 if ids.get(key).is_none() {
942 continue;
943 }
944 item[field] = ids.get(key).unwrap().clone();
945 }
946 }
947
948 object! {
949 total:total,
950 data:data,
951 columns:columns,
952 search_name:search_name.join("/"),
953 filter_columns:filter_columns,
954 btn_all:array![],
955 btn_api:array![],
956 btn_ids:array![]
957 }
958 }
959 fn table_column(&mut self, field: JsonValue) -> JsonValue {
960 object! {
961 name:field["field"].clone(),
962 label:field["title"].clone(),
963 align:"center",
964 field:field["field"].clone(),
965 sortable:true,
966 mode:field["mode"].clone(),
967 }
968 }
969 fn filter_column(&mut self, field: JsonValue) -> JsonValue {
970 object! {
971 name:field["field"].clone(),
972 label:field["title"].clone(),
973 mode:field["mode"].clone(),
974 option:field["option"].clone(),
975 api:field["api"].clone(),
976 }
977 }
978 fn tools(&mut self) -> Tools {
980 let tools = PLUGIN_TOOLS.lock().unwrap();
981 let tools = tools.get("tools").unwrap().clone();
982 tools
983 }
984 fn btn(&mut self) -> Btn {
987 let mut btn = Btn::new(self.api().as_str());
988 btn.fields(self.params().clone());
989 btn.icon(self.icon());
990 btn.desc(self.description());
991 btn.title(self.title());
992 btn.btn_type(BtnType::Api);
993 btn.btn_color(BtnColor::Primary);
994 btn.path(self.api().clone().replace(".", "/").as_str());
995 btn
996 }
997}
998#[derive(Debug, Clone)]
999pub struct Btn {
1000 api: String,
1001 title: String,
1002 desc: String,
1003 btn_type: BtnType,
1004 color: BtnColor,
1005 icon: String,
1006 cnd: Vec<JsonValue>,
1007 url: String,
1008 path: String,
1009 fields: JsonValue,
1010}
1011impl Btn {
1012 pub fn new(api: &str) -> Self {
1013 Self {
1014 api: api.to_string(),
1015 title: "".to_string(),
1016 desc: "".to_string(),
1017 btn_type: BtnType::Api,
1018 color: BtnColor::Primary,
1019 icon: "".to_string(),
1020 cnd: vec![],
1021 url: "".to_string(),
1022 path: "".to_string(),
1023 fields: object! {},
1024 }
1025 }
1026 pub fn path(&mut self, path: &str) -> &mut Self {
1027 self.path = path.to_string();
1028 self
1029 }
1030 pub fn cnd(&mut self, cnd: Vec<JsonValue>) -> &mut Self {
1031 self.cnd = cnd;
1032 self
1033 }
1034 pub fn btn_type(&mut self, btn_type: BtnType) -> &mut Self {
1035 self.btn_type = btn_type;
1036 self
1037 }
1038 pub fn btn_color(&mut self, btn_color: BtnColor) -> &mut Self {
1039 self.color = btn_color;
1040 self
1041 }
1042 pub fn fields(&mut self, fields: JsonValue) -> &mut Self {
1043 self.fields = fields;
1044 self
1045 }
1046 pub fn url(&mut self, url: &str) -> &mut Self {
1047 self.url = url.to_string();
1048 self
1049 }
1050 pub fn title(&mut self, title: &str) -> &mut Self {
1051 self.title = title.to_string();
1052 self
1053 }
1054 pub fn desc(&mut self, desc: &str) -> &mut Self {
1055 self.desc = desc.to_string();
1056 self
1057 }
1058 pub fn icon(&mut self, icon: &str) -> &mut Self {
1059 self.icon = icon.to_string();
1060 self
1061 }
1062 pub fn json(&mut self) -> JsonValue {
1063 object! {
1064 api:self.api.clone(),
1065 title:self.title.clone(),
1066 desc:self.desc.clone(),
1067 btn_type:self.btn_type.clone().str(),
1068 color:self.color.clone().str(),
1069 icon:self.icon.clone(),
1070 cnd:self.cnd.clone(),
1071 url:self.url.clone(),
1072 path:self.path.clone(),
1073 fields:self.fields.clone()
1074 }
1075 }
1076}
1077
1078#[derive(Debug, Clone)]
1080pub enum InterfaceType {
1081 API,
1082 BTN,
1083 MENU,
1084}
1085
1086impl InterfaceType {
1087 pub fn str(self) -> &'static str {
1088 match self {
1089 InterfaceType::API => "api",
1090 InterfaceType::BTN => "btn",
1091 InterfaceType::MENU => "menu",
1092 }
1093 }
1094 pub fn types() -> Vec<&'static str> {
1095 vec!["api", "btn", "menu"]
1096 }
1097}
1098
1099#[derive(Debug, Clone)]
1101pub enum BtnType {
1102 Form,
1104 FormDownload,
1106 FormCustom,
1108 FormData,
1109 Url,
1111 Api,
1113 Download,
1115 Path,
1117 DialogCustom,
1119}
1120
1121impl BtnType {
1122 fn str(self) -> &'static str {
1123 match self {
1124 BtnType::Form => "form",
1125 BtnType::FormDownload => "form_download",
1126 BtnType::FormCustom => "form_custom",
1127 BtnType::FormData => "form_data",
1128 BtnType::Api => "api",
1129 BtnType::Download => "download",
1130 BtnType::Url => "url",
1131 BtnType::Path => "path",
1132 BtnType::DialogCustom => "dialog_custom",
1133 }
1134 }
1135}
1136#[derive(Debug, Clone)]
1138pub enum BtnColor {
1139 Primary,
1140 Red,
1141 Blue,
1142 Yellow,
1143 Green,
1144}
1145
1146impl BtnColor {
1147 fn str(self) -> &'static str {
1148 match self {
1149 BtnColor::Primary => "primary",
1150 BtnColor::Red => "negative",
1151 BtnColor::Blue => "info",
1152 BtnColor::Yellow => "warning",
1153 BtnColor::Green => "positive",
1154 }
1155 }
1156}