br-plugin 1.6.8

This is an Plugin
Documentation
use std::any::type_name;
use json::{array, JsonValue, object};
use crate::{BtnColor, BtnMode, PLUGIN_TOOLS, Response, Tools};
use crate::model::{ModelTemp};

/// 动作
pub trait Action {
    /// 作者
    fn author(&mut self) -> &'static str {
        "Blue Rain"
    }
    /// 动标题
    fn title(&mut self) -> &'static str;
    /// 动作api
    fn api(&mut self) -> String {
        let t = type_name::<Self>().split("::").collect::<Vec<&str>>();
        if t.len() == 3 {
            // println!("未知的api: {} {}", type_name::<Self>(), self.title());
            return "".to_string();
        }
        let plugin = t[2];
        let module = t[3];
        let action = t[4];
        format!("{plugin}.{module}.{action}")
    }

    /// 支持模式
    /// org 企业模式
    /// admin 平台模式
    /// user 普通模式
    fn mode(&mut self) -> Vec<&'static str> {
        vec![]
    }
    /// 菜单 icon
    fn icon(&mut self) -> &'static str { "" }

    /// 菜单排序
    fn menu_sort(&mut self) -> usize { 0 }

    /// 是否开放接口
    fn openapi(&mut self) -> bool { false }

    /// 是否使用密钥
    fn token(&mut self) -> bool { true }
    /// API描述
    fn describe(&mut self) -> &'static str { "" }
    /// 是否公开
    fn public(&mut self) -> bool { true }
    /// 是否权限组显示
    fn auth(&mut self) -> bool { true }
    /// 接口类型 btn api menu
    fn interface_type(&mut self) -> InterfaceType {
        InterfaceType::Api
    }
    /// 依赖接口
    fn dependent(&mut self) -> Vec<&'static str> {
        vec![]
    }
    /// 请求参数入口
    fn params(&mut self) -> JsonValue { object! {} }
    /// 检测
    fn _check(&mut self, mut request: JsonValue) -> (bool, String, JsonValue) {
        let params = self.params();

        let mut new_request = object! {};
        for (key, field) in params.entries() {
            match field["require"].as_bool().unwrap() {
                true => {
                    if request[key].is_null() && !field["def"].is_empty() {
                        request[key] = field["def"].clone();
                    }
                    if request[key].is_null() {
                        return (false, format!("缺少参数 {}: {}\r\n错误API: {}", key, field["title"], self.api()), request);
                    }
                    if request[key].is_string() && request[key].is_empty() {
                        return (false, format!("请填写【{}】内容\r\n错误API: {}", field["title"], self.api()), request);
                    }
                }
                false => {
                    if request[key].is_null() {
                        request[key] = field["def"].clone();
                    }
                    match field["mode"].as_str().unwrap() {
                        "switch" => {
                            if request[key].is_empty() {
                                request[key] = field["def"].clone();
                            }
                        }
                        _ => {
                            if request[key].is_empty() || request[key].is_empty() {
                                request[key] = field["def"].clone();
                            }
                        }
                    }
                    if request[key] == *"null" {
                        request[key] = field["def"].clone();
                    }
                }
            }
            new_request[key] = request[key].clone();
        }
        (true, "验证通过".to_string(), new_request)
    }
    /// 执行参数入口
    fn run(&mut self, header: JsonValue, request: JsonValue) -> Response {
        let (state, msg, request) = self._check(request.clone());
        if !state {
            return self.fail(&msg);
        }
        self.index(header.clone(), request.clone())
    }
    /// 执行参数入口
    fn get(&mut self, header: JsonValue, request: JsonValue) -> Result<JsonValue, String> {
        let (state, msg, request) = self._check(request.clone());
        if !state {
            let re = self.fail(&msg);
            return Err(re.get_data_msg());
        }
        let t = self.index(header.clone(), request.clone());
        if t.clone().get_data_code() != 0 {
            return Err(t.clone().get_data_msg());
        }
        Ok(t.get_data_data())
    }

    fn index(&mut self, header: JsonValue, request: JsonValue) -> Response;
    /// 业务成功返回
    fn success(&mut self, data: JsonValue, msg: &str) -> Response {
        Response::success(data, msg).clone()
    }
    /// 业务错误返回
    fn fail(&mut self, msg: &str) -> Response {
        Response::fail(msg).clone()
    }
    /// 业务错误返回
    fn error(&mut self, code: usize, msg: String) -> Response {
        Response::error(code, msg).clone()
    }
    fn notify(&mut self, msg: &str, btn_name: &str, path: &str) -> Response {
        Response::notify(msg, btn_name, path).clone()
    }
    /// 登陆返回
    fn login(&mut self, msg: &str) -> Response {
        Response::login(msg).clone()
    }
    /// 下载返回
    fn download(&mut self, filename: &str) -> Response {
        Response::download(filename).clone()
    }
    /// 下载并删除文件所在目录
    fn download_delete_dir(&mut self, filename: &str) -> Response {
        Response::download_delete_dir(filename).clone()
    }
    /// 重定型返回
    fn redirect(&mut self, url: &str) -> Response {
        Response::redirect(url).clone()
    }
    /// 获取工具集合
    fn tools(&mut self) -> Tools {
        PLUGIN_TOOLS.lock().unwrap().get("tools").unwrap().clone()
    }
    /// 获取菜单信息
    /// * title 菜单名称
    fn menu_info(&mut self, title: &str) -> JsonValue {
        let api = self.api();
        let apis: Vec<&str> = api.split(".").collect();
        let info = object! {
            title:if title.is_empty() {self.title()}else{title},
            api:self.api(),
            addon:apis[0],
            model:apis[1],
            action:apis[2],
            icon:self.icon(),
            path:format!("/{}",self.api().replace(".","/")),
            interface_type:self.interface_type().str()
        };
        info
    }
    fn btn_info_data(&mut self, title: &str) -> JsonValue {
        let mut params = array![];
        for (_field, item) in self.params().entries() {
            params.push(item.clone()).unwrap();
        }
        let api = self.api();
        let apis: Vec<&str> = api.split(".").collect();
        let info = object! {
            title:if title.is_empty() {self.title()}else{title},
            api:self.api(),
            addon:apis[0],
            model:apis[1],
            action:apis[2],
            icon:self.icon(),
            path:format!("/{}",self.api().replace(".","/")),
            params:params,
            interface_type:self.interface_type().str()
        };
        info
    }
    /// 获取按钮信息
    /// * title 菜单名称
    /// * mode 按钮模式
    /// * color 按钮颜色
    /// * match_condition 显示条件
    fn btn_info(&mut self, title: &str, mode: BtnMode, color: BtnColor, match_condition: Vec<Vec<&str>>) -> JsonValue {
        let mut btn = object! {};
        if title.is_empty() {
            btn["title"] = self.title().into();
        } else {
            btn["title"] = title.into();
        }
        btn["api"] = self.api().into();
        let mut params = array![];
        for (_, item) in self.params().entries() {
            params.push(item.clone()).unwrap();
        }
        btn["params"] = params;
        btn["color"] = JsonValue::from(color.from());
        btn["icon"] = JsonValue::from(self.icon());
        btn["mode"] = JsonValue::from(mode.from());
        btn["match_condition"] = match_condition.into();
        if btn["mode"].as_str().unwrap()=="form_custom" {
            btn["path"] = format!("/{}", self.api().replace(".", "/")).into();
        }
        btn
    }
    /// 获取跳转按钮信息
    /// * title 菜单名称
    /// * mode 按钮模式
    /// * color 按钮颜色
    /// * match_condition 显示条件
    fn btn_info_to(&mut self, title: &str, path: &str, mode: BtnMode, color: BtnColor, match_condition: Vec<Vec<&str>>) -> JsonValue {
        let mut btn = object! {};
        if title.is_empty() {
            btn["title"] = self.title().into();
        } else {
            btn["title"] = title.into();
        }
        btn["api"] = self.api().into();
        let mut params = array![];
        for (_, item) in self.params().entries() {
            params.push(item.clone()).unwrap();
        }
        if path.is_empty() {
            btn["path"] = format!("/{}", self.api().replace(".", "/")).into();
        } else {
            btn["path"] = JsonValue::from(path);
        }
        btn["params"] = params;
        btn["color"] = JsonValue::from(color.from());
        btn["mode"] = JsonValue::from(mode.from());
        btn["match_condition"] = match_condition.into();
        btn
    }
    /// 获取自定义页面按钮信息
    /// * title 菜单名称
    /// * mode 按钮模式
    /// * color 按钮颜色
    /// * match_condition 显示条件
    fn btn_custom_info(&mut self, title: &str) -> JsonValue {
        let mut btn = object! {};
        if title.is_empty() {
            btn["title"] = self.title().into();
        } else {
            btn["title"] = title.into();
        }
        btn["api"] = self.api().into();
        let mut params = array![];
        for (_, item) in self.params().entries() {
            params.push(item.clone()).unwrap();
        }
        btn["params"] = params;
        btn["auth"] = self.auth().into();
        btn
    }
}


/// 模型模版
pub struct ActionTemp {
    pub model: ModelTemp,
}

impl Action for ActionTemp {
    fn title(&mut self) -> &'static str {
        "测试api"
    }
    fn index(&mut self, _header: JsonValue, _request: JsonValue) -> Response {
        self.fail("无效API")
    }
}

pub enum InterfaceType {
    Api,
    Btn,
    Menu,
}

impl InterfaceType {
    pub fn str(self) -> &'static str {
        match self {
            InterfaceType::Api => "api",
            InterfaceType::Btn => "btn",
            InterfaceType::Menu => "menu"
        }
    }
}