lsb hai 3 meses
pai
achega
d26fb9b201

+ 1 - 1
Loto.pro.user

@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE QtCreatorProject>
-<!-- Written by QtCreator 18.0.2, 2026-01-28T22:18:58. -->
+<!-- Written by QtCreator 18.0.2, 2026-01-29T02:52:57. -->
 <qtcreator>
  <data>
   <variable>EnvironmentId</variable>

+ 66 - 27
src/httpclient/HttpClient.cpp

@@ -34,7 +34,12 @@ bool HttpClient::getRequest(const QString &url, const QString &token, const QByt
     requestInfo.setUrl(QUrl(strUrl));
     requestInfo.setRawHeader("Authorization", token.toUtf8());
     requestInfo.setRawHeader("tenant_id", Config()->tenant_id.toUtf8());
-    // 发送 post 请求
+
+    qDebug().noquote() << "[HTTP GET] url=" << strUrl
+        << " tenant_id=" << Config()->tenant_id
+        << " Authorization=" << (token.isEmpty() ? "(empty)" : "(set)");
+
+    // 发送 get 请求
     QNetworkReply* reply = pHttpMgr->get(requestInfo);
 
     // 添加超时处理,1ms 超时
@@ -94,6 +99,11 @@ bool HttpClient::postRequest(const QString &url, const QString &token, const QBy
     requestInfo.setRawHeader("Authorization", token.toUtf8());
     requestInfo.setRawHeader("tenant_id", Config()->tenant_id.toUtf8());
 
+    qDebug().noquote() << "[HTTP POST] url=" << strUrl
+        << " tenant_id=" << Config()->tenant_id
+        << " Authorization=" << (token.isEmpty() ? "(empty)" : "(set)")
+        << " body=" << QString::fromUtf8(inData);
+
     // 发送 post 请求
     QNetworkReply* reply = pHttpMgr->post(requestInfo, inData);
 
@@ -151,7 +161,12 @@ bool HttpClient::putRequest(const QString &url, const QString &token, const QByt
     requestInfo.setRawHeader("Authorization", token.toUtf8());
     requestInfo.setRawHeader("tenant_id", Config()->tenant_id.toUtf8());
 
-    // 发送 post 请求
+    qDebug().noquote() << "[HTTP PUT] url=" << strUrl
+        << " tenant_id=" << Config()->tenant_id
+        << " Authorization=" << (token.isEmpty() ? "(empty)" : "(set)")
+        << " body=" << QString::fromUtf8(inData);
+
+    // 发送 put 请求
     QNetworkReply* reply = pHttpMgr->put(requestInfo, inData);
 
     // 添加超时处理,1ms 超时
@@ -198,6 +213,7 @@ void HttpClient::run()
     {
         if(m_workStat != httpWorkStat::httpWorkSleep)
         {
+            m_mutex.lock();
             QString res = "";
             switch(m_workStat)
             {
@@ -208,9 +224,29 @@ void HttpClient::run()
             }
 
             QByteArray bb = res.toUtf8();
-            m_mutex.unlock();
+            QString postUrl = m_postUrl;
             m_workStat = httpWorkStat::httpWorkSleep;
-            //emit signalResponseData(m_id, m_postUrl, bb);
+            m_mutex.unlock();
+
+            // GET 请求在工作线程完成,在此发射信号,避免在主线程阻塞
+            if (postUrl == Config()->jobTicketsUrl) {
+                emit signalResponseGetJobTickets(bb);
+            }
+            else if (postUrl == Config()->workNodeDetail) {
+                emit signalResponseGetWorkNodeDetail(bb);
+            }
+            else if (postUrl == Config()->workNodeDetailForm) {
+                emit signalResponseGetFormById(bb);
+            }
+            else if (postUrl == Config()->userInfoUrl) {
+                emit signalResponseGetUserInfoUrl(bb);
+            }
+            else if (postUrl == Config()->keyMACByNFC) {
+                emit signalResponseGetKeyMAC(bb);
+            }
+            else if (postUrl == Config()->isolationPointById) {
+                emit signalResponseGetIsolationPointInfo(bb);
+            }
         }
 
         msleep(10);
@@ -238,7 +274,11 @@ QString HttpClient::postJsonRequest()
     requestInfo.setRawHeader("Authorization", auth.toUtf8());
     requestInfo.setRawHeader("tenant-id", Config()->tenant_id.toUtf8());
 
-    // QString strInfo = requestInfo.url().toString();
+    qDebug().noquote() << "[HTTP POST(Json)] url=" << url
+        << " tenant_id=" << Config()->tenant_id
+        << " postUrl=" << m_postUrl
+        << " Authorization=" << (auth.isEmpty() ? "(empty)" : "(set)")
+        << " body=" << QString::fromUtf8(m_httpData);
 
     // 发送 post 请求
     QNetworkReply* reply = pHttpMgr->post(requestInfo, m_httpData);
@@ -337,6 +377,11 @@ QString HttpClient::postFormdataRequest()
     requestInfo.setRawHeader("Authorization", auth.toUtf8());
     requestInfo.setRawHeader("tenant_id", Config()->tenant_id.toUtf8());
 
+    qDebug().noquote() << "[HTTP POST(FormData)] url=" << url
+        << " tenant_id=" << Config()->tenant_id
+        << " postUrl=" << m_postUrl
+        << " Authorization=" << (auth.isEmpty() ? "(empty)" : "(set)");
+
     // 发送 post 请求
     QNetworkReply* reply = pHttpMgr->post(requestInfo, multiPart);
     multiPart->setParent(reply); // reply删除时会自动删除multiPart
@@ -420,6 +465,13 @@ QString HttpClient::getRequest()
     QString auth = m_token;
     requestInfo.setRawHeader("Authorization", auth.toUtf8());
     requestInfo.setRawHeader("tenant_id", Config()->tenant_id.toUtf8());
+
+    qDebug().noquote() << "[HTTP GET(thread)] url=" << url
+        << " tenant_id=" << Config()->tenant_id
+        << " postUrl=" << m_postUrl
+        << " query=" << getJsonStr
+        << " Authorization=" << (auth.isEmpty() ? "(empty)" : "(set)");
+
     // 发送 get 请求
     QNetworkReply* reply = pHttpMgr->get(requestInfo);
 
@@ -483,6 +535,12 @@ QString HttpClient::putJsonRequest()
     requestInfo.setRawHeader("Authorization", auth.toUtf8());
     requestInfo.setRawHeader("tenant-id", Config()->tenant_id.toUtf8());
 
+    qDebug().noquote() << "[HTTP PUT(Json)] url=" << url
+        << " tenant_id=" << Config()->tenant_id
+        << " postUrl=" << m_postUrl
+        << " Authorization=" << (auth.isEmpty() ? "(empty)" : "(set)")
+        << " body=" << QString::fromUtf8(m_httpData);
+
     // 发送 put 请求
     QNetworkReply* reply = pHttpMgr->put(requestInfo, m_httpData);
 
@@ -590,35 +648,16 @@ void HttpClient::slotPostRequestData(quint64 id, QString postUrl, QByteArray dat
 
 void HttpClient::slotGetRequestData(quint64 id, QString postUrl, QByteArray data, QString token)
 {
+    // 不在主线程执行同步 getRequest(),否则会阻塞 UI 导致“无响应”
+    // 将参数交给工作线程,由 run() 中执行 getRequest() 并发射信号
     m_mutex.lock();
     this->m_id = id;
     this->m_postUrl = postUrl;
     this->m_httpData = data;
     this->m_token = token;
     HttpClient::sToken = token;
-
-    QString res = getRequest();
-    QByteArray bb = res.toUtf8();
+    this->m_workStat = httpWorkStat::httpWorkGet;
     m_mutex.unlock();
-
-    if (m_postUrl == Config()->jobTicketsUrl) {
-        emit signalResponseGetJobTickets(bb);
-    }
-    else if (m_postUrl == Config()->workNodeDetail) {
-        emit signalResponseGetWorkNodeDetail(bb);
-    }
-    else if (m_postUrl == Config()->workNodeDetailForm) {
-        emit signalResponseGetFormById(bb);
-    }
-    else if (m_postUrl == Config()->userInfoUrl) {
-        emit signalResponseGetUserInfoUrl(bb);
-    }
-    else if (m_postUrl == Config()->keyMACByNFC) {
-        emit signalResponseGetKeyMAC(bb);
-    }
-    else if (m_postUrl == Config()->isolationPointById) {
-        emit signalResponseGetIsolationPointInfo(bb);
-    }
 }
 
 void HttpClient::slotPutRequestData(quint64 id, QString postUrl, QByteArray data, QByteArray file, QString token)

+ 11 - 1
src/httpclient/HttpGetWorkNodeDetail.cpp

@@ -94,6 +94,8 @@ void HttpGetWorkNodeDetail::clearWorkNodeFormModel()
 {
     WorkNodeFormModel::instance()->clear();
     WorkNodeFormModel::instance()->setFormJsonInfo("");
+    WorkNodeFormModel::instance()->setFormName("");
+    WorkNodeFormModel::instance()->setDescription("");
 }
 
 void HttpGetWorkNodeDetail::run()
@@ -185,13 +187,21 @@ void HttpGetWorkNodeDetail::slotHttpResponseGetWorkNodeDetail(QByteArray data)
                     WorkNodeFormModel::instance()->setPointsList(vDataObj.value("points").toArray());
                     qDebug() << WorkNodeFormModel::instance()->pointsList();
                 }
-
                 // 页面分类:审核、录入信息
                 WorkNodeFormModel::instance()->setModelType(vDataObj.value("type").toString());
 
                 QJsonObject formData = parseJsonString(vDataObj.value("formData").toString());
                 WorkNodeFormModel::instance()->setFormJsonInfo(vDataObj.value("formData").toString());
                 
+                // description:优先从 data 根取,若无则从 formData 取(仅审核等接口可能返回)
+                if (vDataObj.contains("description") && vDataObj.value("description").isString()) {
+                    WorkNodeFormModel::instance()->setDescription(vDataObj.value("description").toString());
+                } else if (formData.contains("description") && formData.value("description").isString()) {
+                    WorkNodeFormModel::instance()->setDescription(formData.value("description").toString());
+                } else {
+                    WorkNodeFormModel::instance()->setDescription("");
+                }
+                
                 // 解析表单名称(当前任务名称)
                 if (formData.contains("name") && formData.value("name").isString()) {
                     WorkNodeFormModel::instance()->setFormName(formData.value("name").toString());

+ 11 - 0
src/httpclient/WorkNodeFormModel.h

@@ -41,6 +41,7 @@ class WorkNodeFormModel : public QAbstractListModel
     Q_PROPERTY(QJsonArray nodeUserList READ nodeUserList WRITE setNodeUserList NOTIFY nodeUserListChanged)
     Q_PROPERTY(int workId READ workId WRITE setWorkId NOTIFY workIdChanged)
     Q_PROPERTY(QString formName READ formName WRITE setFormName NOTIFY formNameChanged)
+    Q_PROPERTY(QString description READ description WRITE setDescription NOTIFY descriptionChanged)
 private:
     explicit WorkNodeFormModel(QObject *parent=nullptr);
     explicit WorkNodeFormModel() = default;
@@ -132,11 +133,20 @@ public:
         m_formName = name;
         emit formNameChanged();
     }
+
+    QString description() const {
+        return m_description;
+    }
+    void setDescription(const QString& desc) {
+        m_description = desc;
+        emit descriptionChanged();
+    }
 signals:
     void formJsonInfoChanged();
     void nodeUserListChanged();
     void workIdChanged();
     void formNameChanged();
+    void descriptionChanged();
 private:
     QList<FormControl> m_formList;
 
@@ -153,6 +163,7 @@ private:
     int m_workId;
 
     QString m_formName;
+    QString m_description;
 };
 
 #endif // WORKNODEFORMMODEL_H

+ 5 - 1
src/main.cpp

@@ -5,7 +5,7 @@
 
 #include "./interactive/InteractiveCAN.h"
 #include "./usr/LotoQmlPlugin.h"
-
+#include "./usr/config.h"
 
 int main(int argc, char **argv)
 {
@@ -16,6 +16,10 @@ int main(int argc, char **argv)
 
     qputenv("QT_IM_MODULE", QByteArray("qtvirtualkeyboard"));
 
+    // 先加载配置(含 tenant_id),若 config.xml 存在则覆盖默认值
+    Config()->configRead();
+    qDebug() << "[Config] tenant_id =" << Config()->tenant_id << "httpHost =" << Config()->httpHost;
+
     InteractiveCAN::instance();
 
     QQmlApplicationEngine engine;

+ 80 - 91
src/qml/WorkingPage.qml

@@ -15,6 +15,7 @@ Rectangle {
     property bool showJobTicketColockProcess: false
 
     property int currentNodeId
+    property string currentNodeName: ""
     property string titleIconCharacter: "\uf0ae"
     property string titleText: "审核作业"
     property string sopIconCharacter: '\uf292'
@@ -74,8 +75,9 @@ Rectangle {
         id: httpRefreshJobTickets
     }
     
-    // 刷新数据状态
+    // 刷新数据状态(true=刷新后 replace 列表页,false=刷新后 pop)
     property bool isRefreshingData: false
+    property bool refreshThenPop: false
     
     Connections {
         target: httpRefreshJobTickets
@@ -90,17 +92,33 @@ Rectangle {
                 try {
                     httpClientThread.signalResponseGetJobTickets.disconnect(httpRefreshJobTickets.slotHttpResponseGetJobTickets);
                 } catch(e) {}
-                // 跳转到列表页
-                appStackView.replace("JobTicketPage.qml", { autoNavigateToDetail: false });
+                if (refreshThenPop) {
+                    refreshThenPop = false;
+                    appStackView.pop();
+                } else {
+                    appStackView.replace("JobTicketPage.qml", { autoNavigateToDetail: false });
+                }
             }
         }
     }
     
-    // 刷新数据并跳转到列表页
+    // 刷新数据并跳转到列表页(replace)
     function refreshDataAndGoToList() {
         console.log("[WorkingPage.qml] 开始刷新数据");
         isRefreshingData = true;
-        // 连接信号
+        refreshThenPop = false;
+        _doRefreshList();
+    }
+    
+    // 刷新数据后返回列表页(pop,列表页已存在故只刷新数据)
+    function refreshDataAndPop() {
+        console.log("[WorkingPage.qml] 开始刷新数据(返回列表)");
+        isRefreshingData = true;
+        refreshThenPop = true;
+        _doRefreshList();
+    }
+    
+    function _doRefreshList() {
         try {
             httpRefreshJobTickets.signalGetRequestData.disconnect(httpClientThread.slotGetRequestData);
         } catch(e) {}
@@ -109,7 +127,6 @@ Rectangle {
         } catch(e) {}
         httpRefreshJobTickets.signalGetRequestData.connect(httpClientThread.slotGetRequestData);
         httpClientThread.signalResponseGetJobTickets.connect(httpRefreshJobTickets.slotHttpResponseGetJobTickets);
-        // 发起请求
         httpRefreshJobTickets.start();
     }
     
@@ -170,114 +187,60 @@ Rectangle {
                     verticalAlignment: Text.AlignVCenter
                 }
 
-                // 当前任务(副标题)
+                // 当前任务(副标题,使用 currentNodeName
                 Row {
                     anchors.verticalCenter: parent.verticalCenter
                     spacing: 6
-                    visible: WorkNodeFormModel.formName !== ""
+                    visible: (control.currentNodeName !== "" || WorkNodeFormModel.formName !== "")
                     
                     Text {
                         text: "当前任务:"
                         color: "#888888"
                         font.pixelSize: 16
-                        // 普通文字不使用图标字体
                         anchors.verticalCenter: parent.verticalCenter
                     }
                     Text {
-                        text: WorkNodeFormModel.formName
+                        text: control.currentNodeName !== "" ? control.currentNodeName : WorkNodeFormModel.formName
                         color: "#40A9FF"
                         font.pixelSize: 16
-                        // 普通文字不使用图标字体
                         anchors.verticalCenter: parent.verticalCenter
                     }
                 }
 
-                // 作业编号
-                Row {
+                // 任务状态(放在当前任务后面,无图标)
+                Text {
                     anchors.verticalCenter: parent.verticalCenter
-                    spacing: 8
-                    visible: sopInfoText !== ""
-                    
-                    Text {
-                        text: sopIconCharacter
-                        color: "#40A9FF"
-                        font.pixelSize: 16
-                        font.family: iconFont.name
-                        anchors.verticalCenter: parent.verticalCenter
-                    }
-                    Text {
-                        text: sopInfoText
-                        color: "#a0a0a0"
-                        font.pixelSize: 16
-                        // 普通文字不使用图标字体
-                        anchors.verticalCenter: parent.verticalCenter
-                    }
+                    visible: workingStateText !== ""
+                    text: "任务状态:" + workingStateText
+                    color: "#52c41a"
+                    font.pixelSize: 16
                 }
 
-                // 执行人
-                Row {
+                // 作业编号(无图标,显示属性名)
+                Text {
                     anchors.verticalCenter: parent.verticalCenter
-                    spacing: 8
-                    visible: userName !== ""
-                    
-                    Text {
-                        text: userIconCharacter
-                        color: "#40A9FF"
-                        font.pixelSize: 16
-                        font.family: iconFont.name
-                        anchors.verticalCenter: parent.verticalCenter
-                    }
-                    Text {
-                        text: userName
-                        color: "#a0a0a0"
-                        font.pixelSize: 16
-                        // 普通文字不使用图标字体
-                        anchors.verticalCenter: parent.verticalCenter
-                    }
+                    visible: sopInfoText !== ""
+                    text: "作业编号: " + sopInfoText
+                    color: "#a0a0a0"
+                    font.pixelSize: 16
                 }
 
-                // 状态
-                Row {
+                // 作业发起人(无图标,显示属性名)
+                Text {
                     anchors.verticalCenter: parent.verticalCenter
-                    spacing: 8
-                    visible: workingStateText !== ""
-                    
-                    Text {
-                        text: workingStateCharacter
-                        color: "#52c41a"
-                        font.pixelSize: 16
-                        font.family: iconFont.name
-                        anchors.verticalCenter: parent.verticalCenter
-                    }
-                    Text {
-                        text: workingStateText
-                        color: "#52c41a"
-                        font.pixelSize: 16
-                        // 普通文字不使用图标字体
-                        anchors.verticalCenter: parent.verticalCenter
-                    }
+                    visible: userName !== ""
+                    text: "作业发起人: " + userName
+                    color: "#a0a0a0"
+                    font.pixelSize: 16
                 }
 
-                // 时间
-                Row {
+                // 发起时间(无图标,显示属性名)
+                Text {
                     anchors.verticalCenter: parent.verticalCenter
-                    spacing: 8
                     visible: workingTimeText !== ""
-                    
-                    Text {
-                        text: workingTimeCharacter
-                        color: "#40A9FF"
-                        font.pixelSize: 16
-                        font.family: iconFont.name
-                        anchors.verticalCenter: parent.verticalCenter
-                    }
-                    Text {
-                        text: workingTimeText
-                        color: "#a0a0a0"
-                        font.pixelSize: 16
-                        // 时间文字不使用图标字体,避免冒号显示异常
-                        anchors.verticalCenter: parent.verticalCenter
-                    }
+                    text: "发起时间: " + workingTimeText
+                    color: "#a0a0a0"
+                    font.pixelSize: 16
                 }
             }
         }
@@ -311,9 +274,35 @@ Rectangle {
                 jobNodeId: WorkNodeFormModel.workId
             }
 
+            // 作业内容(仅审核界面显示,字段为 description)
+            Column {
+                id: __jobDescriptionArea
+                width: parent.width - 92
+                visible: control.showFormCard && WorkNodeFormModel.modelType === "review"
+                spacing: 8
+                anchors.left: parent.left
+                anchors.top: parent.top
+
+                Text {
+                    text: "作业内容:"
+                    color: "#888888"
+                    font.pixelSize: 16
+                }
+                Text {
+                    width: parent.width - 20
+                    text: WorkNodeFormModel.description
+                    color: "white"
+                    font.pixelSize: 15
+                    wrapMode: Text.Wrap
+                    visible: WorkNodeFormModel.description !== ""
+                }
+            }
+
             FormCard {
                 id: formCard
                 visible: control.showFormCard
+                anchors.top: (WorkNodeFormModel.modelType === "review" && WorkNodeFormModel.description !== "") ? __jobDescriptionArea.bottom : parent.top
+                anchors.topMargin: (WorkNodeFormModel.modelType === "review" && WorkNodeFormModel.description !== "") ? 15 : 0
                 iconSize: 24
                 textColor: "white"
                 readOnly: control.workingStateText === "已完成"  // 已完成状态表单不可编辑
@@ -386,7 +375,8 @@ Rectangle {
                     MouseArea {
                         anchors.fill: parent
                         onClicked: {
-                            appStackView.pop();
+                            // 返回前先刷新作业列表,再 pop 回列表页
+                            control.refreshDataAndPop();
                         }
                     }
                 }
@@ -516,7 +506,7 @@ Rectangle {
                 cancelBtnText: "退出系统"
             });
             alertDialogComp.parent = appAlertDialog;
-            // 继续操作 - 返回作业列表页
+            // 继续操作 - 仅关闭弹窗,留在当前页(不跳转到列表页)
             alertDialogComp.confirm.connect(function () { successContinueCallback(alertDialogComp); });
             // 退出系统 - 返回首页
             alertDialogComp.cancel.connect(function () { successExitCallback(alertDialogComp); });
@@ -525,13 +515,12 @@ Rectangle {
         }
     }
     
-    // 成功后继续操作 - 刷新数据后返回作业列表页
+    // 成功后继续操作 - 仅关闭弹窗,留在当前作业页(不跳转到列表页)
     function successContinueCallback(componentObj) {
         componentObj.visible = false;
         appAlertDialog.sourceComponent = null;
         componentObj.destroy();
-        // 刷新数据后跳转到列表页
-        refreshDataAndGoToList();
+        // 不调用 refreshDataAndGoToList(),留在当前页
     }
     
     // 成功后退出系统 - 返回首页

+ 2 - 1
src/qml/components/JobTicketCard.qml

@@ -153,7 +153,8 @@ Rectangle {
                                     textNegativeBtn: textNegativeBtnStr,
                                     textOpsitiveBtn: textOpsitiveBtnStr,
 
-                                    currentNodeId: jobNodeId
+                                    currentNodeId: jobNodeId,
+                                    currentNodeName: control.currentJobTicketName
                               });
         }
     }

+ 5 - 0
src/usr/config.cpp

@@ -115,6 +115,7 @@ void config::configWrite(void)
     //server
     xmlWriter.writeStartElement("server");
     xmlWriter.writeTextElement("httpHost", httpHost);
+    xmlWriter.writeTextElement("tenant_id", tenant_id);
     xmlWriter.writeStartElement("httpPort");
     xmlWriter.writeEndElement(); // httpPort
     xmlWriter.writeEndElement(); // server
@@ -239,6 +240,10 @@ void config::getServerValue(QString key, QString value)
     {
         httpHost = value;
     }
+    else if(key == "tenant_id")
+    {
+        tenant_id = value;
+    }
 }
 
 void config::getParamValue(QString key, QString value)

+ 1 - 1
src/usr/config.h

@@ -75,7 +75,7 @@ public:
 
     QString httpHost = "120.27.232.27:9292";
 //    QString httpHost = "192.168.0.10:48080";
-    QString tenant_id = "1";
+    QString tenant_id = "149";
 
     QString userInfoUrl = "/admin-api/system/user/profile/get";                                             // 用户中心
     QString updateUserInfoUrl = "/admin-api/system/user/profile/update";                                    // 更新用户信息