Prechádzať zdrojové kódy

V0.1.8
1、添加了标准UI库,包括css文件
2、修改了QtFtp,添加了阻塞等待时间

Apple 8 mesiacov pred
rodič
commit
f8e6da0597
50 zmenil súbory, kde vykonal 469 pridanie a 61 odobranie
  1. 2 0
      Libraries/LHQLog/src/LHQLogAPI.h
  2. 1 1
      Libraries/Libraries.cmake
  3. 8 0
      UI/Resource/Standard.qrc
  4. BIN
      UI/Resource/Standard_ICON/Checked.png
  5. BIN
      UI/Resource/Standard_ICON/CloseAll.png
  6. BIN
      UI/Resource/Standard_ICON/CloseAll2.png
  7. BIN
      UI/Resource/Standard_ICON/Date.png
  8. BIN
      UI/Resource/Standard_ICON/Delete.png
  9. BIN
      UI/Resource/Standard_ICON/Delete2.png
  10. BIN
      UI/Resource/Standard_ICON/Dialog_close.png
  11. BIN
      UI/Resource/Standard_ICON/Dialog_close2.png
  12. BIN
      UI/Resource/Standard_ICON/DownArrow.png
  13. BIN
      UI/Resource/Standard_ICON/GroupOfTwo_B.png
  14. BIN
      UI/Resource/Standard_ICON/GroupOfTwo_G.png
  15. BIN
      UI/Resource/Standard_ICON/IPSet_Black.png
  16. BIN
      UI/Resource/Standard_ICON/IPSet_Blue.png
  17. BIN
      UI/Resource/Standard_ICON/KeyMap.png
  18. BIN
      UI/Resource/Standard_ICON/Light.png
  19. BIN
      UI/Resource/Standard_ICON/Notify.png
  20. BIN
      UI/Resource/Standard_ICON/PartClose.png
  21. BIN
      UI/Resource/Standard_ICON/PartClose2.png
  22. BIN
      UI/Resource/Standard_ICON/SerialInEnable.png
  23. BIN
      UI/Resource/Standard_ICON/SerialInNoEnable.png
  24. BIN
      UI/Resource/Standard_ICON/Switch_Close.png
  25. BIN
      UI/Resource/Standard_ICON/Switch_Close_NoEdit.png
  26. BIN
      UI/Resource/Standard_ICON/Switch_Open.png
  27. BIN
      UI/Resource/Standard_ICON/Switch_OpenNoEdit.png
  28. BIN
      UI/Resource/Standard_ICON/Time.png
  29. BIN
      UI/Resource/Standard_ICON/Timing_Black.png
  30. BIN
      UI/Resource/Standard_ICON/Timing_Blue.png
  31. BIN
      UI/Resource/Standard_ICON/Tip.png
  32. BIN
      UI/Resource/Standard_ICON/Tip/Complete2x.png
  33. BIN
      UI/Resource/Standard_ICON/Tip/Failed2x.png
  34. BIN
      UI/Resource/Standard_ICON/Tip/Tips2x.png
  35. BIN
      UI/Resource/Standard_ICON/Tip/Wait2x.png
  36. BIN
      UI/Resource/Standard_ICON/Unchaecked.png
  37. BIN
      UI/Resource/Standard_ICON/WhiteBox.png
  38. BIN
      UI/Resource/Standard_ICON/add_white.png
  39. BIN
      UI/Resource/Standard_ICON/logo-ESM-8C.png
  40. BIN
      UI/Resource/Standard_ICON/logo.ico
  41. BIN
      UI/Resource/Standard_ICON/logo.png
  42. BIN
      UI/Resource/Standard_ICON/minimize.png
  43. BIN
      UI/Resource/Standard_ICON/minimize2.png
  44. 218 0
      UI/Resource/qss/selectDialog.css
  45. 157 37
      common/CurlFtp/CurlFtp.cpp
  46. 21 2
      common/CurlFtp/CurlFtp.h
  47. 11 18
      common/LHLog/LHLogInit.cpp
  48. 2 1
      common/LHLog/LHLogInit.h
  49. 44 1
      common/ftp/QtFtp.cpp
  50. 5 1
      common/ftp/QtFtp.h

+ 2 - 0
Libraries/LHQLog/src/LHQLogAPI.h

@@ -14,6 +14,7 @@
 #define MyLog(msg)      qDebug() << "[" << __FILE__ << __FUNCTION__ << __LINE__ << QTime::currentTime().toString("hh:mm:ss.zzz") << "]" << msg
 
 
+
 #define LimitLog(interval, msg) \
     do{\
         static QElapsedTimer timer;\
@@ -75,4 +76,5 @@ private:
     FunDoWriteLog       fnDoWriteLog;
     FunDoWriteFileLog   fnDoWriteFileLog;
 };
+
 extern CLHQLogApi g_apiLhQLog;

+ 1 - 1
Libraries/Libraries.cmake

@@ -20,7 +20,7 @@ endif()
 # 这一段主要是搜索生成的标准开源库
 # fmt、spdlog、CURL等
 # fmt和spdlog的64位支持动态库和静态库,32位只支持静态库
-# spdlog设置 USING_SPDLOG_STATIC_LIB = TRUE,使用静态库,否则使用动态库,默认使用动态库
+# spdlog设置 ENABLE_SPDLOG_STATIC_LIB = TRUE,使用静态库,否则使用动态库,默认使用动态库
 # CURL只支持动态库,debug版本的.cmake文件也经过修改,全部指向release版本的动态库,方便和LHHTTPAPI一起调用
 
 if(CMAKE_SYSTEM_NAME MATCHES "Windows")

+ 8 - 0
UI/Resource/Standard.qrc

@@ -0,0 +1,8 @@
+<RCC>
+    <qresource prefix="/">
+        <file>Standard_ICON/Dialog_close.png</file>
+        <file>Standard_ICON/Dialog_close2.png</file>
+        <file>Standard_ICON/DownArrow.png</file>
+        <file>qss/selectDialog.css</file>
+    </qresource>
+</RCC>

BIN
UI/Resource/Standard_ICON/Checked.png


BIN
UI/Resource/Standard_ICON/CloseAll.png


BIN
UI/Resource/Standard_ICON/CloseAll2.png


BIN
UI/Resource/Standard_ICON/Date.png


BIN
UI/Resource/Standard_ICON/Delete.png


BIN
UI/Resource/Standard_ICON/Delete2.png


BIN
UI/Resource/Standard_ICON/Dialog_close.png


BIN
UI/Resource/Standard_ICON/Dialog_close2.png


BIN
UI/Resource/Standard_ICON/DownArrow.png


BIN
UI/Resource/Standard_ICON/GroupOfTwo_B.png


BIN
UI/Resource/Standard_ICON/GroupOfTwo_G.png


BIN
UI/Resource/Standard_ICON/IPSet_Black.png


BIN
UI/Resource/Standard_ICON/IPSet_Blue.png


BIN
UI/Resource/Standard_ICON/KeyMap.png


BIN
UI/Resource/Standard_ICON/Light.png


BIN
UI/Resource/Standard_ICON/Notify.png


BIN
UI/Resource/Standard_ICON/PartClose.png


BIN
UI/Resource/Standard_ICON/PartClose2.png


BIN
UI/Resource/Standard_ICON/SerialInEnable.png


BIN
UI/Resource/Standard_ICON/SerialInNoEnable.png


BIN
UI/Resource/Standard_ICON/Switch_Close.png


BIN
UI/Resource/Standard_ICON/Switch_Close_NoEdit.png


BIN
UI/Resource/Standard_ICON/Switch_Open.png


BIN
UI/Resource/Standard_ICON/Switch_OpenNoEdit.png


BIN
UI/Resource/Standard_ICON/Time.png


BIN
UI/Resource/Standard_ICON/Timing_Black.png


BIN
UI/Resource/Standard_ICON/Timing_Blue.png


BIN
UI/Resource/Standard_ICON/Tip.png


BIN
UI/Resource/Standard_ICON/Tip/Complete2x.png


BIN
UI/Resource/Standard_ICON/Tip/Failed2x.png


BIN
UI/Resource/Standard_ICON/Tip/Tips2x.png


BIN
UI/Resource/Standard_ICON/Tip/Wait2x.png


BIN
UI/Resource/Standard_ICON/Unchaecked.png


BIN
UI/Resource/Standard_ICON/WhiteBox.png


BIN
UI/Resource/Standard_ICON/add_white.png


BIN
UI/Resource/Standard_ICON/logo-ESM-8C.png


BIN
UI/Resource/Standard_ICON/logo.ico


BIN
UI/Resource/Standard_ICON/logo.png


BIN
UI/Resource/Standard_ICON/minimize.png


BIN
UI/Resource/Standard_ICON/minimize2.png


+ 218 - 0
UI/Resource/qss/selectDialog.css

@@ -0,0 +1,218 @@
+
+QWidget{
+    background: transparent;
+    border-radius: 8px;
+    font-family: 思源黑体R;
+    font-weight: 400;
+    font-size: 14px;
+    color: #3A3F63;
+    line-height: 21px;
+    text-align: left;
+    font-style: normal;
+}
+
+QWidget#widget
+{
+    border-radius: 8px;
+    background: #FFFFFF;
+}
+
+/* 分割线 */
+QLabel#label_line1
+{
+    background: #E6E9F4;
+}
+
+/* 左上角标题 */
+QLabel#label_title
+{
+    font-family: 思源黑体R;
+    font-weight: bold;
+    font-size: 18px;
+    color: #3A3F63;
+    line-height: 27px;
+    text-align: left;
+    font-style: normal;
+    text-transform: uppercase;
+}
+
+/* 警告label */
+QLabel#label_warn
+{
+    font-weight: 400;
+    font-size: 14px;
+    color: #D21F21;
+    line-height: 21px;
+    text-align: left;
+    font-style: normal;
+}
+
+/*********** 按钮设置 ***********/
+QPushButton{
+    text-align: center;
+    font-family: 思源黑体M;
+    font-weight: 400;
+    font-size: 14px;
+    line-height: 21px;
+}
+/* 关闭按钮 */
+QPushButton#pBtn_close{
+    image: url(:/Standard_ICON/Dialog_close.png);
+}
+QPushButton#pBtn_close:hover
+{
+    image: url(:/Standard_ICON/Dialog_close2.png);
+}
+
+/********* 普通方框按钮三种状态效果 *********/
+QPushButton#pBtn_cancel:enabled,#pBtn_getChannel:enabled
+{
+    background: #FFFFFF;
+    border-radius: 16px;
+    border: 1px solid #E6E9F4;
+    color: #3A3F63;
+}
+QPushButton#pBtn_cancel:hover,#pBtn_getChannel:hover
+{
+    background: #FFFFFF;
+    border-radius: 16px;
+    border: 1px solid #4458FE;
+    color: #4458FE;
+}
+/* 普通方框按钮 */
+QPushButton#pBtn_getChannel:enabled
+{
+    background: #FFFFFF;
+    border-radius: 4px;
+    border: 1px solid #E6E9F4;
+    color: #3A3F63;
+}
+QPushButton#pBtn_getChannel:hover
+{
+    background: #FFFFFF;
+    border-radius: 4px;
+    border: 1px solid #4458FE;
+    color: #4458FE;
+}
+
+/********* 带有底色按钮三种状态效果 *********/
+QPushButton#pBtn_ok
+{
+    color:white;
+    background: qlineargradient( x0:1,x1:1,y1:0,y2:0,stop:1 #4F8AFF,stop:0 #4B5EFF);
+    border-radius: 16px;
+}
+
+QPushButton#pBtn_ok:hover
+{
+    color:white;
+    background: qlineargradient( x0:1,x1:1,y1:0,y2:0,stop:0 #5D73FF,stop:1 #6092FF);
+    border-radius: 16px;
+}
+    
+
+
+QLabel#label_devWarn,QLabel#label_timeWarn,QLabel#label_actionWarn
+{
+    font-weight: 400;
+    font-size: 14px;
+    color: #D21F21;
+    line-height: 21px;
+    text-align: left;
+    font-style: normal;
+}
+    
+    
+/********************************* QComboBox *****************************/
+
+QComboBox
+{
+    border: 1px solid #E6E9F4;
+    border-radius: 4px;
+    background:#FFFFFF;
+    padding-left: 12px;
+}
+QComboBox[Warn=true]
+{
+    border: 1px solid #D21F21;
+    border-radius: 4px;
+    background:#FFFFFF;
+    padding-left: 12px;
+}
+QComboBox[hover]
+{
+    border: 1px solid #4458FE;
+    border-radius: 4px;
+    background:#FFFFFF;
+}
+/* 下拉箭头所在的位置方框 */
+QComboBox::drop-down
+{
+    width: 24px;
+    border: none;
+    }
+/* 下拉箭头图标 */
+QComboBox::down-arrow
+{
+    image: url(:/Standard_ICON/DownArrow.png);
+    height:16px;
+    width:16px;
+}
+/* 下拉条样式,就是view */
+QComboBox QAbstractItemView
+{
+    outline:0px solid gray;
+    font-size:14px;
+    background:#ffffff;
+    color: #3A3F63;
+    margin: 4px;
+    border-radius: 2px;
+    border: none;
+}
+/* 使下面两句生效,需要加上如下语句 */
+/* m_comBoxDev->setView(new QListView()); */
+QComboBox QAbstractItemView::item
+{
+    font-size:14px;
+    border-radius:2px;
+    color: #3A3F63;
+    padding-left: 8px;
+    height: 30px;
+}
+
+QComboBox QAbstractItemView::item:selected
+{
+    background: #EEF2FF;
+    font-size:14px;
+    color: #3a3f63;
+    height: 30px;
+    padding-left: 8px;
+}
+
+/******** combobox 滚动条  *********/
+QComboBox QScrollBar::vertical{ /*主体部分*/
+    width:8px;
+    background:transparent;
+    border:none;
+    border-radius:5px;
+}
+QComboBox QScrollBar::handle::vertical{ /*滑块主体*/
+    width: 8px;
+    background: #E2E2E2;
+    border-radius: 3px;
+    min-width: 8px;
+}
+QComboBox QScrollBar::handle::vertical:hover{
+    background:transparent;
+}
+QComboBox QScrollBar::add-line::vertical{/*上箭头*/
+    border:none;
+}
+QComboBox QScrollBar::sub-line::vertical{/*下箭头*/
+    border:none;
+}
+    
+    
+
+    
+    

+ 157 - 37
common/CurlFtp/CurlFtp.cpp

@@ -4,16 +4,83 @@
 #include <regex>
 #include <iosfwd>
 
-CurlFtp::CurlFtp()
+
+/* 是否有初始化实例,主要用于静态函数调用curl_global_cleanup()函数前判断,有实例就不调用 */
+static bool hasInstace = false;
+
+/* ==================================================================================
+ * *********************************** 全局函数 *************************************
+ * ================================================================================== */
+
+/**
+ * @brief 写入回调函数
+ * 
+ * @param contents curl的数据缓冲区
+ * @param size 数据大小,单位是size_t
+ * @param nmemb size_t的单位字节数
+ * @param s 用户提供的字符串
+ * @return size_t 总共获取到的数据大小,单位是字节
+ */
+static size_t writeStringCallback(void *contents, size_t size, size_t nmemb, std::string *s) 
 {
+    size_t newLength = size*nmemb;
+    size_t oldLength = s->size();
+    try
+    {
+        s->resize(oldLength + newLength);
+    }
+    catch(std::bad_alloc &e)
+    {
+        //handle memory problem
+        return 0;
+    }
 
+    std::copy((char*)contents,(char*)contents+newLength,s->begin()+oldLength);
+    return size*nmemb;
 }
 
 
-CurlFtp::~CurlFtp()
+/**
+ * @brief 写入回调函数,listFiles需要调用
+ * 
+ * @param buffer curl下载回来的数据
+ * @param size 数据大小
+ * @param nmemb 数据单位字节数
+ * @param userp 用户传进来的容器
+ * @return int 返回拷贝的字节数
+ */
+static int writeStringListCallback(void* buffer, size_t size, size_t nmemb, void* userp)
+{
+    std::vector<std::string>* fileList = static_cast<std::vector<std::string>*>(userp);
+    std::string line(static_cast<char*>(buffer), size * nmemb);
+    // printf("line = %s\n", line.c_str());
+    fileList->push_back(line);
+    return size * nmemb;
+}
+
+
+
+/* ==================================================================================
+ * *********************************** 成员函数 *************************************
+ * ================================================================================== */
+
+
+CurlFtp::CurlFtp()
 {
+    /* 调用初始化函数,这个函数可以重复调用 */
+    curl_global_init(CURL_GLOBAL_DEFAULT);
+    /* 初始化curl */
+    m_curl = curl_easy_init();
+    hasInstace = true;
+}
 
 
+CurlFtp::~CurlFtp()
+{
+    /* 清理curl */
+    curl_easy_cleanup(m_curl);
+    curl_global_cleanup();
+    hasInstace = false;
 }
 
 /* 检查文件夹是否存在,不确定好不好用 */
@@ -88,64 +155,44 @@ std::string CurlFtp::listDir(const std::string &ftpUrl, const std::string &usern
     CURLcode res;
     bool result = false;
     std::string retList;
-
+    /* 1. 初始化curl,这个函数需要在调用任何curl函数之前 */
     curl_global_init(CURL_GLOBAL_DEFAULT);
+    /* 2. 获取一个curl句柄 */
     curl = curl_easy_init();
     if(curl) 
     {
+        /* 3. 设置curl选项 */
         curl_easy_setopt(curl, CURLOPT_URL, ftpUrl.c_str());
         curl_easy_setopt(curl, CURLOPT_USERNAME, username.c_str());
         curl_easy_setopt(curl, CURLOPT_PASSWORD, password.c_str());
         // curl_easy_setopt(curl, CURLOPT_DIRLISTONLY, 1L); // We only want the directory listing
 
-        
-        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeCallback);
+        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeStringCallback);
         curl_easy_setopt(curl, CURLOPT_WRITEDATA, &retList);
 
+        /* 4. 发送信息,一直等待知道返回 */
         res = curl_easy_perform(curl);
         // printf("res = %d\n", res);
         if(res != CURLE_OK) 
         {
             fprintf(stderr, "getDirList() failed, error code %d, :%s\n",res, curl_easy_strerror(res));
-        }
-        else 
+        } else 
         {
             // std::cout << "Directory list: \n" << retList << std::endl;
         }
+        /* 5. 清理curl */
         curl_easy_cleanup(curl);
     }
-    
-    curl_global_cleanup();
+    if(hasInstace == false)
+    {
+        curl_global_cleanup();
+    }
     return retList;
 }
 
-/* 写入回调函数,listDir需要调用 */
-size_t CurlFtp::writeCallback(void *contents, size_t size, size_t nmemb, std::string *s) 
-{
-    size_t newLength = size*nmemb;
-    size_t oldLength = s->size();
-    try
-    {
-        s->resize(oldLength + newLength);
-    }
-    catch(std::bad_alloc &e)
-    {
-        //handle memory problem
-        return 0;
-    }
 
-    std::copy((char*)contents,(char*)contents+newLength,s->begin()+oldLength);
-    return size*nmemb;
-}
 
-// Callback function to collect the list of files
-static int filelistCallback(void* buffer, size_t size, size_t nmemb, void* userp)
-{
-    std::vector<std::string>* fileList = static_cast<std::vector<std::string>*>(userp);
-    std::string line(static_cast<char*>(buffer), size * nmemb);
-    fileList->push_back(line);
-    return size * nmemb;
-}
+
 
 /* 列出文件夹中的所有文件 */
 bool CurlFtp::listFiles(const std::string &ftpUrl, const std::string &username, const std::string &password, std::vector<std::string>& fileList)
@@ -162,7 +209,7 @@ bool CurlFtp::listFiles(const std::string &ftpUrl, const std::string &username,
         curl_easy_setopt(curl, CURLOPT_USERNAME, username.c_str());
         curl_easy_setopt(curl, CURLOPT_PASSWORD, password.c_str());
         curl_easy_setopt(curl, CURLOPT_DIRLISTONLY, 1L);
-        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, filelistCallback);
+        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeStringListCallback);
         curl_easy_setopt(curl, CURLOPT_WRITEDATA, &fileList);
 
         res = curl_easy_perform(curl);
@@ -182,7 +229,10 @@ bool CurlFtp::listFiles(const std::string &ftpUrl, const std::string &username,
         curl_easy_cleanup(curl);
     }
 
-    curl_global_cleanup();
+    if(hasInstace == false)
+    {
+        curl_global_cleanup();
+    }
     return result;
 }
 
@@ -228,7 +278,77 @@ bool CurlFtp::createDir(const std::string &ftpUrl, const std::string &username,
         curl_slist_free_all(headerlist);
     }
 
-    curl_global_cleanup();
+    if(hasInstace == false)
+    {
+        curl_global_cleanup();
+    }
+    return result;
+}
+
+
+/* 设置IP和端口 */
+bool CurlFtp::setFtpIPAndPort(const std::string& IP, const std::string& port)
+{
+    /*先判断是否有ftp器前缀,通过正则表达式,取出IP地址和端口号,去掉前缀和后面的'/ */
+    m_IP = IP;
+    m_port = port;
+    m_ftpUrl = "ftp://" + m_IP + ":" + m_port;
+    printf("ftpUrl = %s\n", m_ftpUrl.c_str());
+
+    return true;
+}
+
+
+/* 设置用户名和密码 */
+bool CurlFtp::setFtpUsernameAndPassword(const std::string& username, const std::string& password)
+{
+    m_username = username;
+    m_password = password;
+
+    return true;
+}
+
+/* 列出文件列表 */
+bool CurlFtp::listAll(std::string dir, std::vector<std::string>& fileList)
+{
+    if(m_IP.empty() || m_port.empty())
+    {
+        printf("IP or port is empty\n");
+        return false;
+    }
+    if(m_curl == nullptr)
+    {
+        printf("m_curl is nullptr\n");
+        return false;
+    } 
+    bool result = false;
+    /* 先设置FTP地址 */
+    std::string ftpUrl = m_ftpUrl + dir;
+    curl_easy_setopt(m_curl, CURLOPT_URL, ftpUrl.c_str());
+    /* 设置用户名和密码 */
+    curl_easy_setopt(m_curl, CURLOPT_USERNAME, m_username.c_str());
+    curl_easy_setopt(m_curl, CURLOPT_PASSWORD, m_password.c_str());
+
+    /* 设置列出文件命令,只列出文件名称,不携带信息 */
+    // curl_easy_setopt(m_curl, CURLOPT_DIRLISTONLY, 1L);
+    /* 设置回调函数 */
+    curl_easy_setopt(m_curl, CURLOPT_WRITEFUNCTION, writeStringListCallback);
+    /* 设置需要写入的容器 */
+    curl_easy_setopt(m_curl, CURLOPT_WRITEDATA, &fileList);
+
+    /* 发送请求 */
+    m_res = curl_easy_perform(m_curl);
+    if(m_res != CURLE_OK) 
+    {
+        fprintf(stderr, "Failed to get file list, error code :%d ,%s\n", m_res, curl_easy_strerror(m_res));
+        result = false;
+    } else 
+    {
+        result = true;
+    }
+
+
+    // curl_easy_cleanup(m_curl);
     return result;
 }
 

+ 21 - 2
common/CurlFtp/CurlFtp.h

@@ -4,6 +4,7 @@
 #include "curl/curl.h"
 #include <string>
 #include <vector>
+#include <mutex>
 
 class CurlFtp
 {
@@ -18,12 +19,30 @@ public:
     // static bool isDirExists(const std::string &ftpUrl, const std::string &username, const std::string &password);
     /* 使用正则表达式提取出文件夹 */
     // static bool CurlFtp::extractDirectories(const std::string& responseString);
-    /* 回调函数 */
-    static size_t writeCallback(void *contents, size_t size, size_t nmemb, std::string *s);
 
     /* 创建文件夹 */
     static bool createDir(const std::string &ftpUrl, const std::string &username, const std::string &password, const std::string &dirName);
 
+    /* 设置IP和端口 */
+    bool setFtpIPAndPort(const std::string& IP, const std::string& port);
+    /* 设置用户名和密码 */
+    bool setFtpUsernameAndPassword(const std::string& username, const std::string& password);
+    /* 列出文件列表 */
+    bool listAll(std::string dir, std::vector<std::string>& fileList);
+
+private:
+    std::mutex m_mutexCurl;                 /* curl互斥锁 */
+    CURL* m_curl = nullptr;                 /* curl句柄 */
+    CURLcode m_res = CURLE_OK;              /* 返回值 */
+    std::string m_responseString;           /*  */
+
+    std::string m_IP;                       /* IP */
+    std::string m_port;                     /* 端口 */
+    std::string m_ftpUrl;                   /* ftpUrl */
+    std::string m_username;
+    std::string m_password;
+    std::string m_dirName;
+
 };
 
 

+ 11 - 18
common/LHLog/LHLogInit.cpp

@@ -8,8 +8,10 @@
 #include <QString>
 #include <QApplication>
 
-/* 初始化spdlog,输入的是模组名称,可以为空 */
-void initLog(QString ModuleName)
+/* 初始化spdlog,输入的是模组名称,可以为空
+ * lhQLog是一个全局函数,在库LHQLog中定义
+ */
+void initLog(QString ModuleName, CLHQLogApi& lhQLog)
 {
 
     try {
@@ -23,7 +25,7 @@ void initLog(QString ModuleName)
     #elif C_RELEASE
         QString libName = QCoreApplication::applicationDirPath() + "/LHQLog.dll";
     #endif
-        auto sink_custom = std::make_shared<spdlog::sinks::LHLog_file_sink_mt>(&g_apiLhQLog, libName, ModuleName);
+        auto sink_custom = std::make_shared<spdlog::sinks::LHLog_file_sink_mt>(&lhQLog, libName, ModuleName);
         /* 给默认记录器用的sink */
         auto sink_default = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
  
@@ -50,17 +52,11 @@ void initLog(QString ModuleName)
         // }
         /* 创建一个标准输出 */
         auto logger_main = std::make_shared<spdlog::logger>("main",begin(sinks),end(sinks));
+        /* 创建一个WebAPI logger */
+        auto logger_WebAPI = std::make_shared<spdlog::logger>("WebAPI",begin(sinks),end(sinks));
+        /* 创建一个发射机通用 Logger */
+        auto logger_Transmitter = std::make_shared<spdlog::logger>("Transmitter",begin(sinks),end(sinks));
 
-        /* 创建一个Line输出Logger */
-        auto logger_Line = std::make_shared<spdlog::logger>("Line",begin(sinks),end(sinks));
-        /* 创建一个Device输出Logger */
-        auto logger_Device = std::make_shared<spdlog::logger>("Device",begin(sinks),end(sinks));
-        /* 创建一个FlowChart logger */
-        auto logger_FlowChart = std::make_shared<spdlog::logger>("FlowChart",begin(sinks),end(sinks));
-        /* 创建一个Database logger */
-        auto logger_Database = std::make_shared<spdlog::logger>("Database",begin(sinks),end(sinks));
-        /* 创建一个MQTT logger */
-        auto logger_MQTT = std::make_shared<spdlog::logger>("MQTT",begin(sinks),end(sinks));
 
 //        /* 创建一个设备Info logger */
 //        auto logger_Info = std::make_shared<spdlog::logger>("DevInfo",begin(sinks),end(sinks));
@@ -68,11 +64,8 @@ void initLog(QString ModuleName)
 
         /* 注册到注册表 */
         spdlog::register_logger(logger_main);
-        spdlog::register_logger(logger_Line);
-        spdlog::register_logger(logger_Device);
-        spdlog::register_logger(logger_FlowChart);
-        spdlog::register_logger(logger_Database);
-        spdlog::register_logger(logger_MQTT);
+        spdlog::register_logger(logger_WebAPI);
+        spdlog::register_logger(logger_Transmitter);
 
         /* 设置spdlog输出级别,默认的估计不输出debug这个级别
          * 这是默认的设置,可以在外面单数设置输出方式

+ 2 - 1
common/LHLog/LHLogInit.h

@@ -2,8 +2,9 @@
 #define LHLOGINIT_H
 
 class QString;
+class CLHQLogApi;
 
-void initLog(QString ModuleName);
+void initLog(QString ModuleName, CLHQLogApi& lhQLog);
 
 
 

+ 44 - 1
common/ftp/QtFtp.cpp

@@ -14,6 +14,7 @@ QtFtp::QtFtp(QObject *parent)
     /* 设置超时定时器 */
     m_timer.setTimerType(Qt::PreciseTimer);
     m_timer.setSingleShot(true);
+    connect(&m_timer,SIGNAL(timeout()),this,SLOT(do_timeout()));
 }
 
 QtFtp::~QtFtp()
@@ -128,7 +129,7 @@ void QtFtp::getFile(const QString &fileName,const QString &srcPath)
 #endif
 }
 
-/* 下载文件,直接下载到内存 */
+/* 下载文件,直接下载到内存,路径是相对路径,不包含前面的IP地址和端口 */
 void QtFtp::getFile(QByteArray& data,const QString& srcPath)
 {
     m_isFinished = false;
@@ -157,6 +158,7 @@ void QtFtp::getFile(QByteArray& data,const QString& srcPath)
  *  @arg -1 一直等待,将会阻塞在这里
  *  @arg 0 查询是否完成
  *  @arg 正整数,等待完成的时间,设置完成之后再次设置,会覆盖之前的设置
+ *  @arg < -1,阻塞等待传入的值的绝对值时间
  * @return true 上传或下载完成
  * @return false 上传或下载进行中
  */
@@ -179,6 +181,17 @@ bool QtFtp::waitFinished(int msecs)
         m_timer.start(msecs);
         return m_isFinished;
     }
+    else if(msecs < -1)
+    {
+        QEventLoop loop;
+        connect(this, &QtFtp::signal_uploadState, &loop, &QEventLoop::quit);
+        connect(this, &QtFtp::signal_downloadState, &loop, &QEventLoop::quit);
+        m_timer.start(-msecs);
+        connect(&m_timer, &QTimer::timeout, &loop, &QEventLoop::quit);
+        loop.exec();
+        
+        return false;
+    }
     return m_isFinished;
 }
 
@@ -197,6 +210,10 @@ bool QtFtp::getResult()
 /* 上传完成 */
 void QtFtp::do_uploadFinished()
 {
+    if(m_timer.isActive())
+    {
+        m_timer.stop();
+    }
     if(m_reply->error() == QNetworkReply::NoError)
     {
         m_result = true;
@@ -250,6 +267,10 @@ bool QtFtp::createDir(const QString& path)
 /* 完成,保存文件 */
 void QtFtp::do_downloadFinished()
 {
+    if(m_timer.isActive())
+    {
+        m_timer.stop();
+    }
     if(m_reply->error() == QNetworkReply::NoError)
     {
         m_file.write(m_reply->readAll());
@@ -274,6 +295,10 @@ void QtFtp::do_downloadFinished()
 /* 下载完成,保存数据 */
 void QtFtp::do_downloadFinishedToData()
 {
+    if(m_timer.isActive())
+    {
+        m_timer.stop();
+    }
     if(m_reply->error() == QNetworkReply::NoError)
     {
         *m_downloadData = m_reply->readAll();
@@ -309,6 +334,10 @@ void QtFtp::do_downloadProgress(qint64 bytesReceived, qint64 bytesTotal)
 /* ftp其他任务完成槽函数 */
 void QtFtp::do_finished()
 {
+    if(m_timer.isActive())
+    {
+        m_timer.stop();
+    }
     m_isFinished = true;
     if(m_reply->error() == QNetworkReply::NoError)
     {
@@ -327,6 +356,20 @@ void QtFtp::do_finished()
     m_isFinished = true;
 }
 
+/* 定时器超时函数 */
+void QtFtp::do_timeout()
+{
+    if(m_reply != nullptr)
+    {
+        m_reply->abort();
+        m_reply->deleteLater();
+        m_reply = nullptr;
+        m_result = false;
+    }
+    emit signal_uploadState(false);
+    emit signal_downloadState(false);
+}
+
 /* ftp发送错误槽函数 */
 #if defined (QT_VERSION) && QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
 void QtFtp::do_ftpReplyError(QNetworkReply::NetworkError error)

+ 5 - 1
common/ftp/QtFtp.h

@@ -13,6 +13,8 @@
 
 /**
  * @brief 封装一个FTP类,这里没有单开一个线程,在调用线程中工作
+ *        这里的上传下载路径都是相对路径,不包含前面的IP地址和端口
+ *   注意:目前只支持单个请求,即一个请求完成后才能进行下一个请求
  */
 class QtFtp : public QObject
 {
@@ -31,7 +33,7 @@ public:
     void putFile(const QByteArray& data,const QString& farPath);
     /* 下载文件 */
     void getFile(const QString& fileName,const QString &srcPath);   
-    /* 下载文件,直接下载到内存 */
+    /* 下载文件,直接下载到内存,路径是相对路径,不包含前面的IP地址和端口 */
     void getFile(QByteArray& data,const QString& srcPath);
     /* 等待完成 */
     bool waitFinished(int msecs = 30000);
@@ -69,6 +71,8 @@ private slots:
     void do_downloadProgress(qint64 bytesReceived, qint64 bytesTotal);
     /* ftp其他任务完成槽函数 */
     void do_finished();
+    /* 定时器超时函数 */
+    void do_timeout();
 
     #if defined (QT_VERSION) && QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
     void do_ftpReplyError(QNetworkReply::NetworkError error);       /* ftp发送错误槽函数 */