From f56f083a7e59e58dd44913b11ce4e959fb0475cc Mon Sep 17 00:00:00 2001
From: LAPTOP-T815PCOQ\25526 <mr.liuyang@126.com>
Date: 星期三, 20 十一月 2024 19:16:44 +0800
Subject: [PATCH] 1. 添加运行日志界面2.运行日志基本功能已经完成
---
SourceCode/Bond/BondEq/Resource.h | 0
SourceCode/Bond/BondEq/View/ChangePasswordDlg.cpp | 4
SourceCode/Bond/BondEq/View/UserManagerDlg.h | 0
SourceCode/Bond/BondEq/BondEq.rc | 0
SourceCode/Bond/BondEq/stdafx.h | 4
SourceCode/Bond/BondEq/BondEqDlg.cpp | 44 ++-
SourceCode/Bond/x64/Debug/Config/BondEq.db | 0
SourceCode/Bond/BondEq/View/LoginDlg.cpp | 3
SourceCode/Bond/BondEq/BondEq.vcxproj | 6
SourceCode/Bond/BondEq/View/SystemLogManagerDlg.h | 48 ++++
SourceCode/Bond/BondEq/View/SystemLogManagerDlg.cpp | 266 ++++++++++++++++++++++++
SourceCode/Bond/BondEq/DBManager/UserManager.cpp | 35 +++
SourceCode/Bond/BondEq/DBManager/UserManager.h | 2
SourceCode/Bond/BondEq/View/UserManagerDlg.cpp | 25 +
SourceCode/Bond/BondEq/DBManager/SystemLogManager.h | 35 ++
SourceCode/Bond/BondEq/DBManager/SystemLogManager.cpp | 162 ++++++++++++++
16 files changed, 592 insertions(+), 42 deletions(-)
diff --git a/SourceCode/Bond/BondEq/BondEq.rc b/SourceCode/Bond/BondEq/BondEq.rc
index 28c39e3..4c7a132 100644
--- a/SourceCode/Bond/BondEq/BondEq.rc
+++ b/SourceCode/Bond/BondEq/BondEq.rc
Binary files differ
diff --git a/SourceCode/Bond/BondEq/BondEq.vcxproj b/SourceCode/Bond/BondEq/BondEq.vcxproj
index 55b39dd..926d220 100644
--- a/SourceCode/Bond/BondEq/BondEq.vcxproj
+++ b/SourceCode/Bond/BondEq/BondEq.vcxproj
@@ -244,10 +244,11 @@
<ClInclude Include="targetver.h" />
<ClInclude Include="ToolUnits.h" />
<ClInclude Include="TopToolbar.h" />
- <ClInclude Include="UserManagerDlg.h" />
<ClInclude Include="VerticalLine.h" />
<ClInclude Include="View\ChangePasswordDlg.h" />
<ClInclude Include="View\LoginDlg.h" />
+ <ClInclude Include="View\SystemLogManagerDlg.h" />
+ <ClInclude Include="View\UserManagerDlg.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="CPLC.cpp" />
@@ -305,10 +306,11 @@
</ClCompile>
<ClCompile Include="ToolUnits.cpp" />
<ClCompile Include="TopToolbar.cpp" />
- <ClCompile Include="UserManagerDlg.cpp" />
<ClCompile Include="VerticalLine.cpp" />
<ClCompile Include="View\ChangePasswordDlg.cpp" />
<ClCompile Include="View\LoginDlg.cpp" />
+ <ClCompile Include="View\SystemLogManagerDlg.cpp" />
+ <ClCompile Include="View\UserManagerDlg.cpp" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="BondEq.rc" />
diff --git a/SourceCode/Bond/BondEq/BondEqDlg.cpp b/SourceCode/Bond/BondEq/BondEqDlg.cpp
index 1a8a2ec..9668aa4 100644
--- a/SourceCode/Bond/BondEq/BondEqDlg.cpp
+++ b/SourceCode/Bond/BondEq/BondEqDlg.cpp
@@ -9,13 +9,13 @@
#include "Common.h"
#include "CBonder.h"
#include "SettingsDlg.h"
-#include "UserManager.h"
-#include "SystemLogManager.h"
#include "LoginDlg.h"
#include "ChangePasswordDlg.h"
#include "InputDialog.h"
#include "UserManagerDlg.h"
+// test
+#include "SystemLogManagerDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
@@ -184,21 +184,15 @@
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);
// 菜单
@@ -243,6 +237,7 @@
// 更新登录状态
UpdateLoginStatus();
+ logManager.log(SystemLogManager::LogType::Info, _T("BondEq启动..."));
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
@@ -368,11 +363,7 @@
KillTimer(1);
#endif
- std::string strUsername = UserManager::getInstance().getCurrentUser();
- if (strUsername.empty()) {
- strUsername = "SYSTEM";
- }
- SystemLogManager::getInstance().log(SystemLogManager::LogType::Info, _T("BondEq关闭..."), strUsername);
+ SystemLogManager::getInstance().log(SystemLogManager::LogType::Info, _T("BondEq关闭..."));
}
void CBondEqDlg::OnSize(UINT nType, int cx, int cy)
@@ -533,6 +524,7 @@
LRESULT CBondEqDlg::OnToolbarBtnClicked(WPARAM wParam, LPARAM lParam)
{
int id = (int)lParam;
+ SystemLogManager& logManager = SystemLogManager::getInstance();
if (id == IDC_BUTTON_RUN || id == IDC_BUTTON_STOP || id == IDC_BUTTON_SETTINGS)
{
CInputDialog inputDialog(_T("验证用户"), _T("请输入用户密码:"));
@@ -545,6 +537,7 @@
std::string strPass = UserManager::getInstance().getCurrentPass();
if (inputText.Compare(strPass.c_str()) != 0) {
AfxMessageBox(_T("密码错误!"));
+ logManager.log(SystemLogManager::LogType::Info, _T("验证时,密码错误!"));
return 0;
}
}
@@ -552,10 +545,12 @@
if (id == IDC_BUTTON_RUN) {
m_pTopToolbar->GetBtn(IDC_BUTTON_RUN)->EnableWindow(FALSE);
m_pTopToolbar->GetBtn(IDC_BUTTON_STOP)->EnableWindow(TRUE);
+ logManager.log(SystemLogManager::LogType::Operation, _T("运行..."));
}
else if (id == IDC_BUTTON_STOP) {
m_pTopToolbar->GetBtn(IDC_BUTTON_RUN)->EnableWindow(TRUE);
m_pTopToolbar->GetBtn(IDC_BUTTON_STOP)->EnableWindow(FALSE);
+ logManager.log(SystemLogManager::LogType::Operation, _T("停止..."));
}
else if (id == IDC_BUTTON_SETTINGS) {
CSettingsDlg dlg;
@@ -569,20 +564,28 @@
loginDlg.DoModal();
}
else if (1 == menuId) {
+ // test
+ CSystemLogManagerDlg dlg;
+ dlg.DoModal();
+
CChangePasswordDlg changePasswordDlg;
changePasswordDlg.DoModal();
}
else if (2 == menuId) {
CUserManagerDlg dlg;
- dlg.DoModal();
+ if (dlg.DoModal()!= IDOK) {
+ logManager.log(SystemLogManager::LogType::Operation, _T("用户管理的预操作被取消!"));
+ }
}
else if (3 == menuId) {
- int ret = AfxMessageBox(_T("是否切换用户?切换用户会退出当前账号!"), MB_OK | MB_ICONEXCLAMATION);
- if (ret != MB_OK) {
+ int ret = AfxMessageBox(_T("是否切换用户?切换用户会退出当前账号!"), MB_OKCANCEL | MB_ICONEXCLAMATION);
+ if (ret != IDOK) {
return 0;
}
+ logManager.log(SystemLogManager::LogType::Operation, _T("确认切换角色!"));
if (userManager.isLoggedIn()) {
+ logManager.log(SystemLogManager::LogType::Info, _T("退出登录!"));
userManager.logout();
}
@@ -592,11 +595,12 @@
else {
CString cstrMessage;
cstrMessage.Format(_T("是否退出用户 [%s]?"), userManager.getCurrentUser().c_str());
- int ret = AfxMessageBox(_T(cstrMessage), MB_OK | MB_ICONEXCLAMATION);
- if (ret != MB_OK) {
+ int ret = AfxMessageBox(_T(cstrMessage), MB_OKCANCEL | MB_ICONEXCLAMATION);
+ if (ret != IDOK) {
return 0;
}
+ logManager.log(SystemLogManager::LogType::Info, _T("退出登录!"));
userManager.logout();
}
diff --git a/SourceCode/Bond/BondEq/DBManager/SystemLogManager.cpp b/SourceCode/Bond/BondEq/DBManager/SystemLogManager.cpp
index 92a6502..d4efa64 100644
--- a/SourceCode/Bond/BondEq/DBManager/SystemLogManager.cpp
+++ b/SourceCode/Bond/BondEq/DBManager/SystemLogManager.cpp
@@ -1,5 +1,4 @@
#include "stdafx.h"
-#include "SystemLogManager.h"
#include <iostream>
#include <sstream>
#include <stdexcept>
@@ -41,18 +40,49 @@
log_type TEXT NOT NULL,
event TEXT NOT NULL,
username TEXT NOT NULL,
- timestamp DATETIME DEFAULT CURRENT_TIMESTAMP
+ timestamp DATETIME DEFAULT (datetime('now', 'localtime'))
)
)";
return (*m_pDB)->executeQuery(createTableQuery);
}
// 添加日志
+bool SystemLogManager::log(LogType logType, const std::string& event) {
+ if (!m_pDB || !(*m_pDB)) {
+ std::cerr << "Database connection is not set." << std::endl;
+ return false;
+ }
+
+ // 清理旧日志
+ cleanOldLogs(30);
+
+ std::string strUsername = UserManager::getInstance().getCurrentUser();
+ if (strUsername.empty()) {
+ strUsername = "SYSTEM";
+ }
+
+ std::ostringstream query;
+ query << "INSERT INTO system_logs (log_type, event, username) VALUES ("
+ << "'" << logTypeToString(logType) << "', "
+ << "'" << event << "', "
+ << "'" << strUsername << "')";
+ return (*m_pDB)->executeQuery(query.str());
+}
+
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::vector<std::string> vecUserInfo = UserManager::getInstance().getUserInfo(username);
+ if (username.empty() || vecUserInfo.empty()) {
+ std::cerr << "Username empty." << std::endl;
+ return false;
+ }
+
+ // 清理旧日志
+ cleanOldLogs(30);
std::ostringstream query;
query << "INSERT INTO system_logs (log_type, event, username) VALUES ("
@@ -90,6 +120,132 @@
return logs;
}
+// 获取筛选后的日志数据
+std::vector<std::vector<std::string>> SystemLogManager::getFilteredLogs(
+ const std::string& logType,
+ const std::string& username,
+ const std::string& description,
+ const std::string& startTime,
+ const std::string& endTime,
+ int pageNumber,
+ int pageSize)
+{
+ if (!m_pDB || !(*m_pDB)) {
+ throw std::runtime_error("Database connection is not set.");
+ }
+
+ // 构建基础 SQL 查询
+ std::ostringstream query;
+ query << "SELECT id, log_type, event, username, timestamp FROM system_logs WHERE 1=1";
+
+ // 按日志类型筛选
+ if (logType != "ALL") {
+ query << " AND log_type = '" << logType << "'";
+ }
+
+ // 按用户名筛选
+ if (username != "ALL") {
+ query << " AND username = '" << username << "'";
+ }
+
+ // 按描述关键词筛选
+ if (!description.empty()) {
+ query << " AND event LIKE '%" << description << "%'";
+ }
+
+ // 按时间范围筛选
+ if (!startTime.empty()) {
+ query << " AND timestamp >= '" << startTime << "'";
+ }
+ if (!endTime.empty()) {
+ query << " AND timestamp <= '" << endTime << "'";
+ }
+
+ // 分页逻辑:设置 LIMIT 和 OFFSET
+ int offset = (pageNumber - 1) * pageSize;
+ query << " ORDER BY timestamp DESC"; // 按时间降序排列
+ query << " LIMIT " << pageSize << " OFFSET " << offset;
+
+ // 执行查询
+ return (*m_pDB)->fetchResults(query.str());
+}
+
+// 获取符合条件的日志总数
+int SystemLogManager::getTotalLogCount(
+ const std::string& logType,
+ const std::string& username,
+ const std::string& description,
+ const std::string& startTime,
+ const std::string& endTime)
+{
+ // 检查数据库连接是否可用
+ if (!m_pDB || !(*m_pDB)) {
+ throw std::runtime_error("Database connection is not set.");
+ }
+
+ // 构建基础 SQL 查询
+ std::ostringstream query;
+ query << "SELECT COUNT(*) FROM system_logs WHERE 1=1";
+
+ // 按日志类型筛选
+ if (logType != "ALL") {
+ query << " AND log_type = '" << logType << "'";
+ }
+
+ // 按用户名筛选
+ if (username != "ALL") {
+ query << " AND username = '" << username << "'";
+ }
+
+ // 按描述关键词筛选
+ if (!description.empty()) {
+ query << " AND event LIKE '%" << description << "%'";
+ }
+
+ // 按时间范围筛选
+ if (!startTime.empty()) {
+ query << " AND timestamp >= '" << startTime << "'";
+ }
+ if (!endTime.empty()) {
+ query << " AND timestamp <= '" << endTime << "'";
+ }
+
+ // 执行查询
+ auto results = (*m_pDB)->fetchResults(query.str());
+
+ // 返回记录总数
+ if (!results.empty() && !results[0].empty()) {
+ return std::stoi(results[0][0]); // 第一行第一列是计数值
+ }
+
+ return 0; // 如果没有结果,返回 0
+}
+
+void SystemLogManager::cleanOldLogs(int daysToKeep)
+{
+ if (!m_pDB || !(*m_pDB)) {
+ throw std::runtime_error("Database connection is not set.");
+ }
+
+ // 获取当前日期并计算截断日期
+ time_t now = time(nullptr);
+ tm timeInfo;
+ localtime_s(&timeInfo, &now);
+ timeInfo.tm_mday -= daysToKeep; // 计算指定天数之前的日期
+ mktime(&timeInfo); // 规范化日期
+
+ char buffer[20];
+ strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", &timeInfo);
+ std::string cutoffDate(buffer);
+
+ std::ostringstream query;
+ query << "DELETE FROM system_logs WHERE timestamp < '" << cutoffDate << "'";
+ bool ret = (*m_pDB)->executeQuery(query.str());
+ if (!ret) {
+ throw std::runtime_error("System Log cleanup operation failed.");
+ }
+}
+
// 转换日志类型为字符串
std::string SystemLogManager::logTypeToString(LogType logType) const {
switch (logType) {
@@ -102,4 +258,4 @@
default:
return _T("未知");
}
-}
+}
\ No newline at end of file
diff --git a/SourceCode/Bond/BondEq/DBManager/SystemLogManager.h b/SourceCode/Bond/BondEq/DBManager/SystemLogManager.h
index 290e046..075fdec 100644
--- a/SourceCode/Bond/BondEq/DBManager/SystemLogManager.h
+++ b/SourceCode/Bond/BondEq/DBManager/SystemLogManager.h
@@ -10,9 +10,10 @@
class SystemLogManager {
public:
enum class LogType {
- Info, // 信息日志
- Error, // 错误日志
- Operation // 操作日志
+ Info,
+ Error,
+ Operation,
+ Unknown
};
// 获取单例实例
@@ -21,14 +22,36 @@
// 设置数据库连接
void setDatabase(std::unique_ptr<BL::Database>& db);
+ // 初始化日志表
+ bool initializeLogTable();
+
// 添加日志
- bool log(LogType logType, const std::string& event, const std::string& username = "SYSTEM");
+ bool log(LogType logType, const std::string& event);
+ bool log(LogType logType, const std::string& event, const std::string& username);
// 获取日志
std::vector<std::vector<std::string>> SystemLogManager::getLogs(int startPosition = -1, int count = -1);
- // 初始化日志表
- bool initializeLogTable();
+ // 获取筛选后的日志数据
+ std::vector<std::vector<std::string>> getFilteredLogs(
+ const std::string& logType,
+ const std::string& username,
+ const std::string& description,
+ const std::string& startTime,
+ const std::string& endTime,
+ int pageNumber,
+ int pageSize);
+
+ // 获取符合条件的日志总数
+ int getTotalLogCount(
+ const std::string& logType,
+ const std::string& username,
+ const std::string& description,
+ const std::string& startTime,
+ const std::string& endTime);
+
+ // 清理超过指定天数的旧日志
+ void cleanOldLogs(int daysToKeep = 30);
private:
// 构造函数(私有化)
diff --git a/SourceCode/Bond/BondEq/DBManager/UserManager.cpp b/SourceCode/Bond/BondEq/DBManager/UserManager.cpp
index bd3f4df..db9f1e5 100644
--- a/SourceCode/Bond/BondEq/DBManager/UserManager.cpp
+++ b/SourceCode/Bond/BondEq/DBManager/UserManager.cpp
@@ -48,7 +48,7 @@
role INT NOT NULL,
session_timeout INT DEFAULT 30,
session_expiration INT DEFAULT 72,
- last_login TIMESTAMP
+ last_login DATETIME DEFAULT (datetime('now', 'localtime'))
)
)";
m_pDB->executeQuery(createTableQuery);
@@ -411,6 +411,39 @@
return success;
}
+// 获取所有用户名称
+std::vector<std::string> UserManager::getUsernames() {
+ std::vector<std::string> usernames;
+ std::string query = "SELECT username FROM users";
+ auto results = m_pDB->fetchResults(query);
+
+ for (const auto& row : results) {
+ if (!row.empty()) {
+ usernames.push_back(row[0]); // 获取用户名列的值
+ }
+ }
+
+ return usernames;
+}
+
+// 获取指定用户名的用户信息
+std::vector<std::string> UserManager::getUserInfo(const std::string& username)
+{
+ // 构建查询语句
+ std::ostringstream query;
+ query << "SELECT username, password, role, session_timeout, session_expiration, last_login "
+ << "FROM users WHERE username = '" << username << "'";
+
+ // 执行查询并获取结果
+ auto results = m_pDB->fetchResults(query.str());
+ if (results.empty()) {
+ return {};
+ }
+
+ // 返回查询到的第一行数据
+ return results[0];
+}
+
// 更新最后活动时间,用于无操作超时检测
void UserManager::updateActivityTime() {
m_tpLastActivity = std::chrono::system_clock::now();
diff --git a/SourceCode/Bond/BondEq/DBManager/UserManager.h b/SourceCode/Bond/BondEq/DBManager/UserManager.h
index 44bb5cc..590b2e1 100644
--- a/SourceCode/Bond/BondEq/DBManager/UserManager.h
+++ b/SourceCode/Bond/BondEq/DBManager/UserManager.h
@@ -41,6 +41,8 @@
bool changeUserRole(const std::string& username, UserRole newRole);
bool changeUserSessionTimeout(const std::string& username, int newTimeoutMinutes);
bool changeUserSessionExpiration(const std::string& username, int newExpirationHours);
+ std::vector<std::string> getUsernames();
+ std::vector<std::string> getUserInfo(const std::string& username);
// 会话文件操作
bool loadSession(); // 从会话文件加载会话信息
diff --git a/SourceCode/Bond/BondEq/Resource.h b/SourceCode/Bond/BondEq/Resource.h
index bd8fa27..4f930a8 100644
--- a/SourceCode/Bond/BondEq/Resource.h
+++ b/SourceCode/Bond/BondEq/Resource.h
Binary files differ
diff --git a/SourceCode/Bond/BondEq/View/ChangePasswordDlg.cpp b/SourceCode/Bond/BondEq/View/ChangePasswordDlg.cpp
index 7fe322e..3ac5196 100644
--- a/SourceCode/Bond/BondEq/View/ChangePasswordDlg.cpp
+++ b/SourceCode/Bond/BondEq/View/ChangePasswordDlg.cpp
@@ -5,7 +5,6 @@
#include "BondEq.h"
#include "afxdialogex.h"
#include "ChangePasswordDlg.h"
-#include "UserManager.h"
// CChangePasswordDlg 瀵硅瘽妗�
@@ -82,6 +81,7 @@
return;
}
+ SystemLogManager& logManager = SystemLogManager::getInstance();
if (newPassword.Compare(currentPassword) == 0) {
EndDialog(IDCANCEL);
return;
@@ -101,12 +101,14 @@
if (userManager.isLoggedIn() && strCurrentPassword.compare(userManager.getCurrentPass()) == 0) {
if (changeUserPassword(userManager, strUsername, strNewPassword)) {
EndDialog(IDOK);
+ logManager.log(SystemLogManager::LogType::Info, "淇敼瀵嗙爜鎴愬姛锛�", strUsername);
}
}
else {
if (userManager.login(strUsername, strCurrentPassword)) {
if (changeUserPassword(userManager, strUsername, strNewPassword)) {
EndDialog(IDOK);
+ logManager.log(SystemLogManager::LogType::Info, "淇敼瀵嗙爜鎴愬姛锛�", strUsername);
}
else {
userManager.logout();
diff --git a/SourceCode/Bond/BondEq/View/LoginDlg.cpp b/SourceCode/Bond/BondEq/View/LoginDlg.cpp
index 9dae4f8..b78c28d 100644
--- a/SourceCode/Bond/BondEq/View/LoginDlg.cpp
+++ b/SourceCode/Bond/BondEq/View/LoginDlg.cpp
@@ -5,7 +5,6 @@
#include "BondEq.h"
#include "afxdialogex.h"
#include "LoginDlg.h"
-#include "UserManager.h"
#include "ChangePasswordDlg.h"
@@ -98,12 +97,14 @@
#endif
UserManager& userManager = UserManager::getInstance();
+ SystemLogManager& logManager = SystemLogManager::getInstance();
if (!userManager.login(strUsername, strPassword, (m_checkRememberPassword.GetCheck() == BST_CHECKED))) {
AfxMessageBox(_T("鐧诲綍澶辫触銆�"));
return;
}
EndDialog(IDOK);
+ logManager.log(SystemLogManager::LogType::Info, _T("鐧诲綍鎴愬姛..."));
}
void CLoginDlg::OnBnClickedChangePassword()
diff --git a/SourceCode/Bond/BondEq/View/SystemLogManagerDlg.cpp b/SourceCode/Bond/BondEq/View/SystemLogManagerDlg.cpp
new file mode 100644
index 0000000..40e4492
--- /dev/null
+++ b/SourceCode/Bond/BondEq/View/SystemLogManagerDlg.cpp
@@ -0,0 +1,266 @@
+锘�// SystemLogManagerDlg.cpp: 瀹炵幇鏂囦欢
+//
+
+#include "stdafx.h"
+#include "BondEq.h"
+#include "afxdialogex.h"
+#include "SystemLogManagerDlg.h"
+#include "UserManager.h"
+#include "SystemLogManager.h"
+
+
+// CSystemLogManagerDlg 瀵硅瘽妗�
+
+IMPLEMENT_DYNAMIC(CSystemLogManagerDlg, CDialogEx)
+
+CSystemLogManagerDlg::CSystemLogManagerDlg(CWnd* pParent /*=nullptr*/)
+ : CDialogEx(IDD_DIALOG_SYSTEM_LOG_MANAGER, pParent)
+{
+
+}
+
+CSystemLogManagerDlg::~CSystemLogManagerDlg()
+{
+}
+
+void CSystemLogManagerDlg::DoDataExchange(CDataExchange* pDX)
+{
+ CDialogEx::DoDataExchange(pDX);
+ DDX_Control(pDX, IDC_COMBO_TYPE, m_comboType);
+ DDX_Control(pDX, IDC_COMBO_USER, m_comboUser);
+ DDX_Control(pDX, IDC_DATETIMEPICKER_START, m_dateTimeStart);
+ DDX_Control(pDX, IDC_DATETIMEPICKER_END, m_dateTimeEnd);
+ DDX_Control(pDX, IDC_EDIT_DESCRIPTION, m_editDescription);
+ DDX_Control(pDX, IDC_CUSTOM_LIST_LOGS, m_listLogs);
+ DDX_Control(pDX, IDC_STATIC_PAGE_NUMBER, m_staticPageNum);
+}
+
+void CSystemLogManagerDlg::InitSystemLogManager()
+{
+ if (m_listLogs.GetSafeHwnd() == NULL)
+ return;
+
+ int nRows = 21; // 鍖呮嫭琛ㄥご锛�1 琛岋級鍜屾暟鎹紙20 琛岋級
+ int nCols = 5;
+
+ int nFixRows = 1;
+ int nFixCols = 0;
+ int nRowIdx = 0;
+ int nColIdx = 0;
+
+ m_listLogs.DeleteAllItems();
+ m_listLogs.SetVirtualMode(FALSE);
+ m_listLogs.GetDefaultCell(TRUE, FALSE)->SetBackClr(g_nGridFixCellColor); // 璁剧疆鍥哄畾琛岃儗鏅壊
+ m_listLogs.GetDefaultCell(FALSE, TRUE)->SetBackClr(g_nGridFixCellColor); // 璁剧疆鍥哄畾鍒楄儗鏅壊
+ m_listLogs.GetDefaultCell(FALSE, FALSE)->SetBackClr(g_nGridCellColor); // 璁剧疆鍗曞厓鏍艰儗鏅壊
+ m_listLogs.SetFixedTextColor(g_nGridFixFontColor); // 璁剧疆鍥哄畾琛屽垪瀛椾綋棰滆壊
+
+ m_listLogs.SetRowCount(nRows);
+ m_listLogs.SetColumnCount(nCols);
+ m_listLogs.SetFixedRowCount(nFixRows);
+ m_listLogs.SetFixedColumnCount(nFixCols);
+
+ // Col
+ m_listLogs.SetColumnWidth(nColIdx, 20);
+ m_listLogs.SetItemText(nRowIdx, nColIdx++, _T("No."));
+ m_listLogs.SetColumnWidth(nColIdx, 70);
+ m_listLogs.SetItemText(nRowIdx, nColIdx++, _T("绫诲瀷"));
+ m_listLogs.SetColumnWidth(nColIdx, 150);
+ m_listLogs.SetItemText(nRowIdx, nColIdx++, _T("浜嬩欢"));
+ m_listLogs.SetColumnWidth(nColIdx, 70);
+ m_listLogs.SetItemText(nRowIdx, nColIdx++, _T("鐢ㄦ埛"));
+ m_listLogs.SetColumnWidth(nColIdx, 70);
+ m_listLogs.SetItemText(nRowIdx, nColIdx++, _T("鏃堕棿"));
+
+ // 鍒涘缓 20 琛岀┖鐧芥暟鎹
+ for (int i = 1; i < nRows; ++i) {
+ for (int j = 0; j < nCols; ++j) {
+ m_listLogs.SetItemText(i, j, _T("")); // 鍒濆鍖栦负绌哄瓧绗︿覆
+ }
+ }
+
+ m_listLogs.SetFixedRowSelection(FALSE);
+ m_listLogs.SetFixedColumnSelection(FALSE);
+ m_listLogs.SetEditable(FALSE);
+ m_listLogs.SetRowResize(FALSE);
+ m_listLogs.SetColumnResize(TRUE);
+ m_listLogs.ExpandColumnsToFit(TRUE);
+ m_listLogs.SetListMode(TRUE); // 鍚敤鍒楄〃妯″紡
+ m_listLogs.EnableSelection(TRUE); // 鍚敤閫夋嫨
+ m_listLogs.SetSingleRowSelection(TRUE); // 鑷姩鏁磋楂樹寒锛堥檺鍒朵负鍗曡閫夋嫨锛�
+ m_listLogs.ExpandLastColumn(); // 鏈�鍚庝竴鍒楀~鍏呯綉鏍�
+
+ try {
+ FillSystemLogManager();
+ }
+ catch (const std::exception& ex) {
+ CString errorMsg;
+ errorMsg.Format(_T("鍒濆鍖栬繍琛屾棩蹇楀け璐ワ細%s"), CString(ex.what()));
+ AfxMessageBox(errorMsg, MB_ICONERROR);
+ }
+}
+
+void CSystemLogManagerDlg::FillSystemLogManager()
+{
+ // 鑾峰彇绛涢�夋潯浠�
+ CString selectedType, selectedUser, description;
+ m_comboType.GetLBText(m_comboType.GetCurSel(), selectedType);
+ m_comboUser.GetLBText(m_comboUser.GetCurSel(), selectedUser);
+ m_editDescription.GetWindowText(description);
+
+ COleDateTime startTime, endTime;
+ m_dateTimeStart.GetTime(startTime);
+ m_dateTimeEnd.GetTime(endTime);
+ CString strStartTime = startTime.Format(_T("%Y-%m-%d %H:%M:%S"));
+ CString strEndTime = endTime.Format(_T("%Y-%m-%d %H:%M:%S"));
+
+ std::string type = CT2A(selectedType);
+ std::string user = CT2A(selectedUser);
+ std::string desc = CT2A(description);
+ std::string start = CT2A(strStartTime);
+ std::string end = CT2A(strEndTime);
+
+ // 鑾峰彇鏃ュ織绠$悊瀹炰緥
+ SystemLogManager& logManager = SystemLogManager::getInstance();
+
+ int pageSize = 20; // 姣忛〉鏄剧ず 20 鏉¤褰�
+ int totalRecords = logManager.getTotalLogCount(type, user, desc, start, end);
+ m_nTotalPages = (totalRecords + pageSize - 1) / pageSize;
+ auto logs = logManager.getFilteredLogs(type, user, desc, start, end, m_nCurrentPage, pageSize);
+
+ // 鏇存柊琛ㄦ牸鏁版嵁
+ int rowIdx = 1;
+ for (const auto& log : logs) {
+ m_listLogs.SetItemText(rowIdx, 0, CString(std::to_string(rowIdx).c_str())); // 搴忓彿
+ m_listLogs.SetItemText(rowIdx, 1, CString(log[1].c_str())); // 绫诲瀷
+ m_listLogs.SetItemText(rowIdx, 2, CString(log[2].c_str())); // 浜嬩欢
+ m_listLogs.SetItemText(rowIdx, 3, CString(log[3].c_str())); // 鐢ㄦ埛
+ m_listLogs.SetItemText(rowIdx, 4, CString(log[4].c_str())); // 鏃堕棿
+ ++rowIdx;
+ }
+
+ // 娓呯┖澶氫綑琛�
+ for (; rowIdx <= 20; ++rowIdx) {
+ m_listLogs.SetItemText(rowIdx, 0, CString(std::to_string(rowIdx).c_str())); // 搴忓彿鍒�
+ for (int colIdx = 1; colIdx < m_listLogs.GetColumnCount(); ++colIdx) {
+ m_listLogs.SetItemText(rowIdx, colIdx, _T(""));
+ }
+ }
+
+ m_listLogs.Invalidate();
+ m_listLogs.UpdateWindow();
+ m_listLogs.ExpandColumnsToFit(FALSE);
+ m_listLogs.ExpandLastColumn();
+ UpdatePageInfo();
+}
+
+void CSystemLogManagerDlg::UpdatePageInfo()
+{
+ // 鏍煎紡鍖栭〉鐮佷俊鎭负 "褰撳墠椤�/鎬婚〉鏁�"
+ CString pageInfo;
+ pageInfo.Format(_T("%d/%d 椤�"), m_nCurrentPage, m_nTotalPages);
+ m_staticPageNum.SetWindowText(pageInfo);
+}
+
+
+BEGIN_MESSAGE_MAP(CSystemLogManagerDlg, CDialogEx)
+ ON_BN_CLICKED(IDC_BUTTON_SEARCH, &CSystemLogManagerDlg::OnBnClickedButtonSearch)
+ ON_BN_CLICKED(IDC_BUTTON_PREV_PAGE, &CSystemLogManagerDlg::OnBnClickedButtonPrevPage)
+ ON_BN_CLICKED(IDC_BUTTON_NEXT_PAGE, &CSystemLogManagerDlg::OnBnClickedButtonNextPage)
+END_MESSAGE_MAP()
+
+
+// CSystemLogManagerDlg 娑堟伅澶勭悊绋嬪簭
+
+
+BOOL CSystemLogManagerDlg::OnInitDialog()
+{
+ CDialogEx::OnInitDialog();
+
+ // TODO: 鍦ㄦ娣诲姞棰濆鐨勫垵濮嬪寲
+ m_nCurrentPage = 1; // 浠庣涓�椤靛紑濮�
+ m_nTotalPages = 1; // 榛樿鎬婚〉鏁颁负 1
+
+ m_comboType.AddString(_T("ALL"));
+ m_comboType.AddString(_T("淇℃伅"));
+ m_comboType.AddString(_T("鎿嶄綔"));
+ m_comboType.AddString(_T("閿欒"));
+ m_comboType.AddString(_T("鏈煡"));
+ m_comboType.SetCurSel(0);
+
+ m_comboUser.AddString(_T("ALL"));
+ m_comboUser.AddString(_T("SYSTEM"));
+ auto usernames = UserManager::getInstance().getUsernames();
+ for (const auto& username : usernames) {
+ CString cstrUsername(username.c_str());
+ m_comboUser.AddString(cstrUsername);
+ }
+ m_comboUser.SetCurSel(0);
+
+ // 璁剧疆涓� 30 澶╁墠
+ COleDateTime currentTime = COleDateTime::GetCurrentTime();
+ COleDateTime defaultStartTime = currentTime - COleDateTimeSpan(30, 0, 0, 0);
+ m_dateTimeStart.SetTime(defaultStartTime);
+
+ InitSystemLogManager();
+
+ return TRUE; // return TRUE unless you set the focus to a control
+ // 寮傚父: OCX 灞炴�ч〉搴旇繑鍥� FALSE
+}
+
+
+
+void CSystemLogManagerDlg::OnBnClickedButtonSearch()
+{
+ // TODO: 鍦ㄦ娣诲姞鎺т欢閫氱煡澶勭悊绋嬪簭浠g爜
+ try {
+ m_nCurrentPage = 1;
+ FillSystemLogManager();
+ }
+ catch (const std::exception& ex) {
+ CString errorMsg;
+ errorMsg.Format(_T("鎼滅储澶辫触锛�%s"), CString(ex.what()));
+ AfxMessageBox(errorMsg, MB_ICONERROR);
+ }
+}
+
+
+void CSystemLogManagerDlg::OnBnClickedButtonPrevPage()
+{
+ // TODO: 鍦ㄦ娣诲姞鎺т欢閫氱煡澶勭悊绋嬪簭浠g爜
+ try {
+ if (m_nCurrentPage > 1) {
+ m_nCurrentPage--;
+ FillSystemLogManager();
+ }
+ else {
+ AfxMessageBox(_T("宸茬粡鏄涓�椤碉紒"));
+ }
+ }
+ catch (const std::exception& ex) {
+ CString errorMsg;
+ errorMsg.Format(_T("鍒囨崲鍒颁笂涓�椤靛け璐ワ細%s"), CString(ex.what()));
+ AfxMessageBox(errorMsg, MB_ICONERROR);
+ }
+}
+
+
+void CSystemLogManagerDlg::OnBnClickedButtonNextPage()
+{
+ // TODO: 鍦ㄦ娣诲姞鎺т欢閫氱煡澶勭悊绋嬪簭浠g爜
+ try {
+ if (m_nCurrentPage < m_nTotalPages) {
+ m_nCurrentPage++;
+ FillSystemLogManager();
+ }
+ else {
+ AfxMessageBox(_T("宸茬粡鏄渶鍚庝竴椤碉紒"));
+ }
+ }
+ catch (const std::exception& ex) {
+ CString errorMsg;
+ errorMsg.Format(_T("鍒囨崲鍒颁笅涓�椤靛け璐ワ細%s"), CString(ex.what()));
+ AfxMessageBox(errorMsg, MB_ICONERROR);
+ }
+}
+
diff --git a/SourceCode/Bond/BondEq/View/SystemLogManagerDlg.h b/SourceCode/Bond/BondEq/View/SystemLogManagerDlg.h
new file mode 100644
index 0000000..c7a0601
--- /dev/null
+++ b/SourceCode/Bond/BondEq/View/SystemLogManagerDlg.h
@@ -0,0 +1,48 @@
+锘�#pragma once
+#include "afxdialogex.h"
+#include "GridCtrl.h"
+
+
+// CSystemLogManagerDlg 瀵硅瘽妗�
+
+class CSystemLogManagerDlg : public CDialogEx
+{
+ DECLARE_DYNAMIC(CSystemLogManagerDlg)
+
+public:
+ CSystemLogManagerDlg(CWnd* pParent = nullptr); // 鏍囧噯鏋勯�犲嚱鏁�
+ virtual ~CSystemLogManagerDlg();
+
+// 瀵硅瘽妗嗘暟鎹�
+#ifdef AFX_DESIGN_TIME
+ enum { IDD = IDD_DIALOG_SYSTEM_LOG_MANAGER };
+#endif
+
+private:
+ void InitSystemLogManager();
+ void FillSystemLogManager();
+ void UpdatePageInfo();
+
+private:
+ int m_nCurrentPage; // 褰撳墠椤电爜
+ int m_nTotalPages; // 鎬婚〉鏁�
+
+private:
+ CComboBox m_comboType;
+ CComboBox m_comboUser;
+ CDateTimeCtrl m_dateTimeStart;
+ CDateTimeCtrl m_dateTimeEnd;
+ CEdit m_editDescription;
+ CGridCtrl m_listLogs;
+ CStatic m_staticPageNum;
+
+protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 鏀寔
+
+ DECLARE_MESSAGE_MAP()
+public:
+ virtual BOOL OnInitDialog();
+ afx_msg void OnBnClickedButtonSearch();
+ afx_msg void OnBnClickedButtonPrevPage();
+ afx_msg void OnBnClickedButtonNextPage();
+};
diff --git a/SourceCode/Bond/BondEq/UserManagerDlg.cpp b/SourceCode/Bond/BondEq/View/UserManagerDlg.cpp
similarity index 95%
rename from SourceCode/Bond/BondEq/UserManagerDlg.cpp
rename to SourceCode/Bond/BondEq/View/UserManagerDlg.cpp
index f58d1e6..512eb5e 100644
--- a/SourceCode/Bond/BondEq/UserManagerDlg.cpp
+++ b/SourceCode/Bond/BondEq/View/UserManagerDlg.cpp
@@ -6,7 +6,6 @@
#include "afxdialogex.h"
#include "UserManagerDlg.h"
#include "InputDialog.h"
-#include "UserManager.h"
#include "NewCellTypes/GridCellCombo.h"
#include "NewCellTypes/GridCellNumeric.h"
@@ -202,12 +201,12 @@
CString inputText = inputDialog.GetInputText();
if (inputText.IsEmpty()) {
- AfxMessageBox(_T("鐢ㄦ埛鍚嶄笉鑳戒负绌猴紒"), MB_OK | MB_ICONEXCLAMATION);
+ AfxMessageBox(_T("鐢ㄦ埛鍚嶄笉鑳戒负绌猴紒"));
return;
}
if (IsUsernameDuplicate(inputText)) {
- AfxMessageBox(_T("鐢ㄦ埛鍚嶉噸澶嶏紒"), MB_OK | MB_ICONEXCLAMATION);
+ AfxMessageBox(_T("鐢ㄦ埛鍚嶉噸澶嶏紒"));
return;
}
@@ -259,6 +258,11 @@
pGridCtrl->ExpandLastColumn();
pGridCtrl->Invalidate();
pGridCtrl->UpdateWindow();
+
+ CString cstrMessage;
+ cstrMessage.Format(_T("棰勬坊鍔犵敤鎴� [%s]锛�"), inputText);
+ std::string strMessage = CT2A(cstrMessage);
+ SystemLogManager::getInstance().log(SystemLogManager::LogType::Operation, strMessage);
}
void CUserManagerDlg::DeleteSelectedRow(CGridCtrl* pGridCtrl)
@@ -286,7 +290,7 @@
if (selectedUser == currentUser) {
CString message;
message.Format(_T("鐢ㄦ埛 [%s] 鏄綋鍓嶇櫥褰曠敤鎴凤紝涓嶈兘鍒犻櫎锛�"), currentUser);
- AfxMessageBox(message, MB_OK | MB_ICONEXCLAMATION);
+ AfxMessageBox(message);
return;
}
@@ -294,7 +298,7 @@
}
if (rowsToDelete.empty()) {
- AfxMessageBox(_T("璇峰厛閫夋嫨瑕佸垹闄ょ殑琛岋紒"), MB_OK | MB_ICONINFORMATION);
+ AfxMessageBox(_T("璇峰厛閫夋嫨瑕佸垹闄ょ殑琛岋紒"));
return;
}
@@ -302,6 +306,11 @@
if (rowsToDelete.size() == 1) {
CString selectedUser = pGridCtrl->GetItemText(rowsToDelete[0], 1);
message.Format(_T("纭畾瑕佸垹闄ら�変腑鐢ㄦ埛 [%s] 鍚楋紵"), selectedUser);
+
+ CString cstrMessage;
+ cstrMessage.Format(_T("棰勫垹闄ょ敤鎴� [%s]锛�"), selectedUser);
+ std::string strMessage = CT2A(cstrMessage);
+ SystemLogManager::getInstance().log(SystemLogManager::LogType::Operation, strMessage);
}
else {
message.Format(_T("纭畾瑕佸垹闄ら�変腑鐨� %d 涓敤鎴峰悧锛�"), rowsToDelete.size());
@@ -319,7 +328,7 @@
}
}
else {
- AfxMessageBox(_T("璇峰厛閫夋嫨瑕佸垹闄ょ殑鐢ㄦ埛锛�"), MB_OK | MB_ICONINFORMATION);
+ AfxMessageBox(_T("璇峰厛閫夋嫨瑕佸垹闄ょ殑鐢ㄦ埛锛�"));
}
}
@@ -498,14 +507,14 @@
CCellRange selectedRange = m_gridUserManager.GetSelectedCellRange();
if (!selectedRange.IsValid()) {
- AfxMessageBox(_T("璇峰厛閫夋嫨瑕佹彃鍏ョ殑浣嶇疆锛�"), MB_OK | MB_ICONINFORMATION);
+ AfxMessageBox(_T("璇峰厛閫夋嫨瑕佹彃鍏ョ殑浣嶇疆锛�"));
return;
}
int minRow = selectedRange.GetMinRow();
int maxRow = selectedRange.GetMaxRow();
if (minRow < 1) {
- AfxMessageBox(_T("璇烽�夋嫨鏈夋晥鐨勮锛�"), MB_OK | MB_ICONEXCLAMATION);
+ AfxMessageBox(_T("璇烽�夋嫨鏈夋晥鐨勮锛�"));
return;
}
diff --git a/SourceCode/Bond/BondEq/UserManagerDlg.h b/SourceCode/Bond/BondEq/View/UserManagerDlg.h
similarity index 100%
rename from SourceCode/Bond/BondEq/UserManagerDlg.h
rename to SourceCode/Bond/BondEq/View/UserManagerDlg.h
diff --git a/SourceCode/Bond/BondEq/stdafx.h b/SourceCode/Bond/BondEq/stdafx.h
index cf4ecaf..c82164e 100644
--- a/SourceCode/Bond/BondEq/stdafx.h
+++ b/SourceCode/Bond/BondEq/stdafx.h
@@ -47,6 +47,10 @@
#include "..\DatabaseSDK\include\MySQLDatabase.h"
#include "..\DatabaseSDK\include\SQLiteDatabase.h"
+// 单例模式的数据库管理类
+#include "UserManager.h"
+#include "SystemLogManager.h"
+
// 控件样式
static UINT g_nGridFixCellColor = RGB(144, 200, 246);
static UINT g_nGridFixFontColor = RGB(0, 0, 0);
diff --git a/SourceCode/Bond/x64/Debug/Config/BondEq.db b/SourceCode/Bond/x64/Debug/Config/BondEq.db
index 4e066d3..3ce9c51 100644
--- a/SourceCode/Bond/x64/Debug/Config/BondEq.db
+++ b/SourceCode/Bond/x64/Debug/Config/BondEq.db
Binary files differ
--
Gitblit v1.9.3