#include "sysrole.h"
#include <QResizeEvent>
#include <QToolBar>
#include <QVBoxLayout>
#include <QElapsedTimer>
#include <tbaseutil/tdataresponse.h>
#include <tbaseutil/tdataparse.h>
#include <tbaseutil/tenumlist.h>
#include <tbaseutil/ttheme.h>
#include <tdatabaseutil/tsqlconnectionpoolv2.h>
#include <tdatabaseutil/tsqlselectorv2.h>
#include <tdatabaseutil/tsqlqueryv2.h>
#include <topcore/topcore.h>
#include <topcore/topclasssqlthread.h>
#include <topcore/topenummanager.h>
#include <toputil/t.h>
#include <twidget/tmessagebar.h>
#include <twidget/tmessagebox.h>
#include <twidget/ttableview.h>
#include <twidget/ttableviewdialog.h>
#include <twidget/ttreeview.h>
#include <twidget/ttreemodel.h>
#include <twidget/ttoolbar.h>
#include <twidget/tuiloader.h>
#include "sysrolethread.h"

SysRole::SysRole(const QString &iModuleNameStr, const QVariantMap iUrlPars, QWidget *iParent)
    : TopClassAbs(iParent)
{
    this->setLicenseKey("");
    this->initModule(iModuleNameStr, iUrlPars);
    connect(APP, SIGNAL(notification(QString,QVariant,QString)), this, SLOT(onNotification(QString,QVariant,QString)));
    //初始化productCategory配置
    QVariant prodCfg = iUrlPars.value("product_category");
    if (prodCfg.type() == QVariant::List || prodCfg.type() == QVariant::StringList) {
        for (QVariant row : prodCfg.toList()) {
            mProductCategoryLst.append(row.toString());
        }
    } else if (!prodCfg.toString().isEmpty()) {
        mProductCategoryLst.append(prodCfg.toString());
    }

    if (mProductCategoryLst.isEmpty()) {
        mProductCategoryLst.append(APP->productCategory());
    }

    QWidget *centerWgt = new QWidget(this);
    this->setCentralWidget(centerWgt);
    QVBoxLayout *centerLayout = new QVBoxLayout(centerWgt);
    centerLayout->setMargin(0);
    centerLayout->setSpacing(0);

    if (QToolBar *toolbar = qobject_cast<QToolBar *>(uim()->getWidget("MAIN_TOOLBAR"))) {
        centerLayout->addWidget(toolbar, 0);
    }

    mBodyLayout = new QHBoxLayout();
    centerLayout->addLayout(mBodyLayout, 1);
    mBodyLayout->setMargin(TTHEME_DP(16));
    mBodyLayout->setSpacing(0);

    mUiLoader = new TUiLoader(this);
    connect(mUiLoader, SIGNAL(dataChanged()), this, SLOT(setDataModified()));
    mUiLoader->setScriptEngine(APP->scriptEngine());
    mUiLoader->setSelf(this);
    mUiLoader->setMaximumWidth(800);
    mUiLoader->setProperty("SS_BG", "PANEL");
    mUiLoader->setProperty("SS_BORDER", 1);

    mBodyLayout->addStretch(1);
    mBodyLayout->addWidget(mUiLoader, 99999);
    mBodyLayout->addStretch(1);

    mUiLoader->setUiStr(ui("role-info").toString());

    mRgtSearchEntry = qobject_cast<TSearchEntry *>(mUiLoader->getObject("rgt_searchentry"));
    if (mRgtSearchEntry != nullptr) {
        mRgtSearchEntry->setPlaceholderText(ttr("Search %1"));
        connect(mRgtSearchEntry, SIGNAL(search(QString,QVariant)),
                this, SLOT(searchRightList(QString,QVariant)));
    }
    mRgtTreeView = qobject_cast<TTreeView *>(mUiLoader->getObject("RGT_LIST"));
    mUserTableView = qobject_cast<TTableView *>(mUiLoader->getObject("USER_LIST"));

    if (mUserTableView != nullptr) {
        mUserTableView->setStyleSheet("QTableView{border-width:0px;}");
        mUserTableView->verticalHeader()->setVisible(false);
        mUserTableView->setSelectionMode(TTableView::ExtendedSelection);
        mUserTableView->setContextMenu(new QMenu());
        mUserTableView->horizontalHeader()->setStretchLastSection(true);
    }
    connect(mUserTableView->selectionModel(), &QItemSelectionModel::selectionChanged, this, [=](){
        mUiLoader->refreshState();
    });
    if (mRgtTreeView != nullptr) {
        initRgtTreeView();
    }

    //恢复窗体尺寸及布局;
    restoreSizeState();
    //当URL传入包含UID时, 在initModule()中会自动赋值给UID;
    //在界面初始化完成后执行uidChangeEvent, 填充界面数据;
    uidChangeEvent(this->uid());
    //刷新Action状态;
    refreshActionState();
}

SysRole::~SysRole()
{
    saveSizeState();
}

void SysRole::reload()
{
    QString uidStr = lastUid().isEmpty() ? uid() : lastUid();
    setUid(uidStr, true);
}

void SysRole::copy()
{
    setLastUid(this->uid());
    setUid(0, false);
    QVariantMap data;
    data.insert("name", "");
    data.insert("id", "");
    setRoleData(data);
    setTitle(ttr("New Role"));
    setDataModified(true);
}

void SysRole::createRole()
{
    mUiLoader->clearValues();
    setLastUid(this->uid());
    setUid(0, true);
    //新建时可通过配置设置默认值
    QVariantMap defaultValueMap;
    defaultValueMap.insert("product_category", mProductCategoryLst);
    defaultValueMap = defaultValueMap.unite(config("default_value").toMap());
    if (!defaultValueMap.contains("RGT_LIST")) {
        defaultValueMap.insert("RGT_LIST", "");
    }
    if (!mRgtLoaded) {
        loadRgtNames();
        mRgtLoaded = true;
    }
    setRoleData(defaultValueMap);
    setDataModified(true);
}

void SysRole::clearData()
{
    mUiLoader->loadValues(QVariantMap(), true);
    if (mUserTableView != nullptr) {
        mUserTableView->loadData(QVariantList());
    }
    if (mRgtTreeView != nullptr) {
        mRgtTreeView->clearSelection();
    }
}

void SysRole::setRoleData(const QVariantMap &iDataMap)
{
    mUiLoader->loadValues(iDataMap, false);
    if (mRgtTreeView != nullptr && iDataMap.contains("RGT_LIST")) {
        QVariantList rgtIdLst = iDataMap.value("RGT_LIST").toList();
        QVariantList allDataLst = mRgtTreeView->allDataMap();
        for (QVariant &data : allDataLst) {
            QVariantMap dataMap = data.toMap();
            setPermissionData(dataMap, rgtIdLst);
            data = dataMap;
        }
        QVariantMap stateMap;
        getExpandedState(stateMap, allDataLst);
        mRgtTreeView->loadTreeData(allDataLst);
        if (mFirstLoaded) {
            mRgtTreeView->collapseAll();
            mFirstLoaded = false;
        }
        mRgtTreeView->restoreRowsExpanded(stateMap);
    }
    if (iDataMap.contains("name")) {
        setTitle(ttr("Role-%1").arg(iDataMap.value("name").toString()));
    }
}

void SysRole::setPermissionData(QVariantMap &iDataMap, const QVariantList &iRgtIdLst)
{
    QStringList permissionLst = iDataMap.value("permission_name").toStringList();
    int check = 0;
    QVariantList children = iDataMap.value("CHILDREN").toList();
    if (!children.isEmpty()) {
        // 有子节点,先判断所有子节点的权限,然后在判断该节点权限
        int unCheckCount = 0;
        int checkCount = 0;
        for (QVariant &child : children) {
            QVariantMap childMap = child.toMap();
            setPermissionData(childMap, iRgtIdLst);
            child = childMap;
            int childCheck = childMap.value("check").toInt();
            if (childCheck == 0) {
                unCheckCount++;
            } else if (childCheck == 1) {
                checkCount++;
            }
        }
        if (unCheckCount == children.length()) {
            check = 0; // 未勾选
        } else if (checkCount == children.length()) {
            check = 1; // 已勾选
        } else {
            check = -1; // 部分勾选
        }
        iDataMap.insert("CHILDREN", children);
    } else {
        // 无子节点,直接判断该节点权限
        for (const QString &pName: permissionLst) {
            //有权限被包含, 有权限没被包含
            if (check == 1 && !iRgtIdLst.contains(QVariant::fromValue(pName))) {
                check = -1;
            }
            //有权限被包含
            if (check == 0 && iRgtIdLst.contains(QVariant::fromValue(pName))) {
                check = 1;
            }
        }
    }
    iDataMap.insert("check", check);
}

static void fetchPermissionName(const QVariantList &permissionDataLst, QVariantList &permissionNameLst)
{
    for (const auto & i : permissionDataLst) {
        QVariantMap iMap = i.toMap();
        if (iMap.contains("CHILDREN")) {
            fetchPermissionName(iMap.value("CHILDREN").toList(), permissionNameLst);
        } else {
            int check = iMap.value("check").toInt();
            QStringList permissionLst = iMap.value("permission_name").toStringList();
            if (check != 0) {
                for (QString pName: permissionLst) {
                    permissionNameLst << QVariant::fromValue(pName);
                }
            }
        }
    }
}

QVariantMap SysRole::getRoleData() const
{
    QVariantMap dataMap = mUiLoader->getAllValues(true).toVariant().toMap();
    dataMap.insert("label", dataMap.value("name"));
    QVariantList permissionNameLst;
    QVariantList roleUserIdLst;
    auto rgtData = mRgtTreeView->allDataMap();
    fetchPermissionName(rgtData, permissionNameLst);
    for (QVariant item : mUserTableView->getData("value").toList()) {
        int userId = item.toMap().value("id").toInt();
        roleUserIdLst.push_back(userId);
    }
    dataMap["RGT_LIST"] = permissionNameLst;
    dataMap["USER_LIST"] = roleUserIdLst;
    dataMap.insert("id", this->uid());
    if (dataMap.value("product_category").toStringList().isEmpty()) {
        dataMap.insert("product_category", mProductCategoryLst);
    }
    dataMap.insert("config_product_category", mProductCategoryLst);
    return dataMap;
}

void SysRole::saveData()
{
    // 有效性验证
    QVariantList errLst = mUiLoader->validateAll("COMMIT", true, "ERROR");
    if (!errLst.isEmpty()) {
        QStringList errStrLst;
        for (QVariant err : errLst) {
            errStrLst.append(err.toMap().value("text").toString());
        }
        TMessageBox::error(this, ttr("Saving data failed!"), errStrLst.join("\n"));
        return;
    }

    t::saving(this);
    auto roleData = getRoleData();
    QVariant data = doThreadWork(new SysRoleThread(this), "SAVE_DATA", roleData);
    unloading();
    TDataResponse dataRes(data.toMap());
    if (dataRes.hasError()) {
        alertError(ttr("Save data failed!"), dataRes.errText());
    } else {
        setUid(dataRes.data().toInt());
        emit dataSaved(this->uid());
        alertOk(ttr("Data saved"));
    }
}

void SysRole::loadRgtNames()
{
    t::loading(this);
    QVariant data = doThreadWork(new SysRoleThread(this), "LOAD_RGT",
                                 QVariant::fromValue(mProductCategoryLst));
    unloading();
    TDataResponse dataRes(data.toMap());
    if (dataRes.hasError()) {
        alertError(ttr("Load data failed!"), dataRes.errText());
    } else {
        mRgtTreeView->selectionModel()->clear();
        QVariantList items = getTransferedData(dataRes.data().toList());
        mRgtTreeView->loadFlattenData(items, "index");
        mRgtTreeView->collapseAll();
    }
}

void SysRole::searchRightList(const QString &iSearchText, const QVariant &iOptions)
{
    QRegExp rx(iSearchText);
    rx.setPatternSyntax(QRegExp::Wildcard);
    rx.setCaseSensitivity(Qt::CaseInsensitive);
    QStringList searchlst = iOptions.toStringList();
    if (searchlst.isEmpty()) {
        searchlst = QStringList() << "text";
    }
    QModelIndexList modelIndexLst = mRgtTreeView->findRows(rx, searchlst, 1);
    //搜索时如果有子节点,将子节点全部展示
    while (!modelIndexLst.isEmpty()) {
        int rowCount = mRgtTreeModel->rowCount(modelIndexLst.first());
        for (int i = 0; i < rowCount; ++i) {
            mRgtTreeModel->setRowVisible(modelIndexLst.first().child(i, 0), true);
            modelIndexLst.append(modelIndexLst.first().child(i, 0));
        }
        modelIndexLst.removeFirst();
    }
}

void SysRole::onNotification(QString iNotifyKeyStr, QVariant iDataVar, QString iUuidStr)
{
    Q_UNUSED(iDataVar);
    Q_UNUSED(iUuidStr);
    if (iNotifyKeyStr.compare("sys-user-save") == 0) {
        reload();
    }
}

void SysRole::uidChangeEvent(const QString &iUidStr)
{
    if (iUidStr.toInt() == 0) {
        setTitle(ttr("New Role"));
        clearData();
    } else {
        t::loading(this);
        QVariantMap paraMap;
        paraMap.insert("uid", this->uid());
        paraMap.insert("config_product_category", mProductCategoryLst);
        QVariant data = doThreadWork(new SysRoleThread(this), "LOAD_DATA", paraMap);
        TDataResponse dataRes(data.toMap());
        unloading();

        if (!mRgtLoaded) {
            loadRgtNames();
            mRgtLoaded = true;
        }
        if (dataRes.hasError()) {
            alertError(ttr("Load data failed!"), dataRes.errText());
        } else {
            QVariantMap dataMap = dataRes.data().toMap();
            clearData();
            setRoleData(dataMap);
            alertOk(ttr("Data loaded"));
        }
    }
    setDataModified(false);
}

void SysRole::resizeEvent(QResizeEvent *iEvent)
{
    QSize size = iEvent->size();
    if (size.width() > this->perfectSize().width()) {
        mBodyLayout->setMargin(TTHEME_DP(16));
        mUiLoader->setProperty("SS_BORDER", 1);
        mUiLoader->setStyleSheet(".Q{}");
    } else {
        mBodyLayout->setMargin(0);
        mUiLoader->setProperty("SS_BORDER", 0);
        mUiLoader->setStyleSheet(".Q{}");
    }
}

void SysRole::initRgtTreeView()
{
    QVariantList headerItems;
    QVariantList nameItemLst;
    nameItemLst << "name" << "text" << "display" << ttr("Right Name")
                        << "displayRole" << QString("$text")
                        << "resizeMode" << "Interactive" << "size" << 300
                        << "checkStateRole"<< "$check"
                        << "flagsRole" << "ItemIsEnabled|ItemIsSelectable|ItemIsUserCheckable"
                        << "checkStateSync"<< true;//checkStateSync自动判断关联项状态

    headerItems << TDataParse::variantList2Map(nameItemLst);

    mTreeDataLst = QStringList() << "text" << "check" << "permission_name" << "index";
    mRgtTreeModel = qobject_cast<TTreeModel *>(mRgtTreeView->model());
    mRgtTreeView->setHeaderItem(headerItems);
    mRgtTreeView->setDataKeyList(mTreeDataLst);
    mRgtTreeView->setPrimaryKey("index");
    mRgtTreeView->header()->setStretchLastSection(true);
    mRgtTreeView->setSelectionMode(QAbstractItemView::ExtendedSelection);

    if (QMenu *treePopup = qobject_cast<QMenu *>(uim()->getWidget("PERMISSION_TREEVIEW_POPUP"))) {
        mRgtTreeView->setContextMenu(treePopup);
    }
}

QVariantList SysRole::getTransferedData(QVariantList iDataLst)
{
    QVariantList result;
    if (iDataLst.isEmpty()) {
        return result;
    }

    qSort(iDataLst.begin(), iDataLst.end(), [](const QVariant &var, const QVariant &var2) {
        return var.toMap()["permission_name"].toString() < var2.toMap()["permission_name"].toString();
    });

    mParentNameIndexMap.clear();
    mRefMap.clear();
    for (int i = 0; i < iDataLst.count(); ++i) {
        QVariant rd = iDataLst.at(i);
        QStringList tmpLst = rd.toMap().value("text").toString().split('/');

        if (tmpLst.count() == 0) {
            continue;
        }

        QString first_name = tmpLst[0];
        if (!mParentNameIndexMap.keys().contains(first_name)) {
            int index = mParentNameIndexMap.values().count() + 1;
            QVariantMap map;
            map.insert("index", index);
            mParentNameIndexMap.insert(first_name, map);
        }

        QVariantMap ele_map = mRefMap.value(first_name).toMap();
        for (int j = 1; j < tmpLst.count(); ++j) {
            QVariantMap single_map;
            single_map = ele_map.value(QString::number(j)).toMap();
            QStringList name_list;
            for (int k = 0; k < j + 1; ++k) {
                name_list.append(tmpLst[k]);
            }
            QString ele_name = name_list.join("/");
            if (!single_map.keys().contains(ele_name)) {
                QVariantMap map;
                map.insert("index", QString::number(single_map.values().count() + 1));
                single_map.insert(ele_name,map);
                ele_map.insert(QString::number(j),single_map);
            }
        }
        mRefMap.insert(first_name, ele_map);
    }
    //存在text相同, 权限名不同的权限
    QVariantList mergedDataLst;
    while (iDataLst.length() > 0) {
        QVariantMap firstMap = iDataLst.takeFirst().toMap();
        firstMap.insert("permission_name", QStringList() << firstMap.value("permission_name").toString());
        QList<int> similarLst;
        QString text = firstMap.value("text").toString().trimmed();
        QString productCategory = firstMap.value("product_category").toString().trimmed();
        for (int i = 0; i < iDataLst.length(); ++i) {
            QVariantMap curMap = iDataLst[i].toMap();
            if (text == curMap.value("text").toString().trimmed() && productCategory == curMap.value("product_category").toString().trimmed()) {
                similarLst << i;
                firstMap.insert("permission_name",
                                firstMap.value("permission_name").toStringList() << curMap.value("permission_name").toString()
                                );
                break;
            }
        }

        for (int i = 0, idx = 0; i < similarLst.length(); ++i) {
            iDataLst.removeAt(similarLst[i] - idx);
            ++idx;
        }
        mergedDataLst << firstMap;
    }

    for (int i = 0; i < mergedDataLst.length(); ++i) {
        QVariant rd = mergedDataLst[i];
        QStringList tmpLst = rd.toMap().value("text").toString().split('/');
        for (int j = 0; j < tmpLst.count(); ++j) {
            QVariantMap map = getItemDataMap(rd, j);
            if (map.isEmpty()) {
                continue;
            }
            result.append(map);
        }
    }

    return result;
}

QVariantMap SysRole::getItemDataMap(QVariant iValue, int iIdx)
{
    QVariantMap datamap;
    QVariantMap map = iValue.toMap();
    QStringList textlst = map.value("text").toString().split("/");
    QString text = textlst.at(iIdx);
    int count = textlst.count();
    if (iIdx == 0) {
        if (mParentNameIndexMap.value(text).toMap().value("exist").toBool()) {
            return datamap;
        }
        datamap.insert("index",
                       QString::number(mParentNameIndexMap.value(text).toMap().value("index").toInt()));
        QVariantMap map = mParentNameIndexMap.value(text).toMap();
        map.insert("exist",true);
        mParentNameIndexMap.insert(text,map);
    } else {
        QStringList indexlst;
        QVariantMap ref_map = mRefMap.value(textlst.at(0)).toMap();

        QStringList name_list;
        for (int k = 0; k < iIdx + 1; k++) {
            name_list.append(textlst[k]);
        }
        QString ele_name = name_list.join("/");
        QVariantMap index_map = ref_map.value(QString::number(iIdx)).toMap();
        QVariantMap ele_map = index_map.value(ele_name).toMap();
        if (ele_map.value("exist").toBool()) {
            return datamap;
        }
        indexlst.append(QString::number(mParentNameIndexMap.value(textlst.at(0)).toMap().value("index").toInt()));
        for (int i = 1; i < iIdx + 1; i++) {
            QStringList name_list2;
            for (int k = 0; k < i + 1; k++) {
                name_list2.append(textlst[k]);
            }
            QString ele_name2 = name_list2.join("/");
            QVariantMap index_map2 = ref_map.value(QString::number(i)).toMap();
            QString index = index_map2.value(ele_name2).toMap().value("index").toString();
            indexlst.append(index);
        }
        ele_map.insert("exist",true);
        index_map.insert(ele_name,ele_map);
        ref_map.insert(QString::number(iIdx),index_map);
        mRefMap.insert(textlst.at(0),ref_map);
        datamap.insert("index",indexlst.join("."));
    }
    datamap.insert("check",0);
    datamap.insert("text",text);
    if (iIdx == (count - 1)) {
        QStringList permissionLst;
        for (const QString &permission: map.value("permission_name").toStringList()) {
            permissionLst << (map.value("product_category").toString() + "%" + permission);
        }
        datamap.insert("permission_name", permissionLst);
    }

    return datamap;
}

void SysRole::getExpandedState(QVariantMap &oStateMap, const QVariantList iDataList)
{
    for (QVariant var: iDataList) {
        QString value = var.toMap().value("index").toString();
        QVariantList children = var.toMap().value("CHILDREN").toList();
        if (children.size() > 0) {
            getExpandedState(oStateMap, children);
        }
        QModelIndex idx = mRgtTreeView->findRow(value);
        if (idx.isValid()) {
            bool expanded = mRgtTreeView->isExpanded(idx);
            oStateMap.insert(value, expanded);
        }
    }
}

void SysRole::showAddUser()
{
    if (mUserTableView == nullptr) {
        return;
    }

    TSqlSelectorV2 selector;
    selector.setTable("sys_user AS U LEFT JOIN pub_contacts AS C ON U.contcat_id = C.id");
    selector.setReturnRowCount(true);
    selector.fieldRef() << "U.id" << "U.username"<< "U.remark" << "U.fullname";
    selector.setFieldFormat("product_category", "array");
    TSqlWhereCompsiteV2 whereCompsite;
    if (!mProductCategoryLst.contains("*")) {
        whereCompsite.append("product_category",  mProductCategoryLst, "@>");
        whereCompsite.append("product_category",  "{*}");
        whereCompsite.setLogic(TSqlWhereCompsiteV2::Logic_Or);
        selector.whereRef().append(whereCompsite);
    }

    selector.setOrder("id",Qt::DescendingOrder);
    QVariant iData = doThreadWork(new TopClassSqlThread(this), TOPSQLTHREAD_SELECT_ARRAYMAP, QVariant::fromValue(selector));
    TDataResponse dataRes(iData.toMap());
    if (dataRes.hasError()) {
        alertError(ttr("Get user list failed!"), dataRes.errText());
    }
    TTableViewDialog *dialog = new TTableViewDialog(this);
    dialog->resize(400, 400);
    dialog->setTitle(ttr("Add User"));
    dialog->setButtons(QStringList()
                       << ttr("Ok") + ":Ok:Yes"
                       << ttr("Cancel") + ":Cancel:Cancel"
                       << ttr("Clear All") + ":UnselectAll:ResetRole");

    QVariantList headerItems;
    headerItems << QVariant();
    headerItems << TDataParse::variantList2Map(
                       QVariantList() << "name" << "username" << "display" << ttr("Login Name") <<
                       "displayRole" << "$username" << "resizeMode" << "Interactive" );
    headerItems << TDataParse::variantList2Map(
                       QVariantList() << "name" << "fullname" << "display" << ttr("Full Name") <<
                       "displayRole" << "$fullname" << "resizeMode" << "Interactive");
    headerItems << TDataParse::variantList2Map(
                       QVariantList() << "name" << "remark" << "display" << ttr("Remark") <<
                       "displayRole" << "$remark" << "resizeMode" << "Stretch");

    dialog->setPrimaryKey("id");
    dialog->setDataKeyList(QStringList() << "id" << "username" << "fullname" << "remark");
    dialog->setHeaderItem(headerItems);
    dialog->setSearchKeys(QStringList() << "username" << "fullname" << "remark");
    dialog->setSelectionMode(QAbstractItemView::MultiSelection);

    QVariantList tableData;

    QVariantList exists = mUserTableView->getData("primary_keys").toList();
    QVariantList userLst = iData.toMap().value("data").toList();
    for (QVariant item : userLst) {
        int userId = item.toMap().value("id").toInt();
        if (!exists.contains(userId)) {
            tableData.append(item);
        }
    }
    dialog->loadData(tableData);

    QVariantList selList = dialog->run();
    if (selList.size() == 0) {
        return;
    }
    QModelIndexList indexs =  mUserTableView->appendRows(selList);
    mUserTableView->unselectAll();
    mUserTableView->selectRows(indexs);
    mUserTableView->scrollToBottom();
}

void SysRole::collapsePermissionTree()
{
    if (mRgtTreeView != nullptr) {
        mRgtTreeView->collapseAll();
    }
}

void SysRole::expandPermissionTree()
{
    if (mRgtTreeView != nullptr) {
        mRgtTreeView->expandAll();
    }
}