添加文件路径接口函数和文件下载接口函数

This commit is contained in:
lnk
2025-07-31 13:38:55 +08:00
parent 8e4e45ce31
commit 78938827f7
2 changed files with 209 additions and 4 deletions

View File

@@ -2649,6 +2649,60 @@ void Set_xml_nodeinfo()
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////录播波形匹配
// 工具函数:解析 "dd/MM/yyyy,hh:mm:ss.zzz" 格式的字符串为时间戳(毫秒)
static long long parse_datetime_to_epoch_ms(const std::string& dt_str) {
std::tm tm = {};
char dummy;
int ms = 0;
std::istringstream ss(dt_str);
ss >> std::get_time(&tm, "%d/%m/%Y,%H:%M:%S") >> dummy >> ms;
if (ss.fail()) return 0;
std::time_t time_sec = std::mktime(&tm);
if (time_sec < 0) return 0;
return static_cast<long long>(time_sec) * 1000 + ms;
}
// 主函数:从 .cfg 文件中提取起始和触发时间戳(毫秒)
bool extract_timestamp_from_cfg_file(const std::string& cfg_path, long long& start_tm, long long& trig_tm) {
struct stat st;
if (stat(cfg_path.c_str(), &st) != 0) {
std::cerr << "File not found: " << cfg_path << "\n";
return false;
}
std::ifstream infile(cfg_path);
if (!infile) {
std::cerr << "Cannot open file: " << cfg_path << "\n";
return false;
}
std::string line, prev_line, current_line;
while (std::getline(infile, line)) {
// 去除前后空白
line.erase(line.find_last_not_of(" \t\r\n") + 1);
line.erase(0, line.find_first_not_of(" \t\r\n"));
std::string upper = line;
std::transform(upper.begin(), upper.end(), upper.begin(), ::toupper);
if (upper == "ASCII" || upper == "BINARY") break;
prev_line = current_line;
current_line = line;
}
if (prev_line.length() > 3) prev_line = prev_line.substr(0, prev_line.length() - 3);
if (current_line.length() > 3) current_line = current_line.substr(0, current_line.length() - 3);
start_tm = parse_datetime_to_epoch_ms(prev_line);
trig_tm = parse_datetime_to_epoch_ms(current_line);
return start_tm > 0 && trig_tm > 0;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////数据转换函数
// DataArrayItem to_json
@@ -2760,4 +2814,117 @@ std::vector<DeviceInfo> GenerateDeviceInfoFromLedger(const std::vector<terminal_
}
return devices;
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////录波文件通知
bool assign_qvvr_file_list(const std::string& id, ushort nCpuNo, const std::vector<std::string>& file_list_raw) {
std::vector<std::string> file_names;
// 1. 提取文件名部分
for (const auto& full_path : file_list_raw) {
size_t pos = full_path.find_last_of("/\\");
if (pos != std::string::npos && pos + 1 < full_path.size()) {
file_names.push_back(full_path.substr(pos + 1));
} else {
file_names.push_back(full_path);
}
}
// 2. 遍历终端
for (auto& dev : terminal_devlist) {
if (dev.terminal_id == id) {
for (auto& monitor : dev.line) {
try {
ushort monitor_seq = static_cast<ushort>(std::stoi(monitor.logical_device_seq));
if (monitor_seq == nCpuNo) {
// 构造 qvvr_file
qvvr_file qfile;
qfile.file_name.assign(file_names.begin(), file_names.end());
qfile.is_download = false;
qfile.is_pair = false;
qfile.file_time_count = 0; // 可后续补充
qfile.file_start =false;
// 添加到唯一的 qvvrevent
monitor.qvvrevent.qvvrfile.push_back(std::move(qfile));
return true;
}
} catch (...) {
continue;
}
}
}
}
return false;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////下载成功通知
bool update_qvvr_file_download(const std::string& filename_with_mac, const std::string& terminal_id) {
// 去除 mac 路径前缀
size_t pos = filename_with_mac.find_last_of("/\\");
std::string filename = (pos != std::string::npos) ? filename_with_mac.substr(pos + 1) : filename_with_mac;
// 提取逻辑序号(如 PQM1 → 1
size_t under_pos = filename.find('_');
if (under_pos == std::string::npos) return false;
std::string type_part = filename.substr(0, under_pos); // e.g. PQMonitor_PQM1
size_t num_start = type_part.find_last_not_of("0123456789");
if (num_start == std::string::npos || num_start + 1 >= type_part.size()) return false;
std::string seq_str = type_part.substr(num_start + 1);
ushort logical_seq = static_cast<ushort>(std::stoi(seq_str));
for (auto& dev : terminal_devlist) {
if (dev.terminal_id != terminal_id) continue;
for (auto& monitor : dev.line) {
try {
ushort monitor_seq = static_cast<ushort>(std::stoi(monitor.logical_device_seq));
if (monitor_seq != logical_seq) continue;
} catch (...) {
continue;
}
// 匹配监测点下 qvvrfile 中的 file_name
for (auto& qfile : monitor.qvvrevent.qvvrfile) {
auto it = std::find(qfile.file_name.begin(), qfile.file_name.end(), filename);
if (it != qfile.file_name.end()) {
// 添加到 file_download去重
if (std::find(qfile.file_download.begin(), qfile.file_download.end(), filename) == qfile.file_download.end()) {
qfile.file_download.push_back(filename);
}
qfile.file_time_count = 0;
qfile.file_start = true;
// 检查 file_download 是否与 file_name 完全一致(集合相同)
std::set<std::string> s_name(qfile.file_name.begin(), qfile.file_name.end());
std::set<std::string> s_down(qfile.file_download.begin(), qfile.file_download.end());
if (s_name == s_down) {
qfile.is_download = true;
// 找到其中的 .cfg 文件进行匹配
for (const auto& f : qfile.file_download) {
if (f.size() >= 4 && f.substr(f.size() - 4) == ".cfg") {
if (compare_qvvr_and_file(f)) {//提取文件时标和监测点事件的时标匹配
qfile.is_pair = true;
//发送所有文件
//发送暂态事件
}
break; // 只处理第一个 cfg 文件
}
}
}
return true;
}
}
}
}
return false;
}