1use std::any::type_name;
2use json::{array, JsonValue, object};
3use crate::{BtnColor, BtnMode, PLUGIN_TOOLS, Response, Tools};
4use crate::model::{ModelTemp};
5
6pub trait Action {
8 fn author(&mut self) -> &'static str {
10 "Blue Rain"
11 }
12 fn title(&mut self) -> &'static str;
14 fn api(&mut self) -> String {
16 let t = type_name::<Self>().split("::").collect::<Vec<&str>>();
17 if t.len() == 3 {
18 return "".to_string();
20 }
21 let plugin = t[2];
22 let module = t[3];
23 let action = t[4];
24 format!("{plugin}.{module}.{action}")
25 }
26
27 fn mode(&mut self) -> Vec<&'static str> {
32 vec![]
33 }
34 fn icon(&mut self) -> &'static str { "" }
36
37 fn menu_sort(&mut self) -> usize { 0 }
39
40 fn openapi(&mut self) -> bool { false }
42
43 fn token(&mut self) -> bool { true }
45 fn describe(&mut self) -> &'static str { "" }
47 fn public(&mut self) -> bool { true }
49 fn auth(&mut self) -> bool { true }
51 fn interface_type(&mut self) -> InterfaceType {
53 InterfaceType::Api
54 }
55 fn dependent(&mut self) -> Vec<&'static str> {
57 vec![]
58 }
59 fn params(&mut self) -> JsonValue { object! {} }
61 fn _check(&mut self, mut request: JsonValue) -> (bool, String, JsonValue) {
63 let params = self.params();
64
65 let mut new_request = object! {};
66 for (key, field) in params.entries() {
67 match field["require"].as_bool().unwrap() {
68 true => {
69 if request[key].is_null() && !field["def"].is_empty() {
70 request[key] = field["def"].clone();
71 }
72 if request[key].is_null() {
73 return (false, format!("缺少参数 {}: {}\r\n错误API: {}", key, field["title"], self.api()), request);
74 }
75 if request[key].is_string() && request[key].is_empty() {
76 return (false, format!("请填写【{}】内容\r\n错误API: {}", field["title"], self.api()), request);
77 }
78 }
79 false => {
80 if request[key].is_null() {
81 request[key] = field["def"].clone();
82 }
83 match field["mode"].as_str().unwrap() {
84 "switch" => {
85 if request[key].is_empty() {
86 request[key] = field["def"].clone();
87 }
88 }
89 _ => {
90 if request[key].is_empty() || request[key].is_empty() {
91 request[key] = field["def"].clone();
92 }
93 }
94 }
95 if request[key] == *"null" {
96 request[key] = field["def"].clone();
97 }
98 }
99 }
100 new_request[key] = request[key].clone();
101 }
102 (true, "验证通过".to_string(), new_request)
103 }
104 fn run(&mut self, header: JsonValue, request: JsonValue) -> Response {
106 let (state, msg, request) = self._check(request.clone());
107 if !state {
108 return self.fail(&msg);
109 }
110 self.index(header.clone(), request.clone())
111 }
112 fn get(&mut self, header: JsonValue, request: JsonValue) -> Result<JsonValue, String> {
114 let (state, msg, request) = self._check(request.clone());
115 if !state {
116 let re = self.fail(&msg);
117 return Err(re.get_data_msg());
118 }
119 let t = self.index(header.clone(), request.clone());
120 if t.clone().get_data_code() != 0 {
121 return Err(t.clone().get_data_msg());
122 }
123 Ok(t.get_data_data())
124 }
125
126 fn index(&mut self, header: JsonValue, request: JsonValue) -> Response;
127 fn success(&mut self, data: JsonValue, msg: &str) -> Response {
129 Response::success(data, msg).clone()
130 }
131 fn fail(&mut self, msg: &str) -> Response {
133 Response::fail(msg).clone()
134 }
135 fn error(&mut self, code: usize, msg: String) -> Response {
137 Response::error(code, msg).clone()
138 }
139 fn notify(&mut self, msg: &str, btn_name: &str, path: &str) -> Response {
140 Response::notify(msg, btn_name, path).clone()
141 }
142 fn login(&mut self, msg: &str) -> Response {
144 Response::login(msg).clone()
145 }
146 fn download(&mut self, filename: &str) -> Response {
148 Response::download(filename).clone()
149 }
150 fn download_delete_dir(&mut self, filename: &str) -> Response {
152 Response::download_delete_dir(filename).clone()
153 }
154 fn redirect(&mut self, url: &str) -> Response {
156 Response::redirect(url).clone()
157 }
158 fn tools(&mut self) -> Tools {
160 PLUGIN_TOOLS.lock().unwrap().get("tools").unwrap().clone()
161 }
162 fn menu_info(&mut self, title: &str) -> JsonValue {
165 let api = self.api();
166 let apis: Vec<&str> = api.split(".").collect();
167 let info = object! {
168 title:if title.is_empty() {self.title()}else{title},
169 api:self.api(),
170 addon:apis[0],
171 model:apis[1],
172 action:apis[2],
173 icon:self.icon(),
174 path:format!("/{}",self.api().replace(".","/")),
175 interface_type:self.interface_type().str()
176 };
177 info
178 }
179 fn btn_info_data(&mut self, title: &str) -> JsonValue {
180 let mut params = array![];
181 for (_field, item) in self.params().entries() {
182 params.push(item.clone()).unwrap();
183 }
184 let api = self.api();
185 let apis: Vec<&str> = api.split(".").collect();
186 let info = object! {
187 title:if title.is_empty() {self.title()}else{title},
188 api:self.api(),
189 addon:apis[0],
190 model:apis[1],
191 action:apis[2],
192 icon:self.icon(),
193 path:format!("/{}",self.api().replace(".","/")),
194 params:params,
195 interface_type:self.interface_type().str()
196 };
197 info
198 }
199 fn btn_info(&mut self, title: &str, mode: BtnMode, color: BtnColor, match_condition: Vec<Vec<&str>>) -> JsonValue {
205 let mut btn = object! {};
206 if title.is_empty() {
207 btn["title"] = self.title().into();
208 } else {
209 btn["title"] = title.into();
210 }
211 btn["api"] = self.api().into();
212 let mut params = array![];
213 for (_, item) in self.params().entries() {
214 params.push(item.clone()).unwrap();
215 }
216 btn["params"] = params;
217 btn["color"] = JsonValue::from(color.from());
218 btn["icon"] = JsonValue::from(self.icon());
219 btn["mode"] = JsonValue::from(mode.from());
220 btn["match_condition"] = match_condition.into();
221 if btn["mode"].as_str().unwrap()=="form_custom" {
222 btn["path"] = format!("/{}", self.api().replace(".", "/")).into();
223 }
224 btn
225 }
226 fn btn_info_to(&mut self, title: &str, path: &str, mode: BtnMode, color: BtnColor, match_condition: Vec<Vec<&str>>) -> JsonValue {
232 let mut btn = object! {};
233 if title.is_empty() {
234 btn["title"] = self.title().into();
235 } else {
236 btn["title"] = title.into();
237 }
238 btn["api"] = self.api().into();
239 let mut params = array![];
240 for (_, item) in self.params().entries() {
241 params.push(item.clone()).unwrap();
242 }
243 if path.is_empty() {
244 btn["path"] = format!("/{}", self.api().replace(".", "/")).into();
245 } else {
246 btn["path"] = JsonValue::from(path);
247 }
248 btn["params"] = params;
249 btn["color"] = JsonValue::from(color.from());
250 btn["mode"] = JsonValue::from(mode.from());
251 btn["match_condition"] = match_condition.into();
252 btn
253 }
254 fn btn_custom_info(&mut self, title: &str) -> JsonValue {
260 let mut btn = object! {};
261 if title.is_empty() {
262 btn["title"] = self.title().into();
263 } else {
264 btn["title"] = title.into();
265 }
266 btn["api"] = self.api().into();
267 let mut params = array![];
268 for (_, item) in self.params().entries() {
269 params.push(item.clone()).unwrap();
270 }
271 btn["params"] = params;
272 btn["auth"] = self.auth().into();
273 btn
274 }
275}
276
277
278pub struct ActionTemp {
280 pub model: ModelTemp,
281}
282
283impl Action for ActionTemp {
284 fn title(&mut self) -> &'static str {
285 "测试api"
286 }
287 fn index(&mut self, _header: JsonValue, _request: JsonValue) -> Response {
288 self.fail("无效API")
289 }
290}
291
292pub enum InterfaceType {
293 Api,
294 Btn,
295 Menu,
296}
297
298impl InterfaceType {
299 pub fn str(self) -> &'static str {
300 match self {
301 InterfaceType::Api => "api",
302 InterfaceType::Btn => "btn",
303 InterfaceType::Menu => "menu"
304 }
305 }
306}