diff --git a/DataBaseLMS/CMakeLists.txt b/DataBaseLMS/CMakeLists.txt index fb0c152..b5c50e1 100644 --- a/DataBaseLMS/CMakeLists.txt +++ b/DataBaseLMS/CMakeLists.txt @@ -25,6 +25,8 @@ add_library(DataBaseLMS SHARED tasksAmmFim.cpp tasksAmmFim.h typeQueryToDB.h + timingoftrainee.cpp + timingoftrainee.h ) target_link_libraries(DataBaseLMS PRIVATE Qt5::Widgets) diff --git a/DataBaseLMS/databaselms.cpp b/DataBaseLMS/databaselms.cpp index 64aa5f3..23892cf 100644 --- a/DataBaseLMS/databaselms.cpp +++ b/DataBaseLMS/databaselms.cpp @@ -1691,6 +1691,56 @@ int DataBaseLMS::updateTrainee(Trainee trainee) return queryExecInt(queryStr); } +int DataBaseLMS::insertTimingTrainee(int id_trainee) +{ + QString queryStr = QString("INSERT INTO public.timings (entry_time, exit_time, operating_time, timing_trainee) " + "VALUES (DEFAULT, DEFAULT, DEFAULT, %1) " + "RETURNING timings.timing_id").arg( + QString::number(id_trainee)); + + return queryExecInt(queryStr); +} + +int DataBaseLMS::updateTimingTrainee(int id_trainee, TimingOfTrainee timing) +{ + QString queryStr = QString("UPDATE public.timings " + "SET entry_time = '%1', exit_time = '%2', operating_time = '%3', timing_trainee = %4 " + "WHERE timing_id = %5 " + "RETURNING timings.timing_id").arg( + timing.getEntryTimeS(), + timing.getExitTimeS(), + timing.getOperatingTimeS(), + QString::number(id_trainee), + QString::number(timing.getID()) ); + + return queryExecInt(queryStr); +} + +TimingOfTrainee DataBaseLMS::selectTimingTrainee(int id_trainee) +{ + TimingOfTrainee timing(id_trainee); + + QString queryStr = QString("SELECT timings.timing_id, timings.entry_time, timings.exit_time, timings.operating_time, timings.timing_trainee " + "FROM public.timings " + "WHERE timing_trainee = '%1'").arg(id_trainee); + + QSqlQuery querySel = QSqlQuery(*db); + + if(queryExec(queryStr, &querySel)) + { + if (querySel.first()) + {//Тайминг + timing.setID(querySel.value(0).toInt()); + timing.setEntryTime(querySel.value(1).toDateTime()); + timing.setExitTime(querySel.value(2).toDateTime()); + timing.setOperatingTime(querySel.value(3).toTime()); + timing.setTraineeID(querySel.value(4).toInt()); + } + } + + return timing; +} + int DataBaseLMS::queryExecInt(QString queryStr) { QSqlQuery query = QSqlQuery(*db); diff --git a/DataBaseLMS/databaselms.h b/DataBaseLMS/databaselms.h index b431be4..0f0568f 100644 --- a/DataBaseLMS/databaselms.h +++ b/DataBaseLMS/databaselms.h @@ -8,6 +8,7 @@ #include "trainee.h" #include "group.h" #include "tasksAmmFim.h" +#include "timingoftrainee.h" class DataBaseSettings { @@ -101,6 +102,11 @@ protected: int deleteTrainee(int id_trainee); int updateTrainee(Trainee trainee); + //Тайминг + int insertTimingTrainee(int id_trainee); + int updateTimingTrainee(int id_trainee, TimingOfTrainee timing); + TimingOfTrainee selectTimingTrainee(int id_trainee); + private: DataBaseSettings getDataBaseSettings(); int queryExecInt(QString queryStr); diff --git a/DataBaseLMS/interfacedatabaselms.cpp b/DataBaseLMS/interfacedatabaselms.cpp index 988f457..c439a8a 100644 --- a/DataBaseLMS/interfacedatabaselms.cpp +++ b/DataBaseLMS/interfacedatabaselms.cpp @@ -1,6 +1,8 @@ #include #include #include +#include +#include #include "interfacedatabaselms.h" InterfaceDataBaseLMS::InterfaceDataBaseLMS(QWidget* parent): @@ -218,6 +220,46 @@ bool InterfaceDataBaseLMS::deAuthorizationAllTrainees() return updateAllTraineesLoggedIn(false); } +int InterfaceDataBaseLMS::entryTraineeOnSimulator(int id_trainee) +{ + TimingOfTrainee timing(id_trainee); + + timing = selectTimingTrainee(id_trainee); + + if(!timing.getID()) + {//Еще нет записи + int timing_id = insertTimingTrainee(id_trainee); + timing.setID(timing_id); + + if(!timing_id) + return 0; + } + + timing.fixEntry(); + + return updateTimingTrainee(id_trainee, timing); +} + +int InterfaceDataBaseLMS::exitTraineeFromSimulator(int id_trainee) +{ + TimingOfTrainee timing(id_trainee); + + timing = selectTimingTrainee(id_trainee); + + if(!timing.getID()) + {//Еще нет записи + int timing_id = insertTimingTrainee(id_trainee); + timing.setID(timing_id); + + if(!timing_id) + return 0; + } + + timing.fixExit(); + + return updateTimingTrainee(id_trainee, timing); +} + QString InterfaceDataBaseLMS::getNameTraineeOnComputer(QString computer_name) { return selectTraineeNameOnComputer(computer_name); diff --git a/DataBaseLMS/interfacedatabaselms.h b/DataBaseLMS/interfacedatabaselms.h index 701e55e..e7484d3 100644 --- a/DataBaseLMS/interfacedatabaselms.h +++ b/DataBaseLMS/interfacedatabaselms.h @@ -51,6 +51,11 @@ public: bool deAuthorizationTrainee(QString login); bool deAuthorizationAllTrainees(); + //Регистрация тайминга Обучаемого + int entryTraineeOnSimulator(int id_trainee); + int exitTraineeFromSimulator(int id_trainee); + + //void setTasks(QString login, QStringList tasks); QString getNameTraineeOnComputer(QString computer_name); diff --git a/DataBaseLMS/timingoftrainee.cpp b/DataBaseLMS/timingoftrainee.cpp new file mode 100644 index 0000000..e5fee2e --- /dev/null +++ b/DataBaseLMS/timingoftrainee.cpp @@ -0,0 +1,71 @@ +#include "timingoftrainee.h" + +TimingOfTrainee::TimingOfTrainee(int trainee_id): + timing_id(0), + trainee_id(trainee_id) +{ + //QDateTime dataTimeCurr = QDateTime::currentDateTime(); + dataTimeNull = QDateTime::fromString("2000-01-01 00:00:00.000", "yyyy-MM-dd hh:mm:ss.zzz"); + setOperatingTime(QTime::fromString("00:00:00")); + setEntryTime(dataTimeNull); + setExitTime(dataTimeNull); +} + + +void TimingOfTrainee::setEntryTimeS(QString entry_time) +{ + entryTime_str = entry_time; + entryTime = QDateTime::fromString(entry_time); +} + +void TimingOfTrainee::setEntryTime(QDateTime entry_time) +{ + entryTime = entry_time; + entryTime_str = entry_time.toString("yyyy-MM-dd hh:mm:ss.zzz"); +} + + +void TimingOfTrainee::setExitTimeS(QString exit_time) +{ + exitTime_str = exit_time; + exitTime = QDateTime::fromString(exit_time); +} + +void TimingOfTrainee::setExitTime(QDateTime exit_time) +{ + exitTime = exit_time; + exitTime_str = exit_time.toString("yyyy-MM-dd hh:mm:ss.zzz"); +} + + +void TimingOfTrainee::setOperatingTimeS(QString operating_time) +{ + operatingTime_str = operating_time; + operatingTime = QTime::fromString(operating_time); +} + +void TimingOfTrainee::setOperatingTime(QTime operating_time) +{ + operatingTime = operating_time; + operatingTime_str = operating_time.toString(); +} + +void TimingOfTrainee::fixEntry() +{ + QDateTime dataTimeCurr = QDateTime::currentDateTime(); + setEntryTime(dataTimeCurr); +} + +void TimingOfTrainee::fixExit() +{ + QDateTime dataTimeCurr = QDateTime::currentDateTime(); + setExitTime(dataTimeCurr); + if(entryTime != dataTimeNull) + calculateOperatingTime(); +} + +void TimingOfTrainee::calculateOperatingTime() +{ + int cntSec = entryTime.secsTo(exitTime); + setOperatingTime(getOperatingTime().addSecs(cntSec)); +} diff --git a/DataBaseLMS/timingoftrainee.h b/DataBaseLMS/timingoftrainee.h new file mode 100644 index 0000000..5ef9af5 --- /dev/null +++ b/DataBaseLMS/timingoftrainee.h @@ -0,0 +1,60 @@ +#ifndef TIMINGOFTRAINEE_H +#define TIMINGOFTRAINEE_H + +#include +#include + +class TimingOfTrainee +{ +public: + TimingOfTrainee(int trainee_id); + + void setID(int timing_id){this->timing_id = timing_id;} + int getID(){return timing_id;} + + void setTraineeID(int trainee_id){this->trainee_id = trainee_id;} + int getTraineeID(){return trainee_id;} + + + void setEntryTimeS(QString entry_time); + void setEntryTime(QDateTime entry_time); + + QString getEntryTimeS(){return entryTime_str;} + QDateTime getEntryTime(){return entryTime;} + + + void setExitTimeS(QString exit_time); + void setExitTime(QDateTime exit_time); + + QString getExitTimeS(){return exitTime_str;} + QDateTime getExitTime(){return exitTime;} + + + void setOperatingTimeS(QString operating_time); + void setOperatingTime(QTime operating_time); + + QString getOperatingTimeS(){return operatingTime_str;} + QTime getOperatingTime(){return operatingTime;} + + void fixEntry(); + void fixExit(); + +private: + void calculateOperatingTime(); + +private: + int timing_id; + int trainee_id; + + QString entryTime_str; //"yyyy-MM-dd hh:mm:ss.zzz" + QString exitTime_str; //"yyyy-MM-dd hh:mm:ss.zzz" + QString operatingTime_str; //"hh:mm:ss" + + QDateTime entryTime; + QDateTime exitTime; + QTime operatingTime; + + QDateTime dataTimeNull; +}; + +#endif // TIMINGOFTRAINEE_H diff --git a/ServerLMS/Data/Client.h b/ServerLMS/Data/Client.h index 27e6400..9b01df0 100644 --- a/ServerLMS/Data/Client.h +++ b/ServerLMS/Data/Client.h @@ -96,6 +96,16 @@ public: isLoggedIn = value; } + void setAccessType(QString type) + { + accessType = type; + } + QString getAccessType() + { + return accessType; + } + + QString getId() { @@ -120,6 +130,7 @@ private: bool isUnity = false; TypeClientAutorization TypeClient; + QString accessType = ""; }; #endif // CLIENT_H diff --git a/ServerLMS/Systems/Parsers/processparser.cpp b/ServerLMS/Systems/Parsers/processparser.cpp index ec26ce1..42cf7b7 100644 --- a/ServerLMS/Systems/Parsers/processparser.cpp +++ b/ServerLMS/Systems/Parsers/processparser.cpp @@ -11,7 +11,7 @@ void ProcessParser::initialize(ProcessingSystem *processingSystem) this->processingSystem = processingSystem; } -void ProcessParser::read(ClientHandler *client, QByteArray array) +void ProcessParser::slot_read(ClientHandler *client, QByteArray array) { QXmlStreamReader xmlReader(array); diff --git a/ServerLMS/Systems/Parsers/processparser.h b/ServerLMS/Systems/Parsers/processparser.h index 63fb1ab..01a39b4 100644 --- a/ServerLMS/Systems/Parsers/processparser.h +++ b/ServerLMS/Systems/Parsers/processparser.h @@ -12,8 +12,9 @@ class ProcessParser : public QObject public: explicit ProcessParser(QObject *parent = nullptr); void initialize(ProcessingSystem *processingSystem); - void read(ClientHandler *client, QByteArray array); +public slots: + void slot_read(ClientHandler *client, QByteArray array); signals: void sigLogMessage(QString text); diff --git a/ServerLMS/Systems/processingsystem.cpp b/ServerLMS/Systems/processingsystem.cpp index 0da1138..ed655ce 100644 --- a/ServerLMS/Systems/processingsystem.cpp +++ b/ServerLMS/Systems/processingsystem.cpp @@ -4,8 +4,8 @@ ProcessingSystem::ProcessingSystem(ProviderDBLMS* providerDBLMS, UpdateController* updateController, QObject *parent): QObject(parent), - providerDBLMS(nullptr), - updateController(nullptr) + updateController(nullptr), + providerDBLMS(nullptr) { this->providerDBLMS = providerDBLMS; this->updateController = updateController; @@ -58,6 +58,7 @@ void ProcessingSystem::processingClientAutorization(ClientHandler *client, Clien {//Авторизуется инструктор client->getClient()->setLogin(clientAutorization.Login); + client->getClient()->setAccessType("instructor"); client->getClient()->setTypeClient(clientAutorization.TypeClient); emit sigUpdateListClients(); @@ -73,6 +74,7 @@ void ProcessingSystem::processingClientAutorization(ClientHandler *client, Clien {//Авторизуется обучаемый client->getClient()->setLogin(clientAutorization.Login); + client->getClient()->setAccessType("trainee"); emit sigUpdateListClients(); //KAV redact @@ -120,6 +122,7 @@ void ProcessingSystem::processingClientDeAutorization(ClientHandler *client, Cli {//ДеАвторизуется обучаемый client->getClient()->setLogin(""); + client->getClient()->setAccessType(""); emit sigUpdateListClients(); arrayAnswer = dataParser->ClientAnswer()->deAuthorization(true, clientDeAutorization.Login); @@ -128,6 +131,7 @@ void ProcessingSystem::processingClientDeAutorization(ClientHandler *client, Cli {//ДеАвторизуется инструктор client->getClient()->setLogin(""); + client->getClient()->setAccessType(""); emit sigUpdateListClients(); arrayAnswer = dataParser->ClientAnswer()->deAuthorization(true, clientDeAutorization.Login); @@ -160,6 +164,38 @@ void ProcessingSystem::processingClientDeAutorization(QString login) } } +void ProcessingSystem::processingEntryUnityClient(ClientHandler *client) +{ + QString login = client->getClient()->getLogin(); + QString accessType = client->getClient()->getAccessType(); + + if(accessType == "trainee") + { + int id_trainee = providerDBLMS->getIdTraineeByLogin(login); + providerDBLMS->entryTraineeOnSimulator(id_trainee); + } + else if(accessType == "instructor") + { + //Здесь пока ничего не происходит + } +} + +void ProcessingSystem::processingExitUnityClient(ClientHandler *client) +{ + QString login = client->getClient()->getLogin(); + QString accessType = client->getClient()->getAccessType(); + + if(accessType == "trainee") + { + int id_trainee = providerDBLMS->getIdTraineeByLogin(login); + providerDBLMS->exitTraineeFromSimulator(id_trainee); + } + else if(accessType == "instructor") + { + //Здесь пока ничего не происходит + } +} + void ProcessingSystem::processingClientQueryToDB(ClientHandler *client, ClientQueryToDB clientQueryToDB, int id, void* data) { qDebug() << "ProcessingQueryThread " << QThread::currentThreadId(); @@ -487,9 +523,24 @@ void ProcessingSystem::processingClientNotify(ClientHandler *client, ClientNotif sendTaskListToUnity(client); client->getSocket()->flush(); } + else if(clientNotify.Code == commandStartTimerClient) + { + //Фиксируем время входа Юнити-клиента + if (client->getClient()->getIsUnity()) + { + processingEntryUnityClient(client); + } + } else if(clientNotify.Code == commandDisableClient) { qDebug() << "processing thread: " << QThread::currentThreadId(); + + //Фиксируем время выхода Юнити-клиента + if (client->getClient()->getIsUnity()) + { + processingExitUnityClient(client); + } + client->sendDisable(); } else if(clientNotify.Code == commandGetServerDataList) diff --git a/ServerLMS/Systems/processingsystem.h b/ServerLMS/Systems/processingsystem.h index 2a9dd23..82affed 100644 --- a/ServerLMS/Systems/processingsystem.h +++ b/ServerLMS/Systems/processingsystem.h @@ -52,6 +52,9 @@ public: ClientHandler* getUnityClientById(int id); void processingClientDeAutorization(QString login); + + void processingEntryUnityClient(ClientHandler *client); + void processingExitUnityClient(ClientHandler *client); signals: void sigUpdateListClients(); void sigListsInstructorsTraineesChanged(); diff --git a/ServerLMS/Systems/recognizesystem.cpp b/ServerLMS/Systems/recognizesystem.cpp index a74ff5a..e2d2b9c 100644 --- a/ServerLMS/Systems/recognizesystem.cpp +++ b/ServerLMS/Systems/recognizesystem.cpp @@ -27,7 +27,7 @@ void RecognizeSystem::initialize(UpdateController *updateController,DataParser* connect(this,&RecognizeSystem::sigChangeVersion,updateController,&UpdateController::changeAssetVersion,Qt::AutoConnection); connect(this,&RecognizeSystem::sigDeleteVersion,updateController,&UpdateController::deleteAssetVersion,Qt::AutoConnection); connect(this,&RecognizeSystem::sigCopyVersion,updateController,&UpdateController::createCopyVersion,Qt::AutoConnection); - connect(this,&RecognizeSystem::sigXmlParser,dataParser->getProcessParser(),&ProcessParser::read,Qt::DirectConnection); + connect(this,&RecognizeSystem::sigXmlParser,dataParser->getProcessParser(),&ProcessParser::slot_read,Qt::DirectConnection); qDebug() << "Recognize init thread ID " << QThread::currentThreadId(); } @@ -430,7 +430,7 @@ void RecognizeSystem::recognize() if(packetType == PacketType::TYPE_DISABLE) { - clientHandler->sendDisable(); + clientHandler->sendDisable(); } packetType = PacketType::TYPE_NONE; @@ -450,6 +450,7 @@ void RecognizeSystem::packetTypeInit(PacketType packet,Client *client) else if (packet == PacketType::TYPE_UNITY) { client->setUnity(true); + //Фиксируем время входа Юнити-клиента } isPackageTypeInited = true; diff --git a/ServerLMS/Systems/recognizesystem.h b/ServerLMS/Systems/recognizesystem.h index 7d54af4..84a4283 100644 --- a/ServerLMS/Systems/recognizesystem.h +++ b/ServerLMS/Systems/recognizesystem.h @@ -59,7 +59,7 @@ private: bool isPackageTypeInited; void packetTypeInit(PacketType packet,Client *client); - void packetTypeInit(PacketType type); + //void packetTypeInit(PacketType type); bool checkIsChangeable(); }; diff --git a/ServerLMS/Systems/tools.h b/ServerLMS/Systems/tools.h index 327f37a..78dc068 100644 --- a/ServerLMS/Systems/tools.h +++ b/ServerLMS/Systems/tools.h @@ -39,6 +39,7 @@ static const QString commandGetServerDataList = "GETSERVERDATALIST"; static const QString commandCheckVersionList = "CHECKVERSIONLIST"; static const QString commandReadyClient = "READY"; static const QString commandDisableClient = "DISABLE"; +static const QString commandStartTimerClient = "UNITYSTARTTIMER"; static const QString commandDuplicateVerName = "DUPLICATEVERNAME"; static const QString commandHashCompleteClient = "HASHSENDCOMPLETE"; static const QString commandCanChangeVersion = "CANCHANGE"; diff --git a/ServerLMS/providerdblms.cpp b/ServerLMS/providerdblms.cpp index bc98394..2576e5e 100644 --- a/ServerLMS/providerdblms.cpp +++ b/ServerLMS/providerdblms.cpp @@ -222,6 +222,22 @@ bool ProviderDBLMS::deAuthorizationAll() return res1 && res2; } +bool ProviderDBLMS::entryTraineeOnSimulator(int id_trainee) +{ + if(dbLMS->entryTraineeOnSimulator(id_trainee)) + return true; + else + return false; +} + +bool ProviderDBLMS::exitTraineeFromSimulator(int id_trainee) +{ + if(dbLMS->exitTraineeFromSimulator(id_trainee)) + return true; + else + return false; +} + int ProviderDBLMS::getIdTraineeByLogin(QString login) { int id_trainee = 0; diff --git a/ServerLMS/providerdblms.h b/ServerLMS/providerdblms.h index cd081df..58835b3 100644 --- a/ServerLMS/providerdblms.h +++ b/ServerLMS/providerdblms.h @@ -28,6 +28,10 @@ public: //Общая деавторизация bool deAuthorizationAll(); + //Регистрация тайминга Обучаемого + bool entryTraineeOnSimulator(int id_trainee); + bool exitTraineeFromSimulator(int id_trainee); + // int getIdTraineeByLogin(QString login); int getIdInstructorByLogin(QString login); diff --git a/ServerLMS/serverlmswidget.cpp b/ServerLMS/serverlmswidget.cpp index 64b8eed..3f436d3 100644 --- a/ServerLMS/serverlmswidget.cpp +++ b/ServerLMS/serverlmswidget.cpp @@ -132,16 +132,24 @@ bool ServerLMSWidget::stopServer() //Закрываем все открытые сокеты foreach(int idSocket, clientsMap.keys()) { - clientsMap[idSocket]->sigSendXmlAnswer(arrayAnswer,PacketType::TYPE_XMLANSWER); + ClientHandler* clientHandlerOpen = clientsMap[idSocket]; + + //Фиксируем время выхода Юнити-клиента + if(clientHandlerOpen->getClient()->getIsUnity()) + { + processingSystem->processingExitUnityClient(clientHandlerOpen); + } + + clientHandlerOpen->sigSendXmlAnswer(arrayAnswer, PacketType::TYPE_XMLANSWER); //while (!clientsMap[idSocket]->sigSocketFlush()) {} QString str = QString(arrayAnswer); emit sigLog("To Client: " + str); //slotDisconnectClient(clientsMap[idSocket]->get, QString peerPort) - processingSystem->processingClientDeAutorization(clientsMap[idSocket]->getClient()->getLogin()); + processingSystem->processingClientDeAutorization(clientHandlerOpen->getClient()->getLogin()); - clientsMap[idSocket]->sigSocketClose(); + clientHandlerOpen->sigSocketClose(); //clientsMap.remove(idSocket); removeClient(idSocket); }