LAPTOP-SNT8I5JK\Boounion
2025-09-17 62bec5118f5e5fe750017cf2f12d4a428ab092df
SourceCode/Bond/Servo/AlarmManager.cpp
@@ -1,4 +1,5 @@
#include "stdafx.h"
#include "Common.h"
#include "AlarmManager.h"
#include <sstream>
#include <fstream>
@@ -88,7 +89,53 @@
            FOREIGN KEY (unit_id) REFERENCES units(unit_id)
        )
    )";
    return m_pDB->executeQuery(createAlarmsTableQuery);
    if (!m_pDB->executeQuery(createAlarmsTableQuery)) {
        return false;
    }
    // 设备列表 (ID -> 名称)
    std::vector<std::pair<int, std::string>> devices = {
        {EQ_ID_LOADPORT1, EQ_NAME_LOADPORT1},
        {EQ_ID_LOADPORT2, EQ_NAME_LOADPORT2},
        {EQ_ID_LOADPORT3, EQ_NAME_LOADPORT3},
        {EQ_ID_LOADPORT4, EQ_NAME_LOADPORT4},
        {EQ_ID_ARM_TRAY1, EQ_NAME_ARM_TRAY1},
        {EQ_ID_ARM_TRAY2, EQ_NAME_ARM_TRAY2},
        {EQ_ID_ALIGNER, EQ_NAME_ALIGNER},
        {EQ_ID_FLIPER, EQ_NAME_FLIPER},
        {EQ_ID_VACUUMBAKE, EQ_NAME_VACUUMBAKE},
        {EQ_ID_Bonder1, EQ_NAME_BONDER1},
        {EQ_ID_Bonder2, EQ_NAME_BONDER2},
        {EQ_ID_BAKE_COOLING, EQ_NAME_BAKE_COOLING},
        {EQ_ID_MEASUREMENT, EQ_NAME_MEASUREMENT},
        {EQ_ID_EFEM, EQ_NAME_EFEM},
        {EQ_ID_ARM, EQ_NAME_ARM},
        {EQ_ID_OPERATOR_REMOVE, EQ_NAME_OPERATOR_REMOVE}
    };
    // 插入 devices 和对应的默认 unit
    for (const auto& dev : devices) {
        int nDeviceId = dev.first;
        const std::string& strDeviceName = dev.second;
        // 插入设备
        std::ostringstream ossDev;
        ossDev << "INSERT OR IGNORE INTO devices (device_id, device_name) VALUES("
            << nDeviceId << ", '" << strDeviceName << "')";
        if (!m_pDB->executeQuery(ossDev.str())) {
            return false;
        }
        // 插入默认单元 (unit_id = 0, unit_name = device_name)
        std::ostringstream ossUnit;
        ossUnit << "INSERT OR IGNORE INTO units (device_id, unit_id, unit_name) VALUES("
            << nDeviceId << ", 0, '" << strDeviceName << "')";
        if (!m_pDB->executeQuery(ossUnit.str())) {
            return false;
        }
    }
    return true;
}
// 销毁报警表
@@ -487,17 +534,7 @@
}
// 筛选报警数据
std::vector<AlarmData> AlarmManager::getFilteredAlarms(
    const std::string& id,
    const std::string& severityLevel,
    const std::string& deviceName,
    const std::string& unitName,
    const std::string& description,
    const std::string& startTime,
    const std::string& endTime,
    int pageNumber,
    int pageSize) {
std::vector<AlarmData> AlarmManager::getFilteredAlarms(const std::string& keyword, const std::string& startTime, const std::string& endTime, int pageNumber, int pageSize) {
    if (!m_pDB) {
        return {};
    }
@@ -507,25 +544,20 @@
        SELECT a.id, a.severity_level, a.device_id, a.unit_id, d.device_name, u.unit_name, a.description, a.start_time, a.end_time
        FROM alarms a
        JOIN devices d ON a.device_id = d.device_id
        JOIN units u ON a.device_id = u.device_id AND a.unit_id = u.unit_id
        JOIN units u   ON a.device_id = u.device_id AND a.unit_id = u.unit_id
        WHERE 1=1)";
    // 传入的过滤条件
    if (!id.empty()) {
        query << " AND a.id = '" << id << "'";
    // 统一关键字模糊查询
    if (!keyword.empty()) {
        query << " AND ("
            << "a.id LIKE '%" << keyword << "%' OR "
            << "a.severity_level LIKE '%" << keyword << "%' OR "
            << "d.device_name LIKE '%" << keyword << "%' OR "
            << "u.unit_name LIKE '%" << keyword << "%' OR "
            << "a.description LIKE '%" << keyword << "%')";
    }
    if (!severityLevel.empty()) {
        query << " AND a.severity_level = '" << severityLevel << "'";
    }
    if (!deviceName.empty()) {
        query << " AND d.device_name LIKE '%" << deviceName << "%'";
    }
    if (!unitName.empty()) {
        query << " AND u.unit_name LIKE '%" << unitName << "%'";
    }
    if (!description.empty()) {
        query << " AND a.description LIKE '%" << description << "%'";
    }
    // 时间条件
    if (!startTime.empty()) {
        query << " AND a.start_time >= '" << startTime << "'";
    }
@@ -534,9 +566,10 @@
    }
    // 分页设置
    int offset = (pageNumber - 1) * pageSize;
    query << " ORDER BY a.start_time DESC LIMIT " << pageSize << " OFFSET " << offset;
    int nOffset = (pageNumber - 1) * pageSize;
    query << " ORDER BY a.start_time DESC LIMIT " << pageSize << " OFFSET " << nOffset;
    // 查询
    auto results = m_pDB->fetchResults(query.str());
    // 遍历查询结果,填充 AlarmData 结构体
@@ -560,41 +593,30 @@
}
// 获取符合条件的报警总数
int AlarmManager::getTotalAlarmCount(
    const std::string& id,
    const std::string& severityLevel,
    const std::string& deviceName,
    const std::string& unitName,
    const std::string& description,
    const std::string& startTime,
    const std::string& endTime) {
int AlarmManager::getTotalAlarmCount(const std::string& keyword, const std::string& startTime, const std::string& endTime) {
    if (!m_pDB) {
        return 0;
    }
    std::ostringstream query;
    query << "SELECT COUNT(*) FROM alarms a "
        << "JOIN devices d ON a.device_id = d.device_id "
        << "JOIN units u ON a.device_id = u.device_id AND a.unit_id = u.unit_id "
        << "WHERE 1=1";
    query << R"(
        SELECT COUNT(*)
        FROM alarms a
        JOIN devices d ON a.device_id = d.device_id
        JOIN units u   ON a.device_id = u.device_id AND a.unit_id = u.unit_id
        WHERE 1=1)";
    // 添加过滤条件
    if (!id.empty()) {
        query << " AND a.id = '" << id << "'";
    // 统一关键字模糊查询
    if (!keyword.empty()) {
        query << " AND ("
            << "a.id LIKE '%" << keyword << "%' OR "
            << "a.severity_level LIKE '%" << keyword << "%' OR "
            << "d.device_name LIKE '%" << keyword << "%' OR "
            << "u.unit_name LIKE '%" << keyword << "%' OR "
            << "a.description LIKE '%" << keyword << "%')";
    }
    if (!severityLevel.empty()) {
        query << " AND a.severity_level = '" << severityLevel << "'";
    }
    if (!deviceName.empty()) {
        query << " AND d.device_name LIKE '%" << deviceName << "%'";
    }
    if (!unitName.empty()) {
        query << " AND u.unit_name LIKE '%" << unitName << "%'";
    }
    if (!description.empty()) {
        query << " AND a.description LIKE '%" << description << "%'";
    }
    // 时间条件
    if (!startTime.empty()) {
        query << " AND a.start_time >= '" << startTime << "'";
    }
@@ -762,16 +784,33 @@
// 读取报警文件
bool AlarmManager::readAlarmFile(const std::string& filename) {
    std::ifstream file(filename);
    std::string line;
    bool first_line = true;
    std::ifstream file(filename, std::ios::binary);
    if (!file.is_open()) {
        std::cerr << "Error opening file!" << std::endl;
        return false;
    }
    while (std::getline(file, line)) {
    auto getline_cross = [](std::ifstream& f, std::string& out) -> bool {
        out.clear();
        char ch;
        while (f.get(ch)) {
            if (ch == '\r') {
                // 处理 \r\n 或 单独 \r
                if (f.peek() == '\n') f.get();
                break;
            }
            else if (ch == '\n') {
                break;
            }
            out.push_back(ch);
        }
        return !out.empty() || !f.eof();
    };
    std::string line;
    bool first_line = true;
    while (getline_cross(file, line)) {
        if (first_line) {
            first_line = false;
            continue;
@@ -781,23 +820,29 @@
        std::string cell;
        AlarmInfo alarm;
        std::getline(ss, cell, ',');
        std::getline(ss, alarm.strUnitID, ',');
        std::getline(ss, alarm.strUnitNo, ',');
        std::getline(ss, cell, ',');
        alarm.nAlarmLevel = std::stoi(cell);
        std::getline(ss, cell, ',');
        alarm.nAlarmCode = std::stoi(cell);
        std::getline(ss, cell, ',');
        alarm.nAlarmID = std::stoi(cell);
        std::getline(ss, alarm.strAlarmText, ',');
        std::getline(ss, alarm.strDescription, ',');
        try {
            if (!std::getline(ss, cell, ',')) throw std::runtime_error("Missing field: No");
            if (!std::getline(ss, alarm.strUnitID, ',')) throw std::runtime_error("Missing field: UnitID");
            if (!std::getline(ss, alarm.strUnitNo, ',')) throw std::runtime_error("Missing field: UnitNo");
            if (!std::getline(ss, cell, ',')) throw std::runtime_error("Missing field: AlarmLevel");
            alarm.nAlarmLevel = std::stoi(cell);
            if (!std::getline(ss, cell, ',')) throw std::runtime_error("Missing field: AlarmCode");
            alarm.nAlarmCode = std::stoi(cell);
            if (!std::getline(ss, cell, ',')) throw std::runtime_error("Missing field: AlarmID");
            alarm.nAlarmID = std::stoi(cell);
            if (!std::getline(ss, alarm.strAlarmText, ',')) throw std::runtime_error("Missing field: AlarmText");
            if (!std::getline(ss, alarm.strDescription, ',')) throw std::runtime_error("Missing field: Description");
        if (m_mapAlarm.find(alarm.nAlarmID) == m_mapAlarm.end()) {
            m_mapAlarm[alarm.nAlarmID] = alarm;
            if (m_mapAlarm.find(alarm.nAlarmID) == m_mapAlarm.end()) {
                m_mapAlarm[alarm.nAlarmID] = alarm;
            }
            else {
                std::cerr << "Duplicate AlarmID: " << alarm.nAlarmID << std::endl;
            }
        }
        else {
            std::cerr << "Duplicate AlarmID: " << alarm.nAlarmID << std::endl;
        catch (const std::exception& e) {
            std::cerr << "Error parsing line: " << line << " - " << e.what() << std::endl;
            continue;
        }
    }