This commit is contained in:
lnk
2025-10-28 20:59:05 +08:00
parent f69a6d2105
commit 06a2f3a75b
4 changed files with 926 additions and 144 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -10,6 +10,8 @@
#include <sstream>
#include <iostream>
#include <unordered_set>
///////////////////////////////////////////////////////////////////////////////////////////
#include "nlohmann/json.hpp"
@@ -78,15 +80,13 @@ public:
//暂态文件用
bool direct_mode = false; // 直下文件开关true 表示不按时间窗,仅按目标文件名
std::vector<std::string> target_filetimes; // 直下文件匹配时间
std::list<std::string> file_paths; // 已下载/要上报的完整路径(用于最终结果)
std::string target_filetimes; // 直下文件匹配时间yyyyMMdd_HHmmss仅 direct_mode=true 时有效
// ★新增:按“目录名 -> 文件名列表”的映射;由“其他线程”在目录请求成功后回填
std::map<std::string, std::vector<tag_dir_info>> dir_files;
// ★新增:候选目录(可扩展)
std::vector<std::string> dir_candidates{
std::vector<std::string> dir_candidates{
"/cf/COMTRADE",
"/bd0/COMTRADE",
"/sd0/COMTRADE",
@@ -103,9 +103,12 @@ public:
ActionResult download_result = ActionResult::PENDING; // 当前文件的下载结果
// ★新增:下载队列(已筛选出在时间窗内的文件,含完整路径)
std::list<std::string> download_queue;
std::list<std::string> download_queue; //一个时间可能对应多个文件
std::string downloading_file; // 当前正在下载的文件(完整路径)
std::unordered_set<std::string> required_files; // 本次应当下载成功的文件全集
std::unordered_set<std::string> file_success; // 已下载成功的文件集合
// ★新增:一个便捷复位
void reset_runtime(bool keep_direct = false)
{
@@ -117,6 +120,10 @@ public:
download_queue.clear();
downloading_file.clear();
dir_files.clear();
required_files.clear();
file_success.clear();
// ★新增:按需保留直下文件开关和目标名
if (!keep_direct) {
direct_mode = false;
@@ -807,6 +814,12 @@ inline void print_terminal(const update_dev& tmnl) { print_terminal_common(tmnl)
inline void print_terminal(const terminal_dev& tmnl) { print_terminal_common(tmnl); }
///////////////////////////////////////////////////////////////////////////////////////////////////////////////小工具
// 小工具:判断 s 是否以 suffix 结尾
static inline bool has_suffix(const std::string& s, const std::string& suffix) {
if (suffix.size() > s.size()) return false;
return std::equal(suffix.rbegin(), suffix.rend(), s.rbegin());
}
inline std::string trim_cstr(const char* s, size_t n) {
if (!s) return {};
size_t end = 0;
@@ -817,6 +830,15 @@ inline std::string trim_cstr(const char* s, size_t n) {
return out;
}
// 去首尾空格
inline std::string trim_copy(const std::string& s) {
size_t b = s.find_first_not_of(" \t\r\n");
if (b == std::string::npos) return "";
size_t e = s.find_last_not_of(" \t\r\n");
return s.substr(b, e - b + 1);
}
//清洗字符串
inline std::string sanitize(std::string s) {
// 截断第一个 NUL 及其后内容
size_t z = s.find('\0');
@@ -844,6 +866,22 @@ inline std::string now_yyyy_mm_dd_hh_mm_ss() {
return oss.str();
}
// 简单键值提取(兼容半角/全角冒号)
inline bool parse_kv_line(const std::string& line,
const std::string& key,
std::string& out) {
std::string k1 = key + ":";
std::string k2 = key + "";
if (line.compare(0, k1.size(), k1) == 0) {
out = trim_copy(line.substr(k1.size()));
return true;
} else if (line.compare(0, k2.size(), k2) == 0) {
out = trim_copy(line.substr(k2.size()));
return true;
}
return false;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////实时数据用
// === 专用锁 + 数据表(仅管实时 idx 映射) ===
extern std::mutex devidx_lock; // 新锁(不要用 ledgermtx
@@ -924,4 +962,35 @@ static bool parse_datetime_tm(const std::string& s, std::tm& out) {
}
#endif
/////////////////////////////////////////////////////////////////////////////补招文件记录
// 记录 (guid, monitorId) -> 文件完整路径
extern std::mutex g_recall_file_mtx;
extern std::map<std::pair<std::string,std::string>, std::string> g_recall_file_index;
// 初始化 / 追加 / 删除
bool init_recall_record_file(const std::string& guid,
const std::string& terminalId,
const std::string& monitorId,
const std::string& start,
const std::string& end);
bool append_recall_record_line(const std::string& guid,
const std::string& monitorId,
const std::string& msg);
bool delete_recall_record_file(const std::string& guid,
const std::string& monitorId);
bool get_recall_record_fields_by_guid_monitor(const std::string& guid,
const std::string& monitorId,
std::string& outGuid,
std::string& terminalId,
std::string& outMonitorId,
std::string& startTime,
std::string& endTime,
std::string& msg);
bool SendFileWebAuto(const std::string& id,
const std::string& local_path,
const std::string& remote_path,
std::string& out_filename);

View File

@@ -684,16 +684,9 @@ void Worker::printLedgerinshell(const terminal_dev& dev, int fd) {
// ★新增:直下模式与目标时间列表
os << "\r\x1B[K |-- direct_mode=" << (rf.direct_mode ? "true" : "false")
<< ", target_filetimes(" << rf.target_filetimes.size() << ")\n";
<< ", target_filetimes(" << rf.target_filetimes << ")\n";
{
size_t c = 0;
for (const auto& t : rf.target_filetimes) {
if (c++ >= MAX_ITEMS) break;
os << "\r\x1B[K |-- " << t << "\n";
}
if (rf.target_filetimes.size() > MAX_ITEMS) {
os << "\r\x1B[K |.. (+" << (rf.target_filetimes.size() - MAX_ITEMS) << " more)\n";
}
os << "\r\x1B[K |.. " << rf.target_filetimes << "\n";
}
// ★新增:状态机运行态
@@ -747,19 +740,6 @@ void Worker::printLedgerinshell(const terminal_dev& dev, int fd) {
if (!rf.downloading_file.empty()) {
os << "\r\x1B[K |-- downloading: " << rf.downloading_file << "\n";
}
// ★新增:已下载/待上报的完整路径file_paths
os << "\r\x1B[K |-- file_paths(" << rf.file_paths.size() << ")\n";
{
size_t c = 0;
for (const auto& p : rf.file_paths) {
if (c++ >= MAX_ITEMS) break;
os << "\r\x1B[K |-- " << p << "\n";
}
if (rf.file_paths.size() > MAX_ITEMS) {
os << "\r\x1B[K |.. (+" << (rf.file_paths.size() - MAX_ITEMS) << " more)\n";
}
}
}
if (ld.recall_list_static.size() > MAX_ITEMS) {
os << "\r\x1B[K |.. (+" << (ld.recall_list_static.size() - MAX_ITEMS) << " more)\n";