#include "stdafx.h" #include #include #include // ¾²Ì¬³ÉÔ±±äÁ¿³õʼ»¯ std::unique_ptr SystemLogManager::m_instance = nullptr; std::mutex SystemLogManager::m_mutex; // »ñÈ¡µ¥ÀýʵÀý SystemLogManager& SystemLogManager::getInstance() { if (m_instance == nullptr) { std::lock_guard lock(m_mutex); if (m_instance == nullptr) { m_instance = std::unique_ptr(new SystemLogManager()); } } return *m_instance; } // ¹¹Ô캯Êý SystemLogManager::SystemLogManager() : m_pDB(nullptr) {} // ÉèÖÃÊý¾Ý¿âÁ¬½Ó void SystemLogManager::setDatabase(std::unique_ptr& db) { std::lock_guard 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 (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 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 (" << "'" << logTypeToString(logType) << "', " << "'" << event << "', " << "'" << username << "')"; return (*m_pDB)->executeQuery(query.str()); } // »ñÈ¡ÈÕÖ¾ÄÚÈÝ std::vector> SystemLogManager::getLogs(int startPosition, int count) { std::vector> 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::vector> 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) { case LogType::Info: return _T("ÐÅÏ¢"); case LogType::Error: return _T("´íÎó"); case LogType::Operation: return _T("²Ù×÷"); default: return _T("δ֪"); } }