From 375ac4fca9312ea24a776fba11bd33c9341f0694 Mon Sep 17 00:00:00 2001 From: lzq Date: Wed, 16 Jul 2025 18:14:32 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/application.cpp | 4 +- src/barrier/barrier.cpp | 2 +- src/barrier/barrier.h | 7 ++- src/barrier/generic_barrier.cpp | 82 +++++++++++++++----------- src/barrier/generic_barrier.h | 8 ++- src/barrier/recognize_data.cpp | 9 +++ src/barrier/recognize_data.h | 24 ++++++++ src/common/event_manager.cpp | 47 ++++++++------- src/common/event_manager.h | 14 ++--- src/common/json_util.h | 2 +- src/common/{loging.cpp => logging.cpp} | 0 src/common/{loging.h => logging.h} | 0 src/common/thread_pool.cpp | 51 +++++++++++----- src/common/thread_pool.h | 29 ++++----- src/controller/barrier_controller.cpp | 12 ++++ src/controller/barrier_controller.h | 13 ++++ src/controller/test.cpp | 2 +- src/http/http_svr.cpp | 8 ++- src/oss/oss.cpp | 15 +++-- src/oss/oss.h | 4 +- src/recognize_processor.cpp | 70 ++++++++++------------ src/recognize_processor.h | 7 ++- src/report_svr/report_svr.cpp | 5 +- src/report_svr/report_svr.h | 2 +- src/serial_port/serial_port.cpp | 2 +- src/vidicon/barrier_vidicon.cpp | 28 ++++----- src/vidicon/barrier_vidicon.h | 4 +- src/vidicon/generic_vidicon.cpp | 80 ++++++++++++++++++++++++- src/vidicon/generic_vidicon.h | 7 ++- src/vidicon/test_vidicon.cpp | 9 +-- src/vidicon/test_vidicon.h | 2 +- src/vidicon/vidicon.h | 3 +- 32 files changed, 365 insertions(+), 187 deletions(-) create mode 100644 src/barrier/recognize_data.cpp create mode 100644 src/barrier/recognize_data.h rename src/common/{loging.cpp => logging.cpp} (100%) rename src/common/{loging.h => logging.h} (100%) create mode 100644 src/controller/barrier_controller.cpp create mode 100644 src/controller/barrier_controller.h diff --git a/src/application.cpp b/src/application.cpp index a941533..e838148 100644 --- a/src/application.cpp +++ b/src/application.cpp @@ -111,9 +111,9 @@ namespace zsy LOGGER_INFO("等待..."); std::this_thread::sleep_for(std::chrono::milliseconds(appProperties.delay * 1000)); } - threadPool = std::make_shared(); + threadPool = std::make_shared("通用线程池"); - eventManager = std::make_shared(threadPool); + eventManager = std::make_shared(); httpSvr = std::make_unique(config); diff --git a/src/barrier/barrier.cpp b/src/barrier/barrier.cpp index 713d7f3..376c2f3 100644 --- a/src/barrier/barrier.cpp +++ b/src/barrier/barrier.cpp @@ -4,7 +4,7 @@ #include #include "application.h" -#include "common/loging.h" +#include "common/logging.h" namespace zsy { diff --git a/src/barrier/barrier.h b/src/barrier/barrier.h index 644de41..be4441d 100644 --- a/src/barrier/barrier.h +++ b/src/barrier/barrier.h @@ -1,7 +1,10 @@ #ifndef BARRIER_H #define BARRIER_H +#include #include +#include "recognize_data.h" + namespace zsy { @@ -14,7 +17,9 @@ namespace zsy virtual bool isFront() = 0; - // virtual void resolveRecognizeResult(const std::string &license, const std::string &imageFile) = 0; + virtual std::string sn() = 0; + + virtual std::shared_ptr resolvePhoto(const std::string &imageFile) = 0; }; } // zsy diff --git a/src/barrier/generic_barrier.cpp b/src/barrier/generic_barrier.cpp index 5b50b08..3c62a4c 100644 --- a/src/barrier/generic_barrier.cpp +++ b/src/barrier/generic_barrier.cpp @@ -3,7 +3,7 @@ #include "application.h" #include "recognize_processor.h" #include "common/date_util.h" -#include "common/loging.h" +#include "common/logging.h" #include "common/snowflake.h" #include "common/sys_util.h" @@ -48,39 +48,14 @@ namespace zsy LOGGER_INFO("收到车牌识别结果:{}", body); auto [succ,recognizeResult] = GenericBarrier::parseRecognizeResult(body); - if (!succ) + if (succ) { - LOGGER_ERROR("车牌识别结果解析失败"); - res.set_content(R"({})", "application/json"); - return; + Application::threadPool->submit([recognizeResult] + { + RecognizeProcessor::process(recognizeResult); + LOGGER_INFO("车牌识别结果处理完成"); + }); } - auto serialno = recognizeResult.alarmInfoPlate.serialno; - auto imageFile = recognizeResult.alarmInfoPlate.result.plateResult.imageFile; - auto license = recognizeResult.alarmInfoPlate.result.plateResult.license; - if (serialno.empty() || imageFile.empty() || license.empty()) - { - LOGGER_ERROR("车牌识别结果解析失败"); - res.set_content(R"({})", "application/json"); - return; - } - if (license.find("无") != std::string::npos) - { - LOGGER_WARN("车牌识别失败"); - res.set_content(R"({})", "application/json"); - return; - } - auto barrier = Application::deviceHolder->getBarrier(serialno); - if (!barrier) - { - LOGGER_ERROR("未找到对应的道闸"); - return; - } - - std::thread t([front = barrier->isFront(), serialno,license,imageFile] - { - RecognizeProcessor::process(front, serialno, license, imageFile); - }); - t.detach(); } catch (std::exception &e) { LOGGER_ERROR("车牌识别结果处理失败: {}", e.what()); @@ -137,21 +112,56 @@ namespace zsy return config.name.find("前置") != std::string::npos; } - std::tuple GenericBarrier::parseRecognizeResult(const std::string &jsonStr) + std::string GenericBarrier::sn() + { + return config.sn; + } + + std::shared_ptr GenericBarrier::resolvePhoto(const std::string &imageFile) + { + auto content = SysUtil::base64_decode(imageFile); + return std::make_shared(content, std::ios_base::in | std::ios_base::binary); + } + + std::tuple > GenericBarrier::parseRecognizeResult(const std::string &jsonStr) { try { auto json = nlohmann::json::parse(jsonStr); RecognizeResult result = json.get(); - return std::make_tuple(true, result); + auto sn = result.alarmInfoPlate.serialno; + auto barrier = Application::deviceHolder->getBarrier(sn); + if (!barrier) + { + LOGGER_ERROR("未找到对应的道闸"); + return std::make_tuple(false, nullptr); + } + auto image_file = result.alarmInfoPlate.result.plateResult.imageFile; + auto license = result.alarmInfoPlate.result.plateResult.license; + + if (sn.empty() + || image_file.empty() + || license.empty() + || license.find("无") != std::string::npos + ) + { + LOGGER_ERROR("车牌识别结果解析失败或车牌为:“无”"); + return std::make_tuple(false, nullptr); + } + return std::make_tuple(true, std::make_shared( + barrier->isFront(), + sn, + license, + barrier->resolvePhoto(image_file) + )); } catch (std::exception &e) { LOGGER_ERROR("未找到车牌识别结果:{}", e.what()); - return std::make_tuple(false, RecognizeResult()); + return std::make_tuple(false, nullptr); }catch (...) { LOGGER_ERROR("未知异常,未找到车牌识别结果"); - return std::make_tuple(false, RecognizeResult()); + return std::make_tuple(false, nullptr); } } diff --git a/src/barrier/generic_barrier.h b/src/barrier/generic_barrier.h index c6fc634..5a80f8f 100644 --- a/src/barrier/generic_barrier.h +++ b/src/barrier/generic_barrier.h @@ -5,6 +5,8 @@ #include +#include "recognize_data.h" + namespace zsy { struct DoorReq @@ -150,9 +152,11 @@ namespace zsy bool isFront() override; - // void resolveRecognizeResult(const std::string &license, const std::string &imageFile) override; + std::string sn() override; - static std::tuple parseRecognizeResult(const std::string &jsonStr); + std::shared_ptr resolvePhoto(const std::string &imageFile) override; + + static std::tuple > parseRecognizeResult(const std::string &jsonStr); }; } // zsy diff --git a/src/barrier/recognize_data.cpp b/src/barrier/recognize_data.cpp new file mode 100644 index 0000000..815391e --- /dev/null +++ b/src/barrier/recognize_data.cpp @@ -0,0 +1,9 @@ +#include "recognize_data.h" + +namespace zsy +{ + RecognizeData::RecognizeData(bool isFront, std::string sn, std::string license, std::shared_ptr imageFile) + : isFront(isFront), sn(sn), license(license), imageFile(imageFile) + { + } +} // zsy diff --git a/src/barrier/recognize_data.h b/src/barrier/recognize_data.h new file mode 100644 index 0000000..4d0ad4c --- /dev/null +++ b/src/barrier/recognize_data.h @@ -0,0 +1,24 @@ +#ifndef RECOGNIZE_DATA_H +#define RECOGNIZE_DATA_H +#include +#include + +namespace zsy +{ + struct RecognizeData + { + bool isFront; + std::string sn; + std::string license; + std::shared_ptr imageFile; + + RecognizeData( + bool isFront, + std::string sn, + std::string license, + std::shared_ptr imageFile + ); + }; +} // zsy + +#endif //RECOGNIZE_DATA_H diff --git a/src/common/event_manager.cpp b/src/common/event_manager.cpp index 0884474..a9eac1b 100644 --- a/src/common/event_manager.cpp +++ b/src/common/event_manager.cpp @@ -1,30 +1,40 @@ #include "event_manager.h" +#include "logging.h" + namespace zsy { EventManager::Event::Event(std::string name, const std::string &data) : name(std::move(name)) { - if (data.empty()) { + if (data.empty()) + { this->data = std::nullopt; - } else { + } else + { this->data = nlohmann::json::parse(data); } } - EventManager::EventManager(std::shared_ptr threadPool) - : threadPool(threadPool) + EventManager::EventManager(): threadPool(std::make_shared("事件线程池", 4)) { } - void EventManager::publish(const std::string &name, std::string data) noexcept + void EventManager::subscribe(const std::string &name, const EventHandler &handler) + { + std::lock_guard lock(handlersMutex); + auto handlerPtr = std::make_shared(handler); + handlers[name].push_back(handlerPtr); + } + + void EventManager::publish(const std::string &name, const std::string &data) noexcept { LOGGER_INFO("发布事件:{} {}", name, data); HandlerList *list = nullptr; { - std::lock_guard lock(handlersMutex); + std::shared_lock lock(handlersMutex); auto it = handlers.find(name); if (it != handlers.end()) { @@ -36,23 +46,18 @@ namespace zsy } } - for (auto fn_ptr: *list) + if (list == nullptr || list->size() == 0) { - /*try - { - (*fn_ptr.get())(Event(name, data)); - } catch (const std::exception &e) - { - LOGGER_ERROR("事件处理异常:{} {}", name, e.what()); - }catch (...) - { - LOGGER_ERROR("事件处理异常:{}", name); - }*/ - threadPool->submit([fn = fn_ptr.get(),name,data] + return; + } + + threadPool->submit([list, name, data] + { + for (auto fn_ptr: *list) { try { - (*fn)(Event(name, data)); + (*fn_ptr.get())(Event(name, data)); } catch (const std::exception &e) { LOGGER_ERROR("事件处理异常:{} {}", name, e.what()); @@ -60,7 +65,7 @@ namespace zsy { LOGGER_ERROR("事件处理异常:{}", name); } - }); - } + } + }); } } // zsy diff --git a/src/common/event_manager.h b/src/common/event_manager.h index 25e9531..17070c5 100644 --- a/src/common/event_manager.h +++ b/src/common/event_manager.h @@ -23,21 +23,15 @@ namespace zsy using EventHandler = std::function; using HandlerList = std::vector >; - EventManager(std::shared_ptr threadPool); + EventManager(); - template - void subscribe(const std::string &name, Fn &&handler) - { - std::lock_guard lock(handlersMutex); - auto handlerPtr = std::make_shared(std::forward(handler)); - handlers[name].push_back(handlerPtr); - } + void subscribe(const std::string &name, const EventHandler &handler); - void publish(const std::string &name, std::string data = {}) noexcept; + void publish(const std::string &name, const std::string &data = {}) noexcept; private: std::unordered_map handlers; - std::mutex handlersMutex; + std::shared_mutex handlersMutex; std::shared_ptr threadPool; }; } // zsy diff --git a/src/common/json_util.h b/src/common/json_util.h index bb7d5fd..b1df594 100644 --- a/src/common/json_util.h +++ b/src/common/json_util.h @@ -1,6 +1,6 @@ #ifndef JSON_UTIL_H #define JSON_UTIL_H -#include "common/loging.h" +#include "common/logging.h" #include #define PARSE_JSON(field, to) try \ diff --git a/src/common/loging.cpp b/src/common/logging.cpp similarity index 100% rename from src/common/loging.cpp rename to src/common/logging.cpp diff --git a/src/common/loging.h b/src/common/logging.h similarity index 100% rename from src/common/loging.h rename to src/common/logging.h diff --git a/src/common/thread_pool.cpp b/src/common/thread_pool.cpp index c8579a5..553937f 100644 --- a/src/common/thread_pool.cpp +++ b/src/common/thread_pool.cpp @@ -1,20 +1,22 @@ #include "thread_pool.h" -#include "loging.h" +#include "logging.h" namespace zsy { - ThreadPool::ThreadPool(size_t threadCount): status(0) + ThreadPool::ThreadPool(std::string name, const uint16_t threadCount): name(name), status(0), threadCount(threadCount < 1 ? 1 : threadCount) + { + std::lock_guard lock(status_mtx); + status = 1; + createThread(); + } + + void ThreadPool::createThread() { - if (threadCount < 1) threadCount = 1; - workers.reserve(threadCount); - { - std::unique_lock lock(status_mtx); - status = 1; - } for (size_t i = 0; i < threadCount; ++i) { - workers.emplace_back([this](const std::stop_token &st) + LOGGER_INFO("创建线程:{}-{} 号", name, i); + threads.emplace_back([this,i](const std::stop_token &st) { while (!st.stop_requested()) { @@ -28,7 +30,7 @@ namespace zsy if (st.stop_requested() && tasks.empty()) { - LOGGER_INFO("已停止线程"); + LOGGER_INFO("线程已停止:{}-{} 号", name, i); return; } task = std::move(tasks.front()); @@ -36,26 +38,47 @@ namespace zsy } try { + LOGGER_INFO("开始执行任务:{}-{} 号", name, i); if (task) task(); + LOGGER_INFO("任务执行完成:{}-{} 号", name, i); } catch (const std::exception &e) { - LOGGER_ERROR("任务执行失败: {}", e.what()); + LOGGER_ERROR("任务执行失败:{}-{} 号, {}", name, i, e.what()); } catch (...) { - LOGGER_ERROR("未知异常,任务执行失败"); + LOGGER_ERROR("未知异常,任务执行失败:{}-{} 号", name, i); } } }); } } + void ThreadPool::submit(const std::function &task) + { + addTask(task); + taskCondition.notify_one(); + } + + + void ThreadPool::addTask(const std::function &task) + { + std::shared_lock status_lock(status_mtx); + if (status != 1) + { + LOGGER_ERROR("线程池未启动"); + return; + } + std::unique_lock lock(queueMutex); + tasks.emplace(task); + } + ThreadPool::~ThreadPool() { - std::unique_lock lock(status_mtx); + std::lock_guard lock(status_mtx); status = 2; LOGGER_INFO("正在销毁线程池..."); - workers.clear(); + threads.clear(); LOGGER_INFO("线程池已销毁"); } } // zsy diff --git a/src/common/thread_pool.h b/src/common/thread_pool.h index 2644332..3492f13 100644 --- a/src/common/thread_pool.h +++ b/src/common/thread_pool.h @@ -8,36 +8,29 @@ #include #include -#include "loging.h" - namespace zsy { class ThreadPool { - std::vector workers; // 工作线程 + std::vector threads; // 工作线程 std::queue > tasks; // 任务队列 mutable std::recursive_mutex queueMutex; // 保护任务队列的互斥锁 std::condition_variable_any taskCondition; // 任务通知条件变量 + std::string name; // 0-->不可用,1-->已启动,2-->已关闭 uint8_t status; // 线程池停止标志 + uint16_t threadCount; // 线程池停止标志 std::shared_mutex status_mtx; - public: - explicit ThreadPool(size_t threadCount = std::thread::hardware_concurrency() * 2); + void addTask(const std::function &task); - template - void submit(Fn &&task) noexcept - { - std::shared_lock status_lock(status_mtx); - if (status != 1) - { - LOGGER_ERROR("线程池未启动"); - return; - } - std::unique_lock lock(queueMutex); - tasks.emplace(std::forward(task)); - taskCondition.notify_one(); - } + void createThread(); + + + public: + explicit ThreadPool(std::string name,uint16_t threadCount = std::thread::hardware_concurrency() * 2); + + void submit(const std::function &task); ~ThreadPool(); diff --git a/src/controller/barrier_controller.cpp b/src/controller/barrier_controller.cpp new file mode 100644 index 0000000..c883fe2 --- /dev/null +++ b/src/controller/barrier_controller.cpp @@ -0,0 +1,12 @@ +#include "barrier_controller.h" + +#include "application.h" +#include "recognize_processor.h" +#include "barrier/generic_barrier.h" + +namespace zsy { + BarrierController::BarrierController() + { + + } +} // zsy \ No newline at end of file diff --git a/src/controller/barrier_controller.h b/src/controller/barrier_controller.h new file mode 100644 index 0000000..c5aa74a --- /dev/null +++ b/src/controller/barrier_controller.h @@ -0,0 +1,13 @@ +#ifndef BARRIER_CONTROLLER_H +#define BARRIER_CONTROLLER_H + +namespace zsy { + +class BarrierController { +public: + BarrierController(); +}; + +} // zsy + +#endif //BARRIER_CONTROLLER_H diff --git a/src/controller/test.cpp b/src/controller/test.cpp index d7eb7d1..da3c2eb 100644 --- a/src/controller/test.cpp +++ b/src/controller/test.cpp @@ -116,7 +116,7 @@ namespace zsy { auto sn = req.get_param_value("sn"); auto photograph = Application::deviceHolder->getVidicon(sn)->photograph(); - j["结果"] = photograph; + j["结果"] = ""; } catch (std::exception &e) { LOGGER_ERROR("错误", e.what()); diff --git a/src/http/http_svr.cpp b/src/http/http_svr.cpp index 94f8770..a403c2a 100644 --- a/src/http/http_svr.cpp +++ b/src/http/http_svr.cpp @@ -52,10 +52,14 @@ namespace zsy HttpSvr::~HttpSvr() { - std::unique_lock lock(status_mtx); - status = 1; + { + std::unique_lock lock(status_mtx); + status = 1; + } if (svr) { + LOGGER_INFO("正在停止 HTTP 服务器"); + svr->stop(); } if (svrThread && svrThread->joinable()) diff --git a/src/oss/oss.cpp b/src/oss/oss.cpp index aa3697d..c0bf01d 100644 --- a/src/oss/oss.cpp +++ b/src/oss/oss.cpp @@ -1,7 +1,7 @@ #include "oss.h" #include #include -#include "common/loging.h" +#include "common/logging.h" #include "common/sys_util.h" namespace zsy @@ -11,9 +11,14 @@ namespace zsy { } - std::tuple OSS::upload(const std::string &objectName, std::istream &file) + std::tuple OSS::upload(const std::string &objectName, std::shared_ptr file) { LOGGER_INFO("正在上传文件:{}", objectName); + if (!file) + { + LOGGER_ERROR("文件为空"); + return std::make_tuple(false, ""); + } try { auto now = std::chrono::system_clock::now(); @@ -45,7 +50,7 @@ namespace zsy }; std::stringstream buffer; - buffer << file.rdbuf(); + buffer << file->rdbuf(); const std::string &content = buffer.str(); // 发送请求 @@ -81,8 +86,8 @@ namespace zsy LOGGER_INFO("文件上传失败,文件路径为空"); return std::make_tuple(false, ""); } - std::ifstream file(filePath, std::ios::binary); - if (!file.is_open()) + std::shared_ptr file = std::make_shared(filePath, std::ios::binary); + if (!file->is_open()) { auto [_,code,msg] = SysUtil::getError(); LOGGER_INFO("文件上传失败,无法打开文件:{},错误码:{},错误信息:{}", filePath, code, msg); diff --git a/src/oss/oss.h b/src/oss/oss.h index 6f4bfc5..d660251 100644 --- a/src/oss/oss.h +++ b/src/oss/oss.h @@ -8,7 +8,7 @@ #include #include "oss_properties.h" -#include "common/loging.h" +#include "common/logging.h" namespace zsy @@ -30,7 +30,7 @@ namespace zsy public: OSS(const nlohmann::json &config); - std::tuple upload(const std::string &objectName, std::istream &file); + std::tuple upload(const std::string &objectName, std::shared_ptr file); std::tuple upload(const std::string &objectName, const std::string &filePath); }; diff --git a/src/recognize_processor.cpp b/src/recognize_processor.cpp index 0bacfa2..54cdfd0 100644 --- a/src/recognize_processor.cpp +++ b/src/recognize_processor.cpp @@ -1,61 +1,31 @@ #include "recognize_processor.h" #include "application.h" #include "common/date_util.h" -#include "common/loging.h" +#include "common/logging.h" #include "common/sys_util.h" #include "common/snowflake.h" namespace zsy { - void RecognizeProcessor::process(bool front, const std::string &sn, const std::string &license, const std::string &imageFile) + void RecognizeProcessor::process(std::shared_ptr data) { + const std::string &sn = data->sn; + const std::string &license = data->license; try { - if (front) + if (data->isFront) { - // 播放语音 1 - Application::threadPool->submit([sn] - { - Application::deviceHolder->getSoundColumn(sn)->play("欢迎光临"); - }); + Application::threadPool->submit([sn] { Application::deviceHolder->getSoundColumn(sn)->play("欢迎光临"); }); } - // 上传车头照 - auto imageFileDecode = SysUtil::base64_decode(imageFile); - const std::shared_ptr imageFileStream = std::make_shared(imageFileDecode, std::ios_base::in | std::ios_base::binary); - auto photoId = Snowflake::genIdStr(); - std::string date = DateUtil::format(Ymd); + // 上报 1 - auto reportPassResult = Application::reportSvr->reportPass(license, sn, ""); + auto reportPassResult = Application::reportSvr->reportPass(license, sn); if (!(reportPassResult.code == 0 && (reportPassResult.data.type == 1 || reportPassResult.data.type == 2))) { LOGGER_INFO("不进行后续处理"); return; } - auto [carFrontUrlSucc,carFrontUrl] = Application::oss->upload(date + "/" + "front_" + photoId + ".jpg", *imageFileStream); - - // 上报结果 type 不为 0,播放语音 2 并读地磅,拍车斗并上传 - Application::threadPool->submit([sn] - { - Application::deviceHolder->getSoundColumn(sn)->play("正在称重,请稍后"); - }); - double weight = Application::deviceHolder->getPlatformScale(sn)->reading(); - auto photographPath = Application::deviceHolder->getVidicon(sn)->photograph(); - auto [carBodyUrlSucc,carBodyUrl] = Application::oss->upload(date + "/" + "body_" + photoId + ".jpg", photographPath); - if (!photographPath.empty()) - { - auto pathPtr = SysUtil::ch_vlt(photographPath.c_str()); - if (std::remove(pathPtr.get()) != 0) - { - auto [_,code,msg] = SysUtil::getError(); - LOGGER_ERROR("临时照片删除失败:{},错误码:{},错误信息:{}", photographPath, code, msg); - } else - { - LOGGER_ERROR("临时照片删除成功:{}", photographPath); - } - } - - // 上报 2 - Application::reportSvr->report(license, sn, weight, carFrontUrl, carBodyUrl, reportPassResult.data.orderNo); + addition_process(reportPassResult.data.orderNo, data); } catch (std::exception &e) { LOGGER_ERROR("车牌识别结果处理失败: {}", e.what()); @@ -65,4 +35,26 @@ namespace zsy LOGGER_ERROR("未知异常,车牌识别结果处理失败"); } } + + void RecognizeProcessor::addition_process(const std::string &orderNo, std::shared_ptr data) + { + const std::string &sn = data->sn; + const std::string &license = data->license; + std::shared_ptr frontImageFile = data->imageFile; + // 上报结果 type 不为 0,播放语音 2 并读地磅,拍车斗并上传 + Application::threadPool->submit([sn] { Application::deviceHolder->getSoundColumn(sn)->play("正在称重,请稍后"); }); + + + auto weight = Application::deviceHolder->getPlatformScale(sn)->reading(); + + std::string date = DateUtil::format(Ymd); + auto photoId = Snowflake::genIdStr(); + auto bodyImageFile = Application::deviceHolder->getVidicon(sn)->photograph(); + auto [carFrontUrlSucc,carFrontUrl] = Application::oss->upload(date + "/" + "front_" + photoId + ".jpg", frontImageFile); + + auto [carBodyUrlSucc,carBodyUrl] = Application::oss->upload(date + "/" + "body_" + photoId + ".jpg", bodyImageFile); + + // 上报 2 + Application::reportSvr->report(license, sn, weight, carFrontUrl, carBodyUrl, orderNo); + } } // zsy diff --git a/src/recognize_processor.h b/src/recognize_processor.h index fbc371c..f958273 100644 --- a/src/recognize_processor.h +++ b/src/recognize_processor.h @@ -1,14 +1,19 @@ #ifndef RECOGNIZE_PROCESSOR_H #define RECOGNIZE_PROCESSOR_H +#include #include +#include "barrier/barrier.h" + namespace zsy { class RecognizeProcessor { public: - static void process(bool front, const std::string& sn, const std::string& license, const std::string& imageFile); + static void process(std::shared_ptr data); + + static void addition_process(const std::string &orderNo,std::shared_ptr data); }; } // zsy diff --git a/src/report_svr/report_svr.cpp b/src/report_svr/report_svr.cpp index 8572022..81c43dc 100644 --- a/src/report_svr/report_svr.cpp +++ b/src/report_svr/report_svr.cpp @@ -3,7 +3,7 @@ #include #include -#include "common/loging.h" +#include "common/logging.h" namespace zsy { @@ -12,7 +12,7 @@ namespace zsy { } - ReportPassResult ReportSvr::reportPass(const std::string &license, const std::string &sn, const std::string &carFrontUrl) + ReportPassResult ReportSvr::reportPass(const std::string &license, const std::string &sn) { try { @@ -22,7 +22,6 @@ namespace zsy ReportData reportData; reportData.carNumber = license; reportData.carDiscernCode = sn; - reportData.photoFront = carFrontUrl; nlohmann::json data = reportData; diff --git a/src/report_svr/report_svr.h b/src/report_svr/report_svr.h index f54784e..9030f29 100644 --- a/src/report_svr/report_svr.h +++ b/src/report_svr/report_svr.h @@ -111,7 +111,7 @@ namespace zsy public: ReportSvr(const nlohmann::json &config); - ReportPassResult reportPass(const std::string &license, const std::string &sn, const std::string &carFrontUrl); + ReportPassResult reportPass(const std::string &license, const std::string &sn); ReportResult report(const std::string &license, diff --git a/src/serial_port/serial_port.cpp b/src/serial_port/serial_port.cpp index d3ff15a..001193e 100644 --- a/src/serial_port/serial_port.cpp +++ b/src/serial_port/serial_port.cpp @@ -1,6 +1,6 @@ #include "serial_port.h" -#include "common/loging.h" +#include "common/logging.h" #include "common/sys_util.h" namespace zsy diff --git a/src/vidicon/barrier_vidicon.cpp b/src/vidicon/barrier_vidicon.cpp index f3cf361..8f83927 100644 --- a/src/vidicon/barrier_vidicon.cpp +++ b/src/vidicon/barrier_vidicon.cpp @@ -8,7 +8,7 @@ namespace zsy { - bool BarrierVidicon::saveImageToFile(const std::string &decodedImageData, const std::string &filePath) + void BarrierVidicon::saveImageToFile(const std::string &decodedImageData, const std::string &filePath) { try { @@ -29,12 +29,12 @@ namespace zsy { throw std::system_error(errno, std::generic_category(), "写入文件失败"); } - - return true; } catch (const std::exception &e) { LOGGER_ERROR("图片保存失败"); - return false; + }catch (...) + { + LOGGER_ERROR("未知异常,图片保存失败"); } } @@ -46,8 +46,7 @@ namespace zsy : config(config) , hasNewContent(false) { - SysUtil::createDirs(SysUtil::HOME_DIR + "\\temp"); - auto cli = Application::mqttCliHolder->localCli(); + // SysUtil::createDirs(SysUtil::HOME_DIR + "\\temp"); Application::eventManager->subscribe(MqttCli::TYPE_LOCAL + "/device/" + config.ip + "/message/up/snapshot", [this](const EventManager::Event &event) { if (!event.data.has_value()) @@ -63,7 +62,7 @@ namespace zsy imageContent = res.payload.image_content; hasNewContent.store(true); }); - Application::eventManager->subscribe(MqttCli::TYPE_LOCAL + "/device/" + config.ip + "/message/down/snapshot/reply", [this](const EventManager::Event &event) + Application::eventManager->subscribe(MqttCli::TYPE_LOCAL + "/device/" + config.ip + "/message/down/snapshot/reply", [this](const EventManager::Event &event) { if (!event.data.has_value()) { @@ -76,12 +75,12 @@ namespace zsy }); } - std::string BarrierVidicon::photograph() + std::shared_ptr BarrierVidicon::photograph() { try { LOGGER_INFO("摄像机正在拍照,设备名称:{}", config.name); - const long timestamp = static_cast(DateUtil::timestamp()/1000); + const long timestamp = static_cast(DateUtil::timestamp() / 1000); nlohmann::json j{ {"id", "photograph" + std::to_string(timestamp)}, {"sn", config.ip}, @@ -117,10 +116,9 @@ namespace zsy } while (i <= 10 && !hasNewContent.load()); const auto filename = "car_body_" + Snowflake::genIdStr() + ".jpg"; - std::string path = SysUtil::HOME_DIR + "\\temp\\" + filename; auto content = SysUtil::base64_decode(imageContent); - bool res = saveImageToFile(content, path); - return path; + + return std::make_shared(content, std::ios_base::in | std::ios_base::binary); } else { LOGGER_ERROR("未找到 MQTT 本地客户端"); @@ -132,16 +130,16 @@ namespace zsy { LOGGER_ERROR("未知异常,拍照失败"); } - return ""; + return nullptr; } catch (std::exception &e) { LOGGER_ERROR("摄像机拍照失败:{}", e.what()); - return {}; + return nullptr; } catch (...) { LOGGER_ERROR("未知异常,摄像机拍照失败"); - return {}; + return nullptr; } } } diff --git a/src/vidicon/barrier_vidicon.h b/src/vidicon/barrier_vidicon.h index fbc54c1..b27809f 100644 --- a/src/vidicon/barrier_vidicon.h +++ b/src/vidicon/barrier_vidicon.h @@ -34,14 +34,14 @@ namespace zsy std::atomic hasNewContent; std::string imageContent; - bool saveImageToFile(const std::string &decodedImageData, const std::string &filePath); + void saveImageToFile(const std::string &decodedImageData, const std::string &filePath); public: ~BarrierVidicon() override; explicit BarrierVidicon(const VidiconProperties &config); - std::string photograph() override; + std::shared_ptr photograph() override; }; } diff --git a/src/vidicon/generic_vidicon.cpp b/src/vidicon/generic_vidicon.cpp index aacae39..05395b5 100644 --- a/src/vidicon/generic_vidicon.cpp +++ b/src/vidicon/generic_vidicon.cpp @@ -1,4 +1,7 @@ #include "generic_vidicon.h" + +#include + #include "HCNetSDK.h" #include "common/snowflake.h" #include "common/sys_util.h" @@ -15,7 +18,76 @@ namespace zsy SysUtil::createDirs(SysUtil::HOME_DIR + "\\temp"); } - std::string GenericVidicon::photograph() + std::shared_ptr GenericVidicon::read(const std::string &filePath) + { + if (!std::filesystem::exists(filePath)) + { + LOGGER_ERROR("文件不存在:{}", filePath); + return nullptr; + } + + std::uintmax_t fileSize = 0; + try + { + fileSize = std::filesystem::file_size(filePath); + } catch (const std::filesystem::filesystem_error &e) + { + LOGGER_ERROR("获取文件大小失败 - {}", e.what()); + return nullptr; + } + // 打开文件 + std::ifstream file(filePath, std::ios::binary); + if (!file.is_open()) + { + LOGGER_ERROR("错误: 无法打开文件 {}", filePath); + return nullptr; + } + + std::string fileContent; + fileContent.reserve(fileSize); + + char buffer[4096]; + while (file.read(buffer, sizeof(buffer))) + { + fileContent.append(buffer, sizeof(buffer)); + } + + // 处理最后一块可能不完整的数据 + if (file.gcount() > 0) + { + fileContent.append(buffer, file.gcount()); + } + + // 检查读取是否成功 + if (!file.eof()) + { + LOGGER_ERROR("错误: 读取文件 '{}' 时发生错误", filePath); + return nullptr; + } + + // 关闭文件 + file.close(); + + return std::make_shared(fileContent, std::ios_base::in | std::ios_base::binary); + } + + void GenericVidicon::remove(const std::string &photographPath) + { + if (!photographPath.empty()) + { + auto pathPtr = SysUtil::ch_vlt(photographPath.c_str()); + if (std::remove(pathPtr.get()) != 0) + { + auto [_,code,msg] = SysUtil::getError(); + LOGGER_ERROR("临时照片删除失败:{},错误码:{},错误信息:{}", photographPath, code, msg); + } else + { + LOGGER_ERROR("临时照片删除成功:{}", photographPath); + } + } + } + + std::shared_ptr GenericVidicon::photograph() { try { @@ -73,7 +145,11 @@ namespace zsy NET_DVR_Logout_V30(lLoginID); NET_DVR_Cleanup(); - return path; + auto content = read(path); + + remove(path); + + return content; } catch (std::exception &e) { LOGGER_ERROR("摄像机拍照失败:{}", e.what()); diff --git a/src/vidicon/generic_vidicon.h b/src/vidicon/generic_vidicon.h index 4de8107..4d9f6fe 100644 --- a/src/vidicon/generic_vidicon.h +++ b/src/vidicon/generic_vidicon.h @@ -8,12 +8,17 @@ namespace zsy class GenericVidicon : public Vidicon { VidiconProperties config; + public: ~GenericVidicon() override; GenericVidicon(const VidiconProperties &config); - std::string photograph() override; + std::shared_ptr read(const std::string &photographPath); + + void remove(const std::string &photographPath); + + std::shared_ptr photograph() override; }; } // zsy diff --git a/src/vidicon/test_vidicon.cpp b/src/vidicon/test_vidicon.cpp index 0f9ad3d..aff2657 100644 --- a/src/vidicon/test_vidicon.cpp +++ b/src/vidicon/test_vidicon.cpp @@ -1,8 +1,9 @@ #include "test_vidicon.h" -namespace zsy { - std::string TestVidicon::photograph() +namespace zsy +{ + std::shared_ptr TestVidicon::photograph() { - return ""; + return nullptr; } -} // zsy \ No newline at end of file +} // zsy diff --git a/src/vidicon/test_vidicon.h b/src/vidicon/test_vidicon.h index 3b3d813..12facb6 100644 --- a/src/vidicon/test_vidicon.h +++ b/src/vidicon/test_vidicon.h @@ -7,7 +7,7 @@ namespace zsy class TestVidicon : public Vidicon { public: - std::string photograph() override; + std::shared_ptr photograph() override; }; } // zsy diff --git a/src/vidicon/vidicon.h b/src/vidicon/vidicon.h index 788463e..0882408 100644 --- a/src/vidicon/vidicon.h +++ b/src/vidicon/vidicon.h @@ -1,5 +1,6 @@ #ifndef VIDICON_H #define VIDICON_H +#include #include @@ -10,7 +11,7 @@ namespace zsy public: virtual ~Vidicon() = default; - virtual std::string photograph() = 0; + virtual std::shared_ptr photograph() = 0; }; }