#[cfg(any(feature = "mysql", feature = "mssql", feature = "sqlite"))]
use std::{fs};
#[cfg(any(feature = "mysql", feature = "mssql", feature = "sqlite"))]
use std::collections::HashMap;
#[cfg(any(feature = "mysql", feature = "mssql", feature = "sqlite"))]
use std::fs::File;
#[cfg(any(feature = "mysql", feature = "mssql", feature = "sqlite"))]
use std::io::Write;
use std::path::PathBuf;
use br_fields::Field;
use json::{array, JsonValue, object};

#[cfg(any(feature = "mysql", feature = "mssql", feature = "sqlite"))]
use br_db::Table;
use crate::{BtnColor, BtnMode, PLUGIN_TOOLS, Tools};
use crate::action::{Action, ActionTemp};
use crate::addon::AddonTemp;
#[cfg(any(feature = "mysql", feature = "mssql", feature = "sqlite"))]
use crate::table::Tables;


/// 模型
pub trait Model {
    /// 版本号
    fn version(&mut self) -> &'static str {
        "0.0.1"
    }
    /// 模型名称
    fn name(&mut self) -> &'static str { "" }
    /// 模型标题
    fn title(&mut self) -> &'static str;
    /// 模型描述
    fn describe(&mut self) -> &'static str { "" }

    /// 数据库表名称
    fn table(&mut self) -> &'static str;
    /// 数据库唯一约束
    fn unique(&mut self) -> Vec<&'static str> {
        return vec![];
    }
    /// 查询索引
    fn index(&mut self) -> Vec<Vec<&'static str>> {
        return vec![];
    }
    /// 主键
    fn primary_key(&mut self) -> &'static str {
        return "id";
    }
    /// 数据库分区
    fn partition(&mut self) -> bool {
        return false;
    }
    /// 分区配置
    /// *列名
    /// *分区key
    /// *实例 array![str, array![range1, range2, range3...]]
    /// *如果在已有分区的情况下想要修改分区的参照列，先要将当前分区代码删除后刷库，然后写新的分区规则再刷库
    fn partition_columns(&mut self) -> JsonValue {
        return array![];
    }
    /// 字段列表
    fn fields(&mut self) -> JsonValue;
    /// 初始化数据库
    fn init_data(&mut self) {}
    /// 创建安装json
    #[cfg(any(feature = "mysql", feature = "mssql", feature = "sqlite"))]
    fn json(&mut self) -> Table {
        Table {
            version: self.version().parse().unwrap(),
            table: self.table().parse().unwrap(),
            title: self.title().parse().unwrap(),
            primary_key: self.primary_key().parse().unwrap(),
            unique: self.unique().iter().map(|x| x.to_string()).collect(),
            index: self.index().iter().map(|x| x.iter().map(|y| y.to_string()).collect()).collect(),
            fields: self.fields(),
            partition: self.partition(),
            partition_columns: self.partition_columns(),
        }
    }
    /// 创建安装文件
    #[cfg(any(feature = "mysql", feature = "mssql", feature = "sqlite"))]
    fn create_json_file(&mut self, path: &str) -> bool {
        let json = self.json();
        let o = PathBuf::from(path);
        if !o.is_dir() {
            fs::create_dir_all(o.clone()).unwrap();
        }
        let version = self.version();
        let version = version.replace(".", "_");
        let dir = o.join(format!("{}_{}.json", self.table(), version));
        let mut f = File::create(dir.to_str().unwrap()).unwrap();
        match f.write_all(json.to_string().as_bytes()) {
            Ok(_) => true,
            Err(_) => false
        }
    }
    /// 模型动作
    fn action(&mut self, name: &str) -> Box<dyn Action>;
    /// 前端搜索字段
    fn table_fields(&mut self) -> JsonValue {
        let mut params = object! {};
        params["load"] = br_fields::select::Radio::new(false, "load", "加载内容", vec!["col", "data"], "data").field();
        params["page"] = br_fields::int::Int::new(false, "page", "页数", 15, 1).field();
        params["limit"] = br_fields::int::Int::new(false, "limit", "记录数", 10, 25).field();
        params["where"] = br_fields::text::Json::new(false, "where", "条件", array![]).field();
        params["filter"] = br_fields::text::Text::new(false, "filter", "模糊搜索", "").field();
        params["order"] = br_fields::text::Json::new(false, "order", "排序", array!["id",true]).field();
        return params;
    }
    /// 获取工具集合
    fn tools(&mut self) -> Tools {
        let db = PLUGIN_TOOLS.lock().unwrap();
        let db = db.get("tools").unwrap().clone();
        db
    }
    /// 前端-数据表
    #[cfg(any(feature = "mysql", feature = "mssql", feature = "sqlite"))]
    fn tables(&mut self, _header: JsonValue, request: JsonValue, fields: Vec<&str>, query_fields: Vec<&str>, filter_fields: Vec<&str>) -> JsonValue {
        let load = request["load"].as_str().unwrap();
        let page = request["page"].as_i32().unwrap();
        let limit = request["limit"].as_i32().unwrap();
        let wheres = request["where"].clone();
        let filter = request["filter"].to_string();
        let order = request["order"].clone();
        let columns = self.columns(fields.clone());
        let mut fields_json = vec![];
        for field in columns.members() {
            match field["mode"].as_str().unwrap() {
                "select" | "array" | "json" | "object" => {
                    fields_json.push(field["name"].clone().to_string());
                }
                _ => {}
            }
        }
        // 查询到的数据
        let mut data = {
            let mut db = self.tools().db;
            let db = db.table(self.table());
            // 整合搜索字段
            if filter_fields.len() > 0 && filter != "" {
                db.where_and(filter_fields.join("|").as_str(), "like", format!("%{}%", filter).into());
            }
            if fields.len() > 0 {
                db.field(fields.join(",").as_str());
            }
            for item in wheres.members() {
                db.where_and(item[0].as_str().unwrap_or(""), item[1].as_str().unwrap_or(""), item[2].clone());
            }
            if order.len() > 0 {
                db.order(order[0].as_str().unwrap(), order[1].as_bool().unwrap());
            }
            if fields_json.len() > 0 {
                for json in fields_json.iter() {
                    db.json(&*json);
                }
            }
            db.page(page.clone(), limit.clone()).select()
        };
        // 总记录数
        let total = {
            let mut db = self.tools().db;
            let db = db.table(self.table());
            if filter_fields.len() > 0 && filter != "" {
                db.where_and(filter_fields.join("|").as_str(), "like", format!("%{}%", filter).into());
            }
            for item in wheres.members() {
                db.where_and(item[0].as_str().unwrap_or(""), item[1].as_str().unwrap_or(""), item[2].clone());
            }
            db.count().as_i32().unwrap_or(0)
        };


        let mut fields_table = false;
        let mut fields_list = object! {};
        for field in columns.members() {
            fields_list[field["field"].as_str().unwrap()] = field.clone();
            match field["mode"].as_str().unwrap() {
                "table" => {
                    fields_table = true;
                }
                _ => {}
            }
        }
        if fields_table {
            let mut fields_table_ids = object! {};
            for item in data.members_mut() {
                for (key, field) in fields_list.entries() {
                    match field["mode"].as_str().unwrap() {
                        "table" => {
                            let id = item[key].clone();
                            if id.is_empty() {
                                continue;
                            }
                            if id.to_string().contains(",") {
                                item[key] = array![];
                                let ids = id.to_string();
                                let ids = ids.split(",").collect::<Vec<&str>>();
                                for id in ids.iter() {
                                    if fields_table_ids[id.to_string().as_str()].is_null() {
                                        let table = field["table"].as_str().unwrap();
                                        let fields_list: Vec<&str> = field["fields"].members().map(|x| x.as_str().unwrap()).collect();
                                        let find = self.tools().db.table(table)
                                            .where_and("id", "=", id.to_string().into())
                                            .field(format!("id,{}", fields_list.join(",")).as_str())
                                            .find();
                                        let mut row = object! {};
                                        if !find.is_empty() {
                                            row["id"] = find["id"].clone();
                                            for field in fields_list.iter() {
                                                if row["value"].is_null() {
                                                    row["value"] = format!("{}", find[field.to_string().as_str()]).into();
                                                } else {
                                                    row["value"] = format!("{} | {}", row["value"], find[field.to_string().as_str()]).into();
                                                }
                                            }
                                            fields_table_ids[id.to_string()] = row.clone();
                                        } else {
                                            fields_table_ids[id.to_string()] = object! {};
                                        }
                                    }
                                    if !fields_table_ids[id.to_string()].clone().is_empty() {
                                        item[key].push(fields_table_ids[id.to_string()].clone()).unwrap();
                                    }
                                }
                            } else {
                                item[key] = object! {};
                                if fields_table_ids[id.as_str().unwrap()].is_null() {
                                    let table = field["table"].as_str().unwrap();
                                    let fields_list: Vec<&str> = field["fields"].members().map(|x| x.as_str().unwrap()).collect();
                                    let find = self.tools().db.table(table)
                                        .where_and("id", "=", id.clone())
                                        .field(format!("id,{}", fields_list.join(",")).as_str())
                                        .find();


                                    let mut row = object! {};
                                    if !find.is_empty() {
                                        row["id"] = find["id"].clone();
                                        for field in fields_list.iter() {
                                            if row["value"].is_null() {
                                                row["value"] = format!("{}", find[field.to_string()]).into();
                                            } else {
                                                row["value"] = format!("{} | {}", row["value"], find[field.to_string()]).into();
                                            }
                                        }
                                        fields_table_ids[id.as_str().unwrap()] = row;
                                    } else {
                                        fields_table_ids[id.as_str().unwrap()] = object! {};
                                    }
                                }
                                if !fields_table_ids[id.as_str().unwrap()].clone().is_empty() {
                                    // item[key].push(fields_table_ids[id.as_str().unwrap()].clone()).unwrap();
                                    item[key] = fields_table_ids[id.as_str().unwrap()].clone();
                                }
                            }
                        }
                        _ => {}
                    }
                }
            }
        }

        let mut table = object! {};
        table["total_page"] = JsonValue::from((total as f64 / limit as f64).ceil() as i64);
        table["total_data"] = total.into();
        table["data"] = data.clone();
        match load {
            "col" => {
                table["col"] = columns.clone();
                table["query_fields"] = self.query_fields(query_fields.clone());
                table["filter_title"] = self.filter_title(filter_fields.clone()).into();
            }
            _ => {}
        }
        table
    }
    /// 前端-链表-数据表
    #[cfg(any(feature = "mysql", feature = "mssql", feature = "sqlite"))]
    fn table_join(&mut self, table: &str, header: JsonValue, request: JsonValue) -> Tables {
        let mut db = self.tools().db.clone();
        db.table(table);
        Tables {
            table: table.to_string(),
            header,
            request,
            db: db.clone(),
            search_fields: HashMap::new(),
            hidden_fields: HashMap::new(),
            query_fields: HashMap::new(),
            tables: Vec::new(),
            fields: HashMap::new(),
            columns: array![],
            main_field: HashMap::new(),
            right_field: HashMap::new(),
        }
    }
    /// 前端-树型-搜索字段
    fn table_tree_fields(&mut self) -> JsonValue {
        let mut params = object! {};
        params["where"] = br_fields::text::Json::new(false, "where", "条件", array![]).field();
        return params;
    }
    /// 前端-树型-数据表
    #[cfg(any(feature = "mysql", feature = "mssql", feature = "sqlite"))]
    fn table_tree(&mut self, _header: JsonValue, request: JsonValue, sort: (&str, bool), label: &str, filter_fields: Vec<&str>, search_fields: Vec<&str>) -> JsonValue {
        let t = self.fields_name_list(filter_fields);
        let fields = t.iter().map(|x| x.as_str()).collect::<Vec<&str>>();
        let wheres = request["where"].clone();
        let table = self.table();

        let mut db = self.tools().db;
        let db = db.table(table);

        // 处理字段
        if fields.len() > 0 {
            db.field(fields.join(",").as_str());
        }

        for item in wheres.members() {
            db.where_and(item[0].as_str().unwrap_or(""), item[1].as_str().unwrap_or(""), item[2].clone());
        }

        db.order(sort.0, sort.1);

        let data = db.select();
        let children = self.table_tree_assemble(data, "", table, label);
        let mut table = object! {};
        table["data"] = children.clone();
        table["search_fields"] = self.filter_title(search_fields.clone()).into();
        table
    }
    #[cfg(any(feature = "mysql", feature = "mssql", feature = "sqlite"))]
    fn table_tree_assemble(&mut self, data: JsonValue, pid: &str, field: &str, label: &str) -> JsonValue {
        let mut list = array![];
        let mut children = array![];

        for item in data.members() {
            let pid_pid = item[field].to_string();
            if pid_pid == pid {
                let res = object! {
                    id:item["id"].clone(),
                    label:item[label].clone(),
                    data:item.clone()
                };
                list.push(res.clone()).unwrap();
            } else {
                children.push(item.clone()).unwrap();
            }
        }
        for item in list.members_mut() {
            let pid_new = item["id"].clone();
            let children_list = self.table_tree_assemble(children.clone(), pid_new.to_string().as_str(), field, label);
            if children_list.len() > 0 {
                item["children"] = children_list.clone();
            }
        }
        list
    }
    /// 获取 tree 上级级指定列
    #[cfg(any(feature = "mysql", feature = "mssql", feature = "sqlite"))]
    fn get_tree_parent_ids(&mut self, pid_field: &str, column_field: &str, value: &str) -> JsonValue {
        let mut list = array![value];
        let ids = self.tools().db.table(self.table()).where_and(column_field, "=", value.into()).column(pid_field);
        for item in ids.members() {
            let res = self.get_tree_parent_ids(pid_field, column_field, item.as_str().unwrap());
            for member in res.members() {
                list.push(member.clone()).unwrap();
            }
        }
        return list;
    }
    /// 获取 tree 下级指定列
    #[cfg(any(feature = "mysql", feature = "mssql", feature = "sqlite"))]
    fn get_subordinate_ids(&mut self, pid_field: &str, column_field: &str, value: &str) -> JsonValue {
        let mut list = array![value];
        let ids = self.tools().db.table(self.table()).where_and(pid_field, "=", value.into()).column(column_field);
        for item in ids.members() {
            let res = self.get_subordinate_ids(pid_field, column_field, item.as_str().unwrap());
            for member in res.members() {
                list.push(member.clone()).unwrap();
            }
        }
        return list;
    }
    /// 前端-字典-数据表
    #[cfg(any(feature = "mysql", feature = "mssql", feature = "sqlite"))]
    fn dicts(&mut self, _header: JsonValue, request: JsonValue, fields: Vec<&str>, query_fields: Vec<&str>, filter_fields: Vec<&str>) -> JsonValue {
        let load = request["load"].as_str().unwrap();
        let page = request["page"].as_i32().unwrap();
        let limit = request["limit"].as_i32().unwrap();
        let wheres = request["where"].clone();
        let filter = request["filter"].to_string();
        let order = request["order"].clone();
        let columns = self.columns(fields.clone());
        let mut fields_json = vec![];
        for field in columns.members() {
            match field["mode"].as_str().unwrap() {
                "select" | "array" | "json" | "object" => {
                    fields_json.push(field["name"].as_str().unwrap());
                }
                _ => {}
            }
        }
        // 查询到的数据
        let mut data = {
            let mut db = self.tools().db;
            let db = db.table(self.table());
            // 整合搜索字段
            if filter_fields.len() > 0 && filter != "" {
                db.where_and(filter_fields.join("|").as_str(), "like", format!("%{}%", filter).into());
            }
            if fields.len() > 0 {
                db.field(fields.join(",").as_str());
            }
            for item in wheres.members() {
                db.where_and(item[0].as_str().unwrap_or(""), item[1].as_str().unwrap_or(""), item[2].clone());
            }
            if order.len() > 0 {
                db.order(order[0].as_str().unwrap(), order[1].as_bool().unwrap());
            }
            if fields_json.len() > 0 {
                for json in fields_json.iter() {
                    db.json(&*json);
                }
            }
            db.page(page.clone(), limit.clone()).select()
        };

        // 总记录数
        let total = {
            let mut db = self.tools().db;
            let db = db.table(self.table());
            if filter_fields.len() > 0 && filter != "" {
                db.where_and(filter_fields.join("|").as_str(), "like", format!("%{}%", filter).into());
            }
            for item in wheres.members() {
                db.where_and(item[0].as_str().unwrap_or(""), item[1].as_str().unwrap_or(""), item[2].clone());
            }
            db.count().as_i32().unwrap_or(0)
        };


        let mut fields_table = false;
        let mut fields_list = object! {};
        for field in columns.members() {
            fields_list[field["field"].as_str().unwrap()] = field.clone();
            match field["mode"].as_str().unwrap() {
                "table" => {
                    fields_table = true;
                }
                _ => {}
            }
        }
        if fields_table {
            let mut fields_table_ids = object! {};
            for item in data.members_mut() {
                for (key, field) in fields_list.entries() {
                    match field["mode"].as_str().unwrap() {
                        "table" => {
                            let id = item[key].clone();
                            if id.is_empty() {
                                continue;
                            }
                            if fields_table_ids[id.as_str().unwrap()].is_null() {
                                let table = field["table"].as_str().unwrap();
                                let fields_list: Vec<&str> = field["fields"].members().map(|x| x.as_str().unwrap()).collect();
                                let find = self.tools().db.table(table)
                                    .where_and("id", "=", id.clone())
                                    .field(format!("id,{}", fields_list.join(",")).as_str())
                                    .find();
                                let mut row = object! {};
                                if !find.is_empty() {
                                    row["id"] = find["id"].clone();
                                    for field in fields_list.iter() {
                                        if row["value"].is_null() {
                                            row["value"] = format!("{}", find[field.to_string()]).into();
                                        } else {
                                            row["value"] = format!("{} | {}", row["value"], find[field.to_string()]).into();
                                        }
                                    }
                                    fields_table_ids[id.as_str().unwrap()] = row;
                                } else {
                                    fields_table_ids[id.as_str().unwrap()] = object! {};
                                }
                            }
                            item[key] = fields_table_ids[id.as_str().unwrap()].clone();
                        }
                        _ => {}
                    }
                }
            }
        }

        let mut table = object! {};
        table["total_page"] = JsonValue::from((total as f64 / limit as f64).ceil() as i64);
        table["total_data"] = total.into();
        table["data"] = data.clone();
        match load {
            "col" => {
                table["col"] = columns.clone();
                table["query_fields"] = self.query_fields(query_fields.clone());
                table["filter_title"] = self.filter_title(filter_fields.clone()).into();
            }
            _ => {}
        }
        table
    }

    /// 前端-列数据
    fn columns(&mut self, fields: Vec<&str>) -> JsonValue {
        let columns = self.fields();
        let mut data = array![];
        for (key, field) in columns.entries() {
            if fields.contains(&key) || fields.len() == 0 {
                let mut row = field.clone();
                row["name"] = field["field"].clone();
                row["label"] = field["title"].clone();
                row["align"] = "center".into();
                row["sortable"] = match field["mode"].as_str().unwrap() {
                    "int" | "float" | "switch" | "datetime" | "date" | "time" | "year" | "timestamp" => {
                        true.into()
                    }
                    _ => {
                        false.into()
                    }
                };
                data.push(row.clone()).unwrap();
            }
        }
        data
    }
    /// 前端-高级查询条件字段
    fn query_fields(&mut self, fields: Vec<&str>) -> JsonValue {
        let columns = self.fields();
        let mut data = array![];
        for (key, field) in columns.entries() {
            if fields.contains(&key) {
                let mut row = field.clone();
                row["require"] = JsonValue::from(false);
                data.push(row.clone()).unwrap();
            }
        }
        data
    }
    /// 前端-模糊查询标题
    fn filter_title(&mut self, fields: Vec<&str>) -> String {
        let columns = self.fields();
        let mut data = vec![];
        for (key, field) in columns.entries() {
            if fields.contains(&key) {
                data.push(field["title"].as_str().unwrap());
            }
        }
        format!("搜索 {}", data.join(" "))
    }

    /// 前端-按钮数据
    fn btn_data(&mut self, title: &str, mut action: Box<dyn Action>, mode: BtnMode, color: BtnColor, match_condition: Vec<Vec<&str>>) -> JsonValue {
        let mut btn = object! {};
        if title.is_empty() {
            btn["title"] = action.title().into();
        } else {
            btn["title"] = title.into();
        }
        btn["api"] = action.api().into();
        let mut params = array![];
        for (_, item) in action.params().entries() {
            params.push(item.clone()).unwrap();
        }
        btn["params"] = JsonValue::from(params);
        btn["color"] = JsonValue::from(color.from());
        btn["mode"] = JsonValue::from(mode.from());
        btn["match_condition"] = match_condition.into();
        btn["auth"] = action.auth().into();
        return btn;
    }

    /// 前端 关联搜索字段
    fn table_select_fields(&mut self) -> JsonValue {
        let mut fields = object! {};
        fields[self.primary_key()] = br_fields::str::Key::new(false, self.primary_key(), "ID", 20).field();
        fields["filter"] = br_fields::text::Text::new(false, "filter", "模糊搜索", "").field();
        fields["page"] = br_fields::int::Int::new(false, "page", "页数", 15, 1).field();
        fields["limit"] = br_fields::int::Int::new(false, "limit", "记录数", 10, 25).field();
        return fields;
    }
    /// 前端-select
    #[cfg(any(feature = "mysql", feature = "mssql", feature = "sqlite"))]
    fn table_select(&mut self, request: JsonValue, fields: Vec<&str>, filter: Vec<Vec<&str>>) -> JsonValue {
        let id = request["id"].as_str().unwrap_or("");
        let wheres = request["filter"].as_str().unwrap();
        let page = request["page"].as_i32().unwrap();
        let limit = request["limit"].as_i32().unwrap();

        let mut db = self.tools().db;
        let db = db.table(self.table());
        db.field(format!("id,{}", fields.join(",")).as_str());

        for item in filter.iter() {
            db.where_and(item[0], item[1], item[2].into());
        }
        if wheres != "" {
            if id != "" {
                db.where_or("id", "=", id.into());
            }
            db.where_or(fields.join("|").as_str(), "like", format!("%{}%", wheres).into());
        } else {
            if id != "" {
                db.where_or("id", "=", id.into()).where_or("id", "!=", id.into());
            }
        }

        let data = db.page(page.clone(), limit.clone()).select();
        let mut list = array![];
        for item in data.members() {
            let mut row = object! {};
            row["id"] = item["id"].clone();
            for field in fields.iter() {
                if row["value"].is_null() {
                    row["value"] = format!("{}", item[field.to_string()]).into();
                } else {
                    row["value"] = format!("{} | {}", row["value"], item[field.to_string()]).into();
                }
            }
            list.push(row).unwrap();
        }
        list
    }

    /// 前端-select-where-or
    #[cfg(any(feature = "mysql", feature = "mssql", feature = "sqlite"))]
    fn table_select_or(&mut self, request: JsonValue, fields: Vec<&str>, filter: Vec<Vec<&str>>, where_or: Vec<Vec<&str>>, table: &str) -> JsonValue {
        let id = request["id"].as_str().unwrap_or("");
        let wheres = request["filter"].as_str().unwrap();
        let page = request["page"].as_i32().unwrap();
        let limit = request["limit"].as_i32().unwrap();

        let mut db = self.tools().db;
        let db = if table.is_empty() { db.table(self.table()) } else { db.table(table) };
        db.field(format!("id,{}", fields.join(",")).as_str());

        for item in filter.iter() {
            db.where_and(item[0], item[1], item[2].into());
        }

        for item in where_or.iter() {
            db.where_or(item[0], item[1], item[2].into());
            if wheres != "" {
                db.where_and(fields.join("|").as_str(), "like", format!("%{}%", wheres).into());
            }
        }

        if wheres != "" {
            if id != "" {
                db.where_or("id", "=", id.into());
            }
            db.where_or(fields.join("|").as_str(), "like", format!("%{}%", wheres).into());
        } else {
            if id != "" {
                db.where_or("id", "=", id.into()).where_or("id", "!=", id.into());
            }
        }

        let data = db.page(page.clone(), limit.clone()).select();
        let mut list = array![];
        for item in data.members() {
            let mut row = object! {};
            row["id"] = item["id"].clone();
            for field in fields.iter() {
                if row["value"].is_null() {
                    row["value"] = format!("{}", item[field.to_string()]).into();
                } else {
                    row["value"] = format!("{} | {}", row["value"], item[field.to_string()]).into();
                }
            }
            list.push(row).unwrap();
        }
        list
    }

    /// 前端-select-分页
    #[cfg(any(feature = "mysql", feature = "mssql", feature = "sqlite"))]
    fn table_select_page(&mut self, request: JsonValue, fields: Vec<&str>, filter: Vec<Vec<&str>>, where_or: Vec<Vec<&str>>) -> JsonValue {
        let id = request["id"].as_str().unwrap_or("");
        let wheres = request["filter"].as_str().unwrap();
        let page = request["page"].as_i32().unwrap();
        let limit = request["limit"].as_i32().unwrap();

        let mut db = self.tools().db;
        let db = db.table(self.table());
        db.field(format!("id,{}", fields.join(",")).as_str());

        for item in filter.iter() {
            db.where_and(item[0], item[1], item[2].into());
        }
        for item in where_or.iter() {
            db.where_or(item[0], item[1], item[2].into());
            if wheres != "" {
                db.where_and(fields.join("|").as_str(), "like", format!("%{}%", wheres).into());
            }
        }

        if wheres != "" {
            if id != "" {
                db.where_or("id", "=", id.into());
            }
            db.where_or(fields.join("|").as_str(), "like", format!("%{}%", wheres).into());
        } else {
            if id != "" {
                db.where_or("id", "=", id.into()).where_or("id", "!=", id.into());
            }
        }
        let total_count = db.clone().count();
        let total_page = (total_count.to_string().parse::<f64>().unwrap() / limit.clone().to_string().parse::<f64>().unwrap()).ceil();
        let data = db.page(page.clone(), limit.clone()).select();
        let mut list = array![];
        for item in data.members() {
            let mut row = object! {};
            row["id"] = item["id"].clone();
            for field in fields.iter() {
                if row["value"].is_null() {
                    row["value"] = format!("{}", item[field.to_string()]).into();
                } else {
                    row["value"] = format!("{} | {}", row["value"], item[field.to_string()]).into();
                }
            }
            list.push(row).unwrap();
        }

        object! {
            data: list.clone(),
            total_page: total_page.clone()
        }
    }

    /// 前端 关联字典搜索字段
    fn dict_select_fields(&mut self) -> JsonValue {
        let mut fields = object! {};
        fields["value"] = br_fields::str::Str::new(false, "value", "当前值", 100, "").field();
        fields["filter"] = br_fields::text::Text::new(false, "filter", "模糊搜索", "").field();
        fields["page"] = br_fields::int::Int::new(false, "page", "页数", 15, 1).field();
        fields["limit"] = br_fields::int::Int::new(false, "limit", "记录数", 10, 25).field();
        fields["field"] = br_fields::str::Str::new(true, "field", "值字段", 100, "").field();
        return fields;
    }
    /// 前端-dict-select
    #[cfg(any(feature = "mysql", feature = "mssql", feature = "sqlite"))]
    fn dict_select(&mut self, request: JsonValue, fields: Vec<&str>, filter: Vec<Vec<&str>>) -> JsonValue {
        let value = request["value"].as_str().unwrap_or("");
        let wheres = request["filter"].as_str().unwrap();
        let page = request["page"].as_i32().unwrap();
        let limit = request["limit"].as_i32().unwrap();
        let field = request["field"].as_str().unwrap();

        let mut db = self.tools().db;
        let db = db.table(self.table());
        db.field(format!("{},{}", field, fields.join(",")).as_str());

        for item in filter.iter() {
            db.where_and(item[0], item[1], item[2].into());
        }
        if wheres != "" {
            if value != "" {
                db.where_or(field, "=", value.into());
            }
            db.where_or(fields.join("|").as_str(), "like", format!("%{}%", wheres).into());
        } else {
            if value != "" {
                db.where_or(field, "=", value.into()).where_or(field, "!=", field.into());
            }
        }
        let data = db.page(page.clone(), limit.clone()).select();
        let mut list = array![];
        for item in data.members() {
            let mut row = object! {};
            row["value"] = item[field].clone();
            for field in fields.iter() {
                if row["data"].is_null() {
                    row["data"] = format!("{}", item[field.to_string()]).into();
                } else {
                    row["data"] = format!("{} | {}", row["data"], item[field.to_string()]).into();
                }
            }
            list.push(row).unwrap();
        }
        list
    }

    /// 模型字段名称列表
    fn fields_name_list(&mut self, filter: Vec<&str>) -> Vec<String> {
        let mut fields = vec![];
        for (key, _) in self.fields().entries() {
            if filter.contains(&&*key) {
                continue;
            }
            fields.push(key.to_string());
        }
        fields
    }

    /// 获取模块菜单列表
    #[cfg(any(feature = "mysql", feature = "mssql", feature = "sqlite"))]
    fn get_menu_list(&mut self, mode: &str, addon: &str) -> JsonValue {
        let mut data = self.tools().db;
        data.table("auth_auth")
            .where_and("mode", "like", format!("%{}%", mode).into())
            .where_and("addon", "=", addon.into())
            .where_and("interface_type", "=", "menu".into())
            .order("menu_sort", true).select()
    }
    /// 获取按钮列表
    #[cfg(any(feature = "mysql", feature = "mssql", feature = "sqlite"))]
    fn btn_list(&mut self, mode: &str, addon: &str, model: &str) -> JsonValue {
        self.tools().db.table("auth_auth")
            .where_and("mode", "like", format!("%{}%", mode).into())
            .where_and("addon", "=", addon.into())
            .where_and("model", "=", model.into())
            .where_and("auth", "=", 1.into())
            .select()
    }
}


/// 模型模版
pub struct ModelTemp {
    pub addon: AddonTemp,
}

impl Model for ModelTemp {
    fn name(&mut self) -> &'static str { todo!() }
    fn table(&mut self) -> &'static str {
        todo!()
    }

    fn title(&mut self) -> &'static str {
        todo!()
    }

    fn fields(&mut self) -> JsonValue {
        todo!()
    }

    fn action(&mut self, name: &str) -> Box<dyn Action> {
        match name {
            _ => Box::new(ActionTemp { model: ModelTemp { addon: AddonTemp {} } }),
        }
    }
}