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