#include "stdafx.h" #include "TransferManager.h" #include #include #include #include #include #include // ¾²Ì¬»¥³âËø³õʼ»¯ std::mutex TransferManager::m_mutex; // »ñÈ¡ TransferManager µ¥Àý TransferManager& TransferManager::getInstance() { static TransferManager instance; return instance; } // ¹¹Ô캯Êý TransferManager::TransferManager() { m_pDB = new BL::SQLiteDatabase(); } // Îö¹¹º¯Êý TransferManager::~TransferManager() { if (m_pDB) { delete m_pDB; m_pDB = nullptr; } } // ÈÎÎñ״̬ת»»³É int ÀàÐÍ int TransferManager::statusToInt(TransferStatus status) { return static_cast(status); } // int ÀàÐÍת»»³ÉÈÎÎñ״̬ TransferStatus TransferManager::intToStatus(int value) { switch (value) { case 0: return TransferStatus::Ready; case 1: return TransferStatus::Running; case 2: return TransferStatus::Error; case 3: return TransferStatus::Abort; case 4: return TransferStatus::Completed; default: return TransferStatus::Error; } } // ÈÎÎñ״̬ת»»³É×Ö·û´® std::string TransferManager::statusToString(TransferStatus status) { switch (status) { case TransferStatus::Ready: return "Ready"; case TransferStatus::Running: return "Running"; case TransferStatus::Error: return "Error"; case TransferStatus::Abort: return "Abort"; case TransferStatus::Completed: return "Completed"; default: return "Unknown"; } } // ×Ö·û´®×ª»»³ÉÈÎÎñ״̬ TransferStatus TransferManager::stringToStatus(const std::string& str) { if (str == "Ready") return TransferStatus::Ready; if (str == "Running") return TransferStatus::Running; if (str == "Error") return TransferStatus::Error; if (str == "Abort") return TransferStatus::Abort; if (str == "Completed") return TransferStatus::Completed; return TransferStatus::Error; } // ±¾µØ±àÂëתΪ UTF-8 std::string TransferManager::ansiToUtf8(const std::string& ansiStr) { // 1. ANSI ¡ú UTF-16 int wideLen = MultiByteToWideChar(CP_ACP, 0, ansiStr.c_str(), -1, nullptr, 0); std::wstring wideStr(wideLen, 0); MultiByteToWideChar(CP_ACP, 0, ansiStr.c_str(), -1, &wideStr[0], wideLen); // 2. UTF-16 ¡ú UTF-8 int utf8Len = WideCharToMultiByte(CP_UTF8, 0, wideStr.c_str(), -1, nullptr, 0, nullptr, nullptr); std::string utf8Str(utf8Len, 0); WideCharToMultiByte(CP_UTF8, 0, wideStr.c_str(), -1, &utf8Str[0], utf8Len, nullptr, nullptr); utf8Str.pop_back(); // È¥µô×îºóµÄ '\0' return utf8Str; } // UTF-8 תΪ±¾µØ±àÂë std::string TransferManager::utf8ToAnsi(const std::string& utf8Str) { // 1. UTF-8 ¡ú UTF-16 int wideLen = MultiByteToWideChar(CP_UTF8, 0, utf8Str.c_str(), -1, NULL, 0); std::wstring wideStr(wideLen, 0); MultiByteToWideChar(CP_UTF8, 0, utf8Str.c_str(), -1, &wideStr[0], wideLen); // 2. UTF-16 ¡ú ANSI int ansiLen = WideCharToMultiByte(CP_ACP, 0, wideStr.c_str(), -1, NULL, 0, NULL, NULL); std::string ansiStr(ansiLen, 0); WideCharToMultiByte(CP_ACP, 0, wideStr.c_str(), -1, &ansiStr[0], ansiLen, NULL, NULL); ansiStr.pop_back(); // È¥µô×îºóµÄ '\0' return ansiStr; } // ³õʼ»¯°áÔ˼Ǽ±í bool TransferManager::initTransferTable() { char szPath[MAX_PATH]; GetModuleFileName(NULL, szPath, MAX_PATH); std::string exePath(szPath); std::string dbDir = exePath.substr(0, exePath.find_last_of("\\/")) + "\\DB"; if (!CreateDirectory(dbDir.c_str(), NULL) && GetLastError() != ERROR_ALREADY_EXISTS) { throw std::runtime_error("´´½¨Êý¾Ý¿âĿ¼ʧ°Ü"); } std::string dbPath = dbDir + "\\TransferManager.db"; if (!m_pDB->connect(dbPath, true)) { throw std::runtime_error("Á¬½ÓÊý¾Ý¿âʧ°Ü"); } const std::string createTableSQL = R"( CREATE TABLE IF NOT EXISTS transfers ( record_id INTEGER PRIMARY KEY AUTOINCREMENT, class_id TEXT NOT NULL, status TEXT NOT NULL, create_time TEXT, pick_time TEXT, place_time TEXT, end_time TEXT, description TEXT ); )"; return m_pDB->executeQuery(createTableSQL); } // ²åÈë²âÊÔ°áÔ˼Ǽ void TransferManager::insertTestTransferRecord() { TransferData data; data.strClassID = "Task-20240529-001"; data.strStatus = "Running"; data.strCreateTime = "2024-05-29 10:30:00"; data.strPickTime = "2024-05-29 10:31:00"; data.strPlaceTime = "2024-05-29 10:32:00"; data.strEndTime = "2024-05-29 10:33:00"; data.strDescription = "°áÔ˶¯×÷£º´Ó Port1 ȡƬ ¡ú Port2 ·ÅƬ"; int nRecordId = -1; if (TransferManager::getInstance().addTransferRecord(data, nRecordId)) { std::cout << "²åÈë³É¹¦£¬¼Ç¼ ID = " << nRecordId << std::endl; } else { std::cerr << "²åÈëʧ°Ü£¡" << std::endl; } } // ¶Ï¿ªÊý¾Ý¿âÁ¬½Ó void TransferManager::termTransferTable() { if (m_pDB) { m_pDB->disconnect(); } } // ɾ³ý°áÔ˼Ǽ±í bool TransferManager::destroyTransferTable() { if (!m_pDB) return false; const std::string dropTableSQL = "DROP TABLE IF EXISTS transfers;"; return m_pDB->executeQuery(dropTableSQL); } // ²åÈë°áÔ˼Ǽ bool TransferManager::addTransferRecord(const TransferData& data, int& outRecordId) { if (!m_pDB) { return false; } std::ostringstream oss; oss << "INSERT INTO transfers (class_id, status, create_time, pick_time, place_time, end_time, description) " << "VALUES ('" << ansiToUtf8(data.strClassID) << "', '" << ansiToUtf8(data.strStatus) << "', '" << data.strCreateTime << "', '" << data.strPickTime << "', '" << data.strPlaceTime << "', '" << data.strEndTime << "', '" << ansiToUtf8(data.strDescription) << "') RETURNING record_id;"; std::lock_guard lock(m_mutex); auto results = m_pDB->fetchResults(oss.str()); if (!results.empty() && !results[0].empty()) { try { outRecordId = std::stoi(results[0][0]); return true; } catch (const std::exception& e) { std::cerr << "½âÎö record_id ³ö´í: " << e.what() << std::endl; } } return false; } // ²éѯËùÓаáÔ˼Ǽ std::vector TransferManager::getAllTransfers() { std::vector records; if (!m_pDB) { return records; } const std::string query = R"( SELECT record_id, class_id, status, create_time, pick_time, place_time, end_time, description FROM transfers ORDER BY record_id DESC )"; auto results = m_pDB->fetchResults(query); for (const auto& row : results) { if (row.size() != 8) continue; TransferData data; data.nRecordId = std::stoi(row[0]); data.strClassID = row[1]; data.strStatus = row[2]; data.strCreateTime = row[3]; data.strPickTime = row[4]; data.strPlaceTime = row[5]; data.strEndTime = row[6]; data.strDescription = row[7]; records.push_back(data); } return records; } // ¸ù¾Ý ID ²éѯ°áÔ˼Ǽ TransferData TransferManager::getTransferById(int id) { TransferData data; if (!m_pDB) { return data; } std::ostringstream oss; oss << "SELECT record_id, class_id, status, create_time, pick_time, place_time, end_time, description " << "FROM transfers WHERE record_id = " << id; auto results = m_pDB->fetchResults(oss.str()); if (!results.empty() && results[0].size() == 8) { data.nRecordId = std::stoi(results[0][0]); data.strClassID = results[0][1]; data.strStatus = results[0][2]; data.strCreateTime = results[0][3]; data.strPickTime = results[0][4]; data.strPlaceTime = results[0][5]; data.strEndTime = results[0][6]; data.strDescription = results[0][7]; } return data; } // ¸ù¾Ýʱ¼ä·¶Î§²éѯ°áÔ˼Ǽ std::vector TransferManager::getTransfersByTimeRange(const std::string& startTime, const std::string& endTime) { std::vector records; if (!m_pDB) { return records; } std::ostringstream oss; oss << "SELECT record_id, class_id, status, create_time, pick_time, place_time, end_time, description " << "FROM transfers WHERE 1=1"; if (!startTime.empty()) { oss << " AND create_time >= '" << startTime << "'"; } if (!endTime.empty()) { oss << " AND end_time <= '" << endTime << "'"; } auto results = m_pDB->fetchResults(oss.str()); for (const auto& row : results) { if (row.size() != 8) continue; TransferData data; data.nRecordId = std::stoi(row[0]); data.strClassID = row[1]; data.strStatus = row[2]; data.strCreateTime = row[3]; data.strPickTime = row[4]; data.strPlaceTime = row[5]; data.strEndTime = row[6]; data.strDescription = row[7]; records.push_back(data); } return records; } // ²éѯָ¶¨×´Ì¬µÄ°áÔ˼Ǽ std::vector TransferManager::getTransfersByStatus(const std::string& status) { std::vector records; if (!m_pDB) { return records; } std::ostringstream oss; oss << "SELECT record_id, class_id, status, create_time, pick_time, place_time, end_time, description " << "FROM transfers WHERE status = '" << status << "' " << "ORDER BY create_time DESC"; auto results = m_pDB->fetchResults(oss.str()); for (const auto& row : results) { if (row.size() != 8) continue; TransferData data; data.nRecordId = std::stoi(row[0]); data.strClassID = row[1]; data.strStatus = row[2]; data.strCreateTime = row[3]; data.strPickTime = row[4]; data.strPlaceTime = row[5]; data.strEndTime = row[6]; data.strDescription = row[7]; records.push_back(data); } return records; } // ·ÖÒ³»ñÈ¡°áÔ˼Ǽ //std::vector TransferManager::getTransfers(int startPosition, int count) { // std::vector records; // if (!m_pDB) { // return records; // } // std::ostringstream oss; // oss << "SELECT record_id, class_id, status, create_time, pick_time, place_time, end_time, description " // << "FROM transfers ORDER BY create_time DESC LIMIT " << count << " OFFSET " << startPosition; // auto results = m_pDB->fetchResults(oss.str()); // for (const auto& row : results) { // if (row.size() != 8) continue; // TransferData data; // data.nRecordId = std::stoi(row[0]); // data.strClassID = row[1]; // data.strStatus = row[2]; // data.strCreateTime = row[3]; // data.strPickTime = row[4]; // data.strPlaceTime = row[5]; // data.strEndTime = row[6]; // data.strDescription = row[7]; // records.push_back(data); // } // return records; //} // »ñÈ¡·ûºÏÌõ¼þµÄ¼Ç¼×ÜÊý int TransferManager::getTotalTransferCount() { if (!m_pDB) { return 0; } const std::string query = "SELECT COUNT(*) FROM transfers;"; auto results = m_pDB->fetchResults(query); if (!results.empty() && !results[0].empty()) { try { return std::stoi(results[0][0]); } catch (const std::exception& e) { std::cerr << "Error parsing total count: " << e.what() << std::endl; } } return 0; } // »ñÈ¡·ûºÏÌõ¼þµÄ¼Ç¼×ÜÊý int TransferManager::getTotalTransferCount(const TransferData& filter) { if (!m_pDB) { return 0; } std::ostringstream oss; oss << "SELECT COUNT(*) FROM transfers WHERE 1=1"; // ״̬ɸѡ£¨ÍêȫƥÅ䣩 if (!filter.strStatus.empty()) { oss << " AND status = '" << filter.strStatus << "'"; } // ÃèÊö¹Ø¼ü×ÖÄ£ºýÆ¥Åä if (!filter.strDescription.empty()) { oss << " AND description LIKE '%" << filter.strDescription << "%'"; } // ʱ¼ä·¶Î§É¸Ñ¡ if (!filter.strCreateTime.empty()) { oss << " AND create_time >= '" << filter.strCreateTime << "'"; } if (!filter.strEndTime.empty()) { oss << " AND end_time <= '" << filter.strEndTime << "'"; } auto results = m_pDB->fetchResults(oss.str()); if (!results.empty() && !results[0].empty()) { try { return std::stoi(results[0][0]); } catch (const std::exception& e) { std::cerr << "Error parsing total count: " << e.what() << std::endl; } } return 0; } std::vector TransferManager::getTransfers(const TransferData& filter, int pageNum, int pageSize) { std::vector records; if (!m_pDB) { return records; } std::ostringstream oss; oss << "SELECT record_id, class_id, status, create_time, pick_time, place_time, end_time, description " << "FROM transfers WHERE 1=1"; // Ìõ¼þÆ´½Ó£¨Óë getTotalTransferCount ±£³ÖÒ»Ö£© if (!filter.strStatus.empty()) { oss << " AND status = '" << filter.strStatus << "'"; } if (!filter.strDescription.empty()) { oss << " AND description LIKE '%" << filter.strDescription << "%'"; } if (!filter.strCreateTime.empty()) { oss << " AND create_time >= '" << filter.strCreateTime << "'"; } if (!filter.strEndTime.empty()) { oss << " AND end_time <= '" << filter.strEndTime << "'"; } // ·ÖÒ³¿ØÖÆ int offset = (pageNum - 1) * pageSize; oss << " ORDER BY create_time DESC"; oss << " LIMIT " << pageSize << " OFFSET " << offset; // ²éѯ auto results = m_pDB->fetchResults(oss.str()); for (const auto& row : results) { if (row.size() != 8) continue; TransferData data; data.nRecordId = std::stoi(row[0]); data.strClassID = row[1]; data.strStatus = row[2]; data.strCreateTime = row[3]; data.strPickTime = row[4]; data.strPlaceTime = row[5]; data.strEndTime = row[6]; data.strDescription = row[7]; records.push_back(data); } return records; } // ÇåÀíÔçÓÚijһʱ¼äµÄ°áÔ˼Ǽ void TransferManager::cleanOldTransfers(int daysToKeep) { if (!m_pDB) { return; } std::ostringstream oss; oss << "DELETE FROM transfers WHERE create_time < datetime('now', '-" << daysToKeep << " days')"; m_pDB->executeQuery(oss.str()); } // ¶ÁÈ¡°áÔ˼Ǽ CSV Îļþ bool TransferManager::readTransferFile(const std::string& filename) { std::ifstream file(filename); if (!file.is_open()) { std::cerr << "ÎÞ·¨´ò¿ªÎļþ: " << filename << std::endl; return false; } std::string line; bool firstLine = true; int insertedCount = 0; while (std::getline(file, line)) { if (firstLine) { firstLine = false; continue; } std::stringstream ss(line); std::string cell; TransferData data; try { std::getline(ss, cell, ','); data.nRecordId = std::stoi(cell); std::getline(ss, data.strClassID, ','); std::getline(ss, data.strStatus, ','); std::getline(ss, data.strCreateTime, ','); std::getline(ss, data.strPickTime, ','); std::getline(ss, data.strPlaceTime, ','); std::getline(ss, data.strEndTime, ','); std::getline(ss, data.strDescription, ','); int newId = -1; if (addTransferRecord(data, newId)) { ++insertedCount; } } catch (const std::exception& e) { std::cerr << "¶ÁÈ¡´íÎóÐÐ: " << line << "£¬´íÎó: " << e.what() << std::endl; continue; } } file.close(); std::cout << "³É¹¦µ¼Èë¼Ç¼Êý: " << insertedCount << std::endl; return true; } // ±£´æ°áÔ˼Ǽµ½ CSV Îļþ bool TransferManager::saveTransferFile(const std::string& filename) { std::ofstream file(filename); if (!file.is_open()) { std::cerr << "ÎÞ·¨Ð´ÈëÎļþ: " << filename << std::endl; return false; } // дÈë±êÌâ file << "RecordID,ClassID,Status,CreateTime,PickTime,PlaceTime,EndTime,Description\n"; auto records = getAllTransfers(); for (const auto& data : records) { file << data.nRecordId << "," << data.strClassID << "," << data.strStatus << "," << data.strCreateTime << "," << data.strPickTime << "," << data.strPlaceTime << "," << data.strEndTime << "," << data.strDescription << "\n"; } file.close(); std::cout << "Òѵ¼³ö " << records.size() << " Ìõ¼Ç¼µ½: " << filename << std::endl; return true; }