LAPTOP-T815PCOQ\25526
2024-11-18 29ae330b546e455a23e486882d783015a964fc8c
1. 用户管理界面数据绑定到数据库中
已修改7个文件
已删除1个文件
350 ■■■■ 文件已修改
SourceCode/Bond/BondEq/BondEq.rc 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BondEq/BondEqDlg.cpp 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BondEq/DBManager/UserManager.cpp 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BondEq/Resource.h 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BondEq/UserManagerDlg.cpp 333 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BondEq/UserManagerDlg.h 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/x64/Debug/Config/BondEq.db 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/x64/Debug/Config/BondServo.db 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BondEq/BondEq.rc
Binary files differ
SourceCode/Bond/BondEq/BondEqDlg.cpp
@@ -542,10 +542,10 @@
            CUserManagerDlg dlg;
            dlg.DoModal();
            if (userManager.isLoggedIn()) {
                userManager.logout();
                m_pTopToolbar->SetOperatorBtnText(_T("未登录"));
            }
            //if (userManager.isLoggedIn()) {
            //    userManager.logout();
            //    m_pTopToolbar->SetOperatorBtnText(_T("未登录"));
            //}
        }
    }
SourceCode/Bond/BondEq/DBManager/UserManager.cpp
@@ -293,7 +293,7 @@
        }
        std::string insertQuery = "INSERT INTO users (username, password, role, session_timeout, session_expiration, last_login) VALUES ('" +
            user[0] + "', '" + user[1] + "', " + user[2] + ", " + user[3] + ", " + user[4] + ", '" + user[5] + "')";
            user[0] + "', '" + simpleEncryptDecrypt(user[1], "BandKey") + "', " + user[2] + ", " + user[3] + ", " + user[4] + ", '" + user[5] + "')";
        if (!m_pDB->executeQuery(insertQuery)) {
            std::cerr << "Failed to insert user: " << user[0] << std::endl;
SourceCode/Bond/BondEq/Resource.h
Binary files differ
SourceCode/Bond/BondEq/UserManagerDlg.cpp
@@ -6,6 +6,8 @@
#include "afxdialogex.h"
#include "UserManagerDlg.h"
#include "UserManager.h"
#include "NewCellTypes/GridCellCombo.h"
#include "NewCellTypes/GridCellNumeric.h"
// CUserManagerDlg 对话框
@@ -53,22 +55,6 @@
    m_gridUserManager.SetFixedRowCount(nFixRows);
    m_gridUserManager.SetFixedColumnCount(nFixCols);
    CFont* pFont = m_gridUserManager.GetFont();
    if (pFont)
    {
        LOGFONT lf;
        pFont->GetLogFont(&lf);
        lf.lfItalic = 0;
        lf.lfHeight = 14;
        lf.lfWeight = FW_BOLD;
        _tcscpy_s(lf.lfFaceName, _T("Arial"));
        m_gridUserManager.GetDefaultCell(FALSE, TRUE)->SetFont(&lf);
        m_gridUserManager.GetDefaultCell(TRUE, FALSE)->SetFont(&lf);
        m_gridUserManager.GetDefaultCell(FALSE, FALSE)->SetFont(&lf);
        m_gridUserManager.GetDefaultCell(TRUE, TRUE)->SetFont(&lf);
    }
    // Col
    m_gridUserManager.SetColumnWidth(nColIdx, 90);
    m_gridUserManager.SetItemText(nRowIdx, nColIdx++, _T("No."));
@@ -100,27 +86,188 @@
{
    UserManager& userManager = UserManager::getInstance();
    if (!userManager.isLoggedIn()) {
        AfxMessageBox("未登录");
        AfxMessageBox(_T("未登录"));
        return;
    }
    if (userManager.getCurrentUserRole() != UserRole::SuperAdmin) {
        AfxMessageBox("非管理员用户");
        AfxMessageBox(_T("非管理员用户"));
        return;
    }
    std::vector<std::vector<std::string>> usersData = userManager.getUsers();
    if (usersData.size() > 0) {
    if (!usersData.empty()) {
        m_gridUserManager.SetRowCount(usersData.size() + 1);
        for (size_t i = 0; i < usersData.size(); i++) {
            int nRowIdx = i + 1;
            int nColIdx = 0;
            m_gridUserManager.SetItemText(nRowIdx, nColIdx++, std::to_string(i + 1).c_str());
            for (size_t j = 0; j < usersData[i].size(); j++) {
                if (usersData[i][1].empty()) {
                    continue;
                }
                m_gridUserManager.SetItemText(nRowIdx, nColIdx++, usersData[i][j].c_str());
            }
        }
        m_gridUserManager.Invalidate();
        m_gridUserManager.UpdateWindow();
    }
    CStringArray permissions;
    permissions.Add(_T("管理员"));
    permissions.Add(_T("工程师"));
    permissions.Add(_T("操作员"));
    int nCols = m_gridUserManager.GetColumnCount();
    for (int i = 1; i < m_gridUserManager.GetRowCount(); ++i) {
        m_gridUserManager.SetItemState(i, 0, GVIS_READONLY); // 第一列只读
        m_gridUserManager.SetItemState(i, nCols - 1, GVIS_READONLY); // 最后一列只读
        // 第四列设置权限列为下拉框
        if (m_gridUserManager.SetCellType(i, 3, RUNTIME_CLASS(CGridCellCombo))) {
            CGridCellCombo* pCell = static_cast<CGridCellCombo*>(m_gridUserManager.GetCell(i, 3));
            pCell->SetOptions(permissions);
            pCell->SetStyle(CBS_DROPDOWNLIST);
            CString cstrRole = m_gridUserManager.GetItemText(i, 3);
            int nRole = _ttoi(cstrRole);
            if (nRole < 0 || nRole > 2) {
                CString cstrMessage;
                cstrMessage.Format(_T("用户 [%s],权限异常!将设置成操作员!"), m_gridUserManager.GetItemText(i, 1));
                AfxMessageBox(cstrMessage);
                nRole = 2;
            }
            m_gridUserManager.SetItemText(i, 3, permissions.GetAt(nRole));
        }
        // 第五、六列(会话超时)设置为Numeric
        m_gridUserManager.SetCellType(i, 4, RUNTIME_CLASS(CGridCellNumeric));
        m_gridUserManager.SetCellType(i, 5, RUNTIME_CLASS(CGridCellNumeric));
    }
}
void CUserManagerDlg::AddRow(CGridCtrl* pGridCtrl)
{
    if (!pGridCtrl) return;
    if (pGridCtrl->GetRowCount() <= 0 || pGridCtrl->GetColumnCount() <= 0) {
        AfxMessageBox(_T("网格控件未正确初始化,请检查初始化逻辑!"));
        return;
    }
    int nRowCount = pGridCtrl->GetRowCount();
    pGridCtrl->SetRowCount(nRowCount + 1);
    int newRowIndex = nRowCount;
    CString strText;
    strText.Format(_T("%d"), newRowIndex);
    pGridCtrl->SetItemText(newRowIndex, 0, strText);
    strText.Format(_T("User%d"), newRowIndex);
    pGridCtrl->SetItemText(newRowIndex, 1, strText);
    pGridCtrl->SetItemText(newRowIndex, 2, _T("123456"));
    pGridCtrl->SetItemText(newRowIndex, 3, _T("操作员"));
    pGridCtrl->SetItemText(newRowIndex, 4, _T("30"));
    pGridCtrl->SetItemText(newRowIndex, 5, _T("72"));
    pGridCtrl->SetItemText(newRowIndex, 6, _T("2024-01-01 00:00:00"));
    int nCols = m_gridUserManager.GetColumnCount();
    m_gridUserManager.SetItemState(newRowIndex, 0, GVIS_READONLY); // 第一列
    m_gridUserManager.SetItemState(newRowIndex, nCols - 1, GVIS_READONLY); // 最后一列
    // 第四列设置(权限列)为下拉框
    CStringArray permissions;
    permissions.Add(_T("管理员"));
    permissions.Add(_T("工程师"));
    permissions.Add(_T("操作员"));
    if (m_gridUserManager.SetCellType(newRowIndex, 3, RUNTIME_CLASS(CGridCellCombo))) {
        CGridCellCombo* pCell = static_cast<CGridCellCombo*>(m_gridUserManager.GetCell(newRowIndex, 3));
        pCell->SetOptions(permissions);
        pCell->SetStyle(CBS_DROPDOWNLIST);
        m_gridUserManager.SetItemText(newRowIndex, 3, permissions.GetAt(2));
    }
    // 第五、六列(会话超时)设置为Numeric
    m_gridUserManager.SetCellType(newRowIndex, 4, RUNTIME_CLASS(CGridCellNumeric));
    m_gridUserManager.SetCellType(newRowIndex, 5, RUNTIME_CLASS(CGridCellNumeric));
    pGridCtrl->Invalidate();
    pGridCtrl->UpdateWindow();
}
void CUserManagerDlg::DeleteSelectedRow(CGridCtrl* pGridCtrl)
{
    if (!pGridCtrl) return;
    CCellRange selectedRange = pGridCtrl->GetSelectedCellRange();
    if (selectedRange.IsValid()) {
        CString currentUser = UserManager::getInstance().getCurrentUser().c_str();
        std::vector<int> rowsToDelete;
        for (int row = selectedRange.GetMinRow(); row <= selectedRange.GetMaxRow(); ++row) {
            BOOL isRowSelected = FALSE;
            for (int col = selectedRange.GetMinCol(); col <= selectedRange.GetMaxCol(); ++col) {
                if (pGridCtrl->IsCellSelected(row, col)) {
                    isRowSelected = TRUE;
                    break;
                }
            }
            if (!isRowSelected) {
                continue;
            }
            CString selectedUser = pGridCtrl->GetItemText(row, 1);
            if (selectedUser == currentUser) {
                CString message;
                message.Format(_T("用户 [%s] 是当前登录用户,不能删除!"), currentUser);
                AfxMessageBox(message, MB_OK | MB_ICONEXCLAMATION);
                return;
            }
            rowsToDelete.push_back(row);
        }
        if (rowsToDelete.empty()) {
            AfxMessageBox(_T("请先选择要删除的行!"), MB_OK | MB_ICONINFORMATION);
            return;
        }
        CString message;
        if (rowsToDelete.size() == 1) {
            CString selectedUser = pGridCtrl->GetItemText(rowsToDelete[0], 1);
            message.Format(_T("确定要删除选中用户 [%s] 吗?"), selectedUser);
        }
        else {
            message.Format(_T("确定要删除选中的 %d 个用户吗?"), rowsToDelete.size());
        }
        if (AfxMessageBox(message, MB_YESNO | MB_ICONQUESTION) == IDYES) {
            for (auto it = rowsToDelete.rbegin(); it != rowsToDelete.rend(); ++it) {
                pGridCtrl->DeleteRow(*it);
            }
            pGridCtrl->Invalidate();
            pGridCtrl->UpdateWindow();
        }
    }
    else {
        AfxMessageBox(_T("请先选择要删除的用户!"), MB_OK | MB_ICONINFORMATION);
    }
}
bool CUserManagerDlg::IsUsernameDuplicate(const CString& username)
{
    for (int row = 1; row < m_gridUserManager.GetRowCount(); ++row) {
        if (m_gridUserManager.GetItemText(row, 1) == username) {
            return true;
        }
    }
    return false;
}
void CUserManagerDlg::AdjustControls(int nWidth, int nHeight)
@@ -145,14 +292,9 @@
        if (_tcsicmp(szClassName, _T("MFCGridCtrl")) == 0) {
            CGridCtrl* pGridCtrl = (CGridCtrl*)pWnd;
            //int nRowCount = pGridCtrl->GetRowCount();
            //int newRowHeight = (int)(newHeight / (float)nRowCount);
            //for (int i = 0; i < nRowCount; ++i) {
            //    pGridCtrl->SetRowHeight(i, newRowHeight);
            //}
            pGridCtrl->SetDefCellHeight(newHeight / 20);
            pGridCtrl->ExpandColumnsToFit(TRUE);
            pGridCtrl->Invalidate();
        }
        pWnd->MoveWindow(newX, newY, newWidth, newHeight);
@@ -193,6 +335,10 @@
BEGIN_MESSAGE_MAP(CUserManagerDlg, CDialogEx)
    ON_WM_SIZE()
    ON_BN_CLICKED(IDC_BUTTON_ADD, &CUserManagerDlg::OnBnClickedButtonAdd)
    ON_BN_CLICKED(IDC_BUTTON_DEL, &CUserManagerDlg::OnBnClickedButtonDel)
    ON_BN_CLICKED(IDOK, &CUserManagerDlg::OnBnClickedOk)
    ON_BN_CLICKED(IDC_BUTTON_INSERT, &CUserManagerDlg::OnBnClickedButtonInsert)
END_MESSAGE_MAP()
@@ -204,16 +350,30 @@
    CDialogEx::OnInitDialog();
    // TODO:  在此添加额外的初始化
    CRect rect;
    GetClientRect(&rect);
    m_nInitialWidth = rect.Width();
    m_nInitialHeight = rect.Height();
    CRect screenRect, dlgRect, clientRect;
    SetWindowText(_T("用户管理"));
    SystemParametersInfo(SPI_GETWORKAREA, 0, &screenRect, 0);
    rect.right *= 3;
    rect.bottom *= 3;
    // 调整对话框大小
    MoveWindow(rect);
    GetClientRect(&clientRect);
    m_nInitialWidth = clientRect.Width();
    m_nInitialHeight = clientRect.Height();
    GetWindowRect(&dlgRect);
    int dlgWidth = dlgRect.Width() * 3;
    int dlgHeight = dlgRect.Height() * 3;
    if (dlgWidth > screenRect.Width()) {
        dlgWidth = screenRect.Width();
    }
    if (dlgHeight > screenRect.Height()) {
        dlgHeight = screenRect.Height();
    }
    int centerX = screenRect.left + (screenRect.Width() - dlgWidth) / 2;
    int centerY = screenRect.top + (screenRect.Height() - dlgHeight) / 2;
    MoveWindow(centerX, centerY, dlgWidth, dlgHeight);
    // 初始化用户管理表格
    InitUserManager();
    return TRUE;  // return TRUE unless you set the focus to a control
@@ -231,3 +391,108 @@
    // 遍历对话框中的所有控件
    AdjustControls(rect.Width(), rect.Height());
}
void CUserManagerDlg::OnBnClickedButtonAdd()
{
    // TODO: 在此添加控件通知处理程序代码
    AddRow(&m_gridUserManager);
}
void CUserManagerDlg::OnBnClickedButtonInsert()
{
    // TODO: 在此添加控件通知处理程序代码
    if (!m_gridUserManager.GetSafeHwnd()) return;
    CCellRange selectedRange = m_gridUserManager.GetSelectedCellRange();
    if (!selectedRange.IsValid()) {
        AfxMessageBox(_T("请先选择要插入的位置!"), MB_OK | MB_ICONINFORMATION);
        return;
    }
    int minRow = selectedRange.GetMinRow();
    int maxRow = selectedRange.GetMaxRow();
    if (minRow < 1) {
        AfxMessageBox(_T("请选择有效的行!"), MB_OK | MB_ICONEXCLAMATION);
        return;
    }
    for (int row = maxRow; row >= minRow; --row) {
        std::vector<CString> rowData;
        for (int col = 0; col < m_gridUserManager.GetColumnCount(); ++col) {
            rowData.push_back(m_gridUserManager.GetItemText(row, col));
        }
        m_gridUserManager.InsertRow(_T("新用户"), row);
        CString newUsername = rowData[1];
        int suffix = 1;
        while (IsUsernameDuplicate(newUsername)) {
            newUsername.Format(_T("%s_%d"), rowData[1], suffix++);
        }
        rowData[1] = newUsername;
        for (int col = 0; col < m_gridUserManager.GetColumnCount(); ++col) {
            m_gridUserManager.SetItemText(row, col, rowData[col]);
        }
        CStringArray permissions;
        permissions.Add(_T("管理员"));
        permissions.Add(_T("工程师"));
        permissions.Add(_T("操作员"));
        if (m_gridUserManager.SetCellType(row, 3, RUNTIME_CLASS(CGridCellCombo))) {
            CGridCellCombo* pCell = static_cast<CGridCellCombo*>(m_gridUserManager.GetCell(row, 3));
            pCell->SetOptions(permissions);
            pCell->SetStyle(CBS_DROPDOWNLIST);
            m_gridUserManager.SetItemText(row, 3, rowData[3]);
        }
        m_gridUserManager.SetCellType(row, 4, RUNTIME_CLASS(CGridCellNumeric));
        m_gridUserManager.SetCellType(row, 5, RUNTIME_CLASS(CGridCellNumeric));
    }
    for (int row = 1; row < m_gridUserManager.GetRowCount(); ++row) {
        CString strIndex;
        strIndex.Format(_T("%d"), row);
        m_gridUserManager.SetItemText(row, 0, strIndex);
    }
    m_gridUserManager.Invalidate();
    m_gridUserManager.UpdateWindow();
}
void CUserManagerDlg::OnBnClickedButtonDel()
{
    // TODO: 在此添加控件通知处理程序代码
    DeleteSelectedRow(&m_gridUserManager);
}
void CUserManagerDlg::OnBnClickedOk()
{
    // TODO: 在此添加控件通知处理程序代码
    std::vector<std::vector<std::string>> vecData;
    for (int i = 1; i < m_gridUserManager.GetRowCount(); ++i) {
        std::vector<std::string> rowData;
        for (int j = 1; j < m_gridUserManager.GetColumnCount(); ++j) {
            CString cellText = m_gridUserManager.GetItemText(i, j);
            std::string cellString = CT2A(cellText.GetString());
            if (j == 3) {
                if (cellText == _T("管理员"))
                    cellString = "0";
                else if (cellText == _T("工程师"))
                    cellString = "1";
                else if (cellText == _T("操作员"))
                    cellString = "2";
                else
                    cellString = "2";
            }
            rowData.push_back(cellString);
        }
        vecData.push_back(rowData);
    }
    UserManager::getInstance().setUsers(vecData);
    CDialogEx::OnOK();
}
SourceCode/Bond/BondEq/UserManagerDlg.h
@@ -20,6 +20,9 @@
private:
    void InitUserManager();
    void FillUserManager();
    void AddRow(CGridCtrl* pGridCtrl);
    void DeleteSelectedRow(CGridCtrl* pGridCtrl);
    bool IsUsernameDuplicate(const CString& username);
    void AdjustControls(int nWidth, int nHeight);
    void AdjustControlFont(CWnd* pWnd, int nWidth, int nHeight);
@@ -37,4 +40,8 @@
public:
    virtual BOOL OnInitDialog();
    afx_msg void OnSize(UINT nType, int cx, int cy);
    afx_msg void OnBnClickedButtonAdd();
    afx_msg void OnBnClickedButtonInsert();
    afx_msg void OnBnClickedButtonDel();
    afx_msg void OnBnClickedOk();
};
SourceCode/Bond/x64/Debug/Config/BondEq.db
Binary files differ
SourceCode/Bond/x64/Debug/Config/BondServo.db
Binary files differ