1. 添加系统运行记录表 2. 完善用户管理的部分细节
| | |
| | | <ClInclude Include="Common.h" /> |
| | | <ClInclude Include="Configuration.h" /> |
| | | <ClInclude Include="CPanelProject.h" /> |
| | | <ClInclude Include="DBManager\SystemLogManager.h" /> |
| | | <ClInclude Include="DBManager\UserManager.h" /> |
| | | <ClInclude Include="EQState.h" /> |
| | | <ClInclude Include="EQStateMonitor.h" /> |
| | |
| | | <ClCompile Include="CProjectPageRemoteEqs.cpp" /> |
| | | <ClCompile Include="Configuration.cpp" /> |
| | | <ClCompile Include="CPanelProject.cpp" /> |
| | | <ClCompile Include="DBManager\SystemLogManager.cpp" /> |
| | | <ClCompile Include="DBManager\UserManager.cpp" /> |
| | | <ClCompile Include="EQState.cpp" /> |
| | | <ClCompile Include="EQStateMonitor.cpp" /> |
| | |
| | | #include "CBonder.h" |
| | | #include "SettingsDlg.h" |
| | | #include "UserManager.h" |
| | | #include "SystemLogManager.h" |
| | | #include "LoginDlg.h" |
| | | #include "ChangePasswordDlg.h" |
| | | #include "InputDialog.h" |
| | | |
| | | // test |
| | | #include "AxisSettingsDlg.h" |
| | | #include "UserManagerDlg.h" |
| | | |
| | | |
| | |
| | | SetTimer(1, 60000, nullptr); |
| | | #endif |
| | | userManager.loadSession(); |
| | | std::unique_ptr<BL::Database>& db = userManager.getDatabaseInstance(); |
| | | |
| | | // 设置æ¥å¿æ¨¡åçæ°æ®åºè¿æ¥ |
| | | SystemLogManager& logManager = SystemLogManager::getInstance(); |
| | | logManager.setDatabase(db); |
| | | |
| | | // åå§åæ¥å¿è¡¨ |
| | | if (!logManager.initializeLogTable()) { |
| | | AfxMessageBox("åå§åç³»ç»æ¥å¿è¡¨å¤±è´¥ï¼"); |
| | | return FALSE; |
| | | } |
| | | |
| | | std::string strUsername = userManager.getCurrentUser(); |
| | | if (strUsername.empty()) { |
| | | strUsername = "SYSTEM"; |
| | | } |
| | | logManager.log(SystemLogManager::LogType::Info, _T("BondEqå¯å¨..."), strUsername); |
| | | |
| | | |
| | | // èå |
| | |
| | | UserManager::getInstance().terminateIdleDetection(); |
| | | KillTimer(1); |
| | | #endif |
| | | |
| | | std::string strUsername = UserManager::getInstance().getCurrentUser(); |
| | | if (strUsername.empty()) { |
| | | strUsername = "SYSTEM"; |
| | | } |
| | | SystemLogManager::getInstance().log(SystemLogManager::LogType::Info, _T("BondEqå
³é..."), strUsername); |
| | | } |
| | | |
| | | void CBondEqDlg::OnSize(UINT nType, int cx, int cy) |
| | |
| | | if (menuId == 0) { |
| | | CLoginDlg loginDlg; |
| | | loginDlg.DoModal(); |
| | | UpdateLoginStatus(); |
| | | } |
| | | else if (1 == menuId) { |
| | | CChangePasswordDlg changePasswordDlg; |
| | | if (changePasswordDlg.DoModal() == IDOK) { |
| | | } |
| | | changePasswordDlg.DoModal(); |
| | | } |
| | | else if (2 == menuId) { |
| | | CUserManagerDlg dlg; |
| | |
| | | |
| | | CLoginDlg loginDlg; |
| | | loginDlg.DoModal(); |
| | | UpdateLoginStatus(); |
| | | } |
| | | else { |
| | | CString cstrMessage; |
| | | cstrMessage.Format(_T("æ¯å¦éåºç¨æ· [%s]ï¼"), userManager.getCurrentUser().c_str()); |
| | | int ret = AfxMessageBox(_T(cstrMessage), MB_OK | MB_ICONEXCLAMATION); |
| | | if (ret != MB_OK) { |
| | | return 0; |
| | | } |
| | | |
| | | userManager.logout(); |
| | | UpdateLoginStatus(); |
| | | } |
| | | |
| | | UpdateLoginStatus(); |
| | | } |
| | | |
| | | return 0; |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #include "stdafx.h" |
| | | #include "SystemLogManager.h" |
| | | #include <iostream> |
| | | #include <sstream> |
| | | #include <stdexcept> |
| | | |
| | | // éææååéåå§å |
| | | std::unique_ptr<SystemLogManager> SystemLogManager::m_instance = nullptr; |
| | | std::mutex SystemLogManager::m_mutex; |
| | | |
| | | // è·ååä¾å®ä¾ |
| | | SystemLogManager& SystemLogManager::getInstance() { |
| | | if (m_instance == nullptr) { |
| | | std::lock_guard<std::mutex> lock(m_mutex); |
| | | if (m_instance == nullptr) { |
| | | m_instance = std::unique_ptr<SystemLogManager>(new SystemLogManager()); |
| | | } |
| | | } |
| | | return *m_instance; |
| | | } |
| | | |
| | | // æé 彿° |
| | | SystemLogManager::SystemLogManager() : m_pDB(nullptr) {} |
| | | |
| | | // è®¾ç½®æ°æ®åºè¿æ¥ |
| | | void SystemLogManager::setDatabase(std::unique_ptr<BL::Database>& db) { |
| | | std::lock_guard<std::mutex> lock(m_mutex); |
| | | m_pDB = &db; |
| | | } |
| | | |
| | | // åå§åæ¥å¿è¡¨ |
| | | bool SystemLogManager::initializeLogTable() { |
| | | if (!m_pDB || !(*m_pDB)) { |
| | | std::cerr << "Database connection is not set." << std::endl; |
| | | return false; |
| | | } |
| | | |
| | | const std::string createTableQuery = R"( |
| | | CREATE TABLE IF NOT EXISTS system_logs ( |
| | | id INTEGER PRIMARY KEY AUTOINCREMENT, |
| | | log_type TEXT NOT NULL, |
| | | event TEXT NOT NULL, |
| | | username TEXT NOT NULL, |
| | | timestamp DATETIME DEFAULT CURRENT_TIMESTAMP |
| | | ) |
| | | )"; |
| | | return (*m_pDB)->executeQuery(createTableQuery); |
| | | } |
| | | |
| | | // æ·»å æ¥å¿ |
| | | bool SystemLogManager::log(LogType logType, const std::string& event, const std::string& username) { |
| | | if (!m_pDB || !(*m_pDB)) { |
| | | std::cerr << "Database connection is not set." << std::endl; |
| | | return false; |
| | | } |
| | | |
| | | std::ostringstream query; |
| | | query << "INSERT INTO system_logs (log_type, event, username) VALUES (" |
| | | << "'" << logTypeToString(logType) << "', " |
| | | << "'" << event << "', " |
| | | << "'" << username << "')"; |
| | | return (*m_pDB)->executeQuery(query.str()); |
| | | } |
| | | |
| | | // è·åæ¥å¿å
容 |
| | | std::vector<std::vector<std::string>> SystemLogManager::getLogs(int startPosition, int count) { |
| | | std::vector<std::vector<std::string>> logs; |
| | | |
| | | if (!m_pDB || !(*m_pDB)) { |
| | | std::cerr << "Database connection is not set." << std::endl; |
| | | return logs; |
| | | } |
| | | |
| | | std::ostringstream query; |
| | | |
| | | // 妿 startPosition å count 齿¯ -1ï¼è·åå
¨é¨æ°æ® |
| | | if (startPosition == -1 && count == -1) { |
| | | query << "SELECT id, log_type, event, username, timestamp FROM system_logs"; |
| | | } |
| | | else { |
| | | query << "SELECT id, log_type, event, username, timestamp FROM system_logs " |
| | | << "LIMIT " << count << " OFFSET " << startPosition; |
| | | } |
| | | |
| | | auto results = (*m_pDB)->fetchResults(query.str()); |
| | | for (const auto& row : results) { |
| | | logs.push_back(row); |
| | | } |
| | | |
| | | return logs; |
| | | } |
| | | |
| | | // è½¬æ¢æ¥å¿ç±»å为å符串 |
| | | std::string SystemLogManager::logTypeToString(LogType logType) const { |
| | | switch (logType) { |
| | | case LogType::Info: |
| | | return _T("ä¿¡æ¯"); |
| | | case LogType::Error: |
| | | return _T("é误"); |
| | | case LogType::Operation: |
| | | return _T("æä½"); |
| | | default: |
| | | return _T("δ֪"); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #ifndef SYSTEM_LOG_MANAGER_H |
| | | #define SYSTEM_LOG_MANAGER_H |
| | | |
| | | #include <string> |
| | | #include <memory> |
| | | #include <mutex> |
| | | #include <chrono> |
| | | #include "Database.h" |
| | | |
| | | class SystemLogManager { |
| | | public: |
| | | enum class LogType { |
| | | Info, // ä¿¡æ¯æ¥å¿ |
| | | Error, // é误æ¥å¿ |
| | | Operation // æä½æ¥å¿ |
| | | }; |
| | | |
| | | // è·ååä¾å®ä¾ |
| | | static SystemLogManager& getInstance(); |
| | | |
| | | // è®¾ç½®æ°æ®åºè¿æ¥ |
| | | void setDatabase(std::unique_ptr<BL::Database>& db); |
| | | |
| | | // æ·»å æ¥å¿ |
| | | bool log(LogType logType, const std::string& event, const std::string& username = "SYSTEM"); |
| | | |
| | | // è·åæ¥å¿ |
| | | std::vector<std::vector<std::string>> SystemLogManager::getLogs(int startPosition = -1, int count = -1); |
| | | |
| | | // åå§åæ¥å¿è¡¨ |
| | | bool initializeLogTable(); |
| | | |
| | | private: |
| | | // æé 彿°ï¼ç§æåï¼ |
| | | SystemLogManager(); |
| | | |
| | | // ç¦æ¢æ·è´åèµå¼ |
| | | SystemLogManager(const SystemLogManager&) = delete; |
| | | SystemLogManager& operator=(const SystemLogManager&) = delete; |
| | | |
| | | // è½¬æ¢æ¥å¿ç±»å为å符串 |
| | | std::string logTypeToString(LogType logType) const; |
| | | |
| | | // æ°æ®åºè¿æ¥ |
| | | std::unique_ptr<BL::Database>* m_pDB; |
| | | |
| | | // åä¾å®ä¾ |
| | | static std::unique_ptr<SystemLogManager> m_instance; |
| | | |
| | | // 线ç¨å®å
¨é |
| | | static std::mutex m_mutex; |
| | | }; |
| | | |
| | | #endif // SYSTEM_LOG_MANAGER_H |
| | |
| | | terminateIdleDetection(); |
| | | } |
| | | |
| | | // æä¾æ°æ®åºè¿æ¥ |
| | | std::unique_ptr<BL::Database>& UserManager::getDatabaseInstance() { |
| | | return m_pDB; |
| | | } |
| | | |
| | | // åå§åæ°æ®åºï¼åå»ºç¨æ·è¡¨å¹¶æå
¥åå§ç®¡çåç¨æ· |
| | | bool UserManager::initializeDatabase() { |
| | | std::string dbFilePath = getDatabaseFilePath(); |
| | |
| | | return m_strCurrentUser; |
| | | } |
| | | |
| | | // ä¿®æ¹å½åç»å½ç¨æ·å |
| | | void UserManager::setCurrentUser(const std::string& strName) { |
| | | m_strCurrentUser = strName; |
| | | } |
| | | |
| | | // è·åå½åç»å½ç¨æ·å¯ç |
| | | std::string UserManager::getCurrentPass() const { |
| | | return m_strCurrentPass; |
| | | } |
| | | |
| | | // ä¿®æ¹å½åç»å½ç¨æ·å¯ç |
| | | void UserManager::setCurrentPass(const std::string& strPass) { |
| | | m_strCurrentPass = strPass; |
| | | } |
| | | |
| | | // è·åå½åç»å½ç¨æ·è§è² |
| | | UserRole UserManager::getCurrentUserRole() const { |
| | | return m_enCurrentUserRole; |
| | | } |
| | | |
| | | // ä¿®æ¹å½åç»å½ç¨æ·è§è² |
| | | void UserManager::setCurrentUserRole(UserRole emRole) { |
| | | m_enCurrentUserRole = emRole; |
| | | } |
| | | |
| | | // è·åå½åç»å½ç¨æ·çæ æä½è¶
æ¶æ¶é´ |
| | | std::chrono::minutes UserManager::getSessionTimeout() const { |
| | | return m_tmSessionTimeout; |
| | |
| | | UserManager(const UserManager&) = delete; |
| | | UserManager& operator=(const UserManager&) = delete; |
| | | |
| | | // æä¾æ°æ®åºè¿æ¥ |
| | | std::unique_ptr<BL::Database>& getDatabaseInstance(); |
| | | |
| | | // ç¨æ·æä½ |
| | | bool login(const std::string& username, const std::string& password, bool rememberMe = false); |
| | | void logout(); |
| | |
| | | // è·åå½åç»å½ç¨æ·å |
| | | std::string getCurrentUser() const; |
| | | |
| | | // ä¿®æ¹å½åç»å½ç¨æ·å |
| | | void setCurrentUser(const std::string& strName); |
| | | |
| | | // è·åå½åç»å½ç¨æ·å¯ç |
| | | std::string getCurrentPass() const; |
| | | |
| | | // ä¿®æ¹å½åç»å½ç¨æ·å¯ç |
| | | void setCurrentPass(const std::string& strPass); |
| | | |
| | | // è·åå½åç»å½ç¨æ·è§è² |
| | | UserRole getCurrentUserRole() const; |
| | | |
| | | // ä¿®æ¹å½åç»å½ç¨æ·è§è² |
| | | void setCurrentUserRole(UserRole emRole); |
| | | |
| | | // è·åå½åç»å½ç¨æ·çæ æä½è¶
æ¶æ¶é´ |
| | | std::chrono::minutes getSessionTimeout() const; |
| | | |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // InputDialog.cpp: å®ç°æä»¶ |
| | | // |
| | | |
| | | #include "stdafx.h" |
| | | #include "BondEq.h" |
| | | #include "afxdialogex.h" |
| | | #include "InputDialog.h" |
| | | |
| | | |
| | | // CInputDialog å¯¹è¯æ¡ |
| | | |
| | | IMPLEMENT_DYNAMIC(CInputDialog, CDialogEx) |
| | | |
| | | CInputDialog::CInputDialog(const CString& strTitle, const CString& strPrompt, CWnd* pParent /*=nullptr*/) |
| | | : CDialogEx(IDD_DIALOG_INPUT, pParent), m_strTitle(strTitle), m_strPrompt(strPrompt), m_strInput(_T("")) |
| | | { |
| | | |
| | | } |
| | | |
| | | CInputDialog::~CInputDialog() |
| | | { |
| | | } |
| | | |
| | | CString CInputDialog::GetInputText() const |
| | | { |
| | | return m_strInput; |
| | | } |
| | | |
| | | void CInputDialog::DoDataExchange(CDataExchange* pDX) |
| | | { |
| | | CDialogEx::DoDataExchange(pDX); |
| | | DDX_Control(pDX, IDC_EDIT_INPUT, m_editInput); |
| | | DDX_Control(pDX, IDC_STATIC_PROMPT, m_staticPrompt); |
| | | } |
| | | |
| | | |
| | | BEGIN_MESSAGE_MAP(CInputDialog, CDialogEx) |
| | | ON_BN_CLICKED(IDOK, &CInputDialog::OnBnClickedOk) |
| | | END_MESSAGE_MAP() |
| | | |
| | | |
| | | // CInputDialog æ¶æ¯å¤çç¨åº |
| | | |
| | | |
| | | BOOL CInputDialog::OnInitDialog() |
| | | { |
| | | CDialogEx::OnInitDialog(); |
| | | |
| | | // TODO: 卿¤æ·»å é¢å¤çåå§å |
| | | SetWindowText(m_strTitle); |
| | | m_staticPrompt.SetWindowText(m_strPrompt); |
| | | |
| | | return TRUE; // return TRUE unless you set the focus to a control |
| | | // å¼å¸¸: OCX 屿§é¡µåºè¿å FALSE |
| | | } |
| | | |
| | | |
| | | void CInputDialog::OnBnClickedOk() |
| | | { |
| | | // TODO: 卿¤æ·»å æ§ä»¶éç¥å¤çç¨åºä»£ç |
| | | m_editInput.GetWindowText(m_strInput); |
| | | if (m_strInput.IsEmpty()) { |
| | | AfxMessageBox(_T("è¾å
¥ä¸è½ä¸ºç©ºï¼")); |
| | | return; |
| | | } |
| | | |
| | | CDialogEx::OnOK(); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #pragma once |
| | | #include "afxdialogex.h" |
| | | |
| | | |
| | | // CInputDialog å¯¹è¯æ¡ |
| | | |
| | | class CInputDialog : public CDialogEx |
| | | { |
| | | DECLARE_DYNAMIC(CInputDialog) |
| | | |
| | | public: |
| | | CInputDialog(const CString& strTitle, const CString& strPrompt, CWnd* pParent = nullptr); |
| | | virtual ~CInputDialog(); |
| | | |
| | | CString GetInputText() const; // è·åè¾å
¥å
容 |
| | | |
| | | // å¯¹è¯æ¡æ°æ® |
| | | #ifdef AFX_DESIGN_TIME |
| | | enum { IDD = IDD_DIALOG_INPUT }; |
| | | #endif |
| | | |
| | | private: |
| | | CEdit m_editInput; |
| | | CStatic m_staticPrompt; |
| | | |
| | | CString m_strTitle; // å¯¹è¯æ¡æ é¢ |
| | | CString m_strPrompt; // æç¤ºææ¬ |
| | | CString m_strInput; // è¾å
¥çææ¬ |
| | | |
| | | protected: |
| | | virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV æ¯æ |
| | | |
| | | DECLARE_MESSAGE_MAP() |
| | | public: |
| | | virtual BOOL OnInitDialog(); |
| | | afx_msg void OnBnClickedOk(); |
| | | }; |
| | |
| | | |
| | | #include <set> |
| | | |
| | | const COLORREF CURR_USER_BK_COLOR = RGB(0, 255, 0); |
| | | |
| | | // CUserManagerDlg å¯¹è¯æ¡ |
| | | |
| | |
| | | if (!usersData.empty()) { |
| | | m_gridUserManager.SetRowCount(usersData.size() + 1); |
| | | |
| | | for (size_t i = 0; i < usersData.size(); i++) { |
| | | for (int 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++) { |
| | | for (int j = 0; j < usersData[i].size(); j++) { |
| | | if (usersData[i][1].empty()) { |
| | | continue; |
| | | } |
| | |
| | | } |
| | | |
| | | for (int i = 0; i < nCols; i++) { |
| | | bool ret = m_gridUserManager.SetItemBkColour(nCurrNameRow, i, RGB(0, 255, 0)); |
| | | m_gridUserManager.SetItemBkColour(nCurrNameRow, i, CURR_USER_BK_COLOR); |
| | | } |
| | | m_gridUserManager.SetItemState(nCurrNameRow, 3, GVIS_READONLY); |
| | | |
| | | m_gridUserManager.Invalidate(); |
| | | m_gridUserManager.UpdateWindow(); |
| | |
| | | |
| | | // 第4å为æéå, 第8å为è§è²æè¿°å, 仿 å°ä¸æ¥æ¾å¯¹åºæè¿° |
| | | if (nCol == 3) { |
| | | CString selectedRole = m_gridUserManager.GetItemText(nRow, nCol); |
| | | |
| | | auto it = m_mapRoleDescriptions.find(selectedRole); |
| | | if (it != m_mapRoleDescriptions.end()) { |
| | | m_gridUserManager.SetItemText(nRow, 7, it->second); |
| | | m_gridUserManager.RedrawCell(nRow, 7); |
| | | if (m_gridUserManager.GetItemBkColour(nRow, nCol) == CURR_USER_BK_COLOR) { |
| | | AfxMessageBox(_T("å½åç»å½ç¨æ·æéä¸è½ä¿®æ¹ï¼")); |
| | | } |
| | | else { |
| | | m_gridUserManager.SetItemText(nRow, 7, _T("")); |
| | | m_gridUserManager.RedrawCell(nRow, 7); |
| | | CString selectedRole = m_gridUserManager.GetItemText(nRow, nCol); |
| | | auto it = m_mapRoleDescriptions.find(selectedRole); |
| | | if (it != m_mapRoleDescriptions.end()) { |
| | | m_gridUserManager.SetItemText(nRow, 7, it->second); |
| | | m_gridUserManager.RedrawCell(nRow, 7); |
| | | } |
| | | else { |
| | | m_gridUserManager.SetItemText(nRow, 7, _T("")); |
| | | m_gridUserManager.RedrawCell(nRow, 7); |
| | | } |
| | | } |
| | | } |
| | | |
| | |
| | | std::vector<std::vector<std::string>> vecData; |
| | | std::set<std::string> usernameSet; // ç¨äºåå¨ç¨æ·åï¼æ£æ¥æ¯å¦éå¤ |
| | | |
| | | int nCurrUserRow = -1; |
| | | UserManager& userManager = UserManager::getInstance(); |
| | | for (int i = 1; i < m_gridUserManager.GetRowCount(); ++i) { |
| | | std::vector<std::string> rowData; |
| | | CString cellText = m_gridUserManager.GetItemText(i, 1); |
| | | std::string username = CT2A(cellText.GetString()); |
| | | |
| | | cellText = m_gridUserManager.GetItemText(i, 2); |
| | | std::string userpass = CT2A(cellText.GetString()); |
| | | |
| | | if (username.empty() || userpass.empty()) { |
| | | AfxMessageBox(_T("ç¨æ·ååå¯ç ä¸è½ä¸ºç©ºï¼")); |
| | | return; |
| | | } |
| | | |
| | | if (usernameSet.find(username) != usernameSet.end()) { |
| | | CString message; |
| | |
| | | AfxMessageBox(message, MB_ICONEXCLAMATION); |
| | | return; |
| | | } |
| | | |
| | | usernameSet.insert(username); |
| | | |
| | | if (nCurrUserRow == -1 && m_gridUserManager.GetItemBkColour(i, 0) == CURR_USER_BK_COLOR){ |
| | | nCurrUserRow = i; |
| | | if (username.compare(userManager.getCurrentUser()) != 0) { |
| | | userManager.setCurrentUser(username); |
| | | } |
| | | |
| | | if (userpass.compare(userManager.getCurrentPass()) != 0) { |
| | | userManager.setCurrentPass(userpass); |
| | | } |
| | | |
| | | userManager.clearSession(); |
| | | userManager.saveSession(); |
| | | } |
| | | |
| | | for (int j = 1; j < m_gridUserManager.GetColumnCount() - 1; ++j) { |
| | | CString cellText = m_gridUserManager.GetItemText(i, j); |
| | |
| | | vecData.push_back(rowData); |
| | | } |
| | | |
| | | UserManager::getInstance().setUsers(vecData); |
| | | userManager.setUsers(vecData); |
| | | CDialogEx::OnOK(); |
| | | } |