chenluhua1980
2026-01-13 155cb7fe0dcb564729c6aecdb65815f3f0ed24e2
SourceCode/Bond/Servo/CPageGlassList.cpp
@@ -13,6 +13,7 @@
#include <unordered_map>
#include <vector>
#include <string>
#include <algorithm>
#include "CProcessDataListDlg.h"
#define PAGE_SIZE                       50
@@ -1363,7 +1364,7 @@
    if (!row.pretty.empty()) {
        CFile file;
        if (file.Open(filePath, CFile::modeCreate | CFile::modeWrite)) {
            file.Write(row.pretty.c_str(), row.pretty.length());
            file.Write(row.pretty.c_str(), (UINT)row.pretty.length());
            file.Close();
            CString strSuccess;
@@ -1481,69 +1482,59 @@
            // 对每个机器生成表格
            for (const auto& machinePair : tempGlass.getAllSVData()) {
                int machineId = machinePair.first;
                const auto& dataByType = machinePair.second;
                CString machineName = CString(SERVO::CServoUtilsTool::getEqName(machineId).c_str());
                csvContent += _T("\n[") + machineName + _T("]\n");
                // 获取该机器的预定义列顺序
                auto columnOrder = getMachineColumnOrder(machineId);
                if (columnOrder.empty()) {
                    csvContent += _T("无预定义列配置\n");
                if (dataByType.empty()) {
                    csvContent += _T("No sensor data\n");
                    continue;
                }
                // 构建表头 - 直接使用中文列名
                CString header = _T("时间戳(ms),本地时间");
                auto columnOrder = getMachineColumnOrder(machineId, &dataByType);
                if (columnOrder.empty()) {
                    csvContent += _T("No exportable columns\n");
                    continue;
                }
                CString header = _T("Timestamp(ms),LocalTime");
                for (const auto& dataType : columnOrder) {
                    header += _T(",");
                    header += CString(dataType.c_str()); // 直接使用中文列名
                    header += CString(dataType.c_str());
                }
                header += _T("\n");
                csvContent += header;
                // 检查是否有数据
                if (machinePair.second.empty()) {
                    csvContent += _T("无传感器数据\n");
                auto baselineIt = std::find_if(columnOrder.begin(), columnOrder.end(),
                    [&](const std::string& type) {
                        auto dataIt = dataByType.find(type);
                        return dataIt != dataByType.end() && !dataIt->second.empty();
                    });
                if (baselineIt == columnOrder.end()) {
                    csvContent += _T("No usable time series\n");
                    continue;
                }
                // 使用第一个数据类型的时间序列作为基准
                const std::string& firstDataType = columnOrder[0];
                auto firstDataTypeIt = machinePair.second.find(firstDataType);
                if (firstDataTypeIt == machinePair.second.end() || firstDataTypeIt->second.empty()) {
                    csvContent += _T("无基准数据类型数据\n");
                    continue;
                }
                const auto& timeSeries = firstDataTypeIt->second;
                // 对于每个时间点,输出一行数据
                for (size_t i = 0; i < timeSeries.size(); i++) {
                const auto& timeSeries = dataByType.at(*baselineIt);
                for (size_t i = 0; i < timeSeries.size(); ++i) {
                    auto timestamp = timeSeries[i].timestamp;
                    // 时间戳(毫秒)
                    auto ms = timePointToMs(timestamp);
                    CString row;
                    row.Format(_T("%lld,"), ms);
                    // 本地时间字符串
                    CString localTime = CString(timePointToString(timestamp).c_str());
                    row += localTime;
                    // 按照预定义的列顺序输出数据
                    for (const auto& dataType : columnOrder) {
                        row += _T(",");
                        auto dataTypeIt = machinePair.second.find(dataType);
                        if (dataTypeIt != machinePair.second.end() && i < dataTypeIt->second.size()) {
                            // 直接按索引获取数据
                        auto dataTypeIt = dataByType.find(dataType);
                        if (dataTypeIt != dataByType.end() && i < dataTypeIt->second.size()) {
                            CString valueStr;
                            valueStr.Format(_T("%.3f"), dataTypeIt->second[i].value);
                            row += valueStr;
                        }
                        else {
                            // 理论上不应该发生,因为您说没有空值
                            row += _T("N/A");
                        }
                    }
@@ -1582,9 +1573,14 @@
    auto* p = reinterpret_cast<NMC_ELC_SHOWFULLTEXT*>(pNMHDR);
    // 对话框显示工艺参数
    CProcessDataListDlg dlg;
    dlg.setRawText(p->text);
    dlg.DoModal();
    if (p->iSubItem == 12) {
        CProcessDataListDlg dlg;
        dlg.setRawText(p->text);
        dlg.DoModal();
    }
    else {
        AfxMessageBox(p->text);
    }
    *pResult = 0;
}
@@ -1919,11 +1915,33 @@
}
// 获取机器预定义的列顺序
std::vector<std::string> CPageGlassList::getMachineColumnOrder(int machineId)
std::vector<std::string> CPageGlassList::getMachineColumnOrder(int machineId,
    const std::unordered_map<std::string, std::vector<SERVO::SVDataItem>>* actualData)
{
    std::vector<std::string> columnOrder;
    auto dataTypes = SERVO::CServoUtilsTool::getEqDataTypes();
    auto it = dataTypes.find(machineId);
    return it != dataTypes.end() ? it->second : std::vector<std::string>();
    if (actualData != nullptr) {
        if (it != dataTypes.end()) {
            for (const auto& name : it->second) {
                if (actualData->find(name) != actualData->end()) {
                    columnOrder.push_back(name);
                }
            }
        }
        for (const auto& kv : *actualData) {
            if (std::find(columnOrder.begin(), columnOrder.end(), kv.first) == columnOrder.end()) {
                columnOrder.push_back(kv.first);
            }
        }
        return columnOrder;
    }
    if (it != dataTypes.end()) {
        columnOrder = it->second;
    }
    return columnOrder;
}
// 时间戳转换为字符串
@@ -1953,13 +1971,25 @@
    for (const auto& machinePair : dataTypes) {
        int machineId = machinePair.first;
        const auto& dataTypeList = machinePair.second;
        std::vector<std::string> filteredTypes;
        if (machineId == EQ_ID_VACUUMBAKE || machineId == EQ_ID_BAKE_COOLING) {
            const char activePrefix = 'A';
            for (const auto& dataType : dataTypeList) {
                if (!dataType.empty() && dataType[0] == activePrefix) {
                    filteredTypes.push_back(dataType);
                }
            }
        }
        const auto& typeList = filteredTypes.empty() ? dataTypeList : filteredTypes;
        
        // 生成时间序列:从当前时间往前推10分钟,每1秒一个数据点
        auto now = std::chrono::system_clock::now();
        auto startTime = now - std::chrono::minutes(10);
        
        // 为每个数据类型生成模拟数据
        for (const auto& dataType : dataTypeList) {
        for (const auto& dataType : typeList) {
            std::vector<SERVO::SVDataItem> mockData;
            
            // 生成600个数据点(10分钟 * 60个点/分钟)