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