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