#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(); } }