zhuizhu 9 сар өмнө
parent
commit
3f6c05525b

+ 5 - 0
appevent.cpp

@@ -175,6 +175,11 @@ QStringList AppEvent::configFilter() const
             "savedPassword"};
 }
 
+void AppEvent::beginExam()
+{
+    emit beginExamSignal();
+}
+
 void AppEvent::loginUser(qint64 id)
 {
     emit loginUserSignal(id);

+ 3 - 0
appevent.h

@@ -59,6 +59,8 @@ public:
     QStringList configFilter() const;
     ;
 
+    // 通知考试开始
+    void beginExam();
     // 更新数据
     void loginUser(qint64 id);
     void loginOutUser(qint64 id);
@@ -69,6 +71,7 @@ public:
 
     void examQuestionChenge() { emit examQuestionChengeSignal(); }
 signals:
+    void beginExamSignal();
     void loginUserSignal(qint64 id);
     void loginOutUserSignal(qint64 id);
     void examsTestUpdateSignal();

+ 11 - 4
examquestionpage.cpp

@@ -25,7 +25,6 @@
 
 #include <layoutbuilder.h>
 
-#include "cwf/sqlquery.h"
 #include <cwf/constants.h>
 #include <cwf/cppwebapplication.h>
 #include <cwf/filter.h>
@@ -91,6 +90,7 @@ ExamsQuestionPage::ExamsQuestionPage(QWidget *parent)
 
     examsNameLineEdit = new QLineEdit;
     fileDirLineEdit = new QLineEdit;
+    examsMaxTimeLineEdit = new QLineEdit;
     selectCheckBox = new QCheckBox;
     selectCheckBox->setDisabled(true);
 
@@ -114,6 +114,10 @@ ExamsQuestionPage::ExamsQuestionPage(QWidget *parent)
                                  PushButton{text(tr("open file")),
                                             onClicked([this]() { getFile(); })},
                                  br,
+                                 tr("exams max time"),
+                                 examsMaxTimeLineEdit,
+                                 "毫秒",
+                                 br,
                                  tr("select"),
                                  selectCheckBox,
                              },
@@ -141,7 +145,7 @@ ExamsQuestionPage::ExamsQuestionPage(QWidget *parent)
     examsView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
     examsView->setSelectionBehavior(QAbstractItemView::SelectRows);
     examsView->setSelectionMode(QAbstractItemView::SingleSelection);
-    examsView->setItemDelegateForColumn(2, new CheckDelegate(this)); // 设置第0列应用委托
+    examsView->setItemDelegateForColumn(3, new CheckDelegate(this)); // 设置第0列应用委托
     // 连接信号和槽
     QObject::connect(pageSize, &QComboBox::currentTextChanged, [this](const QString &) {
         updateExamsView();
@@ -153,6 +157,7 @@ ExamsQuestionPage::ExamsQuestionPage(QWidget *parent)
         examsNameLineEdit->setText(exam.name);
         fileDirLineEdit->setText(exam.fileDir);
         fileDirLineEdit->setToolTip(exam.fileDir);
+        examsMaxTimeLineEdit->setText(QString::number(exam.maxTime));
         selectCheckBox->setChecked(exam.select);
     });
 
@@ -266,7 +271,7 @@ void ExamsQuestionPage::save()
     }
 
     ExamsQuestionModel examsModel(storage);
-    {
+    if (exams.name == "") {
         CWF::SqlQueryManager queryManager(storage);
         queryManager.select("*", examsModel.getTableName()).where("name = ?");
         queryManager.prepare();
@@ -295,10 +300,12 @@ void ExamsQuestionPage::save()
 
     CWF::SqlQueryManager queryManager(storage);
     //queryManager.select("*", examsModel.getTableName()).where("isSelect = ?");
-    queryManager.update(examsModel.getTableName(), "name=?,fileDir=?,isSelect=?").where("id = ?");
+    queryManager.update(examsModel.getTableName(), "name=?,fileDir=?,maxTime=?,isSelect=?")
+        .where("id = ?");
     queryManager.prepare();
     queryManager.addBindValue(examsNameLineEdit->text());
     queryManager.addBindValue(fileDirLineEdit->text());
+    queryManager.addBindValue(examsMaxTimeLineEdit->text().toInt());
     queryManager.addBindValue(selectCheckBox->isChecked());
     queryManager.addBindValue(exams.id);
     QJsonObject status = queryManager.exec();

+ 1 - 0
examquestionpage.h

@@ -39,6 +39,7 @@ private:
 
     QLineEdit *examsNameLineEdit;
     QLineEdit *fileDirLineEdit;
+    QLineEdit *examsMaxTimeLineEdit;
     QCheckBox *selectCheckBox;
 };
 

+ 11 - 0
examtestpage.cpp

@@ -92,6 +92,16 @@ void ExamTestPage::sendExamText()
         QString jsonString = jsonDoc.toJson(QJsonDocument::Compact);
         client->sendTextMessage(jsonString);
     }
+
+    QMessageBox msgBox;
+    msgBox.setText(tr("info"));
+    msgBox.setInformativeText("考试信息已推送到学生端");
+    msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
+    msgBox.setDefaultButton(QMessageBox::Ok);
+    msgBox.setButtonText(QMessageBox::Ok, tr("OK"));
+    msgBox.setButtonText(QMessageBox::Cancel, tr("Cancel"));
+    msgBox.exec();
+    return;
 }
 
 void ExamTestPage::beginExam()
@@ -160,6 +170,7 @@ void ExamTestPage::beginExam()
             client->sendTextMessage(jsonString);
         }
     }
+    emit AppEvent::instance()->beginExam();
 }
 
 void ExamTestPage::unLockScreen()

+ 3 - 0
gradespage.cpp

@@ -159,6 +159,9 @@ GradesPage::GradesPage(QWidget *parent)
     });
     AppEvent *appEvent = AppEvent::instance();
     QObject::connect(appEvent, &AppEvent::examsTestUpdateSignal, [this]() { updateView(); });
+    QObject::connect(appEvent, &AppEvent::beginExamSignal, [this]() {
+        pagination->setCurrentPage(1);
+    });
 
     updateView();
 }

+ 32 - 4
studentpage.cpp

@@ -136,7 +136,7 @@ StudentPage::StudentPage(QWidget *parent)
 
     auto op = Column{PushButton{text(tr("Add")), onClicked([this]() { addStudent(); })},
                      PushButton{text(tr("Remove")), onClicked([this]() { removeStudent(); })},
-                     PushButton{text(tr("Set as Default")), onClicked([this]() { setDefault(); })},
+                     PushButton{text(tr("Set as Offline")), onClicked([this]() { setOffline(); })},
                      st,
                      PushButton{text(tr("Clear...")), onClicked([this]() { Clear(); })},
                      PushButton{text(tr("Import...")), onClicked([this]() { importFile(); })},
@@ -180,6 +180,10 @@ StudentPage::StudentPage(QWidget *parent)
         examsTestLineEdit->setText(student.examTest);
     });
 
+    QObject::connect(appEvent, &AppEvent::beginExamSignal, [this]() {
+        pagination->setCurrentPage(1);
+    });
+
     updateStudentView();
 }
 
@@ -229,7 +233,31 @@ void StudentPage::addStudent()
         updateStudentView();
     }
 }
-void StudentPage::setDefault() {}
+void StudentPage::setOffline()
+{
+    StudentTableModel *model = qobject_cast<StudentTableModel *>(studentView->model());
+
+    const QModelIndex index = studentView->currentIndex();
+    StudentTableModel::Student student = model->getCurrentStudent(index);
+    if (student.id == 0) {
+        return;
+    }
+
+    UserModel userModel(storage);
+    CWF::SqlQueryManager queryManager(storage);
+    //queryManager.select("*", examsModel.getTableName()).where("isSelect = ?");
+    queryManager.update(userModel.getTableName(), "state = 0");
+    queryManager.where("id = ?");
+    queryManager.prepare();
+    queryManager.addBindValue(student.id);
+    QJsonObject status = queryManager.exec();
+
+    if (status["success"].toBool()) {
+        updateStudentView();
+        studentView->setCurrentIndex(index);
+    }
+}
+
 void StudentPage::removeStudent()
 {
     StudentTableModel *model = qobject_cast<StudentTableModel *>(studentView->model());
@@ -319,7 +347,7 @@ void StudentPage::importFile()
         return;
     }
     QXlsx::Document xlsx = QXlsx::Document(filePath);
-
+    // xlsx.currentSheet();
     int nameIndex = -1;
     int SWIDIndex = -1;
     int examineeNumberIndex = -1;
@@ -334,7 +362,7 @@ void StudentPage::importFile()
     for (int col = 0; col < 20; ++col) {
         QVariant value = xlsx.read(1, col);
         QString strValue = value.toString();
-        qDebug() << strValue;
+        qDebug() << col << strValue;
         if (strValue == "\xE5\xA7\x93\xE5\x90\x8D") { // UTF-8 编码的 "姓名"
             nameIndex = col;
         } else if (strValue == "\x53\x57\x5F\x49\x44") { // UTF-8 编码的 "SW_ID"

+ 1 - 1
studentpage.h

@@ -23,7 +23,7 @@ public:
     void updateStudentView();
 
     void addStudent();
-    void setDefault();
+    void setOffline();
     void removeStudent();
     void save();
 

+ 69 - 1
tcontroller.cpp

@@ -161,6 +161,17 @@ void LoginController::doPost(CWF::Request &request, CWF::Response &response) con
                     isok = true;
                 }
             }
+
+            if (obj["state"].toInt() == 1) {
+                response.write(
+                    QJsonObject{{"status", false},
+                                {"message",
+                                 TeacherServer::Tr::tr("Login failed, The user has logged in")},
+                                {"code", 500},
+                                {"data", QJsonValue()}});
+                return;
+            }
+
             if (isok) {
                 QJsonObject UserResponse{{"id", obj["id"]},
                                          {"name", obj["name"]},
@@ -246,9 +257,66 @@ void UserInfoController::doGet(CWF::Request &request, CWF::Response &response) c
         if (json.isObject()) {
             QJsonObject obj = json.toObject();
 
+            int maxTime = obj.value("maxTime").toInt();
+            if (maxTime == 0) { // 获取考题考试时间
+                QString examContent;
+                ///////////// 获取个人用户的考题
+                CWF::SqlQuery query(storage);
+                QJsonObject status = query.exec(QString("SELECT * FROM user WHERE id = %1").arg(id));
+                if (status["success"].toBool()) {
+                    const QJsonArray array = query.toJson();
+                    if (!array.isEmpty()) {
+                        QJsonObject object = array[0].toObject();
+                        examContent = object["examTest"].toString();
+                    }
+                }
+                qDebug() << "个人考试题目:" << examContent;
+                UserModel user(storage);
+                ExamsQuestionModel exams(storage);
+
+                // 个人考试内容是空 获取默认选择的考试内容
+                if (examContent.isEmpty() || examContent == "") {
+                    CWF::SqlQuery query(storage);
+                    QJsonObject status = query.exec(
+                        QString("SELECT * FROM exams_question WHERE isSelect = 1"));
+                    if (status["success"].toBool()) {
+                        const QJsonArray array = query.toJson();
+                        if (!array.isEmpty()) {
+                            QJsonObject object = array[0].toObject();
+                            examContent = object["name"].toString();
+                        }
+                    }
+                }
+                qDebug() << "使用考试题目时间:" << examContent;
+                // 获取考试内容
+
+                CWF::SqlQueryManager queryManager(storage);
+                queryManager.select("*", exams.getTableName()).where("name = ?");
+                queryManager.prepare();
+                queryManager.addBindValue(examContent);
+                queryManager.exec();
+                QJsonArray jsonArray = queryManager.toJson();
+                if (jsonArray.isEmpty()) {
+                    response.write(
+                        QJsonObject{{"status", false},
+                                    {"message",
+                                     TeacherServer::Tr::tr("Failed to obtain exam content")},
+                                    {"code", 500},
+                                    {"data", QJsonValue()}});
+                    return;
+                }
+                qDebug() << "数据库考试题目时间:" << jsonArray;
+                for (const QJsonValue &json : jsonArray) {
+                    if (json.isObject()) {
+                        QJsonObject obj = json.toObject();
+                        maxTime = obj["maxTime"].toInt();
+                    }
+                }
+            }
+
             QJsonObject userInfo;
             userInfo.insert("username", obj.value("name"));
-            userInfo.insert("maxTime", obj.value("maxTime"));
+            userInfo.insert("maxTime", maxTime);
             userInfo.insert("checkinNumber", obj.value("checkinNumber")); // 1 - name
 
             response.write(QJsonObject{{"status", true},

+ 96 - 71
teacherServer_zh_CN.ts

@@ -43,29 +43,32 @@
         <translation>解锁屏幕</translation>
     </message>
     <message>
-        <location filename="examtestpage.cpp" line="125"/>
+        <location filename="examtestpage.cpp" line="97"/>
+        <location filename="examtestpage.cpp" line="135"/>
         <source>info</source>
         <translation>提示</translation>
     </message>
     <message>
-        <location filename="examtestpage.cpp" line="126"/>
+        <location filename="examtestpage.cpp" line="136"/>
         <source>Please set exam questions first</source>
         <translation>请先设置考试题目</translation>
     </message>
     <message>
-        <location filename="examtestpage.cpp" line="129"/>
+        <location filename="examtestpage.cpp" line="101"/>
         <location filename="examtestpage.cpp" line="139"/>
+        <location filename="examtestpage.cpp" line="149"/>
         <source>OK</source>
         <translation>确定</translation>
     </message>
     <message>
-        <location filename="examtestpage.cpp" line="130"/>
+        <location filename="examtestpage.cpp" line="102"/>
         <location filename="examtestpage.cpp" line="140"/>
+        <location filename="examtestpage.cpp" line="150"/>
         <source>Cancel</source>
         <translation>取消</translation>
     </message>
     <message>
-        <location filename="examtestpage.cpp" line="136"/>
+        <location filename="examtestpage.cpp" line="146"/>
         <source>The current exam question is:%1</source>
         <translation>当前考试题目是:%1</translation>
     </message>
@@ -84,75 +87,90 @@
 <context>
     <name>ExamsQuestionPage</name>
     <message>
-        <location filename="examquestionpage.cpp" line="104"/>
+        <location filename="examquestionpage.cpp" line="106"/>
         <source>Test question information</source>
         <translation>考题信息</translation>
     </message>
     <message>
-        <location filename="examquestionpage.cpp" line="106"/>
+        <location filename="examquestionpage.cpp" line="108"/>
         <source>exams name</source>
         <translation>考试名称</translation>
     </message>
     <message>
-        <location filename="examquestionpage.cpp" line="109"/>
+        <location filename="examquestionpage.cpp" line="111"/>
         <source>file dir</source>
         <translation>文件目录</translation>
     </message>
     <message>
-        <location filename="examquestionpage.cpp" line="111"/>
+        <location filename="examquestionpage.cpp" line="113"/>
         <source>open dir</source>
         <translation>打开目录</translation>
     </message>
     <message>
-        <location filename="examquestionpage.cpp" line="112"/>
+        <location filename="examquestionpage.cpp" line="114"/>
         <source>open file</source>
         <translation>打开文件</translation>
     </message>
     <message>
-        <location filename="examquestionpage.cpp" line="115"/>
+        <location filename="examquestionpage.cpp" line="117"/>
+        <source>exams max time</source>
+        <translation type="unfinished">最大完成时间</translation>
+    </message>
+    <message>
+        <location filename="examquestionpage.cpp" line="121"/>
         <source>select</source>
         <translation>选择</translation>
     </message>
     <message>
-        <location filename="examquestionpage.cpp" line="121"/>
+        <location filename="examquestionpage.cpp" line="127"/>
         <source>Add</source>
         <translation>添加</translation>
     </message>
     <message>
-        <location filename="examquestionpage.cpp" line="122"/>
+        <location filename="examquestionpage.cpp" line="128"/>
         <source>Remove</source>
         <translation>删除</translation>
     </message>
     <message>
-        <location filename="examquestionpage.cpp" line="123"/>
+        <location filename="examquestionpage.cpp" line="129"/>
         <source>Set as Default</source>
         <translation>设置为默认</translation>
     </message>
     <message>
-        <location filename="examquestionpage.cpp" line="125"/>
+        <location filename="examquestionpage.cpp" line="131"/>
         <source>Save</source>
         <translation>保存</translation>
     </message>
     <message>
-        <location filename="examquestionpage.cpp" line="130"/>
+        <location filename="examquestionpage.cpp" line="136"/>
         <source>pageSize</source>
         <translation>页大小</translation>
     </message>
+    <message>
+        <location filename="examquestionpage.cpp" line="293"/>
+        <source>Error</source>
+        <translation>错误</translation>
+    </message>
 </context>
 <context>
     <name>ExamsTableModel</name>
     <message>
-        <location filename="widgets/examsmodel.cpp" line="71"/>
+        <location filename="widgets/examsmodel.cpp" line="73"/>
         <source>name</source>
         <translation>姓名</translation>
     </message>
     <message>
-        <location filename="widgets/examsmodel.cpp" line="73"/>
+        <location filename="widgets/examsmodel.cpp" line="75"/>
         <source>fileDir</source>
         <translation>文件目录</translation>
     </message>
     <message>
-        <location filename="widgets/examsmodel.cpp" line="75"/>
+        <location filename="widgets/examsmodel.cpp" line="77"/>
+        <source>exams max time</source>
+        <translation type="unfinished">最大完成时间</translation>
+    </message>
+    <message>
+        <location filename="widgets/examsmodel.cpp" line="79"/>
         <source>select</source>
         <translation>选择</translation>
     </message>
@@ -217,22 +235,22 @@
         <translation>页大小</translation>
     </message>
     <message>
-        <location filename="gradespage.cpp" line="256"/>
+        <location filename="gradespage.cpp" line="259"/>
         <source>This will clear up all grades information</source>
         <translation>这将清理全部成绩信息</translation>
     </message>
     <message>
-        <location filename="gradespage.cpp" line="259"/>
+        <location filename="gradespage.cpp" line="262"/>
         <source>OK</source>
         <translation>确定</translation>
     </message>
     <message>
-        <location filename="gradespage.cpp" line="260"/>
+        <location filename="gradespage.cpp" line="263"/>
         <source>Cancel</source>
         <translation>取消</translation>
     </message>
     <message>
-        <location filename="gradespage.cpp" line="272"/>
+        <location filename="gradespage.cpp" line="275"/>
         <source>file</source>
         <translation>文件</translation>
     </message>
@@ -382,7 +400,7 @@
 <context>
     <name>QObject</name>
     <message>
-        <location filename="examquestionpage.cpp" line="285"/>
+        <location filename="examquestionpage.cpp" line="322"/>
         <location filename="settingspage.cpp" line="69"/>
         <location filename="settingspage.cpp" line="87"/>
         <location filename="settingspage.cpp" line="111"/>
@@ -390,12 +408,12 @@
         <translation></translation>
     </message>
     <message>
-        <location filename="examquestionpage.cpp" line="295"/>
+        <location filename="examquestionpage.cpp" line="332"/>
         <source>选择文件</source>
         <translation></translation>
     </message>
     <message>
-        <location filename="examquestionpage.cpp" line="297"/>
+        <location filename="examquestionpage.cpp" line="334"/>
         <source>所有文件 (*)</source>
         <translation></translation>
     </message>
@@ -514,8 +532,9 @@
     </message>
     <message>
         <location filename="studentpage.cpp" line="139"/>
-        <source>Set as Default</source>
-        <translation>设置为默认</translation>
+        <source>Set as Offline</source>
+        <oldsource>Set as Default</oldsource>
+        <translation>设置为离线</translation>
     </message>
     <message>
         <location filename="studentpage.cpp" line="141"/>
@@ -543,23 +562,23 @@
         <translation>页大小</translation>
     </message>
     <message>
-        <location filename="studentpage.cpp" line="293"/>
+        <location filename="studentpage.cpp" line="321"/>
         <source>This will clear up all grades and student information</source>
         <translation>这将清理全部成绩和学生信息</translation>
     </message>
     <message>
-        <location filename="studentpage.cpp" line="296"/>
+        <location filename="studentpage.cpp" line="324"/>
         <source>OK</source>
         <translation>确定</translation>
     </message>
     <message>
-        <location filename="studentpage.cpp" line="297"/>
+        <location filename="studentpage.cpp" line="325"/>
         <source>Cancel</source>
         <translation>取消</translation>
     </message>
     <message>
-        <location filename="studentpage.cpp" line="313"/>
-        <location filename="studentpage.cpp" line="429"/>
+        <location filename="studentpage.cpp" line="341"/>
+        <location filename="studentpage.cpp" line="460"/>
         <source>file</source>
         <translation>文件</translation>
     </message>
@@ -820,7 +839,7 @@
     <message>
         <location filename="api/tapi.cpp" line="86"/>
         <source>Error</source>
-        <translation type="unfinished"></translation>
+        <translation type="unfinished">错误</translation>
     </message>
     <message>
         <location filename="api/tapi.cpp" line="109"/>
@@ -833,103 +852,109 @@
     <name>TeacherServer::TeacherServer</name>
     <message>
         <location filename="tcontroller.cpp" line="137"/>
-        <location filename="tcontroller.cpp" line="239"/>
-        <location filename="tcontroller.cpp" line="308"/>
-        <location filename="tcontroller.cpp" line="564"/>
-        <location filename="tcontroller.cpp" line="680"/>
+        <location filename="tcontroller.cpp" line="250"/>
+        <location filename="tcontroller.cpp" line="376"/>
+        <location filename="tcontroller.cpp" line="637"/>
+        <location filename="tcontroller.cpp" line="754"/>
         <source>user does not exist</source>
         <translation>用户不存在</translation>
     </message>
     <message>
         <location filename="tcontroller.cpp" line="123"/>
-        <location filename="tcontroller.cpp" line="170"/>
+        <location filename="tcontroller.cpp" line="181"/>
         <source>Login succeeded</source>
         <translation>登录成功</translation>
     </message>
     <message>
-        <location filename="tcontroller.cpp" line="187"/>
-        <location filename="tcontroller.cpp" line="263"/>
-        <location filename="tcontroller.cpp" line="332"/>
+        <location filename="tcontroller.cpp" line="169"/>
+        <source>Login failed, The user has logged in</source>
+        <translation>登录失败,用户已经登录</translation>
+    </message>
+    <message>
+        <location filename="tcontroller.cpp" line="198"/>
+        <location filename="tcontroller.cpp" line="331"/>
+        <location filename="tcontroller.cpp" line="400"/>
         <source>Login failed</source>
         <translation>登录失败</translation>
     </message>
     <message>
-        <location filename="tcontroller.cpp" line="198"/>
-        <location filename="tcontroller.cpp" line="273"/>
-        <location filename="tcontroller.cpp" line="530"/>
+        <location filename="tcontroller.cpp" line="209"/>
+        <location filename="tcontroller.cpp" line="341"/>
+        <location filename="tcontroller.cpp" line="603"/>
         <source>LoginOut failed, no find user</source>
         <translation>退出失败, 没有发现用户</translation>
     </message>
     <message>
-        <location filename="tcontroller.cpp" line="207"/>
-        <location filename="tcontroller.cpp" line="282"/>
-        <location filename="tcontroller.cpp" line="353"/>
-        <location filename="tcontroller.cpp" line="435"/>
-        <location filename="tcontroller.cpp" line="539"/>
-        <location filename="tcontroller.cpp" line="644"/>
+        <location filename="tcontroller.cpp" line="218"/>
+        <location filename="tcontroller.cpp" line="350"/>
+        <location filename="tcontroller.cpp" line="421"/>
+        <location filename="tcontroller.cpp" line="508"/>
+        <location filename="tcontroller.cpp" line="612"/>
+        <location filename="tcontroller.cpp" line="718"/>
         <source>unauthorized</source>
         <translation></translation>
     </message>
     <message>
-        <location filename="tcontroller.cpp" line="401"/>
-        <location filename="tcontroller.cpp" line="420"/>
-        <location filename="tcontroller.cpp" line="484"/>
+        <location filename="tcontroller.cpp" line="303"/>
+        <location filename="tcontroller.cpp" line="469"/>
+        <location filename="tcontroller.cpp" line="493"/>
+        <location filename="tcontroller.cpp" line="557"/>
         <source>Failed to obtain exam content</source>
         <translation></translation>
     </message>
     <message>
-        <location filename="tcontroller.cpp" line="550"/>
-        <location filename="tcontroller.cpp" line="618"/>
+        <location filename="tcontroller.cpp" line="623"/>
+        <location filename="tcontroller.cpp" line="692"/>
         <source>file uploaded successfully</source>
         <translation></translation>
     </message>
     <message>
-        <location filename="tcontroller.cpp" line="624"/>
+        <location filename="tcontroller.cpp" line="698"/>
         <source>Failed to uploaded files</source>
         <translation></translation>
     </message>
     <message>
-        <location filename="tcontroller.cpp" line="635"/>
+        <location filename="tcontroller.cpp" line="709"/>
         <source>answer Time failed, no find user login</source>
         <translation></translation>
     </message>
     <message>
-        <location filename="tcontroller.cpp" line="656"/>
-        <location filename="tcontroller.cpp" line="797"/>
+        <location filename="tcontroller.cpp" line="730"/>
+        <location filename="tcontroller.cpp" line="871"/>
         <source>Update Answer Time successfully</source>
         <translation></translation>
     </message>
     <message>
-        <location filename="tcontroller.cpp" line="804"/>
+        <location filename="tcontroller.cpp" line="878"/>
         <source>Update Answer Time Failed</source>
         <translation></translation>
     </message>
     <message>
-        <location filename="tcontroller.cpp" line="815"/>
+        <location filename="tcontroller.cpp" line="889"/>
         <source>json param error</source>
         <translation></translation>
     </message>
     <message>
-        <location filename="tcontroller.cpp" line="877"/>
+        <location filename="tcontroller.cpp" line="951"/>
         <source>Table data </source>
         <translation></translation>
     </message>
     <message>
-        <location filename="tcontroller.cpp" line="884"/>
+        <location filename="tcontroller.cpp" line="958"/>
         <source>Get Table Data Failed</source>
         <translation></translation>
     </message>
     <message>
         <location filename="tcontroller.cpp" line="94"/>
-        <location filename="tcontroller.cpp" line="413"/>
+        <location filename="tcontroller.cpp" line="486"/>
         <source>ok</source>
         <translation></translation>
     </message>
     <message>
-        <location filename="tcontroller.cpp" line="224"/>
-        <location filename="tcontroller.cpp" line="255"/>
-        <location filename="tcontroller.cpp" line="293"/>
-        <location filename="tcontroller.cpp" line="324"/>
+        <location filename="tcontroller.cpp" line="235"/>
+        <location filename="tcontroller.cpp" line="323"/>
+        <location filename="tcontroller.cpp" line="361"/>
+        <location filename="tcontroller.cpp" line="392"/>
         <source>LoginOut succeeded</source>
         <translation>退出成功</translation>
     </message>
@@ -944,13 +969,13 @@
         <translation>离线</translation>
     </message>
     <message>
-        <location filename="examquestionpage.cpp" line="54"/>
+        <location filename="examquestionpage.cpp" line="55"/>
         <location filename="gradespage.cpp" line="58"/>
         <source>Select</source>
         <translation>选择</translation>
     </message>
     <message>
-        <location filename="examquestionpage.cpp" line="57"/>
+        <location filename="examquestionpage.cpp" line="58"/>
         <location filename="gradespage.cpp" line="61"/>
         <source>Not Selected</source>
         <translation>未选择</translation>

+ 5 - 0
tmodel.h

@@ -83,6 +83,7 @@ class ExamsQuestionModel : public CWF::Model
     Q_OBJECT
     Q_PROPERTY(QString fileDir READ getFileDir WRITE setfileDir)
     Q_PROPERTY(QString name READ getName WRITE setName)
+    Q_PROPERTY(int maxTime READ getMaxTime WRITE setMaxTime)
     Q_PROPERTY(bool isSelect READ getIsSelect WRITE setIsSelect)
 public:
     explicit ExamsQuestionModel(CWF::SqlDatabaseStorage &connection)
@@ -99,9 +100,13 @@ public slots:
     bool getIsSelect() const { return isSelect; }
     void setIsSelect(const bool &value) { isSelect = value; }
 
+    int getMaxTime() const { return maxTime; }
+    void setMaxTime(const int &value) { maxTime = value; }
+
 private:
     QString fileDir;
     QString name;
+    int maxTime; // 最大完成时间
     bool isSelect;
 };
 

+ 6 - 2
widgets/examsmodel.cpp

@@ -19,7 +19,7 @@ void ExamsTableModel::loadJsonData(const QJsonArray &jsonArray)
             exams.name = obj.value("name").toString();
             exams.fileDir = obj.value("fileDir").toString();
             exams.select = (obj.value("isSelect").toInt() != 0);
-
+            exams.maxTime = obj.value("maxTime").toInt();
             studentList.append(exams);
         }
     }
@@ -37,7 +37,7 @@ int ExamsTableModel::rowCount(const QModelIndex &parent) const
 int ExamsTableModel::columnCount(const QModelIndex &parent) const
 {
     Q_UNUSED(parent);
-    return 3;
+    return 4;
 }
 
 QVariant ExamsTableModel::data(const QModelIndex &index, int role) const
@@ -55,6 +55,8 @@ QVariant ExamsTableModel::data(const QModelIndex &index, int role) const
         else if (index.column() == 1)
             return exams.fileDir;
         else if (index.column() == 2)
+            return exams.maxTime;
+        else if (index.column() == 3)
             return exams.select;
     }
     return QVariant();
@@ -72,6 +74,8 @@ QVariant ExamsTableModel::headerData(int section, Qt::Orientation orientation, i
         case 1:
             return tr("fileDir");
         case 2:
+            return tr("exams max time");
+        case 3:
             return tr("select");
         default:
             return QVariant();

+ 1 - 0
widgets/examsmodel.h

@@ -16,6 +16,7 @@ public:
         QString name;
         QString fileDir;
         bool select;
+        int maxTime; // 最大完成时间
     };
     // 加载 JSON 数据
     void loadJsonData(const QJsonArray &jsonArray);