diff --git a/AppConstants.h b/AppConstants.h new file mode 100644 index 0000000..296c53f --- /dev/null +++ b/AppConstants.h @@ -0,0 +1,28 @@ +#ifndef APPCONSTANTS_H +#define APPCONSTANTS_H + +class AppConstants +{ +public: + enum WidgeFrameName + { + MAIN_PAGE = 0, // 主页面 + PERSON_LIST_FORM = 1, // 人员列表页面 + ADD_PERSON_FORM = 2, // 添加人员页面 + ADD_PERSON_CAPTURE_FACE = 21, // 添加/编辑人员时进行人脸拍图 + ADD_PERSON_CAPTURE_IRIS = 22, // 添加/编辑人员时进行虹膜拍图 + SETTING_FORM = 3, // 设置页面 + RECOGNIZE_RESULT_FORM = 4, // 识别结果界面 + IDENTIFY_FORM = 5, // 识别界面 含识别中 和 识别结果 + LOCKSCREEN_FORM = 6 // 锁屏待机界面 + }; + + enum ApplicationState + { + STATE_WAIT = 0, // 待机 + STATE_WORKING = 1, // 工作状态 + STATE_IDENTIFYING = 2, // 识别中 + }; +}; + +#endif // APPCONSTANTS_H diff --git a/AppConstants.h b/AppConstants.h new file mode 100644 index 0000000..296c53f --- /dev/null +++ b/AppConstants.h @@ -0,0 +1,28 @@ +#ifndef APPCONSTANTS_H +#define APPCONSTANTS_H + +class AppConstants +{ +public: + enum WidgeFrameName + { + MAIN_PAGE = 0, // 主页面 + PERSON_LIST_FORM = 1, // 人员列表页面 + ADD_PERSON_FORM = 2, // 添加人员页面 + ADD_PERSON_CAPTURE_FACE = 21, // 添加/编辑人员时进行人脸拍图 + ADD_PERSON_CAPTURE_IRIS = 22, // 添加/编辑人员时进行虹膜拍图 + SETTING_FORM = 3, // 设置页面 + RECOGNIZE_RESULT_FORM = 4, // 识别结果界面 + IDENTIFY_FORM = 5, // 识别界面 含识别中 和 识别结果 + LOCKSCREEN_FORM = 6 // 锁屏待机界面 + }; + + enum ApplicationState + { + STATE_WAIT = 0, // 待机 + STATE_WORKING = 1, // 工作状态 + STATE_IDENTIFYING = 2, // 识别中 + }; +}; + +#endif // APPCONSTANTS_H diff --git a/CasicIrisIdentify.pro b/CasicIrisIdentify.pro index 5d7fea6..575ce3d 100644 --- a/CasicIrisIdentify.pro +++ b/CasicIrisIdentify.pro @@ -1,4 +1,4 @@ -QT += core gui +QT += core gui sql network texttospeech greaterThan(QT_MAJOR_VERSION, 4): QT += widgets @@ -15,20 +15,46 @@ # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 -SOURCES += \ - main.cpp \ - IdentifyForm.cpp +include("dao/dao.pri") +include("device/device.pri") +include("utils/utils.pri") -HEADERS += \ - IdentifyForm.h +SOURCES += main.cpp +SOURCES += ProMemory.cpp +SOURCES += MainWindowForm.cpp +SOURCES += IdentifyForm.cpp +SOURCES += LockScreenForm.cpp -FORMS += \ - IdentifyForm.ui +HEADERS += AppConstants.h +HEADERS += ProMemory.h +HEADERS += MainWindowForm.h +HEADERS += IdentifyForm.h +HEADERS += LockScreenForm.h -TRANSLATIONS += \ - CasicIrisIdentify_zh_CN.ts +FORMS += MainWindowForm.ui +FORMS += IdentifyForm.ui +FORMS += LockScreenForm.ui + +RESOURCES += resource.qrc + +DISTFILES += conf/config.ini + +#TRANSLATIONS += CasicIrisIdentify_zh_CN.ts + +#INCLUDEPATH += include/spdlog +#DEPENDPATH += include/spdlog # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target + + +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lopencv_world420 +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lGxIAPICPPEx + +INCLUDEPATH += $$PWD/include/daheng +DEPENDPATH += $$PWD/include/daheng + +INCLUDEPATH += $$PWD/include +DEPENDPATH += $$PWD/include diff --git a/AppConstants.h b/AppConstants.h new file mode 100644 index 0000000..296c53f --- /dev/null +++ b/AppConstants.h @@ -0,0 +1,28 @@ +#ifndef APPCONSTANTS_H +#define APPCONSTANTS_H + +class AppConstants +{ +public: + enum WidgeFrameName + { + MAIN_PAGE = 0, // 主页面 + PERSON_LIST_FORM = 1, // 人员列表页面 + ADD_PERSON_FORM = 2, // 添加人员页面 + ADD_PERSON_CAPTURE_FACE = 21, // 添加/编辑人员时进行人脸拍图 + ADD_PERSON_CAPTURE_IRIS = 22, // 添加/编辑人员时进行虹膜拍图 + SETTING_FORM = 3, // 设置页面 + RECOGNIZE_RESULT_FORM = 4, // 识别结果界面 + IDENTIFY_FORM = 5, // 识别界面 含识别中 和 识别结果 + LOCKSCREEN_FORM = 6 // 锁屏待机界面 + }; + + enum ApplicationState + { + STATE_WAIT = 0, // 待机 + STATE_WORKING = 1, // 工作状态 + STATE_IDENTIFYING = 2, // 识别中 + }; +}; + +#endif // APPCONSTANTS_H diff --git a/CasicIrisIdentify.pro b/CasicIrisIdentify.pro index 5d7fea6..575ce3d 100644 --- a/CasicIrisIdentify.pro +++ b/CasicIrisIdentify.pro @@ -1,4 +1,4 @@ -QT += core gui +QT += core gui sql network texttospeech greaterThan(QT_MAJOR_VERSION, 4): QT += widgets @@ -15,20 +15,46 @@ # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 -SOURCES += \ - main.cpp \ - IdentifyForm.cpp +include("dao/dao.pri") +include("device/device.pri") +include("utils/utils.pri") -HEADERS += \ - IdentifyForm.h +SOURCES += main.cpp +SOURCES += ProMemory.cpp +SOURCES += MainWindowForm.cpp +SOURCES += IdentifyForm.cpp +SOURCES += LockScreenForm.cpp -FORMS += \ - IdentifyForm.ui +HEADERS += AppConstants.h +HEADERS += ProMemory.h +HEADERS += MainWindowForm.h +HEADERS += IdentifyForm.h +HEADERS += LockScreenForm.h -TRANSLATIONS += \ - CasicIrisIdentify_zh_CN.ts +FORMS += MainWindowForm.ui +FORMS += IdentifyForm.ui +FORMS += LockScreenForm.ui + +RESOURCES += resource.qrc + +DISTFILES += conf/config.ini + +#TRANSLATIONS += CasicIrisIdentify_zh_CN.ts + +#INCLUDEPATH += include/spdlog +#DEPENDPATH += include/spdlog # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target + + +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lopencv_world420 +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lGxIAPICPPEx + +INCLUDEPATH += $$PWD/include/daheng +DEPENDPATH += $$PWD/include/daheng + +INCLUDEPATH += $$PWD/include +DEPENDPATH += $$PWD/include diff --git a/CasicIrisIdentify_zh_CN.ts b/CasicIrisIdentify_zh_CN.ts index 5526fe4..81900df 100644 --- a/CasicIrisIdentify_zh_CN.ts +++ b/CasicIrisIdentify_zh_CN.ts @@ -1,3 +1,12 @@ - + + + IdentifyForm + + + IdentifyForm + + + + diff --git a/AppConstants.h b/AppConstants.h new file mode 100644 index 0000000..296c53f --- /dev/null +++ b/AppConstants.h @@ -0,0 +1,28 @@ +#ifndef APPCONSTANTS_H +#define APPCONSTANTS_H + +class AppConstants +{ +public: + enum WidgeFrameName + { + MAIN_PAGE = 0, // 主页面 + PERSON_LIST_FORM = 1, // 人员列表页面 + ADD_PERSON_FORM = 2, // 添加人员页面 + ADD_PERSON_CAPTURE_FACE = 21, // 添加/编辑人员时进行人脸拍图 + ADD_PERSON_CAPTURE_IRIS = 22, // 添加/编辑人员时进行虹膜拍图 + SETTING_FORM = 3, // 设置页面 + RECOGNIZE_RESULT_FORM = 4, // 识别结果界面 + IDENTIFY_FORM = 5, // 识别界面 含识别中 和 识别结果 + LOCKSCREEN_FORM = 6 // 锁屏待机界面 + }; + + enum ApplicationState + { + STATE_WAIT = 0, // 待机 + STATE_WORKING = 1, // 工作状态 + STATE_IDENTIFYING = 2, // 识别中 + }; +}; + +#endif // APPCONSTANTS_H diff --git a/CasicIrisIdentify.pro b/CasicIrisIdentify.pro index 5d7fea6..575ce3d 100644 --- a/CasicIrisIdentify.pro +++ b/CasicIrisIdentify.pro @@ -1,4 +1,4 @@ -QT += core gui +QT += core gui sql network texttospeech greaterThan(QT_MAJOR_VERSION, 4): QT += widgets @@ -15,20 +15,46 @@ # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 -SOURCES += \ - main.cpp \ - IdentifyForm.cpp +include("dao/dao.pri") +include("device/device.pri") +include("utils/utils.pri") -HEADERS += \ - IdentifyForm.h +SOURCES += main.cpp +SOURCES += ProMemory.cpp +SOURCES += MainWindowForm.cpp +SOURCES += IdentifyForm.cpp +SOURCES += LockScreenForm.cpp -FORMS += \ - IdentifyForm.ui +HEADERS += AppConstants.h +HEADERS += ProMemory.h +HEADERS += MainWindowForm.h +HEADERS += IdentifyForm.h +HEADERS += LockScreenForm.h -TRANSLATIONS += \ - CasicIrisIdentify_zh_CN.ts +FORMS += MainWindowForm.ui +FORMS += IdentifyForm.ui +FORMS += LockScreenForm.ui + +RESOURCES += resource.qrc + +DISTFILES += conf/config.ini + +#TRANSLATIONS += CasicIrisIdentify_zh_CN.ts + +#INCLUDEPATH += include/spdlog +#DEPENDPATH += include/spdlog # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target + + +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lopencv_world420 +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lGxIAPICPPEx + +INCLUDEPATH += $$PWD/include/daheng +DEPENDPATH += $$PWD/include/daheng + +INCLUDEPATH += $$PWD/include +DEPENDPATH += $$PWD/include diff --git a/CasicIrisIdentify_zh_CN.ts b/CasicIrisIdentify_zh_CN.ts index 5526fe4..81900df 100644 --- a/CasicIrisIdentify_zh_CN.ts +++ b/CasicIrisIdentify_zh_CN.ts @@ -1,3 +1,12 @@ - + + + IdentifyForm + + + IdentifyForm + + + + diff --git a/IdentifyForm.cpp b/IdentifyForm.cpp index 348a897..ba1f251 100644 --- a/IdentifyForm.cpp +++ b/IdentifyForm.cpp @@ -1,4 +1,4 @@ -#include "IdentifyForm.h" +#include "IdentifyForm.h" #include "ui_IdentifyForm.h" IdentifyForm::IdentifyForm(QWidget *parent) @@ -6,6 +6,12 @@ , ui(new Ui::IdentifyForm) { ui->setupUi(this); + + // 初始化更新界面的定时器 + // 每秒执行一次 + connect(TimeCounterUtil::getInstance().clockCounter, &QTimer::timeout, this, &IdentifyForm::updateDateAndTime); + + TimeCounterUtil::getInstance().clockCounter->start(1000); } IdentifyForm::~IdentifyForm() @@ -13,3 +19,16 @@ delete ui; } +void IdentifyForm::drawIrisImageOnFrame(QImage image) +{ + // 只在识别界面才显示画面 + if (ui->wgtStacked->currentIndex() == 0) { + ui->labelVideo->setPixmap(QPixmap::fromImage(image)); + } +} + + +void IdentifyForm::updateDateAndTime() +{ + ui->labelTime->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd dddd HH:mm:ss")); +} diff --git a/AppConstants.h b/AppConstants.h new file mode 100644 index 0000000..296c53f --- /dev/null +++ b/AppConstants.h @@ -0,0 +1,28 @@ +#ifndef APPCONSTANTS_H +#define APPCONSTANTS_H + +class AppConstants +{ +public: + enum WidgeFrameName + { + MAIN_PAGE = 0, // 主页面 + PERSON_LIST_FORM = 1, // 人员列表页面 + ADD_PERSON_FORM = 2, // 添加人员页面 + ADD_PERSON_CAPTURE_FACE = 21, // 添加/编辑人员时进行人脸拍图 + ADD_PERSON_CAPTURE_IRIS = 22, // 添加/编辑人员时进行虹膜拍图 + SETTING_FORM = 3, // 设置页面 + RECOGNIZE_RESULT_FORM = 4, // 识别结果界面 + IDENTIFY_FORM = 5, // 识别界面 含识别中 和 识别结果 + LOCKSCREEN_FORM = 6 // 锁屏待机界面 + }; + + enum ApplicationState + { + STATE_WAIT = 0, // 待机 + STATE_WORKING = 1, // 工作状态 + STATE_IDENTIFYING = 2, // 识别中 + }; +}; + +#endif // APPCONSTANTS_H diff --git a/CasicIrisIdentify.pro b/CasicIrisIdentify.pro index 5d7fea6..575ce3d 100644 --- a/CasicIrisIdentify.pro +++ b/CasicIrisIdentify.pro @@ -1,4 +1,4 @@ -QT += core gui +QT += core gui sql network texttospeech greaterThan(QT_MAJOR_VERSION, 4): QT += widgets @@ -15,20 +15,46 @@ # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 -SOURCES += \ - main.cpp \ - IdentifyForm.cpp +include("dao/dao.pri") +include("device/device.pri") +include("utils/utils.pri") -HEADERS += \ - IdentifyForm.h +SOURCES += main.cpp +SOURCES += ProMemory.cpp +SOURCES += MainWindowForm.cpp +SOURCES += IdentifyForm.cpp +SOURCES += LockScreenForm.cpp -FORMS += \ - IdentifyForm.ui +HEADERS += AppConstants.h +HEADERS += ProMemory.h +HEADERS += MainWindowForm.h +HEADERS += IdentifyForm.h +HEADERS += LockScreenForm.h -TRANSLATIONS += \ - CasicIrisIdentify_zh_CN.ts +FORMS += MainWindowForm.ui +FORMS += IdentifyForm.ui +FORMS += LockScreenForm.ui + +RESOURCES += resource.qrc + +DISTFILES += conf/config.ini + +#TRANSLATIONS += CasicIrisIdentify_zh_CN.ts + +#INCLUDEPATH += include/spdlog +#DEPENDPATH += include/spdlog # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target + + +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lopencv_world420 +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lGxIAPICPPEx + +INCLUDEPATH += $$PWD/include/daheng +DEPENDPATH += $$PWD/include/daheng + +INCLUDEPATH += $$PWD/include +DEPENDPATH += $$PWD/include diff --git a/CasicIrisIdentify_zh_CN.ts b/CasicIrisIdentify_zh_CN.ts index 5526fe4..81900df 100644 --- a/CasicIrisIdentify_zh_CN.ts +++ b/CasicIrisIdentify_zh_CN.ts @@ -1,3 +1,12 @@ - + + + IdentifyForm + + + IdentifyForm + + + + diff --git a/IdentifyForm.cpp b/IdentifyForm.cpp index 348a897..ba1f251 100644 --- a/IdentifyForm.cpp +++ b/IdentifyForm.cpp @@ -1,4 +1,4 @@ -#include "IdentifyForm.h" +#include "IdentifyForm.h" #include "ui_IdentifyForm.h" IdentifyForm::IdentifyForm(QWidget *parent) @@ -6,6 +6,12 @@ , ui(new Ui::IdentifyForm) { ui->setupUi(this); + + // 初始化更新界面的定时器 + // 每秒执行一次 + connect(TimeCounterUtil::getInstance().clockCounter, &QTimer::timeout, this, &IdentifyForm::updateDateAndTime); + + TimeCounterUtil::getInstance().clockCounter->start(1000); } IdentifyForm::~IdentifyForm() @@ -13,3 +19,16 @@ delete ui; } +void IdentifyForm::drawIrisImageOnFrame(QImage image) +{ + // 只在识别界面才显示画面 + if (ui->wgtStacked->currentIndex() == 0) { + ui->labelVideo->setPixmap(QPixmap::fromImage(image)); + } +} + + +void IdentifyForm::updateDateAndTime() +{ + ui->labelTime->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd dddd HH:mm:ss")); +} diff --git a/IdentifyForm.h b/IdentifyForm.h index fc857a1..ae1cd22 100644 --- a/IdentifyForm.h +++ b/IdentifyForm.h @@ -1,7 +1,10 @@ -#ifndef IDENTIFYFORM_H +#ifndef IDENTIFYFORM_H #define IDENTIFYFORM_H #include +#include + +#include "utils/UtilInclude.h" QT_BEGIN_NAMESPACE namespace Ui { class IdentifyForm; } @@ -15,7 +18,14 @@ IdentifyForm(QWidget *parent = nullptr); ~IdentifyForm(); +public slots: + void drawIrisImageOnFrame(QImage image); + private: Ui::IdentifyForm *ui; + +private slots: + void updateDateAndTime(); + }; #endif // IDENTIFYFORM_H diff --git a/AppConstants.h b/AppConstants.h new file mode 100644 index 0000000..296c53f --- /dev/null +++ b/AppConstants.h @@ -0,0 +1,28 @@ +#ifndef APPCONSTANTS_H +#define APPCONSTANTS_H + +class AppConstants +{ +public: + enum WidgeFrameName + { + MAIN_PAGE = 0, // 主页面 + PERSON_LIST_FORM = 1, // 人员列表页面 + ADD_PERSON_FORM = 2, // 添加人员页面 + ADD_PERSON_CAPTURE_FACE = 21, // 添加/编辑人员时进行人脸拍图 + ADD_PERSON_CAPTURE_IRIS = 22, // 添加/编辑人员时进行虹膜拍图 + SETTING_FORM = 3, // 设置页面 + RECOGNIZE_RESULT_FORM = 4, // 识别结果界面 + IDENTIFY_FORM = 5, // 识别界面 含识别中 和 识别结果 + LOCKSCREEN_FORM = 6 // 锁屏待机界面 + }; + + enum ApplicationState + { + STATE_WAIT = 0, // 待机 + STATE_WORKING = 1, // 工作状态 + STATE_IDENTIFYING = 2, // 识别中 + }; +}; + +#endif // APPCONSTANTS_H diff --git a/CasicIrisIdentify.pro b/CasicIrisIdentify.pro index 5d7fea6..575ce3d 100644 --- a/CasicIrisIdentify.pro +++ b/CasicIrisIdentify.pro @@ -1,4 +1,4 @@ -QT += core gui +QT += core gui sql network texttospeech greaterThan(QT_MAJOR_VERSION, 4): QT += widgets @@ -15,20 +15,46 @@ # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 -SOURCES += \ - main.cpp \ - IdentifyForm.cpp +include("dao/dao.pri") +include("device/device.pri") +include("utils/utils.pri") -HEADERS += \ - IdentifyForm.h +SOURCES += main.cpp +SOURCES += ProMemory.cpp +SOURCES += MainWindowForm.cpp +SOURCES += IdentifyForm.cpp +SOURCES += LockScreenForm.cpp -FORMS += \ - IdentifyForm.ui +HEADERS += AppConstants.h +HEADERS += ProMemory.h +HEADERS += MainWindowForm.h +HEADERS += IdentifyForm.h +HEADERS += LockScreenForm.h -TRANSLATIONS += \ - CasicIrisIdentify_zh_CN.ts +FORMS += MainWindowForm.ui +FORMS += IdentifyForm.ui +FORMS += LockScreenForm.ui + +RESOURCES += resource.qrc + +DISTFILES += conf/config.ini + +#TRANSLATIONS += CasicIrisIdentify_zh_CN.ts + +#INCLUDEPATH += include/spdlog +#DEPENDPATH += include/spdlog # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target + + +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lopencv_world420 +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lGxIAPICPPEx + +INCLUDEPATH += $$PWD/include/daheng +DEPENDPATH += $$PWD/include/daheng + +INCLUDEPATH += $$PWD/include +DEPENDPATH += $$PWD/include diff --git a/CasicIrisIdentify_zh_CN.ts b/CasicIrisIdentify_zh_CN.ts index 5526fe4..81900df 100644 --- a/CasicIrisIdentify_zh_CN.ts +++ b/CasicIrisIdentify_zh_CN.ts @@ -1,3 +1,12 @@ - + + + IdentifyForm + + + IdentifyForm + + + + diff --git a/IdentifyForm.cpp b/IdentifyForm.cpp index 348a897..ba1f251 100644 --- a/IdentifyForm.cpp +++ b/IdentifyForm.cpp @@ -1,4 +1,4 @@ -#include "IdentifyForm.h" +#include "IdentifyForm.h" #include "ui_IdentifyForm.h" IdentifyForm::IdentifyForm(QWidget *parent) @@ -6,6 +6,12 @@ , ui(new Ui::IdentifyForm) { ui->setupUi(this); + + // 初始化更新界面的定时器 + // 每秒执行一次 + connect(TimeCounterUtil::getInstance().clockCounter, &QTimer::timeout, this, &IdentifyForm::updateDateAndTime); + + TimeCounterUtil::getInstance().clockCounter->start(1000); } IdentifyForm::~IdentifyForm() @@ -13,3 +19,16 @@ delete ui; } +void IdentifyForm::drawIrisImageOnFrame(QImage image) +{ + // 只在识别界面才显示画面 + if (ui->wgtStacked->currentIndex() == 0) { + ui->labelVideo->setPixmap(QPixmap::fromImage(image)); + } +} + + +void IdentifyForm::updateDateAndTime() +{ + ui->labelTime->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd dddd HH:mm:ss")); +} diff --git a/IdentifyForm.h b/IdentifyForm.h index fc857a1..ae1cd22 100644 --- a/IdentifyForm.h +++ b/IdentifyForm.h @@ -1,7 +1,10 @@ -#ifndef IDENTIFYFORM_H +#ifndef IDENTIFYFORM_H #define IDENTIFYFORM_H #include +#include + +#include "utils/UtilInclude.h" QT_BEGIN_NAMESPACE namespace Ui { class IdentifyForm; } @@ -15,7 +18,14 @@ IdentifyForm(QWidget *parent = nullptr); ~IdentifyForm(); +public slots: + void drawIrisImageOnFrame(QImage image); + private: Ui::IdentifyForm *ui; + +private slots: + void updateDateAndTime(); + }; #endif // IDENTIFYFORM_H diff --git a/IdentifyForm.ui b/IdentifyForm.ui index c72a36f..879dc9a 100644 --- a/IdentifyForm.ui +++ b/IdentifyForm.ui @@ -6,13 +6,59 @@ 0 0 - 800 + 600 600 IdentifyForm + + + + 0 + 40 + 600 + 450 + + + + 0 + + + + + + 100 + 10 + 400 + 300 + + + + + + + + + + + + + + 0 + 0 + 600 + 40 + + + + TextLabel + + + Qt::AlignCenter + + diff --git a/AppConstants.h b/AppConstants.h new file mode 100644 index 0000000..296c53f --- /dev/null +++ b/AppConstants.h @@ -0,0 +1,28 @@ +#ifndef APPCONSTANTS_H +#define APPCONSTANTS_H + +class AppConstants +{ +public: + enum WidgeFrameName + { + MAIN_PAGE = 0, // 主页面 + PERSON_LIST_FORM = 1, // 人员列表页面 + ADD_PERSON_FORM = 2, // 添加人员页面 + ADD_PERSON_CAPTURE_FACE = 21, // 添加/编辑人员时进行人脸拍图 + ADD_PERSON_CAPTURE_IRIS = 22, // 添加/编辑人员时进行虹膜拍图 + SETTING_FORM = 3, // 设置页面 + RECOGNIZE_RESULT_FORM = 4, // 识别结果界面 + IDENTIFY_FORM = 5, // 识别界面 含识别中 和 识别结果 + LOCKSCREEN_FORM = 6 // 锁屏待机界面 + }; + + enum ApplicationState + { + STATE_WAIT = 0, // 待机 + STATE_WORKING = 1, // 工作状态 + STATE_IDENTIFYING = 2, // 识别中 + }; +}; + +#endif // APPCONSTANTS_H diff --git a/CasicIrisIdentify.pro b/CasicIrisIdentify.pro index 5d7fea6..575ce3d 100644 --- a/CasicIrisIdentify.pro +++ b/CasicIrisIdentify.pro @@ -1,4 +1,4 @@ -QT += core gui +QT += core gui sql network texttospeech greaterThan(QT_MAJOR_VERSION, 4): QT += widgets @@ -15,20 +15,46 @@ # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 -SOURCES += \ - main.cpp \ - IdentifyForm.cpp +include("dao/dao.pri") +include("device/device.pri") +include("utils/utils.pri") -HEADERS += \ - IdentifyForm.h +SOURCES += main.cpp +SOURCES += ProMemory.cpp +SOURCES += MainWindowForm.cpp +SOURCES += IdentifyForm.cpp +SOURCES += LockScreenForm.cpp -FORMS += \ - IdentifyForm.ui +HEADERS += AppConstants.h +HEADERS += ProMemory.h +HEADERS += MainWindowForm.h +HEADERS += IdentifyForm.h +HEADERS += LockScreenForm.h -TRANSLATIONS += \ - CasicIrisIdentify_zh_CN.ts +FORMS += MainWindowForm.ui +FORMS += IdentifyForm.ui +FORMS += LockScreenForm.ui + +RESOURCES += resource.qrc + +DISTFILES += conf/config.ini + +#TRANSLATIONS += CasicIrisIdentify_zh_CN.ts + +#INCLUDEPATH += include/spdlog +#DEPENDPATH += include/spdlog # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target + + +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lopencv_world420 +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lGxIAPICPPEx + +INCLUDEPATH += $$PWD/include/daheng +DEPENDPATH += $$PWD/include/daheng + +INCLUDEPATH += $$PWD/include +DEPENDPATH += $$PWD/include diff --git a/CasicIrisIdentify_zh_CN.ts b/CasicIrisIdentify_zh_CN.ts index 5526fe4..81900df 100644 --- a/CasicIrisIdentify_zh_CN.ts +++ b/CasicIrisIdentify_zh_CN.ts @@ -1,3 +1,12 @@ - + + + IdentifyForm + + + IdentifyForm + + + + diff --git a/IdentifyForm.cpp b/IdentifyForm.cpp index 348a897..ba1f251 100644 --- a/IdentifyForm.cpp +++ b/IdentifyForm.cpp @@ -1,4 +1,4 @@ -#include "IdentifyForm.h" +#include "IdentifyForm.h" #include "ui_IdentifyForm.h" IdentifyForm::IdentifyForm(QWidget *parent) @@ -6,6 +6,12 @@ , ui(new Ui::IdentifyForm) { ui->setupUi(this); + + // 初始化更新界面的定时器 + // 每秒执行一次 + connect(TimeCounterUtil::getInstance().clockCounter, &QTimer::timeout, this, &IdentifyForm::updateDateAndTime); + + TimeCounterUtil::getInstance().clockCounter->start(1000); } IdentifyForm::~IdentifyForm() @@ -13,3 +19,16 @@ delete ui; } +void IdentifyForm::drawIrisImageOnFrame(QImage image) +{ + // 只在识别界面才显示画面 + if (ui->wgtStacked->currentIndex() == 0) { + ui->labelVideo->setPixmap(QPixmap::fromImage(image)); + } +} + + +void IdentifyForm::updateDateAndTime() +{ + ui->labelTime->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd dddd HH:mm:ss")); +} diff --git a/IdentifyForm.h b/IdentifyForm.h index fc857a1..ae1cd22 100644 --- a/IdentifyForm.h +++ b/IdentifyForm.h @@ -1,7 +1,10 @@ -#ifndef IDENTIFYFORM_H +#ifndef IDENTIFYFORM_H #define IDENTIFYFORM_H #include +#include + +#include "utils/UtilInclude.h" QT_BEGIN_NAMESPACE namespace Ui { class IdentifyForm; } @@ -15,7 +18,14 @@ IdentifyForm(QWidget *parent = nullptr); ~IdentifyForm(); +public slots: + void drawIrisImageOnFrame(QImage image); + private: Ui::IdentifyForm *ui; + +private slots: + void updateDateAndTime(); + }; #endif // IDENTIFYFORM_H diff --git a/IdentifyForm.ui b/IdentifyForm.ui index c72a36f..879dc9a 100644 --- a/IdentifyForm.ui +++ b/IdentifyForm.ui @@ -6,13 +6,59 @@ 0 0 - 800 + 600 600 IdentifyForm + + + + 0 + 40 + 600 + 450 + + + + 0 + + + + + + 100 + 10 + 400 + 300 + + + + + + + + + + + + + + 0 + 0 + 600 + 40 + + + + TextLabel + + + Qt::AlignCenter + + diff --git a/LockScreenForm.cpp b/LockScreenForm.cpp new file mode 100644 index 0000000..58dc54b --- /dev/null +++ b/LockScreenForm.cpp @@ -0,0 +1,14 @@ +#include "LockScreenForm.h" +#include "ui_LockScreenForm.h" + +LockScreenForm::LockScreenForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::LockScreenForm) +{ + ui->setupUi(this); +} + +LockScreenForm::~LockScreenForm() +{ + delete ui; +} diff --git a/AppConstants.h b/AppConstants.h new file mode 100644 index 0000000..296c53f --- /dev/null +++ b/AppConstants.h @@ -0,0 +1,28 @@ +#ifndef APPCONSTANTS_H +#define APPCONSTANTS_H + +class AppConstants +{ +public: + enum WidgeFrameName + { + MAIN_PAGE = 0, // 主页面 + PERSON_LIST_FORM = 1, // 人员列表页面 + ADD_PERSON_FORM = 2, // 添加人员页面 + ADD_PERSON_CAPTURE_FACE = 21, // 添加/编辑人员时进行人脸拍图 + ADD_PERSON_CAPTURE_IRIS = 22, // 添加/编辑人员时进行虹膜拍图 + SETTING_FORM = 3, // 设置页面 + RECOGNIZE_RESULT_FORM = 4, // 识别结果界面 + IDENTIFY_FORM = 5, // 识别界面 含识别中 和 识别结果 + LOCKSCREEN_FORM = 6 // 锁屏待机界面 + }; + + enum ApplicationState + { + STATE_WAIT = 0, // 待机 + STATE_WORKING = 1, // 工作状态 + STATE_IDENTIFYING = 2, // 识别中 + }; +}; + +#endif // APPCONSTANTS_H diff --git a/CasicIrisIdentify.pro b/CasicIrisIdentify.pro index 5d7fea6..575ce3d 100644 --- a/CasicIrisIdentify.pro +++ b/CasicIrisIdentify.pro @@ -1,4 +1,4 @@ -QT += core gui +QT += core gui sql network texttospeech greaterThan(QT_MAJOR_VERSION, 4): QT += widgets @@ -15,20 +15,46 @@ # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 -SOURCES += \ - main.cpp \ - IdentifyForm.cpp +include("dao/dao.pri") +include("device/device.pri") +include("utils/utils.pri") -HEADERS += \ - IdentifyForm.h +SOURCES += main.cpp +SOURCES += ProMemory.cpp +SOURCES += MainWindowForm.cpp +SOURCES += IdentifyForm.cpp +SOURCES += LockScreenForm.cpp -FORMS += \ - IdentifyForm.ui +HEADERS += AppConstants.h +HEADERS += ProMemory.h +HEADERS += MainWindowForm.h +HEADERS += IdentifyForm.h +HEADERS += LockScreenForm.h -TRANSLATIONS += \ - CasicIrisIdentify_zh_CN.ts +FORMS += MainWindowForm.ui +FORMS += IdentifyForm.ui +FORMS += LockScreenForm.ui + +RESOURCES += resource.qrc + +DISTFILES += conf/config.ini + +#TRANSLATIONS += CasicIrisIdentify_zh_CN.ts + +#INCLUDEPATH += include/spdlog +#DEPENDPATH += include/spdlog # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target + + +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lopencv_world420 +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lGxIAPICPPEx + +INCLUDEPATH += $$PWD/include/daheng +DEPENDPATH += $$PWD/include/daheng + +INCLUDEPATH += $$PWD/include +DEPENDPATH += $$PWD/include diff --git a/CasicIrisIdentify_zh_CN.ts b/CasicIrisIdentify_zh_CN.ts index 5526fe4..81900df 100644 --- a/CasicIrisIdentify_zh_CN.ts +++ b/CasicIrisIdentify_zh_CN.ts @@ -1,3 +1,12 @@ - + + + IdentifyForm + + + IdentifyForm + + + + diff --git a/IdentifyForm.cpp b/IdentifyForm.cpp index 348a897..ba1f251 100644 --- a/IdentifyForm.cpp +++ b/IdentifyForm.cpp @@ -1,4 +1,4 @@ -#include "IdentifyForm.h" +#include "IdentifyForm.h" #include "ui_IdentifyForm.h" IdentifyForm::IdentifyForm(QWidget *parent) @@ -6,6 +6,12 @@ , ui(new Ui::IdentifyForm) { ui->setupUi(this); + + // 初始化更新界面的定时器 + // 每秒执行一次 + connect(TimeCounterUtil::getInstance().clockCounter, &QTimer::timeout, this, &IdentifyForm::updateDateAndTime); + + TimeCounterUtil::getInstance().clockCounter->start(1000); } IdentifyForm::~IdentifyForm() @@ -13,3 +19,16 @@ delete ui; } +void IdentifyForm::drawIrisImageOnFrame(QImage image) +{ + // 只在识别界面才显示画面 + if (ui->wgtStacked->currentIndex() == 0) { + ui->labelVideo->setPixmap(QPixmap::fromImage(image)); + } +} + + +void IdentifyForm::updateDateAndTime() +{ + ui->labelTime->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd dddd HH:mm:ss")); +} diff --git a/IdentifyForm.h b/IdentifyForm.h index fc857a1..ae1cd22 100644 --- a/IdentifyForm.h +++ b/IdentifyForm.h @@ -1,7 +1,10 @@ -#ifndef IDENTIFYFORM_H +#ifndef IDENTIFYFORM_H #define IDENTIFYFORM_H #include +#include + +#include "utils/UtilInclude.h" QT_BEGIN_NAMESPACE namespace Ui { class IdentifyForm; } @@ -15,7 +18,14 @@ IdentifyForm(QWidget *parent = nullptr); ~IdentifyForm(); +public slots: + void drawIrisImageOnFrame(QImage image); + private: Ui::IdentifyForm *ui; + +private slots: + void updateDateAndTime(); + }; #endif // IDENTIFYFORM_H diff --git a/IdentifyForm.ui b/IdentifyForm.ui index c72a36f..879dc9a 100644 --- a/IdentifyForm.ui +++ b/IdentifyForm.ui @@ -6,13 +6,59 @@ 0 0 - 800 + 600 600 IdentifyForm + + + + 0 + 40 + 600 + 450 + + + + 0 + + + + + + 100 + 10 + 400 + 300 + + + + + + + + + + + + + + 0 + 0 + 600 + 40 + + + + TextLabel + + + Qt::AlignCenter + + diff --git a/LockScreenForm.cpp b/LockScreenForm.cpp new file mode 100644 index 0000000..58dc54b --- /dev/null +++ b/LockScreenForm.cpp @@ -0,0 +1,14 @@ +#include "LockScreenForm.h" +#include "ui_LockScreenForm.h" + +LockScreenForm::LockScreenForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::LockScreenForm) +{ + ui->setupUi(this); +} + +LockScreenForm::~LockScreenForm() +{ + delete ui; +} diff --git a/LockScreenForm.h b/LockScreenForm.h new file mode 100644 index 0000000..b5ded48 --- /dev/null +++ b/LockScreenForm.h @@ -0,0 +1,25 @@ +#ifndef LOCKSCREENFORM_H +#define LOCKSCREENFORM_H + +#include +#include + +#include "utils/UtilInclude.h" + +namespace Ui { +class LockScreenForm; +} + +class LockScreenForm : public QWidget +{ + Q_OBJECT + +public: + explicit LockScreenForm(QWidget *parent = nullptr); + ~LockScreenForm(); + +private: + Ui::LockScreenForm *ui; +}; + +#endif // LOCKSCREENFORM_H diff --git a/AppConstants.h b/AppConstants.h new file mode 100644 index 0000000..296c53f --- /dev/null +++ b/AppConstants.h @@ -0,0 +1,28 @@ +#ifndef APPCONSTANTS_H +#define APPCONSTANTS_H + +class AppConstants +{ +public: + enum WidgeFrameName + { + MAIN_PAGE = 0, // 主页面 + PERSON_LIST_FORM = 1, // 人员列表页面 + ADD_PERSON_FORM = 2, // 添加人员页面 + ADD_PERSON_CAPTURE_FACE = 21, // 添加/编辑人员时进行人脸拍图 + ADD_PERSON_CAPTURE_IRIS = 22, // 添加/编辑人员时进行虹膜拍图 + SETTING_FORM = 3, // 设置页面 + RECOGNIZE_RESULT_FORM = 4, // 识别结果界面 + IDENTIFY_FORM = 5, // 识别界面 含识别中 和 识别结果 + LOCKSCREEN_FORM = 6 // 锁屏待机界面 + }; + + enum ApplicationState + { + STATE_WAIT = 0, // 待机 + STATE_WORKING = 1, // 工作状态 + STATE_IDENTIFYING = 2, // 识别中 + }; +}; + +#endif // APPCONSTANTS_H diff --git a/CasicIrisIdentify.pro b/CasicIrisIdentify.pro index 5d7fea6..575ce3d 100644 --- a/CasicIrisIdentify.pro +++ b/CasicIrisIdentify.pro @@ -1,4 +1,4 @@ -QT += core gui +QT += core gui sql network texttospeech greaterThan(QT_MAJOR_VERSION, 4): QT += widgets @@ -15,20 +15,46 @@ # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 -SOURCES += \ - main.cpp \ - IdentifyForm.cpp +include("dao/dao.pri") +include("device/device.pri") +include("utils/utils.pri") -HEADERS += \ - IdentifyForm.h +SOURCES += main.cpp +SOURCES += ProMemory.cpp +SOURCES += MainWindowForm.cpp +SOURCES += IdentifyForm.cpp +SOURCES += LockScreenForm.cpp -FORMS += \ - IdentifyForm.ui +HEADERS += AppConstants.h +HEADERS += ProMemory.h +HEADERS += MainWindowForm.h +HEADERS += IdentifyForm.h +HEADERS += LockScreenForm.h -TRANSLATIONS += \ - CasicIrisIdentify_zh_CN.ts +FORMS += MainWindowForm.ui +FORMS += IdentifyForm.ui +FORMS += LockScreenForm.ui + +RESOURCES += resource.qrc + +DISTFILES += conf/config.ini + +#TRANSLATIONS += CasicIrisIdentify_zh_CN.ts + +#INCLUDEPATH += include/spdlog +#DEPENDPATH += include/spdlog # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target + + +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lopencv_world420 +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lGxIAPICPPEx + +INCLUDEPATH += $$PWD/include/daheng +DEPENDPATH += $$PWD/include/daheng + +INCLUDEPATH += $$PWD/include +DEPENDPATH += $$PWD/include diff --git a/CasicIrisIdentify_zh_CN.ts b/CasicIrisIdentify_zh_CN.ts index 5526fe4..81900df 100644 --- a/CasicIrisIdentify_zh_CN.ts +++ b/CasicIrisIdentify_zh_CN.ts @@ -1,3 +1,12 @@ - + + + IdentifyForm + + + IdentifyForm + + + + diff --git a/IdentifyForm.cpp b/IdentifyForm.cpp index 348a897..ba1f251 100644 --- a/IdentifyForm.cpp +++ b/IdentifyForm.cpp @@ -1,4 +1,4 @@ -#include "IdentifyForm.h" +#include "IdentifyForm.h" #include "ui_IdentifyForm.h" IdentifyForm::IdentifyForm(QWidget *parent) @@ -6,6 +6,12 @@ , ui(new Ui::IdentifyForm) { ui->setupUi(this); + + // 初始化更新界面的定时器 + // 每秒执行一次 + connect(TimeCounterUtil::getInstance().clockCounter, &QTimer::timeout, this, &IdentifyForm::updateDateAndTime); + + TimeCounterUtil::getInstance().clockCounter->start(1000); } IdentifyForm::~IdentifyForm() @@ -13,3 +19,16 @@ delete ui; } +void IdentifyForm::drawIrisImageOnFrame(QImage image) +{ + // 只在识别界面才显示画面 + if (ui->wgtStacked->currentIndex() == 0) { + ui->labelVideo->setPixmap(QPixmap::fromImage(image)); + } +} + + +void IdentifyForm::updateDateAndTime() +{ + ui->labelTime->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd dddd HH:mm:ss")); +} diff --git a/IdentifyForm.h b/IdentifyForm.h index fc857a1..ae1cd22 100644 --- a/IdentifyForm.h +++ b/IdentifyForm.h @@ -1,7 +1,10 @@ -#ifndef IDENTIFYFORM_H +#ifndef IDENTIFYFORM_H #define IDENTIFYFORM_H #include +#include + +#include "utils/UtilInclude.h" QT_BEGIN_NAMESPACE namespace Ui { class IdentifyForm; } @@ -15,7 +18,14 @@ IdentifyForm(QWidget *parent = nullptr); ~IdentifyForm(); +public slots: + void drawIrisImageOnFrame(QImage image); + private: Ui::IdentifyForm *ui; + +private slots: + void updateDateAndTime(); + }; #endif // IDENTIFYFORM_H diff --git a/IdentifyForm.ui b/IdentifyForm.ui index c72a36f..879dc9a 100644 --- a/IdentifyForm.ui +++ b/IdentifyForm.ui @@ -6,13 +6,59 @@ 0 0 - 800 + 600 600 IdentifyForm + + + + 0 + 40 + 600 + 450 + + + + 0 + + + + + + 100 + 10 + 400 + 300 + + + + + + + + + + + + + + 0 + 0 + 600 + 40 + + + + TextLabel + + + Qt::AlignCenter + + diff --git a/LockScreenForm.cpp b/LockScreenForm.cpp new file mode 100644 index 0000000..58dc54b --- /dev/null +++ b/LockScreenForm.cpp @@ -0,0 +1,14 @@ +#include "LockScreenForm.h" +#include "ui_LockScreenForm.h" + +LockScreenForm::LockScreenForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::LockScreenForm) +{ + ui->setupUi(this); +} + +LockScreenForm::~LockScreenForm() +{ + delete ui; +} diff --git a/LockScreenForm.h b/LockScreenForm.h new file mode 100644 index 0000000..b5ded48 --- /dev/null +++ b/LockScreenForm.h @@ -0,0 +1,25 @@ +#ifndef LOCKSCREENFORM_H +#define LOCKSCREENFORM_H + +#include +#include + +#include "utils/UtilInclude.h" + +namespace Ui { +class LockScreenForm; +} + +class LockScreenForm : public QWidget +{ + Q_OBJECT + +public: + explicit LockScreenForm(QWidget *parent = nullptr); + ~LockScreenForm(); + +private: + Ui::LockScreenForm *ui; +}; + +#endif // LOCKSCREENFORM_H diff --git a/LockScreenForm.ui b/LockScreenForm.ui new file mode 100644 index 0000000..7f2a6db --- /dev/null +++ b/LockScreenForm.ui @@ -0,0 +1,45 @@ + + + LockScreenForm + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + 180 + 100 + 54 + 12 + + + + TextLabel + + + + + + 180 + 160 + 54 + 12 + + + + TextLabel + + + + + + diff --git a/AppConstants.h b/AppConstants.h new file mode 100644 index 0000000..296c53f --- /dev/null +++ b/AppConstants.h @@ -0,0 +1,28 @@ +#ifndef APPCONSTANTS_H +#define APPCONSTANTS_H + +class AppConstants +{ +public: + enum WidgeFrameName + { + MAIN_PAGE = 0, // 主页面 + PERSON_LIST_FORM = 1, // 人员列表页面 + ADD_PERSON_FORM = 2, // 添加人员页面 + ADD_PERSON_CAPTURE_FACE = 21, // 添加/编辑人员时进行人脸拍图 + ADD_PERSON_CAPTURE_IRIS = 22, // 添加/编辑人员时进行虹膜拍图 + SETTING_FORM = 3, // 设置页面 + RECOGNIZE_RESULT_FORM = 4, // 识别结果界面 + IDENTIFY_FORM = 5, // 识别界面 含识别中 和 识别结果 + LOCKSCREEN_FORM = 6 // 锁屏待机界面 + }; + + enum ApplicationState + { + STATE_WAIT = 0, // 待机 + STATE_WORKING = 1, // 工作状态 + STATE_IDENTIFYING = 2, // 识别中 + }; +}; + +#endif // APPCONSTANTS_H diff --git a/CasicIrisIdentify.pro b/CasicIrisIdentify.pro index 5d7fea6..575ce3d 100644 --- a/CasicIrisIdentify.pro +++ b/CasicIrisIdentify.pro @@ -1,4 +1,4 @@ -QT += core gui +QT += core gui sql network texttospeech greaterThan(QT_MAJOR_VERSION, 4): QT += widgets @@ -15,20 +15,46 @@ # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 -SOURCES += \ - main.cpp \ - IdentifyForm.cpp +include("dao/dao.pri") +include("device/device.pri") +include("utils/utils.pri") -HEADERS += \ - IdentifyForm.h +SOURCES += main.cpp +SOURCES += ProMemory.cpp +SOURCES += MainWindowForm.cpp +SOURCES += IdentifyForm.cpp +SOURCES += LockScreenForm.cpp -FORMS += \ - IdentifyForm.ui +HEADERS += AppConstants.h +HEADERS += ProMemory.h +HEADERS += MainWindowForm.h +HEADERS += IdentifyForm.h +HEADERS += LockScreenForm.h -TRANSLATIONS += \ - CasicIrisIdentify_zh_CN.ts +FORMS += MainWindowForm.ui +FORMS += IdentifyForm.ui +FORMS += LockScreenForm.ui + +RESOURCES += resource.qrc + +DISTFILES += conf/config.ini + +#TRANSLATIONS += CasicIrisIdentify_zh_CN.ts + +#INCLUDEPATH += include/spdlog +#DEPENDPATH += include/spdlog # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target + + +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lopencv_world420 +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lGxIAPICPPEx + +INCLUDEPATH += $$PWD/include/daheng +DEPENDPATH += $$PWD/include/daheng + +INCLUDEPATH += $$PWD/include +DEPENDPATH += $$PWD/include diff --git a/CasicIrisIdentify_zh_CN.ts b/CasicIrisIdentify_zh_CN.ts index 5526fe4..81900df 100644 --- a/CasicIrisIdentify_zh_CN.ts +++ b/CasicIrisIdentify_zh_CN.ts @@ -1,3 +1,12 @@ - + + + IdentifyForm + + + IdentifyForm + + + + diff --git a/IdentifyForm.cpp b/IdentifyForm.cpp index 348a897..ba1f251 100644 --- a/IdentifyForm.cpp +++ b/IdentifyForm.cpp @@ -1,4 +1,4 @@ -#include "IdentifyForm.h" +#include "IdentifyForm.h" #include "ui_IdentifyForm.h" IdentifyForm::IdentifyForm(QWidget *parent) @@ -6,6 +6,12 @@ , ui(new Ui::IdentifyForm) { ui->setupUi(this); + + // 初始化更新界面的定时器 + // 每秒执行一次 + connect(TimeCounterUtil::getInstance().clockCounter, &QTimer::timeout, this, &IdentifyForm::updateDateAndTime); + + TimeCounterUtil::getInstance().clockCounter->start(1000); } IdentifyForm::~IdentifyForm() @@ -13,3 +19,16 @@ delete ui; } +void IdentifyForm::drawIrisImageOnFrame(QImage image) +{ + // 只在识别界面才显示画面 + if (ui->wgtStacked->currentIndex() == 0) { + ui->labelVideo->setPixmap(QPixmap::fromImage(image)); + } +} + + +void IdentifyForm::updateDateAndTime() +{ + ui->labelTime->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd dddd HH:mm:ss")); +} diff --git a/IdentifyForm.h b/IdentifyForm.h index fc857a1..ae1cd22 100644 --- a/IdentifyForm.h +++ b/IdentifyForm.h @@ -1,7 +1,10 @@ -#ifndef IDENTIFYFORM_H +#ifndef IDENTIFYFORM_H #define IDENTIFYFORM_H #include +#include + +#include "utils/UtilInclude.h" QT_BEGIN_NAMESPACE namespace Ui { class IdentifyForm; } @@ -15,7 +18,14 @@ IdentifyForm(QWidget *parent = nullptr); ~IdentifyForm(); +public slots: + void drawIrisImageOnFrame(QImage image); + private: Ui::IdentifyForm *ui; + +private slots: + void updateDateAndTime(); + }; #endif // IDENTIFYFORM_H diff --git a/IdentifyForm.ui b/IdentifyForm.ui index c72a36f..879dc9a 100644 --- a/IdentifyForm.ui +++ b/IdentifyForm.ui @@ -6,13 +6,59 @@ 0 0 - 800 + 600 600 IdentifyForm + + + + 0 + 40 + 600 + 450 + + + + 0 + + + + + + 100 + 10 + 400 + 300 + + + + + + + + + + + + + + 0 + 0 + 600 + 40 + + + + TextLabel + + + Qt::AlignCenter + + diff --git a/LockScreenForm.cpp b/LockScreenForm.cpp new file mode 100644 index 0000000..58dc54b --- /dev/null +++ b/LockScreenForm.cpp @@ -0,0 +1,14 @@ +#include "LockScreenForm.h" +#include "ui_LockScreenForm.h" + +LockScreenForm::LockScreenForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::LockScreenForm) +{ + ui->setupUi(this); +} + +LockScreenForm::~LockScreenForm() +{ + delete ui; +} diff --git a/LockScreenForm.h b/LockScreenForm.h new file mode 100644 index 0000000..b5ded48 --- /dev/null +++ b/LockScreenForm.h @@ -0,0 +1,25 @@ +#ifndef LOCKSCREENFORM_H +#define LOCKSCREENFORM_H + +#include +#include + +#include "utils/UtilInclude.h" + +namespace Ui { +class LockScreenForm; +} + +class LockScreenForm : public QWidget +{ + Q_OBJECT + +public: + explicit LockScreenForm(QWidget *parent = nullptr); + ~LockScreenForm(); + +private: + Ui::LockScreenForm *ui; +}; + +#endif // LOCKSCREENFORM_H diff --git a/LockScreenForm.ui b/LockScreenForm.ui new file mode 100644 index 0000000..7f2a6db --- /dev/null +++ b/LockScreenForm.ui @@ -0,0 +1,45 @@ + + + LockScreenForm + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + 180 + 100 + 54 + 12 + + + + TextLabel + + + + + + 180 + 160 + 54 + 12 + + + + TextLabel + + + + + + diff --git a/MainWindowForm.cpp b/MainWindowForm.cpp new file mode 100644 index 0000000..84f8159 --- /dev/null +++ b/MainWindowForm.cpp @@ -0,0 +1,86 @@ +#include "MainWindowForm.h" +#include "ui_MainWindowForm.h" +#include + +MainWindowForm::MainWindowForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::MainWindowForm) +{ + ui->setupUi(this); + + // 设置窗口透明和大小、位置 + this->setWindowFlags(Qt::FramelessWindowHint); + this->move(1400, 15); + this->resize(SettingConfig::getInstance().WINDOW_WIDTH, SettingConfig::getInstance().WINDOW_HEIGHT); + + // 通过调色板的颜色来设置窗口的统一背景色 + qApp->setPalette(QPalette(QColor(SettingConfig::getInstance().WINDOW_BACKGROUND_COLOR))); + + // 加载css文件设置控件样式 + QFile file(QApplication::applicationDirPath() + "/qss/main.css"); + if (file.open(QFile::ReadOnly)) + { + QString qssStr = QLatin1String(file.readAll()); + this->setStyleSheet(qssStr); + file.close(); + } + + initFormsPtr(); + + // 设置标题文字 + ui->labelTitle->setText(SettingConfig::getInstance().WINDOW_TITLE); + ui->labelCopyright->setText(SettingConfig::getInstance().WINDOW_RIGHTS); + ui->labelVersion->setText(SettingConfig::getInstance().WINDOW_VERSION); + + // 初始化虹膜相机控制 + ProMemory::getInstance().irisCam = new IrisCameraController(this); + ProMemory::getInstance().irisCam->initIrisCamera(); + ProMemory::getInstance().irisCam->openIrisCamera(); + connect(ProMemory::getInstance().irisCam->irisCamHandler, &IrisCameraCapEventHandler::sendIrisFrameToDraw, identifyForm, &IdentifyForm::drawIrisImageOnFrame); + +// LOG_INFO(QString("应用程序启动成功[Application Startup Success]").toStdString()); + qDebug() << "应用程序启动成功[Application Startup Success]"; + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::IDENTIFY_FORM; + ui->wdgtStatced->setCurrentWidget(identifyForm); + + // 开始虹膜相机拍图 + ProMemory::getInstance().irisCam->startCapture(); +} + +MainWindowForm::~MainWindowForm() +{ + delete ui; +} + +void MainWindowForm::lockScreen() +{ + ui->wdgtStatced->setCurrentWidget(lockScreenForm); + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::LOCKSCREEN_FORM; + ProMemory::getInstance().appState = AppConstants::ApplicationState::STATE_WAIT; +} + +void MainWindowForm::keyPressEvent(QKeyEvent *event) +{ + switch (event->key()) { + case Qt::Key_Escape: + QTimer::singleShot(100, qApp, [=](){ + QApplication::quit(); + }); + + default: + QWidget::keyPressEvent(event); + } +} + +void MainWindowForm::initFormsPtr() +{ + // 初始化各个form + lockScreenForm = new LockScreenForm(this); + identifyForm = new IdentifyForm(this); + + // 将form添加到statcked widget中 + ui->wdgtStatced->addWidget(identifyForm); + ui->wdgtStatced->addWidget(lockScreenForm); + + // 绑定按钮函数 +} diff --git a/AppConstants.h b/AppConstants.h new file mode 100644 index 0000000..296c53f --- /dev/null +++ b/AppConstants.h @@ -0,0 +1,28 @@ +#ifndef APPCONSTANTS_H +#define APPCONSTANTS_H + +class AppConstants +{ +public: + enum WidgeFrameName + { + MAIN_PAGE = 0, // 主页面 + PERSON_LIST_FORM = 1, // 人员列表页面 + ADD_PERSON_FORM = 2, // 添加人员页面 + ADD_PERSON_CAPTURE_FACE = 21, // 添加/编辑人员时进行人脸拍图 + ADD_PERSON_CAPTURE_IRIS = 22, // 添加/编辑人员时进行虹膜拍图 + SETTING_FORM = 3, // 设置页面 + RECOGNIZE_RESULT_FORM = 4, // 识别结果界面 + IDENTIFY_FORM = 5, // 识别界面 含识别中 和 识别结果 + LOCKSCREEN_FORM = 6 // 锁屏待机界面 + }; + + enum ApplicationState + { + STATE_WAIT = 0, // 待机 + STATE_WORKING = 1, // 工作状态 + STATE_IDENTIFYING = 2, // 识别中 + }; +}; + +#endif // APPCONSTANTS_H diff --git a/CasicIrisIdentify.pro b/CasicIrisIdentify.pro index 5d7fea6..575ce3d 100644 --- a/CasicIrisIdentify.pro +++ b/CasicIrisIdentify.pro @@ -1,4 +1,4 @@ -QT += core gui +QT += core gui sql network texttospeech greaterThan(QT_MAJOR_VERSION, 4): QT += widgets @@ -15,20 +15,46 @@ # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 -SOURCES += \ - main.cpp \ - IdentifyForm.cpp +include("dao/dao.pri") +include("device/device.pri") +include("utils/utils.pri") -HEADERS += \ - IdentifyForm.h +SOURCES += main.cpp +SOURCES += ProMemory.cpp +SOURCES += MainWindowForm.cpp +SOURCES += IdentifyForm.cpp +SOURCES += LockScreenForm.cpp -FORMS += \ - IdentifyForm.ui +HEADERS += AppConstants.h +HEADERS += ProMemory.h +HEADERS += MainWindowForm.h +HEADERS += IdentifyForm.h +HEADERS += LockScreenForm.h -TRANSLATIONS += \ - CasicIrisIdentify_zh_CN.ts +FORMS += MainWindowForm.ui +FORMS += IdentifyForm.ui +FORMS += LockScreenForm.ui + +RESOURCES += resource.qrc + +DISTFILES += conf/config.ini + +#TRANSLATIONS += CasicIrisIdentify_zh_CN.ts + +#INCLUDEPATH += include/spdlog +#DEPENDPATH += include/spdlog # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target + + +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lopencv_world420 +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lGxIAPICPPEx + +INCLUDEPATH += $$PWD/include/daheng +DEPENDPATH += $$PWD/include/daheng + +INCLUDEPATH += $$PWD/include +DEPENDPATH += $$PWD/include diff --git a/CasicIrisIdentify_zh_CN.ts b/CasicIrisIdentify_zh_CN.ts index 5526fe4..81900df 100644 --- a/CasicIrisIdentify_zh_CN.ts +++ b/CasicIrisIdentify_zh_CN.ts @@ -1,3 +1,12 @@ - + + + IdentifyForm + + + IdentifyForm + + + + diff --git a/IdentifyForm.cpp b/IdentifyForm.cpp index 348a897..ba1f251 100644 --- a/IdentifyForm.cpp +++ b/IdentifyForm.cpp @@ -1,4 +1,4 @@ -#include "IdentifyForm.h" +#include "IdentifyForm.h" #include "ui_IdentifyForm.h" IdentifyForm::IdentifyForm(QWidget *parent) @@ -6,6 +6,12 @@ , ui(new Ui::IdentifyForm) { ui->setupUi(this); + + // 初始化更新界面的定时器 + // 每秒执行一次 + connect(TimeCounterUtil::getInstance().clockCounter, &QTimer::timeout, this, &IdentifyForm::updateDateAndTime); + + TimeCounterUtil::getInstance().clockCounter->start(1000); } IdentifyForm::~IdentifyForm() @@ -13,3 +19,16 @@ delete ui; } +void IdentifyForm::drawIrisImageOnFrame(QImage image) +{ + // 只在识别界面才显示画面 + if (ui->wgtStacked->currentIndex() == 0) { + ui->labelVideo->setPixmap(QPixmap::fromImage(image)); + } +} + + +void IdentifyForm::updateDateAndTime() +{ + ui->labelTime->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd dddd HH:mm:ss")); +} diff --git a/IdentifyForm.h b/IdentifyForm.h index fc857a1..ae1cd22 100644 --- a/IdentifyForm.h +++ b/IdentifyForm.h @@ -1,7 +1,10 @@ -#ifndef IDENTIFYFORM_H +#ifndef IDENTIFYFORM_H #define IDENTIFYFORM_H #include +#include + +#include "utils/UtilInclude.h" QT_BEGIN_NAMESPACE namespace Ui { class IdentifyForm; } @@ -15,7 +18,14 @@ IdentifyForm(QWidget *parent = nullptr); ~IdentifyForm(); +public slots: + void drawIrisImageOnFrame(QImage image); + private: Ui::IdentifyForm *ui; + +private slots: + void updateDateAndTime(); + }; #endif // IDENTIFYFORM_H diff --git a/IdentifyForm.ui b/IdentifyForm.ui index c72a36f..879dc9a 100644 --- a/IdentifyForm.ui +++ b/IdentifyForm.ui @@ -6,13 +6,59 @@ 0 0 - 800 + 600 600 IdentifyForm + + + + 0 + 40 + 600 + 450 + + + + 0 + + + + + + 100 + 10 + 400 + 300 + + + + + + + + + + + + + + 0 + 0 + 600 + 40 + + + + TextLabel + + + Qt::AlignCenter + + diff --git a/LockScreenForm.cpp b/LockScreenForm.cpp new file mode 100644 index 0000000..58dc54b --- /dev/null +++ b/LockScreenForm.cpp @@ -0,0 +1,14 @@ +#include "LockScreenForm.h" +#include "ui_LockScreenForm.h" + +LockScreenForm::LockScreenForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::LockScreenForm) +{ + ui->setupUi(this); +} + +LockScreenForm::~LockScreenForm() +{ + delete ui; +} diff --git a/LockScreenForm.h b/LockScreenForm.h new file mode 100644 index 0000000..b5ded48 --- /dev/null +++ b/LockScreenForm.h @@ -0,0 +1,25 @@ +#ifndef LOCKSCREENFORM_H +#define LOCKSCREENFORM_H + +#include +#include + +#include "utils/UtilInclude.h" + +namespace Ui { +class LockScreenForm; +} + +class LockScreenForm : public QWidget +{ + Q_OBJECT + +public: + explicit LockScreenForm(QWidget *parent = nullptr); + ~LockScreenForm(); + +private: + Ui::LockScreenForm *ui; +}; + +#endif // LOCKSCREENFORM_H diff --git a/LockScreenForm.ui b/LockScreenForm.ui new file mode 100644 index 0000000..7f2a6db --- /dev/null +++ b/LockScreenForm.ui @@ -0,0 +1,45 @@ + + + LockScreenForm + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + 180 + 100 + 54 + 12 + + + + TextLabel + + + + + + 180 + 160 + 54 + 12 + + + + TextLabel + + + + + + diff --git a/MainWindowForm.cpp b/MainWindowForm.cpp new file mode 100644 index 0000000..84f8159 --- /dev/null +++ b/MainWindowForm.cpp @@ -0,0 +1,86 @@ +#include "MainWindowForm.h" +#include "ui_MainWindowForm.h" +#include + +MainWindowForm::MainWindowForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::MainWindowForm) +{ + ui->setupUi(this); + + // 设置窗口透明和大小、位置 + this->setWindowFlags(Qt::FramelessWindowHint); + this->move(1400, 15); + this->resize(SettingConfig::getInstance().WINDOW_WIDTH, SettingConfig::getInstance().WINDOW_HEIGHT); + + // 通过调色板的颜色来设置窗口的统一背景色 + qApp->setPalette(QPalette(QColor(SettingConfig::getInstance().WINDOW_BACKGROUND_COLOR))); + + // 加载css文件设置控件样式 + QFile file(QApplication::applicationDirPath() + "/qss/main.css"); + if (file.open(QFile::ReadOnly)) + { + QString qssStr = QLatin1String(file.readAll()); + this->setStyleSheet(qssStr); + file.close(); + } + + initFormsPtr(); + + // 设置标题文字 + ui->labelTitle->setText(SettingConfig::getInstance().WINDOW_TITLE); + ui->labelCopyright->setText(SettingConfig::getInstance().WINDOW_RIGHTS); + ui->labelVersion->setText(SettingConfig::getInstance().WINDOW_VERSION); + + // 初始化虹膜相机控制 + ProMemory::getInstance().irisCam = new IrisCameraController(this); + ProMemory::getInstance().irisCam->initIrisCamera(); + ProMemory::getInstance().irisCam->openIrisCamera(); + connect(ProMemory::getInstance().irisCam->irisCamHandler, &IrisCameraCapEventHandler::sendIrisFrameToDraw, identifyForm, &IdentifyForm::drawIrisImageOnFrame); + +// LOG_INFO(QString("应用程序启动成功[Application Startup Success]").toStdString()); + qDebug() << "应用程序启动成功[Application Startup Success]"; + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::IDENTIFY_FORM; + ui->wdgtStatced->setCurrentWidget(identifyForm); + + // 开始虹膜相机拍图 + ProMemory::getInstance().irisCam->startCapture(); +} + +MainWindowForm::~MainWindowForm() +{ + delete ui; +} + +void MainWindowForm::lockScreen() +{ + ui->wdgtStatced->setCurrentWidget(lockScreenForm); + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::LOCKSCREEN_FORM; + ProMemory::getInstance().appState = AppConstants::ApplicationState::STATE_WAIT; +} + +void MainWindowForm::keyPressEvent(QKeyEvent *event) +{ + switch (event->key()) { + case Qt::Key_Escape: + QTimer::singleShot(100, qApp, [=](){ + QApplication::quit(); + }); + + default: + QWidget::keyPressEvent(event); + } +} + +void MainWindowForm::initFormsPtr() +{ + // 初始化各个form + lockScreenForm = new LockScreenForm(this); + identifyForm = new IdentifyForm(this); + + // 将form添加到statcked widget中 + ui->wdgtStatced->addWidget(identifyForm); + ui->wdgtStatced->addWidget(lockScreenForm); + + // 绑定按钮函数 +} diff --git a/MainWindowForm.h b/MainWindowForm.h new file mode 100644 index 0000000..7fb2d89 --- /dev/null +++ b/MainWindowForm.h @@ -0,0 +1,38 @@ +#ifndef MAINWINDOWFORM_H +#define MAINWINDOWFORM_H + +#include +#include +#include + +#include "utils/UtilInclude.h" +#include "ProMemory.h" +#include "LockScreenForm.h" +#include "IdentifyForm.h" + +namespace Ui { +class MainWindowForm; +} + +class MainWindowForm : public QWidget +{ + Q_OBJECT + +public: + explicit MainWindowForm(QWidget *parent = nullptr); + ~MainWindowForm(); + +public slots: + void lockScreen(); + +private: + Ui::MainWindowForm *ui; + LockScreenForm * lockScreenForm; + IdentifyForm * identifyForm; + + void keyPressEvent(QKeyEvent *event); + + void initFormsPtr(); +}; + +#endif // MAINWINDOWFORM_H diff --git a/AppConstants.h b/AppConstants.h new file mode 100644 index 0000000..296c53f --- /dev/null +++ b/AppConstants.h @@ -0,0 +1,28 @@ +#ifndef APPCONSTANTS_H +#define APPCONSTANTS_H + +class AppConstants +{ +public: + enum WidgeFrameName + { + MAIN_PAGE = 0, // 主页面 + PERSON_LIST_FORM = 1, // 人员列表页面 + ADD_PERSON_FORM = 2, // 添加人员页面 + ADD_PERSON_CAPTURE_FACE = 21, // 添加/编辑人员时进行人脸拍图 + ADD_PERSON_CAPTURE_IRIS = 22, // 添加/编辑人员时进行虹膜拍图 + SETTING_FORM = 3, // 设置页面 + RECOGNIZE_RESULT_FORM = 4, // 识别结果界面 + IDENTIFY_FORM = 5, // 识别界面 含识别中 和 识别结果 + LOCKSCREEN_FORM = 6 // 锁屏待机界面 + }; + + enum ApplicationState + { + STATE_WAIT = 0, // 待机 + STATE_WORKING = 1, // 工作状态 + STATE_IDENTIFYING = 2, // 识别中 + }; +}; + +#endif // APPCONSTANTS_H diff --git a/CasicIrisIdentify.pro b/CasicIrisIdentify.pro index 5d7fea6..575ce3d 100644 --- a/CasicIrisIdentify.pro +++ b/CasicIrisIdentify.pro @@ -1,4 +1,4 @@ -QT += core gui +QT += core gui sql network texttospeech greaterThan(QT_MAJOR_VERSION, 4): QT += widgets @@ -15,20 +15,46 @@ # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 -SOURCES += \ - main.cpp \ - IdentifyForm.cpp +include("dao/dao.pri") +include("device/device.pri") +include("utils/utils.pri") -HEADERS += \ - IdentifyForm.h +SOURCES += main.cpp +SOURCES += ProMemory.cpp +SOURCES += MainWindowForm.cpp +SOURCES += IdentifyForm.cpp +SOURCES += LockScreenForm.cpp -FORMS += \ - IdentifyForm.ui +HEADERS += AppConstants.h +HEADERS += ProMemory.h +HEADERS += MainWindowForm.h +HEADERS += IdentifyForm.h +HEADERS += LockScreenForm.h -TRANSLATIONS += \ - CasicIrisIdentify_zh_CN.ts +FORMS += MainWindowForm.ui +FORMS += IdentifyForm.ui +FORMS += LockScreenForm.ui + +RESOURCES += resource.qrc + +DISTFILES += conf/config.ini + +#TRANSLATIONS += CasicIrisIdentify_zh_CN.ts + +#INCLUDEPATH += include/spdlog +#DEPENDPATH += include/spdlog # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target + + +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lopencv_world420 +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lGxIAPICPPEx + +INCLUDEPATH += $$PWD/include/daheng +DEPENDPATH += $$PWD/include/daheng + +INCLUDEPATH += $$PWD/include +DEPENDPATH += $$PWD/include diff --git a/CasicIrisIdentify_zh_CN.ts b/CasicIrisIdentify_zh_CN.ts index 5526fe4..81900df 100644 --- a/CasicIrisIdentify_zh_CN.ts +++ b/CasicIrisIdentify_zh_CN.ts @@ -1,3 +1,12 @@ - + + + IdentifyForm + + + IdentifyForm + + + + diff --git a/IdentifyForm.cpp b/IdentifyForm.cpp index 348a897..ba1f251 100644 --- a/IdentifyForm.cpp +++ b/IdentifyForm.cpp @@ -1,4 +1,4 @@ -#include "IdentifyForm.h" +#include "IdentifyForm.h" #include "ui_IdentifyForm.h" IdentifyForm::IdentifyForm(QWidget *parent) @@ -6,6 +6,12 @@ , ui(new Ui::IdentifyForm) { ui->setupUi(this); + + // 初始化更新界面的定时器 + // 每秒执行一次 + connect(TimeCounterUtil::getInstance().clockCounter, &QTimer::timeout, this, &IdentifyForm::updateDateAndTime); + + TimeCounterUtil::getInstance().clockCounter->start(1000); } IdentifyForm::~IdentifyForm() @@ -13,3 +19,16 @@ delete ui; } +void IdentifyForm::drawIrisImageOnFrame(QImage image) +{ + // 只在识别界面才显示画面 + if (ui->wgtStacked->currentIndex() == 0) { + ui->labelVideo->setPixmap(QPixmap::fromImage(image)); + } +} + + +void IdentifyForm::updateDateAndTime() +{ + ui->labelTime->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd dddd HH:mm:ss")); +} diff --git a/IdentifyForm.h b/IdentifyForm.h index fc857a1..ae1cd22 100644 --- a/IdentifyForm.h +++ b/IdentifyForm.h @@ -1,7 +1,10 @@ -#ifndef IDENTIFYFORM_H +#ifndef IDENTIFYFORM_H #define IDENTIFYFORM_H #include +#include + +#include "utils/UtilInclude.h" QT_BEGIN_NAMESPACE namespace Ui { class IdentifyForm; } @@ -15,7 +18,14 @@ IdentifyForm(QWidget *parent = nullptr); ~IdentifyForm(); +public slots: + void drawIrisImageOnFrame(QImage image); + private: Ui::IdentifyForm *ui; + +private slots: + void updateDateAndTime(); + }; #endif // IDENTIFYFORM_H diff --git a/IdentifyForm.ui b/IdentifyForm.ui index c72a36f..879dc9a 100644 --- a/IdentifyForm.ui +++ b/IdentifyForm.ui @@ -6,13 +6,59 @@ 0 0 - 800 + 600 600 IdentifyForm + + + + 0 + 40 + 600 + 450 + + + + 0 + + + + + + 100 + 10 + 400 + 300 + + + + + + + + + + + + + + 0 + 0 + 600 + 40 + + + + TextLabel + + + Qt::AlignCenter + + diff --git a/LockScreenForm.cpp b/LockScreenForm.cpp new file mode 100644 index 0000000..58dc54b --- /dev/null +++ b/LockScreenForm.cpp @@ -0,0 +1,14 @@ +#include "LockScreenForm.h" +#include "ui_LockScreenForm.h" + +LockScreenForm::LockScreenForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::LockScreenForm) +{ + ui->setupUi(this); +} + +LockScreenForm::~LockScreenForm() +{ + delete ui; +} diff --git a/LockScreenForm.h b/LockScreenForm.h new file mode 100644 index 0000000..b5ded48 --- /dev/null +++ b/LockScreenForm.h @@ -0,0 +1,25 @@ +#ifndef LOCKSCREENFORM_H +#define LOCKSCREENFORM_H + +#include +#include + +#include "utils/UtilInclude.h" + +namespace Ui { +class LockScreenForm; +} + +class LockScreenForm : public QWidget +{ + Q_OBJECT + +public: + explicit LockScreenForm(QWidget *parent = nullptr); + ~LockScreenForm(); + +private: + Ui::LockScreenForm *ui; +}; + +#endif // LOCKSCREENFORM_H diff --git a/LockScreenForm.ui b/LockScreenForm.ui new file mode 100644 index 0000000..7f2a6db --- /dev/null +++ b/LockScreenForm.ui @@ -0,0 +1,45 @@ + + + LockScreenForm + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + 180 + 100 + 54 + 12 + + + + TextLabel + + + + + + 180 + 160 + 54 + 12 + + + + TextLabel + + + + + + diff --git a/MainWindowForm.cpp b/MainWindowForm.cpp new file mode 100644 index 0000000..84f8159 --- /dev/null +++ b/MainWindowForm.cpp @@ -0,0 +1,86 @@ +#include "MainWindowForm.h" +#include "ui_MainWindowForm.h" +#include + +MainWindowForm::MainWindowForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::MainWindowForm) +{ + ui->setupUi(this); + + // 设置窗口透明和大小、位置 + this->setWindowFlags(Qt::FramelessWindowHint); + this->move(1400, 15); + this->resize(SettingConfig::getInstance().WINDOW_WIDTH, SettingConfig::getInstance().WINDOW_HEIGHT); + + // 通过调色板的颜色来设置窗口的统一背景色 + qApp->setPalette(QPalette(QColor(SettingConfig::getInstance().WINDOW_BACKGROUND_COLOR))); + + // 加载css文件设置控件样式 + QFile file(QApplication::applicationDirPath() + "/qss/main.css"); + if (file.open(QFile::ReadOnly)) + { + QString qssStr = QLatin1String(file.readAll()); + this->setStyleSheet(qssStr); + file.close(); + } + + initFormsPtr(); + + // 设置标题文字 + ui->labelTitle->setText(SettingConfig::getInstance().WINDOW_TITLE); + ui->labelCopyright->setText(SettingConfig::getInstance().WINDOW_RIGHTS); + ui->labelVersion->setText(SettingConfig::getInstance().WINDOW_VERSION); + + // 初始化虹膜相机控制 + ProMemory::getInstance().irisCam = new IrisCameraController(this); + ProMemory::getInstance().irisCam->initIrisCamera(); + ProMemory::getInstance().irisCam->openIrisCamera(); + connect(ProMemory::getInstance().irisCam->irisCamHandler, &IrisCameraCapEventHandler::sendIrisFrameToDraw, identifyForm, &IdentifyForm::drawIrisImageOnFrame); + +// LOG_INFO(QString("应用程序启动成功[Application Startup Success]").toStdString()); + qDebug() << "应用程序启动成功[Application Startup Success]"; + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::IDENTIFY_FORM; + ui->wdgtStatced->setCurrentWidget(identifyForm); + + // 开始虹膜相机拍图 + ProMemory::getInstance().irisCam->startCapture(); +} + +MainWindowForm::~MainWindowForm() +{ + delete ui; +} + +void MainWindowForm::lockScreen() +{ + ui->wdgtStatced->setCurrentWidget(lockScreenForm); + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::LOCKSCREEN_FORM; + ProMemory::getInstance().appState = AppConstants::ApplicationState::STATE_WAIT; +} + +void MainWindowForm::keyPressEvent(QKeyEvent *event) +{ + switch (event->key()) { + case Qt::Key_Escape: + QTimer::singleShot(100, qApp, [=](){ + QApplication::quit(); + }); + + default: + QWidget::keyPressEvent(event); + } +} + +void MainWindowForm::initFormsPtr() +{ + // 初始化各个form + lockScreenForm = new LockScreenForm(this); + identifyForm = new IdentifyForm(this); + + // 将form添加到statcked widget中 + ui->wdgtStatced->addWidget(identifyForm); + ui->wdgtStatced->addWidget(lockScreenForm); + + // 绑定按钮函数 +} diff --git a/MainWindowForm.h b/MainWindowForm.h new file mode 100644 index 0000000..7fb2d89 --- /dev/null +++ b/MainWindowForm.h @@ -0,0 +1,38 @@ +#ifndef MAINWINDOWFORM_H +#define MAINWINDOWFORM_H + +#include +#include +#include + +#include "utils/UtilInclude.h" +#include "ProMemory.h" +#include "LockScreenForm.h" +#include "IdentifyForm.h" + +namespace Ui { +class MainWindowForm; +} + +class MainWindowForm : public QWidget +{ + Q_OBJECT + +public: + explicit MainWindowForm(QWidget *parent = nullptr); + ~MainWindowForm(); + +public slots: + void lockScreen(); + +private: + Ui::MainWindowForm *ui; + LockScreenForm * lockScreenForm; + IdentifyForm * identifyForm; + + void keyPressEvent(QKeyEvent *event); + + void initFormsPtr(); +}; + +#endif // MAINWINDOWFORM_H diff --git a/MainWindowForm.ui b/MainWindowForm.ui new file mode 100644 index 0000000..e793ebf --- /dev/null +++ b/MainWindowForm.ui @@ -0,0 +1,85 @@ + + + MainWindowForm + + + + 0 + 0 + 600 + 1024 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + 0 + 0 + 600 + 84 + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + + + + TextLabel + + + Qt::AlignBottom|Qt::AlignHCenter + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + diff --git a/AppConstants.h b/AppConstants.h new file mode 100644 index 0000000..296c53f --- /dev/null +++ b/AppConstants.h @@ -0,0 +1,28 @@ +#ifndef APPCONSTANTS_H +#define APPCONSTANTS_H + +class AppConstants +{ +public: + enum WidgeFrameName + { + MAIN_PAGE = 0, // 主页面 + PERSON_LIST_FORM = 1, // 人员列表页面 + ADD_PERSON_FORM = 2, // 添加人员页面 + ADD_PERSON_CAPTURE_FACE = 21, // 添加/编辑人员时进行人脸拍图 + ADD_PERSON_CAPTURE_IRIS = 22, // 添加/编辑人员时进行虹膜拍图 + SETTING_FORM = 3, // 设置页面 + RECOGNIZE_RESULT_FORM = 4, // 识别结果界面 + IDENTIFY_FORM = 5, // 识别界面 含识别中 和 识别结果 + LOCKSCREEN_FORM = 6 // 锁屏待机界面 + }; + + enum ApplicationState + { + STATE_WAIT = 0, // 待机 + STATE_WORKING = 1, // 工作状态 + STATE_IDENTIFYING = 2, // 识别中 + }; +}; + +#endif // APPCONSTANTS_H diff --git a/CasicIrisIdentify.pro b/CasicIrisIdentify.pro index 5d7fea6..575ce3d 100644 --- a/CasicIrisIdentify.pro +++ b/CasicIrisIdentify.pro @@ -1,4 +1,4 @@ -QT += core gui +QT += core gui sql network texttospeech greaterThan(QT_MAJOR_VERSION, 4): QT += widgets @@ -15,20 +15,46 @@ # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 -SOURCES += \ - main.cpp \ - IdentifyForm.cpp +include("dao/dao.pri") +include("device/device.pri") +include("utils/utils.pri") -HEADERS += \ - IdentifyForm.h +SOURCES += main.cpp +SOURCES += ProMemory.cpp +SOURCES += MainWindowForm.cpp +SOURCES += IdentifyForm.cpp +SOURCES += LockScreenForm.cpp -FORMS += \ - IdentifyForm.ui +HEADERS += AppConstants.h +HEADERS += ProMemory.h +HEADERS += MainWindowForm.h +HEADERS += IdentifyForm.h +HEADERS += LockScreenForm.h -TRANSLATIONS += \ - CasicIrisIdentify_zh_CN.ts +FORMS += MainWindowForm.ui +FORMS += IdentifyForm.ui +FORMS += LockScreenForm.ui + +RESOURCES += resource.qrc + +DISTFILES += conf/config.ini + +#TRANSLATIONS += CasicIrisIdentify_zh_CN.ts + +#INCLUDEPATH += include/spdlog +#DEPENDPATH += include/spdlog # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target + + +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lopencv_world420 +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lGxIAPICPPEx + +INCLUDEPATH += $$PWD/include/daheng +DEPENDPATH += $$PWD/include/daheng + +INCLUDEPATH += $$PWD/include +DEPENDPATH += $$PWD/include diff --git a/CasicIrisIdentify_zh_CN.ts b/CasicIrisIdentify_zh_CN.ts index 5526fe4..81900df 100644 --- a/CasicIrisIdentify_zh_CN.ts +++ b/CasicIrisIdentify_zh_CN.ts @@ -1,3 +1,12 @@ - + + + IdentifyForm + + + IdentifyForm + + + + diff --git a/IdentifyForm.cpp b/IdentifyForm.cpp index 348a897..ba1f251 100644 --- a/IdentifyForm.cpp +++ b/IdentifyForm.cpp @@ -1,4 +1,4 @@ -#include "IdentifyForm.h" +#include "IdentifyForm.h" #include "ui_IdentifyForm.h" IdentifyForm::IdentifyForm(QWidget *parent) @@ -6,6 +6,12 @@ , ui(new Ui::IdentifyForm) { ui->setupUi(this); + + // 初始化更新界面的定时器 + // 每秒执行一次 + connect(TimeCounterUtil::getInstance().clockCounter, &QTimer::timeout, this, &IdentifyForm::updateDateAndTime); + + TimeCounterUtil::getInstance().clockCounter->start(1000); } IdentifyForm::~IdentifyForm() @@ -13,3 +19,16 @@ delete ui; } +void IdentifyForm::drawIrisImageOnFrame(QImage image) +{ + // 只在识别界面才显示画面 + if (ui->wgtStacked->currentIndex() == 0) { + ui->labelVideo->setPixmap(QPixmap::fromImage(image)); + } +} + + +void IdentifyForm::updateDateAndTime() +{ + ui->labelTime->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd dddd HH:mm:ss")); +} diff --git a/IdentifyForm.h b/IdentifyForm.h index fc857a1..ae1cd22 100644 --- a/IdentifyForm.h +++ b/IdentifyForm.h @@ -1,7 +1,10 @@ -#ifndef IDENTIFYFORM_H +#ifndef IDENTIFYFORM_H #define IDENTIFYFORM_H #include +#include + +#include "utils/UtilInclude.h" QT_BEGIN_NAMESPACE namespace Ui { class IdentifyForm; } @@ -15,7 +18,14 @@ IdentifyForm(QWidget *parent = nullptr); ~IdentifyForm(); +public slots: + void drawIrisImageOnFrame(QImage image); + private: Ui::IdentifyForm *ui; + +private slots: + void updateDateAndTime(); + }; #endif // IDENTIFYFORM_H diff --git a/IdentifyForm.ui b/IdentifyForm.ui index c72a36f..879dc9a 100644 --- a/IdentifyForm.ui +++ b/IdentifyForm.ui @@ -6,13 +6,59 @@ 0 0 - 800 + 600 600 IdentifyForm + + + + 0 + 40 + 600 + 450 + + + + 0 + + + + + + 100 + 10 + 400 + 300 + + + + + + + + + + + + + + 0 + 0 + 600 + 40 + + + + TextLabel + + + Qt::AlignCenter + + diff --git a/LockScreenForm.cpp b/LockScreenForm.cpp new file mode 100644 index 0000000..58dc54b --- /dev/null +++ b/LockScreenForm.cpp @@ -0,0 +1,14 @@ +#include "LockScreenForm.h" +#include "ui_LockScreenForm.h" + +LockScreenForm::LockScreenForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::LockScreenForm) +{ + ui->setupUi(this); +} + +LockScreenForm::~LockScreenForm() +{ + delete ui; +} diff --git a/LockScreenForm.h b/LockScreenForm.h new file mode 100644 index 0000000..b5ded48 --- /dev/null +++ b/LockScreenForm.h @@ -0,0 +1,25 @@ +#ifndef LOCKSCREENFORM_H +#define LOCKSCREENFORM_H + +#include +#include + +#include "utils/UtilInclude.h" + +namespace Ui { +class LockScreenForm; +} + +class LockScreenForm : public QWidget +{ + Q_OBJECT + +public: + explicit LockScreenForm(QWidget *parent = nullptr); + ~LockScreenForm(); + +private: + Ui::LockScreenForm *ui; +}; + +#endif // LOCKSCREENFORM_H diff --git a/LockScreenForm.ui b/LockScreenForm.ui new file mode 100644 index 0000000..7f2a6db --- /dev/null +++ b/LockScreenForm.ui @@ -0,0 +1,45 @@ + + + LockScreenForm + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + 180 + 100 + 54 + 12 + + + + TextLabel + + + + + + 180 + 160 + 54 + 12 + + + + TextLabel + + + + + + diff --git a/MainWindowForm.cpp b/MainWindowForm.cpp new file mode 100644 index 0000000..84f8159 --- /dev/null +++ b/MainWindowForm.cpp @@ -0,0 +1,86 @@ +#include "MainWindowForm.h" +#include "ui_MainWindowForm.h" +#include + +MainWindowForm::MainWindowForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::MainWindowForm) +{ + ui->setupUi(this); + + // 设置窗口透明和大小、位置 + this->setWindowFlags(Qt::FramelessWindowHint); + this->move(1400, 15); + this->resize(SettingConfig::getInstance().WINDOW_WIDTH, SettingConfig::getInstance().WINDOW_HEIGHT); + + // 通过调色板的颜色来设置窗口的统一背景色 + qApp->setPalette(QPalette(QColor(SettingConfig::getInstance().WINDOW_BACKGROUND_COLOR))); + + // 加载css文件设置控件样式 + QFile file(QApplication::applicationDirPath() + "/qss/main.css"); + if (file.open(QFile::ReadOnly)) + { + QString qssStr = QLatin1String(file.readAll()); + this->setStyleSheet(qssStr); + file.close(); + } + + initFormsPtr(); + + // 设置标题文字 + ui->labelTitle->setText(SettingConfig::getInstance().WINDOW_TITLE); + ui->labelCopyright->setText(SettingConfig::getInstance().WINDOW_RIGHTS); + ui->labelVersion->setText(SettingConfig::getInstance().WINDOW_VERSION); + + // 初始化虹膜相机控制 + ProMemory::getInstance().irisCam = new IrisCameraController(this); + ProMemory::getInstance().irisCam->initIrisCamera(); + ProMemory::getInstance().irisCam->openIrisCamera(); + connect(ProMemory::getInstance().irisCam->irisCamHandler, &IrisCameraCapEventHandler::sendIrisFrameToDraw, identifyForm, &IdentifyForm::drawIrisImageOnFrame); + +// LOG_INFO(QString("应用程序启动成功[Application Startup Success]").toStdString()); + qDebug() << "应用程序启动成功[Application Startup Success]"; + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::IDENTIFY_FORM; + ui->wdgtStatced->setCurrentWidget(identifyForm); + + // 开始虹膜相机拍图 + ProMemory::getInstance().irisCam->startCapture(); +} + +MainWindowForm::~MainWindowForm() +{ + delete ui; +} + +void MainWindowForm::lockScreen() +{ + ui->wdgtStatced->setCurrentWidget(lockScreenForm); + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::LOCKSCREEN_FORM; + ProMemory::getInstance().appState = AppConstants::ApplicationState::STATE_WAIT; +} + +void MainWindowForm::keyPressEvent(QKeyEvent *event) +{ + switch (event->key()) { + case Qt::Key_Escape: + QTimer::singleShot(100, qApp, [=](){ + QApplication::quit(); + }); + + default: + QWidget::keyPressEvent(event); + } +} + +void MainWindowForm::initFormsPtr() +{ + // 初始化各个form + lockScreenForm = new LockScreenForm(this); + identifyForm = new IdentifyForm(this); + + // 将form添加到statcked widget中 + ui->wdgtStatced->addWidget(identifyForm); + ui->wdgtStatced->addWidget(lockScreenForm); + + // 绑定按钮函数 +} diff --git a/MainWindowForm.h b/MainWindowForm.h new file mode 100644 index 0000000..7fb2d89 --- /dev/null +++ b/MainWindowForm.h @@ -0,0 +1,38 @@ +#ifndef MAINWINDOWFORM_H +#define MAINWINDOWFORM_H + +#include +#include +#include + +#include "utils/UtilInclude.h" +#include "ProMemory.h" +#include "LockScreenForm.h" +#include "IdentifyForm.h" + +namespace Ui { +class MainWindowForm; +} + +class MainWindowForm : public QWidget +{ + Q_OBJECT + +public: + explicit MainWindowForm(QWidget *parent = nullptr); + ~MainWindowForm(); + +public slots: + void lockScreen(); + +private: + Ui::MainWindowForm *ui; + LockScreenForm * lockScreenForm; + IdentifyForm * identifyForm; + + void keyPressEvent(QKeyEvent *event); + + void initFormsPtr(); +}; + +#endif // MAINWINDOWFORM_H diff --git a/MainWindowForm.ui b/MainWindowForm.ui new file mode 100644 index 0000000..e793ebf --- /dev/null +++ b/MainWindowForm.ui @@ -0,0 +1,85 @@ + + + MainWindowForm + + + + 0 + 0 + 600 + 1024 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + 0 + 0 + 600 + 84 + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + + + + TextLabel + + + Qt::AlignBottom|Qt::AlignHCenter + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + diff --git a/ProMemory.cpp b/ProMemory.cpp new file mode 100644 index 0000000..19e7403 --- /dev/null +++ b/ProMemory.cpp @@ -0,0 +1,84 @@ +#include "ProMemory.h" + +ProMemory::ProMemory() +{ + +} + +ProMemory::~ProMemory() +{ + +} + +/* +void ProMemory::pushCasicIris(CasicIrisInfo irisInfo) +{ + QMutex mutex; + mutex.lock(); + if (this->irisQueue.size() > 30) + { + QStack empty; + std::swap(empty, irisQueue); + } + + irisQueue.push(irisInfo); + mutex.unlock(); +} +CasicIrisInfo ProMemory::popCasicIris() +{ + CasicIrisInfo result; + + QMutex mutex; + mutex.lock(); + if (this->irisQueue.size() > 0) + { + result = irisQueue.pop(); + } + + mutex.unlock(); + + return result; +} +*/ +int ProMemory::getIrisQueueSize() +{ + int size = 0; + + QMutex mutex; + mutex.lock(); + +// size = this->irisQueue.size(); + + mutex.unlock(); + + return size; +} +bool ProMemory::isIrisQueueEmpty() +{ + bool empty = true; + + QMutex mutex; + mutex.lock(); + +// empty = this->irisQueue.isEmpty(); + + mutex.unlock(); + + return empty; +} +void ProMemory::clearIrisQueue() +{ + QMutex mutex; + mutex.lock(); + +// QStack empty; +// std::swap(empty, irisQueue); + + mutex.unlock(); +} + + +void ProMemory::initIrisFeatures(QString personId) +{ +// irisRegistPro->sendDataToExract(QByteArray(QString("[-u]").append(personId).toLocal8Bit())); +} diff --git a/AppConstants.h b/AppConstants.h new file mode 100644 index 0000000..296c53f --- /dev/null +++ b/AppConstants.h @@ -0,0 +1,28 @@ +#ifndef APPCONSTANTS_H +#define APPCONSTANTS_H + +class AppConstants +{ +public: + enum WidgeFrameName + { + MAIN_PAGE = 0, // 主页面 + PERSON_LIST_FORM = 1, // 人员列表页面 + ADD_PERSON_FORM = 2, // 添加人员页面 + ADD_PERSON_CAPTURE_FACE = 21, // 添加/编辑人员时进行人脸拍图 + ADD_PERSON_CAPTURE_IRIS = 22, // 添加/编辑人员时进行虹膜拍图 + SETTING_FORM = 3, // 设置页面 + RECOGNIZE_RESULT_FORM = 4, // 识别结果界面 + IDENTIFY_FORM = 5, // 识别界面 含识别中 和 识别结果 + LOCKSCREEN_FORM = 6 // 锁屏待机界面 + }; + + enum ApplicationState + { + STATE_WAIT = 0, // 待机 + STATE_WORKING = 1, // 工作状态 + STATE_IDENTIFYING = 2, // 识别中 + }; +}; + +#endif // APPCONSTANTS_H diff --git a/CasicIrisIdentify.pro b/CasicIrisIdentify.pro index 5d7fea6..575ce3d 100644 --- a/CasicIrisIdentify.pro +++ b/CasicIrisIdentify.pro @@ -1,4 +1,4 @@ -QT += core gui +QT += core gui sql network texttospeech greaterThan(QT_MAJOR_VERSION, 4): QT += widgets @@ -15,20 +15,46 @@ # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 -SOURCES += \ - main.cpp \ - IdentifyForm.cpp +include("dao/dao.pri") +include("device/device.pri") +include("utils/utils.pri") -HEADERS += \ - IdentifyForm.h +SOURCES += main.cpp +SOURCES += ProMemory.cpp +SOURCES += MainWindowForm.cpp +SOURCES += IdentifyForm.cpp +SOURCES += LockScreenForm.cpp -FORMS += \ - IdentifyForm.ui +HEADERS += AppConstants.h +HEADERS += ProMemory.h +HEADERS += MainWindowForm.h +HEADERS += IdentifyForm.h +HEADERS += LockScreenForm.h -TRANSLATIONS += \ - CasicIrisIdentify_zh_CN.ts +FORMS += MainWindowForm.ui +FORMS += IdentifyForm.ui +FORMS += LockScreenForm.ui + +RESOURCES += resource.qrc + +DISTFILES += conf/config.ini + +#TRANSLATIONS += CasicIrisIdentify_zh_CN.ts + +#INCLUDEPATH += include/spdlog +#DEPENDPATH += include/spdlog # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target + + +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lopencv_world420 +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lGxIAPICPPEx + +INCLUDEPATH += $$PWD/include/daheng +DEPENDPATH += $$PWD/include/daheng + +INCLUDEPATH += $$PWD/include +DEPENDPATH += $$PWD/include diff --git a/CasicIrisIdentify_zh_CN.ts b/CasicIrisIdentify_zh_CN.ts index 5526fe4..81900df 100644 --- a/CasicIrisIdentify_zh_CN.ts +++ b/CasicIrisIdentify_zh_CN.ts @@ -1,3 +1,12 @@ - + + + IdentifyForm + + + IdentifyForm + + + + diff --git a/IdentifyForm.cpp b/IdentifyForm.cpp index 348a897..ba1f251 100644 --- a/IdentifyForm.cpp +++ b/IdentifyForm.cpp @@ -1,4 +1,4 @@ -#include "IdentifyForm.h" +#include "IdentifyForm.h" #include "ui_IdentifyForm.h" IdentifyForm::IdentifyForm(QWidget *parent) @@ -6,6 +6,12 @@ , ui(new Ui::IdentifyForm) { ui->setupUi(this); + + // 初始化更新界面的定时器 + // 每秒执行一次 + connect(TimeCounterUtil::getInstance().clockCounter, &QTimer::timeout, this, &IdentifyForm::updateDateAndTime); + + TimeCounterUtil::getInstance().clockCounter->start(1000); } IdentifyForm::~IdentifyForm() @@ -13,3 +19,16 @@ delete ui; } +void IdentifyForm::drawIrisImageOnFrame(QImage image) +{ + // 只在识别界面才显示画面 + if (ui->wgtStacked->currentIndex() == 0) { + ui->labelVideo->setPixmap(QPixmap::fromImage(image)); + } +} + + +void IdentifyForm::updateDateAndTime() +{ + ui->labelTime->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd dddd HH:mm:ss")); +} diff --git a/IdentifyForm.h b/IdentifyForm.h index fc857a1..ae1cd22 100644 --- a/IdentifyForm.h +++ b/IdentifyForm.h @@ -1,7 +1,10 @@ -#ifndef IDENTIFYFORM_H +#ifndef IDENTIFYFORM_H #define IDENTIFYFORM_H #include +#include + +#include "utils/UtilInclude.h" QT_BEGIN_NAMESPACE namespace Ui { class IdentifyForm; } @@ -15,7 +18,14 @@ IdentifyForm(QWidget *parent = nullptr); ~IdentifyForm(); +public slots: + void drawIrisImageOnFrame(QImage image); + private: Ui::IdentifyForm *ui; + +private slots: + void updateDateAndTime(); + }; #endif // IDENTIFYFORM_H diff --git a/IdentifyForm.ui b/IdentifyForm.ui index c72a36f..879dc9a 100644 --- a/IdentifyForm.ui +++ b/IdentifyForm.ui @@ -6,13 +6,59 @@ 0 0 - 800 + 600 600 IdentifyForm + + + + 0 + 40 + 600 + 450 + + + + 0 + + + + + + 100 + 10 + 400 + 300 + + + + + + + + + + + + + + 0 + 0 + 600 + 40 + + + + TextLabel + + + Qt::AlignCenter + + diff --git a/LockScreenForm.cpp b/LockScreenForm.cpp new file mode 100644 index 0000000..58dc54b --- /dev/null +++ b/LockScreenForm.cpp @@ -0,0 +1,14 @@ +#include "LockScreenForm.h" +#include "ui_LockScreenForm.h" + +LockScreenForm::LockScreenForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::LockScreenForm) +{ + ui->setupUi(this); +} + +LockScreenForm::~LockScreenForm() +{ + delete ui; +} diff --git a/LockScreenForm.h b/LockScreenForm.h new file mode 100644 index 0000000..b5ded48 --- /dev/null +++ b/LockScreenForm.h @@ -0,0 +1,25 @@ +#ifndef LOCKSCREENFORM_H +#define LOCKSCREENFORM_H + +#include +#include + +#include "utils/UtilInclude.h" + +namespace Ui { +class LockScreenForm; +} + +class LockScreenForm : public QWidget +{ + Q_OBJECT + +public: + explicit LockScreenForm(QWidget *parent = nullptr); + ~LockScreenForm(); + +private: + Ui::LockScreenForm *ui; +}; + +#endif // LOCKSCREENFORM_H diff --git a/LockScreenForm.ui b/LockScreenForm.ui new file mode 100644 index 0000000..7f2a6db --- /dev/null +++ b/LockScreenForm.ui @@ -0,0 +1,45 @@ + + + LockScreenForm + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + 180 + 100 + 54 + 12 + + + + TextLabel + + + + + + 180 + 160 + 54 + 12 + + + + TextLabel + + + + + + diff --git a/MainWindowForm.cpp b/MainWindowForm.cpp new file mode 100644 index 0000000..84f8159 --- /dev/null +++ b/MainWindowForm.cpp @@ -0,0 +1,86 @@ +#include "MainWindowForm.h" +#include "ui_MainWindowForm.h" +#include + +MainWindowForm::MainWindowForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::MainWindowForm) +{ + ui->setupUi(this); + + // 设置窗口透明和大小、位置 + this->setWindowFlags(Qt::FramelessWindowHint); + this->move(1400, 15); + this->resize(SettingConfig::getInstance().WINDOW_WIDTH, SettingConfig::getInstance().WINDOW_HEIGHT); + + // 通过调色板的颜色来设置窗口的统一背景色 + qApp->setPalette(QPalette(QColor(SettingConfig::getInstance().WINDOW_BACKGROUND_COLOR))); + + // 加载css文件设置控件样式 + QFile file(QApplication::applicationDirPath() + "/qss/main.css"); + if (file.open(QFile::ReadOnly)) + { + QString qssStr = QLatin1String(file.readAll()); + this->setStyleSheet(qssStr); + file.close(); + } + + initFormsPtr(); + + // 设置标题文字 + ui->labelTitle->setText(SettingConfig::getInstance().WINDOW_TITLE); + ui->labelCopyright->setText(SettingConfig::getInstance().WINDOW_RIGHTS); + ui->labelVersion->setText(SettingConfig::getInstance().WINDOW_VERSION); + + // 初始化虹膜相机控制 + ProMemory::getInstance().irisCam = new IrisCameraController(this); + ProMemory::getInstance().irisCam->initIrisCamera(); + ProMemory::getInstance().irisCam->openIrisCamera(); + connect(ProMemory::getInstance().irisCam->irisCamHandler, &IrisCameraCapEventHandler::sendIrisFrameToDraw, identifyForm, &IdentifyForm::drawIrisImageOnFrame); + +// LOG_INFO(QString("应用程序启动成功[Application Startup Success]").toStdString()); + qDebug() << "应用程序启动成功[Application Startup Success]"; + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::IDENTIFY_FORM; + ui->wdgtStatced->setCurrentWidget(identifyForm); + + // 开始虹膜相机拍图 + ProMemory::getInstance().irisCam->startCapture(); +} + +MainWindowForm::~MainWindowForm() +{ + delete ui; +} + +void MainWindowForm::lockScreen() +{ + ui->wdgtStatced->setCurrentWidget(lockScreenForm); + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::LOCKSCREEN_FORM; + ProMemory::getInstance().appState = AppConstants::ApplicationState::STATE_WAIT; +} + +void MainWindowForm::keyPressEvent(QKeyEvent *event) +{ + switch (event->key()) { + case Qt::Key_Escape: + QTimer::singleShot(100, qApp, [=](){ + QApplication::quit(); + }); + + default: + QWidget::keyPressEvent(event); + } +} + +void MainWindowForm::initFormsPtr() +{ + // 初始化各个form + lockScreenForm = new LockScreenForm(this); + identifyForm = new IdentifyForm(this); + + // 将form添加到statcked widget中 + ui->wdgtStatced->addWidget(identifyForm); + ui->wdgtStatced->addWidget(lockScreenForm); + + // 绑定按钮函数 +} diff --git a/MainWindowForm.h b/MainWindowForm.h new file mode 100644 index 0000000..7fb2d89 --- /dev/null +++ b/MainWindowForm.h @@ -0,0 +1,38 @@ +#ifndef MAINWINDOWFORM_H +#define MAINWINDOWFORM_H + +#include +#include +#include + +#include "utils/UtilInclude.h" +#include "ProMemory.h" +#include "LockScreenForm.h" +#include "IdentifyForm.h" + +namespace Ui { +class MainWindowForm; +} + +class MainWindowForm : public QWidget +{ + Q_OBJECT + +public: + explicit MainWindowForm(QWidget *parent = nullptr); + ~MainWindowForm(); + +public slots: + void lockScreen(); + +private: + Ui::MainWindowForm *ui; + LockScreenForm * lockScreenForm; + IdentifyForm * identifyForm; + + void keyPressEvent(QKeyEvent *event); + + void initFormsPtr(); +}; + +#endif // MAINWINDOWFORM_H diff --git a/MainWindowForm.ui b/MainWindowForm.ui new file mode 100644 index 0000000..e793ebf --- /dev/null +++ b/MainWindowForm.ui @@ -0,0 +1,85 @@ + + + MainWindowForm + + + + 0 + 0 + 600 + 1024 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + 0 + 0 + 600 + 84 + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + + + + TextLabel + + + Qt::AlignBottom|Qt::AlignHCenter + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + diff --git a/ProMemory.cpp b/ProMemory.cpp new file mode 100644 index 0000000..19e7403 --- /dev/null +++ b/ProMemory.cpp @@ -0,0 +1,84 @@ +#include "ProMemory.h" + +ProMemory::ProMemory() +{ + +} + +ProMemory::~ProMemory() +{ + +} + +/* +void ProMemory::pushCasicIris(CasicIrisInfo irisInfo) +{ + QMutex mutex; + mutex.lock(); + if (this->irisQueue.size() > 30) + { + QStack empty; + std::swap(empty, irisQueue); + } + + irisQueue.push(irisInfo); + mutex.unlock(); +} +CasicIrisInfo ProMemory::popCasicIris() +{ + CasicIrisInfo result; + + QMutex mutex; + mutex.lock(); + if (this->irisQueue.size() > 0) + { + result = irisQueue.pop(); + } + + mutex.unlock(); + + return result; +} +*/ +int ProMemory::getIrisQueueSize() +{ + int size = 0; + + QMutex mutex; + mutex.lock(); + +// size = this->irisQueue.size(); + + mutex.unlock(); + + return size; +} +bool ProMemory::isIrisQueueEmpty() +{ + bool empty = true; + + QMutex mutex; + mutex.lock(); + +// empty = this->irisQueue.isEmpty(); + + mutex.unlock(); + + return empty; +} +void ProMemory::clearIrisQueue() +{ + QMutex mutex; + mutex.lock(); + +// QStack empty; +// std::swap(empty, irisQueue); + + mutex.unlock(); +} + + +void ProMemory::initIrisFeatures(QString personId) +{ +// irisRegistPro->sendDataToExract(QByteArray(QString("[-u]").append(personId).toLocal8Bit())); +} diff --git a/ProMemory.h b/ProMemory.h new file mode 100644 index 0000000..2ecd653 --- /dev/null +++ b/ProMemory.h @@ -0,0 +1,52 @@ +#ifndef PROMEMORY_H +#define PROMEMORY_H + +#include +#include + +#include "AppConstants.h" +//#include "casic/iris/CasicIrisInfo.h" +#include "dao/IrisDataDao.h" + +#include "device/IrisCameraController.h" +//#include "device/iris/IrisRegistProcess.h" +//#include "device/iris/IrisRecogProcess.h" + +class IrisCameraController; +class IrisRegistProcess; +class IrisRecogProcess; + +class ProMemory +{ +public: + ~ProMemory(); + ProMemory(const ProMemory&)=delete; + ProMemory& operator=(const ProMemory&)=delete; + + static ProMemory& getInstance() { + static ProMemory instance; + return instance; + } + +// void pushCasicIris(CasicIrisInfo irisInfo); +// CasicIrisInfo popCasicIris(); + int getIrisQueueSize(); + bool isIrisQueueEmpty(); + void clearIrisQueue(); + + volatile int widgeFrame = 0; // 当前显示的界面 + volatile int appState = 0; // 当前程序所处的状态 + + void initIrisFeatures(QString personId = ""); // 初始化虹膜特征值集合 + + IrisCameraController * irisCam; + IrisRecogProcess * irisRecogPro; + +private: + ProMemory(); + +// QStack irisQueue; // 虹膜信息队列 + QVector irisFeatures; // 虹膜特征值集合 +}; + +#endif // PROMEMORY_H diff --git a/AppConstants.h b/AppConstants.h new file mode 100644 index 0000000..296c53f --- /dev/null +++ b/AppConstants.h @@ -0,0 +1,28 @@ +#ifndef APPCONSTANTS_H +#define APPCONSTANTS_H + +class AppConstants +{ +public: + enum WidgeFrameName + { + MAIN_PAGE = 0, // 主页面 + PERSON_LIST_FORM = 1, // 人员列表页面 + ADD_PERSON_FORM = 2, // 添加人员页面 + ADD_PERSON_CAPTURE_FACE = 21, // 添加/编辑人员时进行人脸拍图 + ADD_PERSON_CAPTURE_IRIS = 22, // 添加/编辑人员时进行虹膜拍图 + SETTING_FORM = 3, // 设置页面 + RECOGNIZE_RESULT_FORM = 4, // 识别结果界面 + IDENTIFY_FORM = 5, // 识别界面 含识别中 和 识别结果 + LOCKSCREEN_FORM = 6 // 锁屏待机界面 + }; + + enum ApplicationState + { + STATE_WAIT = 0, // 待机 + STATE_WORKING = 1, // 工作状态 + STATE_IDENTIFYING = 2, // 识别中 + }; +}; + +#endif // APPCONSTANTS_H diff --git a/CasicIrisIdentify.pro b/CasicIrisIdentify.pro index 5d7fea6..575ce3d 100644 --- a/CasicIrisIdentify.pro +++ b/CasicIrisIdentify.pro @@ -1,4 +1,4 @@ -QT += core gui +QT += core gui sql network texttospeech greaterThan(QT_MAJOR_VERSION, 4): QT += widgets @@ -15,20 +15,46 @@ # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 -SOURCES += \ - main.cpp \ - IdentifyForm.cpp +include("dao/dao.pri") +include("device/device.pri") +include("utils/utils.pri") -HEADERS += \ - IdentifyForm.h +SOURCES += main.cpp +SOURCES += ProMemory.cpp +SOURCES += MainWindowForm.cpp +SOURCES += IdentifyForm.cpp +SOURCES += LockScreenForm.cpp -FORMS += \ - IdentifyForm.ui +HEADERS += AppConstants.h +HEADERS += ProMemory.h +HEADERS += MainWindowForm.h +HEADERS += IdentifyForm.h +HEADERS += LockScreenForm.h -TRANSLATIONS += \ - CasicIrisIdentify_zh_CN.ts +FORMS += MainWindowForm.ui +FORMS += IdentifyForm.ui +FORMS += LockScreenForm.ui + +RESOURCES += resource.qrc + +DISTFILES += conf/config.ini + +#TRANSLATIONS += CasicIrisIdentify_zh_CN.ts + +#INCLUDEPATH += include/spdlog +#DEPENDPATH += include/spdlog # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target + + +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lopencv_world420 +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lGxIAPICPPEx + +INCLUDEPATH += $$PWD/include/daheng +DEPENDPATH += $$PWD/include/daheng + +INCLUDEPATH += $$PWD/include +DEPENDPATH += $$PWD/include diff --git a/CasicIrisIdentify_zh_CN.ts b/CasicIrisIdentify_zh_CN.ts index 5526fe4..81900df 100644 --- a/CasicIrisIdentify_zh_CN.ts +++ b/CasicIrisIdentify_zh_CN.ts @@ -1,3 +1,12 @@ - + + + IdentifyForm + + + IdentifyForm + + + + diff --git a/IdentifyForm.cpp b/IdentifyForm.cpp index 348a897..ba1f251 100644 --- a/IdentifyForm.cpp +++ b/IdentifyForm.cpp @@ -1,4 +1,4 @@ -#include "IdentifyForm.h" +#include "IdentifyForm.h" #include "ui_IdentifyForm.h" IdentifyForm::IdentifyForm(QWidget *parent) @@ -6,6 +6,12 @@ , ui(new Ui::IdentifyForm) { ui->setupUi(this); + + // 初始化更新界面的定时器 + // 每秒执行一次 + connect(TimeCounterUtil::getInstance().clockCounter, &QTimer::timeout, this, &IdentifyForm::updateDateAndTime); + + TimeCounterUtil::getInstance().clockCounter->start(1000); } IdentifyForm::~IdentifyForm() @@ -13,3 +19,16 @@ delete ui; } +void IdentifyForm::drawIrisImageOnFrame(QImage image) +{ + // 只在识别界面才显示画面 + if (ui->wgtStacked->currentIndex() == 0) { + ui->labelVideo->setPixmap(QPixmap::fromImage(image)); + } +} + + +void IdentifyForm::updateDateAndTime() +{ + ui->labelTime->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd dddd HH:mm:ss")); +} diff --git a/IdentifyForm.h b/IdentifyForm.h index fc857a1..ae1cd22 100644 --- a/IdentifyForm.h +++ b/IdentifyForm.h @@ -1,7 +1,10 @@ -#ifndef IDENTIFYFORM_H +#ifndef IDENTIFYFORM_H #define IDENTIFYFORM_H #include +#include + +#include "utils/UtilInclude.h" QT_BEGIN_NAMESPACE namespace Ui { class IdentifyForm; } @@ -15,7 +18,14 @@ IdentifyForm(QWidget *parent = nullptr); ~IdentifyForm(); +public slots: + void drawIrisImageOnFrame(QImage image); + private: Ui::IdentifyForm *ui; + +private slots: + void updateDateAndTime(); + }; #endif // IDENTIFYFORM_H diff --git a/IdentifyForm.ui b/IdentifyForm.ui index c72a36f..879dc9a 100644 --- a/IdentifyForm.ui +++ b/IdentifyForm.ui @@ -6,13 +6,59 @@ 0 0 - 800 + 600 600 IdentifyForm + + + + 0 + 40 + 600 + 450 + + + + 0 + + + + + + 100 + 10 + 400 + 300 + + + + + + + + + + + + + + 0 + 0 + 600 + 40 + + + + TextLabel + + + Qt::AlignCenter + + diff --git a/LockScreenForm.cpp b/LockScreenForm.cpp new file mode 100644 index 0000000..58dc54b --- /dev/null +++ b/LockScreenForm.cpp @@ -0,0 +1,14 @@ +#include "LockScreenForm.h" +#include "ui_LockScreenForm.h" + +LockScreenForm::LockScreenForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::LockScreenForm) +{ + ui->setupUi(this); +} + +LockScreenForm::~LockScreenForm() +{ + delete ui; +} diff --git a/LockScreenForm.h b/LockScreenForm.h new file mode 100644 index 0000000..b5ded48 --- /dev/null +++ b/LockScreenForm.h @@ -0,0 +1,25 @@ +#ifndef LOCKSCREENFORM_H +#define LOCKSCREENFORM_H + +#include +#include + +#include "utils/UtilInclude.h" + +namespace Ui { +class LockScreenForm; +} + +class LockScreenForm : public QWidget +{ + Q_OBJECT + +public: + explicit LockScreenForm(QWidget *parent = nullptr); + ~LockScreenForm(); + +private: + Ui::LockScreenForm *ui; +}; + +#endif // LOCKSCREENFORM_H diff --git a/LockScreenForm.ui b/LockScreenForm.ui new file mode 100644 index 0000000..7f2a6db --- /dev/null +++ b/LockScreenForm.ui @@ -0,0 +1,45 @@ + + + LockScreenForm + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + 180 + 100 + 54 + 12 + + + + TextLabel + + + + + + 180 + 160 + 54 + 12 + + + + TextLabel + + + + + + diff --git a/MainWindowForm.cpp b/MainWindowForm.cpp new file mode 100644 index 0000000..84f8159 --- /dev/null +++ b/MainWindowForm.cpp @@ -0,0 +1,86 @@ +#include "MainWindowForm.h" +#include "ui_MainWindowForm.h" +#include + +MainWindowForm::MainWindowForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::MainWindowForm) +{ + ui->setupUi(this); + + // 设置窗口透明和大小、位置 + this->setWindowFlags(Qt::FramelessWindowHint); + this->move(1400, 15); + this->resize(SettingConfig::getInstance().WINDOW_WIDTH, SettingConfig::getInstance().WINDOW_HEIGHT); + + // 通过调色板的颜色来设置窗口的统一背景色 + qApp->setPalette(QPalette(QColor(SettingConfig::getInstance().WINDOW_BACKGROUND_COLOR))); + + // 加载css文件设置控件样式 + QFile file(QApplication::applicationDirPath() + "/qss/main.css"); + if (file.open(QFile::ReadOnly)) + { + QString qssStr = QLatin1String(file.readAll()); + this->setStyleSheet(qssStr); + file.close(); + } + + initFormsPtr(); + + // 设置标题文字 + ui->labelTitle->setText(SettingConfig::getInstance().WINDOW_TITLE); + ui->labelCopyright->setText(SettingConfig::getInstance().WINDOW_RIGHTS); + ui->labelVersion->setText(SettingConfig::getInstance().WINDOW_VERSION); + + // 初始化虹膜相机控制 + ProMemory::getInstance().irisCam = new IrisCameraController(this); + ProMemory::getInstance().irisCam->initIrisCamera(); + ProMemory::getInstance().irisCam->openIrisCamera(); + connect(ProMemory::getInstance().irisCam->irisCamHandler, &IrisCameraCapEventHandler::sendIrisFrameToDraw, identifyForm, &IdentifyForm::drawIrisImageOnFrame); + +// LOG_INFO(QString("应用程序启动成功[Application Startup Success]").toStdString()); + qDebug() << "应用程序启动成功[Application Startup Success]"; + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::IDENTIFY_FORM; + ui->wdgtStatced->setCurrentWidget(identifyForm); + + // 开始虹膜相机拍图 + ProMemory::getInstance().irisCam->startCapture(); +} + +MainWindowForm::~MainWindowForm() +{ + delete ui; +} + +void MainWindowForm::lockScreen() +{ + ui->wdgtStatced->setCurrentWidget(lockScreenForm); + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::LOCKSCREEN_FORM; + ProMemory::getInstance().appState = AppConstants::ApplicationState::STATE_WAIT; +} + +void MainWindowForm::keyPressEvent(QKeyEvent *event) +{ + switch (event->key()) { + case Qt::Key_Escape: + QTimer::singleShot(100, qApp, [=](){ + QApplication::quit(); + }); + + default: + QWidget::keyPressEvent(event); + } +} + +void MainWindowForm::initFormsPtr() +{ + // 初始化各个form + lockScreenForm = new LockScreenForm(this); + identifyForm = new IdentifyForm(this); + + // 将form添加到statcked widget中 + ui->wdgtStatced->addWidget(identifyForm); + ui->wdgtStatced->addWidget(lockScreenForm); + + // 绑定按钮函数 +} diff --git a/MainWindowForm.h b/MainWindowForm.h new file mode 100644 index 0000000..7fb2d89 --- /dev/null +++ b/MainWindowForm.h @@ -0,0 +1,38 @@ +#ifndef MAINWINDOWFORM_H +#define MAINWINDOWFORM_H + +#include +#include +#include + +#include "utils/UtilInclude.h" +#include "ProMemory.h" +#include "LockScreenForm.h" +#include "IdentifyForm.h" + +namespace Ui { +class MainWindowForm; +} + +class MainWindowForm : public QWidget +{ + Q_OBJECT + +public: + explicit MainWindowForm(QWidget *parent = nullptr); + ~MainWindowForm(); + +public slots: + void lockScreen(); + +private: + Ui::MainWindowForm *ui; + LockScreenForm * lockScreenForm; + IdentifyForm * identifyForm; + + void keyPressEvent(QKeyEvent *event); + + void initFormsPtr(); +}; + +#endif // MAINWINDOWFORM_H diff --git a/MainWindowForm.ui b/MainWindowForm.ui new file mode 100644 index 0000000..e793ebf --- /dev/null +++ b/MainWindowForm.ui @@ -0,0 +1,85 @@ + + + MainWindowForm + + + + 0 + 0 + 600 + 1024 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + 0 + 0 + 600 + 84 + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + + + + TextLabel + + + Qt::AlignBottom|Qt::AlignHCenter + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + diff --git a/ProMemory.cpp b/ProMemory.cpp new file mode 100644 index 0000000..19e7403 --- /dev/null +++ b/ProMemory.cpp @@ -0,0 +1,84 @@ +#include "ProMemory.h" + +ProMemory::ProMemory() +{ + +} + +ProMemory::~ProMemory() +{ + +} + +/* +void ProMemory::pushCasicIris(CasicIrisInfo irisInfo) +{ + QMutex mutex; + mutex.lock(); + if (this->irisQueue.size() > 30) + { + QStack empty; + std::swap(empty, irisQueue); + } + + irisQueue.push(irisInfo); + mutex.unlock(); +} +CasicIrisInfo ProMemory::popCasicIris() +{ + CasicIrisInfo result; + + QMutex mutex; + mutex.lock(); + if (this->irisQueue.size() > 0) + { + result = irisQueue.pop(); + } + + mutex.unlock(); + + return result; +} +*/ +int ProMemory::getIrisQueueSize() +{ + int size = 0; + + QMutex mutex; + mutex.lock(); + +// size = this->irisQueue.size(); + + mutex.unlock(); + + return size; +} +bool ProMemory::isIrisQueueEmpty() +{ + bool empty = true; + + QMutex mutex; + mutex.lock(); + +// empty = this->irisQueue.isEmpty(); + + mutex.unlock(); + + return empty; +} +void ProMemory::clearIrisQueue() +{ + QMutex mutex; + mutex.lock(); + +// QStack empty; +// std::swap(empty, irisQueue); + + mutex.unlock(); +} + + +void ProMemory::initIrisFeatures(QString personId) +{ +// irisRegistPro->sendDataToExract(QByteArray(QString("[-u]").append(personId).toLocal8Bit())); +} diff --git a/ProMemory.h b/ProMemory.h new file mode 100644 index 0000000..2ecd653 --- /dev/null +++ b/ProMemory.h @@ -0,0 +1,52 @@ +#ifndef PROMEMORY_H +#define PROMEMORY_H + +#include +#include + +#include "AppConstants.h" +//#include "casic/iris/CasicIrisInfo.h" +#include "dao/IrisDataDao.h" + +#include "device/IrisCameraController.h" +//#include "device/iris/IrisRegistProcess.h" +//#include "device/iris/IrisRecogProcess.h" + +class IrisCameraController; +class IrisRegistProcess; +class IrisRecogProcess; + +class ProMemory +{ +public: + ~ProMemory(); + ProMemory(const ProMemory&)=delete; + ProMemory& operator=(const ProMemory&)=delete; + + static ProMemory& getInstance() { + static ProMemory instance; + return instance; + } + +// void pushCasicIris(CasicIrisInfo irisInfo); +// CasicIrisInfo popCasicIris(); + int getIrisQueueSize(); + bool isIrisQueueEmpty(); + void clearIrisQueue(); + + volatile int widgeFrame = 0; // 当前显示的界面 + volatile int appState = 0; // 当前程序所处的状态 + + void initIrisFeatures(QString personId = ""); // 初始化虹膜特征值集合 + + IrisCameraController * irisCam; + IrisRecogProcess * irisRecogPro; + +private: + ProMemory(); + +// QStack irisQueue; // 虹膜信息队列 + QVector irisFeatures; // 虹膜特征值集合 +}; + +#endif // PROMEMORY_H diff --git a/conf/config.ini b/conf/config.ini new file mode 100644 index 0000000..66e46ad --- /dev/null +++ b/conf/config.ini @@ -0,0 +1,67 @@ +[recognize] +#最大允许识别时间(ms) +maxMatchTime=10000 +#识别成功界面停留时间(ms) +successTipsLast=5000 +#识别失败界面停留时间(ms) +failureTipsLast=3000 +#人脸识别最大尝试次数 +maxFaceTryCount=20 +#持续没找到人脸的最大次数 +maxFaceNotFoundCount=500 +#注册时最小人脸 +minFaceRegist=240 +#识别时最小人脸 +minFaceRecog=100 + +#虹膜识别最大尝试次数 +maxIrisTryCount=10 +#虹膜识别持续没有找到眼的最大次数 +maxEyeNotFoundCount=50 + +#识别方式[1=人脸;2=虹膜;3=双认证;4=任意] +recogType=4 + +[window] +#界面窗口宽(px) +width=600 +#界面窗口高(px) +height=1024 +#统一背景色 +backgroundColor="#FFFFFF" +#标题 +title="虹膜识别终端" + +[work] +#工作状态检测时最小人脸范围 +minFaceSize=160 +#人脸范围最小横坐标 +minFacePosX=320 +#人脸范围最大横坐标 +maxFacePosX=960 +#人脸范围最小纵坐标 +minFacePosY=180 +#人脸范围最大纵坐标 +maxFacePosY=540 +#人脸太近阈值 +faceCloseSize=360 +#人脸太远阈值 +faceFarSize=480 + +[camera] +#虹膜相机取一幅画面的时间间隔(ms) +irisFrameInterval=100 +#虹膜相机拍摄宽度 +irisFrameWidth=1440 +#虹膜相机拍摄高度 +irisFrameHeight=1080 +#虹膜图像高度 +irisWidth=640 +#虹膜图像高度 +irisHeight=480 + +[log] +#日志文件位置 +logFile="d://irisLogs//casic_log.txt" +#日志级别 +logLevel="trace" diff --git a/AppConstants.h b/AppConstants.h new file mode 100644 index 0000000..296c53f --- /dev/null +++ b/AppConstants.h @@ -0,0 +1,28 @@ +#ifndef APPCONSTANTS_H +#define APPCONSTANTS_H + +class AppConstants +{ +public: + enum WidgeFrameName + { + MAIN_PAGE = 0, // 主页面 + PERSON_LIST_FORM = 1, // 人员列表页面 + ADD_PERSON_FORM = 2, // 添加人员页面 + ADD_PERSON_CAPTURE_FACE = 21, // 添加/编辑人员时进行人脸拍图 + ADD_PERSON_CAPTURE_IRIS = 22, // 添加/编辑人员时进行虹膜拍图 + SETTING_FORM = 3, // 设置页面 + RECOGNIZE_RESULT_FORM = 4, // 识别结果界面 + IDENTIFY_FORM = 5, // 识别界面 含识别中 和 识别结果 + LOCKSCREEN_FORM = 6 // 锁屏待机界面 + }; + + enum ApplicationState + { + STATE_WAIT = 0, // 待机 + STATE_WORKING = 1, // 工作状态 + STATE_IDENTIFYING = 2, // 识别中 + }; +}; + +#endif // APPCONSTANTS_H diff --git a/CasicIrisIdentify.pro b/CasicIrisIdentify.pro index 5d7fea6..575ce3d 100644 --- a/CasicIrisIdentify.pro +++ b/CasicIrisIdentify.pro @@ -1,4 +1,4 @@ -QT += core gui +QT += core gui sql network texttospeech greaterThan(QT_MAJOR_VERSION, 4): QT += widgets @@ -15,20 +15,46 @@ # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 -SOURCES += \ - main.cpp \ - IdentifyForm.cpp +include("dao/dao.pri") +include("device/device.pri") +include("utils/utils.pri") -HEADERS += \ - IdentifyForm.h +SOURCES += main.cpp +SOURCES += ProMemory.cpp +SOURCES += MainWindowForm.cpp +SOURCES += IdentifyForm.cpp +SOURCES += LockScreenForm.cpp -FORMS += \ - IdentifyForm.ui +HEADERS += AppConstants.h +HEADERS += ProMemory.h +HEADERS += MainWindowForm.h +HEADERS += IdentifyForm.h +HEADERS += LockScreenForm.h -TRANSLATIONS += \ - CasicIrisIdentify_zh_CN.ts +FORMS += MainWindowForm.ui +FORMS += IdentifyForm.ui +FORMS += LockScreenForm.ui + +RESOURCES += resource.qrc + +DISTFILES += conf/config.ini + +#TRANSLATIONS += CasicIrisIdentify_zh_CN.ts + +#INCLUDEPATH += include/spdlog +#DEPENDPATH += include/spdlog # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target + + +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lopencv_world420 +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lGxIAPICPPEx + +INCLUDEPATH += $$PWD/include/daheng +DEPENDPATH += $$PWD/include/daheng + +INCLUDEPATH += $$PWD/include +DEPENDPATH += $$PWD/include diff --git a/CasicIrisIdentify_zh_CN.ts b/CasicIrisIdentify_zh_CN.ts index 5526fe4..81900df 100644 --- a/CasicIrisIdentify_zh_CN.ts +++ b/CasicIrisIdentify_zh_CN.ts @@ -1,3 +1,12 @@ - + + + IdentifyForm + + + IdentifyForm + + + + diff --git a/IdentifyForm.cpp b/IdentifyForm.cpp index 348a897..ba1f251 100644 --- a/IdentifyForm.cpp +++ b/IdentifyForm.cpp @@ -1,4 +1,4 @@ -#include "IdentifyForm.h" +#include "IdentifyForm.h" #include "ui_IdentifyForm.h" IdentifyForm::IdentifyForm(QWidget *parent) @@ -6,6 +6,12 @@ , ui(new Ui::IdentifyForm) { ui->setupUi(this); + + // 初始化更新界面的定时器 + // 每秒执行一次 + connect(TimeCounterUtil::getInstance().clockCounter, &QTimer::timeout, this, &IdentifyForm::updateDateAndTime); + + TimeCounterUtil::getInstance().clockCounter->start(1000); } IdentifyForm::~IdentifyForm() @@ -13,3 +19,16 @@ delete ui; } +void IdentifyForm::drawIrisImageOnFrame(QImage image) +{ + // 只在识别界面才显示画面 + if (ui->wgtStacked->currentIndex() == 0) { + ui->labelVideo->setPixmap(QPixmap::fromImage(image)); + } +} + + +void IdentifyForm::updateDateAndTime() +{ + ui->labelTime->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd dddd HH:mm:ss")); +} diff --git a/IdentifyForm.h b/IdentifyForm.h index fc857a1..ae1cd22 100644 --- a/IdentifyForm.h +++ b/IdentifyForm.h @@ -1,7 +1,10 @@ -#ifndef IDENTIFYFORM_H +#ifndef IDENTIFYFORM_H #define IDENTIFYFORM_H #include +#include + +#include "utils/UtilInclude.h" QT_BEGIN_NAMESPACE namespace Ui { class IdentifyForm; } @@ -15,7 +18,14 @@ IdentifyForm(QWidget *parent = nullptr); ~IdentifyForm(); +public slots: + void drawIrisImageOnFrame(QImage image); + private: Ui::IdentifyForm *ui; + +private slots: + void updateDateAndTime(); + }; #endif // IDENTIFYFORM_H diff --git a/IdentifyForm.ui b/IdentifyForm.ui index c72a36f..879dc9a 100644 --- a/IdentifyForm.ui +++ b/IdentifyForm.ui @@ -6,13 +6,59 @@ 0 0 - 800 + 600 600 IdentifyForm + + + + 0 + 40 + 600 + 450 + + + + 0 + + + + + + 100 + 10 + 400 + 300 + + + + + + + + + + + + + + 0 + 0 + 600 + 40 + + + + TextLabel + + + Qt::AlignCenter + + diff --git a/LockScreenForm.cpp b/LockScreenForm.cpp new file mode 100644 index 0000000..58dc54b --- /dev/null +++ b/LockScreenForm.cpp @@ -0,0 +1,14 @@ +#include "LockScreenForm.h" +#include "ui_LockScreenForm.h" + +LockScreenForm::LockScreenForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::LockScreenForm) +{ + ui->setupUi(this); +} + +LockScreenForm::~LockScreenForm() +{ + delete ui; +} diff --git a/LockScreenForm.h b/LockScreenForm.h new file mode 100644 index 0000000..b5ded48 --- /dev/null +++ b/LockScreenForm.h @@ -0,0 +1,25 @@ +#ifndef LOCKSCREENFORM_H +#define LOCKSCREENFORM_H + +#include +#include + +#include "utils/UtilInclude.h" + +namespace Ui { +class LockScreenForm; +} + +class LockScreenForm : public QWidget +{ + Q_OBJECT + +public: + explicit LockScreenForm(QWidget *parent = nullptr); + ~LockScreenForm(); + +private: + Ui::LockScreenForm *ui; +}; + +#endif // LOCKSCREENFORM_H diff --git a/LockScreenForm.ui b/LockScreenForm.ui new file mode 100644 index 0000000..7f2a6db --- /dev/null +++ b/LockScreenForm.ui @@ -0,0 +1,45 @@ + + + LockScreenForm + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + 180 + 100 + 54 + 12 + + + + TextLabel + + + + + + 180 + 160 + 54 + 12 + + + + TextLabel + + + + + + diff --git a/MainWindowForm.cpp b/MainWindowForm.cpp new file mode 100644 index 0000000..84f8159 --- /dev/null +++ b/MainWindowForm.cpp @@ -0,0 +1,86 @@ +#include "MainWindowForm.h" +#include "ui_MainWindowForm.h" +#include + +MainWindowForm::MainWindowForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::MainWindowForm) +{ + ui->setupUi(this); + + // 设置窗口透明和大小、位置 + this->setWindowFlags(Qt::FramelessWindowHint); + this->move(1400, 15); + this->resize(SettingConfig::getInstance().WINDOW_WIDTH, SettingConfig::getInstance().WINDOW_HEIGHT); + + // 通过调色板的颜色来设置窗口的统一背景色 + qApp->setPalette(QPalette(QColor(SettingConfig::getInstance().WINDOW_BACKGROUND_COLOR))); + + // 加载css文件设置控件样式 + QFile file(QApplication::applicationDirPath() + "/qss/main.css"); + if (file.open(QFile::ReadOnly)) + { + QString qssStr = QLatin1String(file.readAll()); + this->setStyleSheet(qssStr); + file.close(); + } + + initFormsPtr(); + + // 设置标题文字 + ui->labelTitle->setText(SettingConfig::getInstance().WINDOW_TITLE); + ui->labelCopyright->setText(SettingConfig::getInstance().WINDOW_RIGHTS); + ui->labelVersion->setText(SettingConfig::getInstance().WINDOW_VERSION); + + // 初始化虹膜相机控制 + ProMemory::getInstance().irisCam = new IrisCameraController(this); + ProMemory::getInstance().irisCam->initIrisCamera(); + ProMemory::getInstance().irisCam->openIrisCamera(); + connect(ProMemory::getInstance().irisCam->irisCamHandler, &IrisCameraCapEventHandler::sendIrisFrameToDraw, identifyForm, &IdentifyForm::drawIrisImageOnFrame); + +// LOG_INFO(QString("应用程序启动成功[Application Startup Success]").toStdString()); + qDebug() << "应用程序启动成功[Application Startup Success]"; + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::IDENTIFY_FORM; + ui->wdgtStatced->setCurrentWidget(identifyForm); + + // 开始虹膜相机拍图 + ProMemory::getInstance().irisCam->startCapture(); +} + +MainWindowForm::~MainWindowForm() +{ + delete ui; +} + +void MainWindowForm::lockScreen() +{ + ui->wdgtStatced->setCurrentWidget(lockScreenForm); + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::LOCKSCREEN_FORM; + ProMemory::getInstance().appState = AppConstants::ApplicationState::STATE_WAIT; +} + +void MainWindowForm::keyPressEvent(QKeyEvent *event) +{ + switch (event->key()) { + case Qt::Key_Escape: + QTimer::singleShot(100, qApp, [=](){ + QApplication::quit(); + }); + + default: + QWidget::keyPressEvent(event); + } +} + +void MainWindowForm::initFormsPtr() +{ + // 初始化各个form + lockScreenForm = new LockScreenForm(this); + identifyForm = new IdentifyForm(this); + + // 将form添加到statcked widget中 + ui->wdgtStatced->addWidget(identifyForm); + ui->wdgtStatced->addWidget(lockScreenForm); + + // 绑定按钮函数 +} diff --git a/MainWindowForm.h b/MainWindowForm.h new file mode 100644 index 0000000..7fb2d89 --- /dev/null +++ b/MainWindowForm.h @@ -0,0 +1,38 @@ +#ifndef MAINWINDOWFORM_H +#define MAINWINDOWFORM_H + +#include +#include +#include + +#include "utils/UtilInclude.h" +#include "ProMemory.h" +#include "LockScreenForm.h" +#include "IdentifyForm.h" + +namespace Ui { +class MainWindowForm; +} + +class MainWindowForm : public QWidget +{ + Q_OBJECT + +public: + explicit MainWindowForm(QWidget *parent = nullptr); + ~MainWindowForm(); + +public slots: + void lockScreen(); + +private: + Ui::MainWindowForm *ui; + LockScreenForm * lockScreenForm; + IdentifyForm * identifyForm; + + void keyPressEvent(QKeyEvent *event); + + void initFormsPtr(); +}; + +#endif // MAINWINDOWFORM_H diff --git a/MainWindowForm.ui b/MainWindowForm.ui new file mode 100644 index 0000000..e793ebf --- /dev/null +++ b/MainWindowForm.ui @@ -0,0 +1,85 @@ + + + MainWindowForm + + + + 0 + 0 + 600 + 1024 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + 0 + 0 + 600 + 84 + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + + + + TextLabel + + + Qt::AlignBottom|Qt::AlignHCenter + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + diff --git a/ProMemory.cpp b/ProMemory.cpp new file mode 100644 index 0000000..19e7403 --- /dev/null +++ b/ProMemory.cpp @@ -0,0 +1,84 @@ +#include "ProMemory.h" + +ProMemory::ProMemory() +{ + +} + +ProMemory::~ProMemory() +{ + +} + +/* +void ProMemory::pushCasicIris(CasicIrisInfo irisInfo) +{ + QMutex mutex; + mutex.lock(); + if (this->irisQueue.size() > 30) + { + QStack empty; + std::swap(empty, irisQueue); + } + + irisQueue.push(irisInfo); + mutex.unlock(); +} +CasicIrisInfo ProMemory::popCasicIris() +{ + CasicIrisInfo result; + + QMutex mutex; + mutex.lock(); + if (this->irisQueue.size() > 0) + { + result = irisQueue.pop(); + } + + mutex.unlock(); + + return result; +} +*/ +int ProMemory::getIrisQueueSize() +{ + int size = 0; + + QMutex mutex; + mutex.lock(); + +// size = this->irisQueue.size(); + + mutex.unlock(); + + return size; +} +bool ProMemory::isIrisQueueEmpty() +{ + bool empty = true; + + QMutex mutex; + mutex.lock(); + +// empty = this->irisQueue.isEmpty(); + + mutex.unlock(); + + return empty; +} +void ProMemory::clearIrisQueue() +{ + QMutex mutex; + mutex.lock(); + +// QStack empty; +// std::swap(empty, irisQueue); + + mutex.unlock(); +} + + +void ProMemory::initIrisFeatures(QString personId) +{ +// irisRegistPro->sendDataToExract(QByteArray(QString("[-u]").append(personId).toLocal8Bit())); +} diff --git a/ProMemory.h b/ProMemory.h new file mode 100644 index 0000000..2ecd653 --- /dev/null +++ b/ProMemory.h @@ -0,0 +1,52 @@ +#ifndef PROMEMORY_H +#define PROMEMORY_H + +#include +#include + +#include "AppConstants.h" +//#include "casic/iris/CasicIrisInfo.h" +#include "dao/IrisDataDao.h" + +#include "device/IrisCameraController.h" +//#include "device/iris/IrisRegistProcess.h" +//#include "device/iris/IrisRecogProcess.h" + +class IrisCameraController; +class IrisRegistProcess; +class IrisRecogProcess; + +class ProMemory +{ +public: + ~ProMemory(); + ProMemory(const ProMemory&)=delete; + ProMemory& operator=(const ProMemory&)=delete; + + static ProMemory& getInstance() { + static ProMemory instance; + return instance; + } + +// void pushCasicIris(CasicIrisInfo irisInfo); +// CasicIrisInfo popCasicIris(); + int getIrisQueueSize(); + bool isIrisQueueEmpty(); + void clearIrisQueue(); + + volatile int widgeFrame = 0; // 当前显示的界面 + volatile int appState = 0; // 当前程序所处的状态 + + void initIrisFeatures(QString personId = ""); // 初始化虹膜特征值集合 + + IrisCameraController * irisCam; + IrisRecogProcess * irisRecogPro; + +private: + ProMemory(); + +// QStack irisQueue; // 虹膜信息队列 + QVector irisFeatures; // 虹膜特征值集合 +}; + +#endif // PROMEMORY_H diff --git a/conf/config.ini b/conf/config.ini new file mode 100644 index 0000000..66e46ad --- /dev/null +++ b/conf/config.ini @@ -0,0 +1,67 @@ +[recognize] +#最大允许识别时间(ms) +maxMatchTime=10000 +#识别成功界面停留时间(ms) +successTipsLast=5000 +#识别失败界面停留时间(ms) +failureTipsLast=3000 +#人脸识别最大尝试次数 +maxFaceTryCount=20 +#持续没找到人脸的最大次数 +maxFaceNotFoundCount=500 +#注册时最小人脸 +minFaceRegist=240 +#识别时最小人脸 +minFaceRecog=100 + +#虹膜识别最大尝试次数 +maxIrisTryCount=10 +#虹膜识别持续没有找到眼的最大次数 +maxEyeNotFoundCount=50 + +#识别方式[1=人脸;2=虹膜;3=双认证;4=任意] +recogType=4 + +[window] +#界面窗口宽(px) +width=600 +#界面窗口高(px) +height=1024 +#统一背景色 +backgroundColor="#FFFFFF" +#标题 +title="虹膜识别终端" + +[work] +#工作状态检测时最小人脸范围 +minFaceSize=160 +#人脸范围最小横坐标 +minFacePosX=320 +#人脸范围最大横坐标 +maxFacePosX=960 +#人脸范围最小纵坐标 +minFacePosY=180 +#人脸范围最大纵坐标 +maxFacePosY=540 +#人脸太近阈值 +faceCloseSize=360 +#人脸太远阈值 +faceFarSize=480 + +[camera] +#虹膜相机取一幅画面的时间间隔(ms) +irisFrameInterval=100 +#虹膜相机拍摄宽度 +irisFrameWidth=1440 +#虹膜相机拍摄高度 +irisFrameHeight=1080 +#虹膜图像高度 +irisWidth=640 +#虹膜图像高度 +irisHeight=480 + +[log] +#日志文件位置 +logFile="d://irisLogs//casic_log.txt" +#日志级别 +logLevel="trace" diff --git a/dao/BaseDao.cpp b/dao/BaseDao.cpp new file mode 100644 index 0000000..f51c144 --- /dev/null +++ b/dao/BaseDao.cpp @@ -0,0 +1,12 @@ +#include "BaseDao.h" +#include "dao/util/ConnectionManager.h" + +BaseDao::BaseDao(QObject *parent) : QObject(parent) +{ + +} + +BaseDao::~BaseDao() +{ + +} diff --git a/AppConstants.h b/AppConstants.h new file mode 100644 index 0000000..296c53f --- /dev/null +++ b/AppConstants.h @@ -0,0 +1,28 @@ +#ifndef APPCONSTANTS_H +#define APPCONSTANTS_H + +class AppConstants +{ +public: + enum WidgeFrameName + { + MAIN_PAGE = 0, // 主页面 + PERSON_LIST_FORM = 1, // 人员列表页面 + ADD_PERSON_FORM = 2, // 添加人员页面 + ADD_PERSON_CAPTURE_FACE = 21, // 添加/编辑人员时进行人脸拍图 + ADD_PERSON_CAPTURE_IRIS = 22, // 添加/编辑人员时进行虹膜拍图 + SETTING_FORM = 3, // 设置页面 + RECOGNIZE_RESULT_FORM = 4, // 识别结果界面 + IDENTIFY_FORM = 5, // 识别界面 含识别中 和 识别结果 + LOCKSCREEN_FORM = 6 // 锁屏待机界面 + }; + + enum ApplicationState + { + STATE_WAIT = 0, // 待机 + STATE_WORKING = 1, // 工作状态 + STATE_IDENTIFYING = 2, // 识别中 + }; +}; + +#endif // APPCONSTANTS_H diff --git a/CasicIrisIdentify.pro b/CasicIrisIdentify.pro index 5d7fea6..575ce3d 100644 --- a/CasicIrisIdentify.pro +++ b/CasicIrisIdentify.pro @@ -1,4 +1,4 @@ -QT += core gui +QT += core gui sql network texttospeech greaterThan(QT_MAJOR_VERSION, 4): QT += widgets @@ -15,20 +15,46 @@ # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 -SOURCES += \ - main.cpp \ - IdentifyForm.cpp +include("dao/dao.pri") +include("device/device.pri") +include("utils/utils.pri") -HEADERS += \ - IdentifyForm.h +SOURCES += main.cpp +SOURCES += ProMemory.cpp +SOURCES += MainWindowForm.cpp +SOURCES += IdentifyForm.cpp +SOURCES += LockScreenForm.cpp -FORMS += \ - IdentifyForm.ui +HEADERS += AppConstants.h +HEADERS += ProMemory.h +HEADERS += MainWindowForm.h +HEADERS += IdentifyForm.h +HEADERS += LockScreenForm.h -TRANSLATIONS += \ - CasicIrisIdentify_zh_CN.ts +FORMS += MainWindowForm.ui +FORMS += IdentifyForm.ui +FORMS += LockScreenForm.ui + +RESOURCES += resource.qrc + +DISTFILES += conf/config.ini + +#TRANSLATIONS += CasicIrisIdentify_zh_CN.ts + +#INCLUDEPATH += include/spdlog +#DEPENDPATH += include/spdlog # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target + + +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lopencv_world420 +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lGxIAPICPPEx + +INCLUDEPATH += $$PWD/include/daheng +DEPENDPATH += $$PWD/include/daheng + +INCLUDEPATH += $$PWD/include +DEPENDPATH += $$PWD/include diff --git a/CasicIrisIdentify_zh_CN.ts b/CasicIrisIdentify_zh_CN.ts index 5526fe4..81900df 100644 --- a/CasicIrisIdentify_zh_CN.ts +++ b/CasicIrisIdentify_zh_CN.ts @@ -1,3 +1,12 @@ - + + + IdentifyForm + + + IdentifyForm + + + + diff --git a/IdentifyForm.cpp b/IdentifyForm.cpp index 348a897..ba1f251 100644 --- a/IdentifyForm.cpp +++ b/IdentifyForm.cpp @@ -1,4 +1,4 @@ -#include "IdentifyForm.h" +#include "IdentifyForm.h" #include "ui_IdentifyForm.h" IdentifyForm::IdentifyForm(QWidget *parent) @@ -6,6 +6,12 @@ , ui(new Ui::IdentifyForm) { ui->setupUi(this); + + // 初始化更新界面的定时器 + // 每秒执行一次 + connect(TimeCounterUtil::getInstance().clockCounter, &QTimer::timeout, this, &IdentifyForm::updateDateAndTime); + + TimeCounterUtil::getInstance().clockCounter->start(1000); } IdentifyForm::~IdentifyForm() @@ -13,3 +19,16 @@ delete ui; } +void IdentifyForm::drawIrisImageOnFrame(QImage image) +{ + // 只在识别界面才显示画面 + if (ui->wgtStacked->currentIndex() == 0) { + ui->labelVideo->setPixmap(QPixmap::fromImage(image)); + } +} + + +void IdentifyForm::updateDateAndTime() +{ + ui->labelTime->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd dddd HH:mm:ss")); +} diff --git a/IdentifyForm.h b/IdentifyForm.h index fc857a1..ae1cd22 100644 --- a/IdentifyForm.h +++ b/IdentifyForm.h @@ -1,7 +1,10 @@ -#ifndef IDENTIFYFORM_H +#ifndef IDENTIFYFORM_H #define IDENTIFYFORM_H #include +#include + +#include "utils/UtilInclude.h" QT_BEGIN_NAMESPACE namespace Ui { class IdentifyForm; } @@ -15,7 +18,14 @@ IdentifyForm(QWidget *parent = nullptr); ~IdentifyForm(); +public slots: + void drawIrisImageOnFrame(QImage image); + private: Ui::IdentifyForm *ui; + +private slots: + void updateDateAndTime(); + }; #endif // IDENTIFYFORM_H diff --git a/IdentifyForm.ui b/IdentifyForm.ui index c72a36f..879dc9a 100644 --- a/IdentifyForm.ui +++ b/IdentifyForm.ui @@ -6,13 +6,59 @@ 0 0 - 800 + 600 600 IdentifyForm + + + + 0 + 40 + 600 + 450 + + + + 0 + + + + + + 100 + 10 + 400 + 300 + + + + + + + + + + + + + + 0 + 0 + 600 + 40 + + + + TextLabel + + + Qt::AlignCenter + + diff --git a/LockScreenForm.cpp b/LockScreenForm.cpp new file mode 100644 index 0000000..58dc54b --- /dev/null +++ b/LockScreenForm.cpp @@ -0,0 +1,14 @@ +#include "LockScreenForm.h" +#include "ui_LockScreenForm.h" + +LockScreenForm::LockScreenForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::LockScreenForm) +{ + ui->setupUi(this); +} + +LockScreenForm::~LockScreenForm() +{ + delete ui; +} diff --git a/LockScreenForm.h b/LockScreenForm.h new file mode 100644 index 0000000..b5ded48 --- /dev/null +++ b/LockScreenForm.h @@ -0,0 +1,25 @@ +#ifndef LOCKSCREENFORM_H +#define LOCKSCREENFORM_H + +#include +#include + +#include "utils/UtilInclude.h" + +namespace Ui { +class LockScreenForm; +} + +class LockScreenForm : public QWidget +{ + Q_OBJECT + +public: + explicit LockScreenForm(QWidget *parent = nullptr); + ~LockScreenForm(); + +private: + Ui::LockScreenForm *ui; +}; + +#endif // LOCKSCREENFORM_H diff --git a/LockScreenForm.ui b/LockScreenForm.ui new file mode 100644 index 0000000..7f2a6db --- /dev/null +++ b/LockScreenForm.ui @@ -0,0 +1,45 @@ + + + LockScreenForm + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + 180 + 100 + 54 + 12 + + + + TextLabel + + + + + + 180 + 160 + 54 + 12 + + + + TextLabel + + + + + + diff --git a/MainWindowForm.cpp b/MainWindowForm.cpp new file mode 100644 index 0000000..84f8159 --- /dev/null +++ b/MainWindowForm.cpp @@ -0,0 +1,86 @@ +#include "MainWindowForm.h" +#include "ui_MainWindowForm.h" +#include + +MainWindowForm::MainWindowForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::MainWindowForm) +{ + ui->setupUi(this); + + // 设置窗口透明和大小、位置 + this->setWindowFlags(Qt::FramelessWindowHint); + this->move(1400, 15); + this->resize(SettingConfig::getInstance().WINDOW_WIDTH, SettingConfig::getInstance().WINDOW_HEIGHT); + + // 通过调色板的颜色来设置窗口的统一背景色 + qApp->setPalette(QPalette(QColor(SettingConfig::getInstance().WINDOW_BACKGROUND_COLOR))); + + // 加载css文件设置控件样式 + QFile file(QApplication::applicationDirPath() + "/qss/main.css"); + if (file.open(QFile::ReadOnly)) + { + QString qssStr = QLatin1String(file.readAll()); + this->setStyleSheet(qssStr); + file.close(); + } + + initFormsPtr(); + + // 设置标题文字 + ui->labelTitle->setText(SettingConfig::getInstance().WINDOW_TITLE); + ui->labelCopyright->setText(SettingConfig::getInstance().WINDOW_RIGHTS); + ui->labelVersion->setText(SettingConfig::getInstance().WINDOW_VERSION); + + // 初始化虹膜相机控制 + ProMemory::getInstance().irisCam = new IrisCameraController(this); + ProMemory::getInstance().irisCam->initIrisCamera(); + ProMemory::getInstance().irisCam->openIrisCamera(); + connect(ProMemory::getInstance().irisCam->irisCamHandler, &IrisCameraCapEventHandler::sendIrisFrameToDraw, identifyForm, &IdentifyForm::drawIrisImageOnFrame); + +// LOG_INFO(QString("应用程序启动成功[Application Startup Success]").toStdString()); + qDebug() << "应用程序启动成功[Application Startup Success]"; + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::IDENTIFY_FORM; + ui->wdgtStatced->setCurrentWidget(identifyForm); + + // 开始虹膜相机拍图 + ProMemory::getInstance().irisCam->startCapture(); +} + +MainWindowForm::~MainWindowForm() +{ + delete ui; +} + +void MainWindowForm::lockScreen() +{ + ui->wdgtStatced->setCurrentWidget(lockScreenForm); + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::LOCKSCREEN_FORM; + ProMemory::getInstance().appState = AppConstants::ApplicationState::STATE_WAIT; +} + +void MainWindowForm::keyPressEvent(QKeyEvent *event) +{ + switch (event->key()) { + case Qt::Key_Escape: + QTimer::singleShot(100, qApp, [=](){ + QApplication::quit(); + }); + + default: + QWidget::keyPressEvent(event); + } +} + +void MainWindowForm::initFormsPtr() +{ + // 初始化各个form + lockScreenForm = new LockScreenForm(this); + identifyForm = new IdentifyForm(this); + + // 将form添加到statcked widget中 + ui->wdgtStatced->addWidget(identifyForm); + ui->wdgtStatced->addWidget(lockScreenForm); + + // 绑定按钮函数 +} diff --git a/MainWindowForm.h b/MainWindowForm.h new file mode 100644 index 0000000..7fb2d89 --- /dev/null +++ b/MainWindowForm.h @@ -0,0 +1,38 @@ +#ifndef MAINWINDOWFORM_H +#define MAINWINDOWFORM_H + +#include +#include +#include + +#include "utils/UtilInclude.h" +#include "ProMemory.h" +#include "LockScreenForm.h" +#include "IdentifyForm.h" + +namespace Ui { +class MainWindowForm; +} + +class MainWindowForm : public QWidget +{ + Q_OBJECT + +public: + explicit MainWindowForm(QWidget *parent = nullptr); + ~MainWindowForm(); + +public slots: + void lockScreen(); + +private: + Ui::MainWindowForm *ui; + LockScreenForm * lockScreenForm; + IdentifyForm * identifyForm; + + void keyPressEvent(QKeyEvent *event); + + void initFormsPtr(); +}; + +#endif // MAINWINDOWFORM_H diff --git a/MainWindowForm.ui b/MainWindowForm.ui new file mode 100644 index 0000000..e793ebf --- /dev/null +++ b/MainWindowForm.ui @@ -0,0 +1,85 @@ + + + MainWindowForm + + + + 0 + 0 + 600 + 1024 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + 0 + 0 + 600 + 84 + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + + + + TextLabel + + + Qt::AlignBottom|Qt::AlignHCenter + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + diff --git a/ProMemory.cpp b/ProMemory.cpp new file mode 100644 index 0000000..19e7403 --- /dev/null +++ b/ProMemory.cpp @@ -0,0 +1,84 @@ +#include "ProMemory.h" + +ProMemory::ProMemory() +{ + +} + +ProMemory::~ProMemory() +{ + +} + +/* +void ProMemory::pushCasicIris(CasicIrisInfo irisInfo) +{ + QMutex mutex; + mutex.lock(); + if (this->irisQueue.size() > 30) + { + QStack empty; + std::swap(empty, irisQueue); + } + + irisQueue.push(irisInfo); + mutex.unlock(); +} +CasicIrisInfo ProMemory::popCasicIris() +{ + CasicIrisInfo result; + + QMutex mutex; + mutex.lock(); + if (this->irisQueue.size() > 0) + { + result = irisQueue.pop(); + } + + mutex.unlock(); + + return result; +} +*/ +int ProMemory::getIrisQueueSize() +{ + int size = 0; + + QMutex mutex; + mutex.lock(); + +// size = this->irisQueue.size(); + + mutex.unlock(); + + return size; +} +bool ProMemory::isIrisQueueEmpty() +{ + bool empty = true; + + QMutex mutex; + mutex.lock(); + +// empty = this->irisQueue.isEmpty(); + + mutex.unlock(); + + return empty; +} +void ProMemory::clearIrisQueue() +{ + QMutex mutex; + mutex.lock(); + +// QStack empty; +// std::swap(empty, irisQueue); + + mutex.unlock(); +} + + +void ProMemory::initIrisFeatures(QString personId) +{ +// irisRegistPro->sendDataToExract(QByteArray(QString("[-u]").append(personId).toLocal8Bit())); +} diff --git a/ProMemory.h b/ProMemory.h new file mode 100644 index 0000000..2ecd653 --- /dev/null +++ b/ProMemory.h @@ -0,0 +1,52 @@ +#ifndef PROMEMORY_H +#define PROMEMORY_H + +#include +#include + +#include "AppConstants.h" +//#include "casic/iris/CasicIrisInfo.h" +#include "dao/IrisDataDao.h" + +#include "device/IrisCameraController.h" +//#include "device/iris/IrisRegistProcess.h" +//#include "device/iris/IrisRecogProcess.h" + +class IrisCameraController; +class IrisRegistProcess; +class IrisRecogProcess; + +class ProMemory +{ +public: + ~ProMemory(); + ProMemory(const ProMemory&)=delete; + ProMemory& operator=(const ProMemory&)=delete; + + static ProMemory& getInstance() { + static ProMemory instance; + return instance; + } + +// void pushCasicIris(CasicIrisInfo irisInfo); +// CasicIrisInfo popCasicIris(); + int getIrisQueueSize(); + bool isIrisQueueEmpty(); + void clearIrisQueue(); + + volatile int widgeFrame = 0; // 当前显示的界面 + volatile int appState = 0; // 当前程序所处的状态 + + void initIrisFeatures(QString personId = ""); // 初始化虹膜特征值集合 + + IrisCameraController * irisCam; + IrisRecogProcess * irisRecogPro; + +private: + ProMemory(); + +// QStack irisQueue; // 虹膜信息队列 + QVector irisFeatures; // 虹膜特征值集合 +}; + +#endif // PROMEMORY_H diff --git a/conf/config.ini b/conf/config.ini new file mode 100644 index 0000000..66e46ad --- /dev/null +++ b/conf/config.ini @@ -0,0 +1,67 @@ +[recognize] +#最大允许识别时间(ms) +maxMatchTime=10000 +#识别成功界面停留时间(ms) +successTipsLast=5000 +#识别失败界面停留时间(ms) +failureTipsLast=3000 +#人脸识别最大尝试次数 +maxFaceTryCount=20 +#持续没找到人脸的最大次数 +maxFaceNotFoundCount=500 +#注册时最小人脸 +minFaceRegist=240 +#识别时最小人脸 +minFaceRecog=100 + +#虹膜识别最大尝试次数 +maxIrisTryCount=10 +#虹膜识别持续没有找到眼的最大次数 +maxEyeNotFoundCount=50 + +#识别方式[1=人脸;2=虹膜;3=双认证;4=任意] +recogType=4 + +[window] +#界面窗口宽(px) +width=600 +#界面窗口高(px) +height=1024 +#统一背景色 +backgroundColor="#FFFFFF" +#标题 +title="虹膜识别终端" + +[work] +#工作状态检测时最小人脸范围 +minFaceSize=160 +#人脸范围最小横坐标 +minFacePosX=320 +#人脸范围最大横坐标 +maxFacePosX=960 +#人脸范围最小纵坐标 +minFacePosY=180 +#人脸范围最大纵坐标 +maxFacePosY=540 +#人脸太近阈值 +faceCloseSize=360 +#人脸太远阈值 +faceFarSize=480 + +[camera] +#虹膜相机取一幅画面的时间间隔(ms) +irisFrameInterval=100 +#虹膜相机拍摄宽度 +irisFrameWidth=1440 +#虹膜相机拍摄高度 +irisFrameHeight=1080 +#虹膜图像高度 +irisWidth=640 +#虹膜图像高度 +irisHeight=480 + +[log] +#日志文件位置 +logFile="d://irisLogs//casic_log.txt" +#日志级别 +logLevel="trace" diff --git a/dao/BaseDao.cpp b/dao/BaseDao.cpp new file mode 100644 index 0000000..f51c144 --- /dev/null +++ b/dao/BaseDao.cpp @@ -0,0 +1,12 @@ +#include "BaseDao.h" +#include "dao/util/ConnectionManager.h" + +BaseDao::BaseDao(QObject *parent) : QObject(parent) +{ + +} + +BaseDao::~BaseDao() +{ + +} diff --git a/dao/BaseDao.h b/dao/BaseDao.h new file mode 100644 index 0000000..1693c88 --- /dev/null +++ b/dao/BaseDao.h @@ -0,0 +1,32 @@ +#ifndef BASEDAO_H +#define BASEDAO_H + +#include +#include +#include +#include + +#include "dao/util/ConnectionManager.h" +#include "utils/UtilInclude.h" + +class BaseDao : public QObject +{ + Q_OBJECT +public: + explicit BaseDao(QObject *parent = nullptr); + ~BaseDao(); + + virtual QVector findAllRecord() = 0; + virtual QVariantMap findRecordById(QString id) = 0; + + virtual QString save(QVariantMap object) = 0; + virtual bool edit(QVariantMap newObject, QString id) = 0; + virtual bool dele(QString id) = 0; + +private: + +signals: + +}; + +#endif // BASEDAO_H diff --git a/AppConstants.h b/AppConstants.h new file mode 100644 index 0000000..296c53f --- /dev/null +++ b/AppConstants.h @@ -0,0 +1,28 @@ +#ifndef APPCONSTANTS_H +#define APPCONSTANTS_H + +class AppConstants +{ +public: + enum WidgeFrameName + { + MAIN_PAGE = 0, // 主页面 + PERSON_LIST_FORM = 1, // 人员列表页面 + ADD_PERSON_FORM = 2, // 添加人员页面 + ADD_PERSON_CAPTURE_FACE = 21, // 添加/编辑人员时进行人脸拍图 + ADD_PERSON_CAPTURE_IRIS = 22, // 添加/编辑人员时进行虹膜拍图 + SETTING_FORM = 3, // 设置页面 + RECOGNIZE_RESULT_FORM = 4, // 识别结果界面 + IDENTIFY_FORM = 5, // 识别界面 含识别中 和 识别结果 + LOCKSCREEN_FORM = 6 // 锁屏待机界面 + }; + + enum ApplicationState + { + STATE_WAIT = 0, // 待机 + STATE_WORKING = 1, // 工作状态 + STATE_IDENTIFYING = 2, // 识别中 + }; +}; + +#endif // APPCONSTANTS_H diff --git a/CasicIrisIdentify.pro b/CasicIrisIdentify.pro index 5d7fea6..575ce3d 100644 --- a/CasicIrisIdentify.pro +++ b/CasicIrisIdentify.pro @@ -1,4 +1,4 @@ -QT += core gui +QT += core gui sql network texttospeech greaterThan(QT_MAJOR_VERSION, 4): QT += widgets @@ -15,20 +15,46 @@ # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 -SOURCES += \ - main.cpp \ - IdentifyForm.cpp +include("dao/dao.pri") +include("device/device.pri") +include("utils/utils.pri") -HEADERS += \ - IdentifyForm.h +SOURCES += main.cpp +SOURCES += ProMemory.cpp +SOURCES += MainWindowForm.cpp +SOURCES += IdentifyForm.cpp +SOURCES += LockScreenForm.cpp -FORMS += \ - IdentifyForm.ui +HEADERS += AppConstants.h +HEADERS += ProMemory.h +HEADERS += MainWindowForm.h +HEADERS += IdentifyForm.h +HEADERS += LockScreenForm.h -TRANSLATIONS += \ - CasicIrisIdentify_zh_CN.ts +FORMS += MainWindowForm.ui +FORMS += IdentifyForm.ui +FORMS += LockScreenForm.ui + +RESOURCES += resource.qrc + +DISTFILES += conf/config.ini + +#TRANSLATIONS += CasicIrisIdentify_zh_CN.ts + +#INCLUDEPATH += include/spdlog +#DEPENDPATH += include/spdlog # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target + + +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lopencv_world420 +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lGxIAPICPPEx + +INCLUDEPATH += $$PWD/include/daheng +DEPENDPATH += $$PWD/include/daheng + +INCLUDEPATH += $$PWD/include +DEPENDPATH += $$PWD/include diff --git a/CasicIrisIdentify_zh_CN.ts b/CasicIrisIdentify_zh_CN.ts index 5526fe4..81900df 100644 --- a/CasicIrisIdentify_zh_CN.ts +++ b/CasicIrisIdentify_zh_CN.ts @@ -1,3 +1,12 @@ - + + + IdentifyForm + + + IdentifyForm + + + + diff --git a/IdentifyForm.cpp b/IdentifyForm.cpp index 348a897..ba1f251 100644 --- a/IdentifyForm.cpp +++ b/IdentifyForm.cpp @@ -1,4 +1,4 @@ -#include "IdentifyForm.h" +#include "IdentifyForm.h" #include "ui_IdentifyForm.h" IdentifyForm::IdentifyForm(QWidget *parent) @@ -6,6 +6,12 @@ , ui(new Ui::IdentifyForm) { ui->setupUi(this); + + // 初始化更新界面的定时器 + // 每秒执行一次 + connect(TimeCounterUtil::getInstance().clockCounter, &QTimer::timeout, this, &IdentifyForm::updateDateAndTime); + + TimeCounterUtil::getInstance().clockCounter->start(1000); } IdentifyForm::~IdentifyForm() @@ -13,3 +19,16 @@ delete ui; } +void IdentifyForm::drawIrisImageOnFrame(QImage image) +{ + // 只在识别界面才显示画面 + if (ui->wgtStacked->currentIndex() == 0) { + ui->labelVideo->setPixmap(QPixmap::fromImage(image)); + } +} + + +void IdentifyForm::updateDateAndTime() +{ + ui->labelTime->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd dddd HH:mm:ss")); +} diff --git a/IdentifyForm.h b/IdentifyForm.h index fc857a1..ae1cd22 100644 --- a/IdentifyForm.h +++ b/IdentifyForm.h @@ -1,7 +1,10 @@ -#ifndef IDENTIFYFORM_H +#ifndef IDENTIFYFORM_H #define IDENTIFYFORM_H #include +#include + +#include "utils/UtilInclude.h" QT_BEGIN_NAMESPACE namespace Ui { class IdentifyForm; } @@ -15,7 +18,14 @@ IdentifyForm(QWidget *parent = nullptr); ~IdentifyForm(); +public slots: + void drawIrisImageOnFrame(QImage image); + private: Ui::IdentifyForm *ui; + +private slots: + void updateDateAndTime(); + }; #endif // IDENTIFYFORM_H diff --git a/IdentifyForm.ui b/IdentifyForm.ui index c72a36f..879dc9a 100644 --- a/IdentifyForm.ui +++ b/IdentifyForm.ui @@ -6,13 +6,59 @@ 0 0 - 800 + 600 600 IdentifyForm + + + + 0 + 40 + 600 + 450 + + + + 0 + + + + + + 100 + 10 + 400 + 300 + + + + + + + + + + + + + + 0 + 0 + 600 + 40 + + + + TextLabel + + + Qt::AlignCenter + + diff --git a/LockScreenForm.cpp b/LockScreenForm.cpp new file mode 100644 index 0000000..58dc54b --- /dev/null +++ b/LockScreenForm.cpp @@ -0,0 +1,14 @@ +#include "LockScreenForm.h" +#include "ui_LockScreenForm.h" + +LockScreenForm::LockScreenForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::LockScreenForm) +{ + ui->setupUi(this); +} + +LockScreenForm::~LockScreenForm() +{ + delete ui; +} diff --git a/LockScreenForm.h b/LockScreenForm.h new file mode 100644 index 0000000..b5ded48 --- /dev/null +++ b/LockScreenForm.h @@ -0,0 +1,25 @@ +#ifndef LOCKSCREENFORM_H +#define LOCKSCREENFORM_H + +#include +#include + +#include "utils/UtilInclude.h" + +namespace Ui { +class LockScreenForm; +} + +class LockScreenForm : public QWidget +{ + Q_OBJECT + +public: + explicit LockScreenForm(QWidget *parent = nullptr); + ~LockScreenForm(); + +private: + Ui::LockScreenForm *ui; +}; + +#endif // LOCKSCREENFORM_H diff --git a/LockScreenForm.ui b/LockScreenForm.ui new file mode 100644 index 0000000..7f2a6db --- /dev/null +++ b/LockScreenForm.ui @@ -0,0 +1,45 @@ + + + LockScreenForm + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + 180 + 100 + 54 + 12 + + + + TextLabel + + + + + + 180 + 160 + 54 + 12 + + + + TextLabel + + + + + + diff --git a/MainWindowForm.cpp b/MainWindowForm.cpp new file mode 100644 index 0000000..84f8159 --- /dev/null +++ b/MainWindowForm.cpp @@ -0,0 +1,86 @@ +#include "MainWindowForm.h" +#include "ui_MainWindowForm.h" +#include + +MainWindowForm::MainWindowForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::MainWindowForm) +{ + ui->setupUi(this); + + // 设置窗口透明和大小、位置 + this->setWindowFlags(Qt::FramelessWindowHint); + this->move(1400, 15); + this->resize(SettingConfig::getInstance().WINDOW_WIDTH, SettingConfig::getInstance().WINDOW_HEIGHT); + + // 通过调色板的颜色来设置窗口的统一背景色 + qApp->setPalette(QPalette(QColor(SettingConfig::getInstance().WINDOW_BACKGROUND_COLOR))); + + // 加载css文件设置控件样式 + QFile file(QApplication::applicationDirPath() + "/qss/main.css"); + if (file.open(QFile::ReadOnly)) + { + QString qssStr = QLatin1String(file.readAll()); + this->setStyleSheet(qssStr); + file.close(); + } + + initFormsPtr(); + + // 设置标题文字 + ui->labelTitle->setText(SettingConfig::getInstance().WINDOW_TITLE); + ui->labelCopyright->setText(SettingConfig::getInstance().WINDOW_RIGHTS); + ui->labelVersion->setText(SettingConfig::getInstance().WINDOW_VERSION); + + // 初始化虹膜相机控制 + ProMemory::getInstance().irisCam = new IrisCameraController(this); + ProMemory::getInstance().irisCam->initIrisCamera(); + ProMemory::getInstance().irisCam->openIrisCamera(); + connect(ProMemory::getInstance().irisCam->irisCamHandler, &IrisCameraCapEventHandler::sendIrisFrameToDraw, identifyForm, &IdentifyForm::drawIrisImageOnFrame); + +// LOG_INFO(QString("应用程序启动成功[Application Startup Success]").toStdString()); + qDebug() << "应用程序启动成功[Application Startup Success]"; + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::IDENTIFY_FORM; + ui->wdgtStatced->setCurrentWidget(identifyForm); + + // 开始虹膜相机拍图 + ProMemory::getInstance().irisCam->startCapture(); +} + +MainWindowForm::~MainWindowForm() +{ + delete ui; +} + +void MainWindowForm::lockScreen() +{ + ui->wdgtStatced->setCurrentWidget(lockScreenForm); + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::LOCKSCREEN_FORM; + ProMemory::getInstance().appState = AppConstants::ApplicationState::STATE_WAIT; +} + +void MainWindowForm::keyPressEvent(QKeyEvent *event) +{ + switch (event->key()) { + case Qt::Key_Escape: + QTimer::singleShot(100, qApp, [=](){ + QApplication::quit(); + }); + + default: + QWidget::keyPressEvent(event); + } +} + +void MainWindowForm::initFormsPtr() +{ + // 初始化各个form + lockScreenForm = new LockScreenForm(this); + identifyForm = new IdentifyForm(this); + + // 将form添加到statcked widget中 + ui->wdgtStatced->addWidget(identifyForm); + ui->wdgtStatced->addWidget(lockScreenForm); + + // 绑定按钮函数 +} diff --git a/MainWindowForm.h b/MainWindowForm.h new file mode 100644 index 0000000..7fb2d89 --- /dev/null +++ b/MainWindowForm.h @@ -0,0 +1,38 @@ +#ifndef MAINWINDOWFORM_H +#define MAINWINDOWFORM_H + +#include +#include +#include + +#include "utils/UtilInclude.h" +#include "ProMemory.h" +#include "LockScreenForm.h" +#include "IdentifyForm.h" + +namespace Ui { +class MainWindowForm; +} + +class MainWindowForm : public QWidget +{ + Q_OBJECT + +public: + explicit MainWindowForm(QWidget *parent = nullptr); + ~MainWindowForm(); + +public slots: + void lockScreen(); + +private: + Ui::MainWindowForm *ui; + LockScreenForm * lockScreenForm; + IdentifyForm * identifyForm; + + void keyPressEvent(QKeyEvent *event); + + void initFormsPtr(); +}; + +#endif // MAINWINDOWFORM_H diff --git a/MainWindowForm.ui b/MainWindowForm.ui new file mode 100644 index 0000000..e793ebf --- /dev/null +++ b/MainWindowForm.ui @@ -0,0 +1,85 @@ + + + MainWindowForm + + + + 0 + 0 + 600 + 1024 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + 0 + 0 + 600 + 84 + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + + + + TextLabel + + + Qt::AlignBottom|Qt::AlignHCenter + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + diff --git a/ProMemory.cpp b/ProMemory.cpp new file mode 100644 index 0000000..19e7403 --- /dev/null +++ b/ProMemory.cpp @@ -0,0 +1,84 @@ +#include "ProMemory.h" + +ProMemory::ProMemory() +{ + +} + +ProMemory::~ProMemory() +{ + +} + +/* +void ProMemory::pushCasicIris(CasicIrisInfo irisInfo) +{ + QMutex mutex; + mutex.lock(); + if (this->irisQueue.size() > 30) + { + QStack empty; + std::swap(empty, irisQueue); + } + + irisQueue.push(irisInfo); + mutex.unlock(); +} +CasicIrisInfo ProMemory::popCasicIris() +{ + CasicIrisInfo result; + + QMutex mutex; + mutex.lock(); + if (this->irisQueue.size() > 0) + { + result = irisQueue.pop(); + } + + mutex.unlock(); + + return result; +} +*/ +int ProMemory::getIrisQueueSize() +{ + int size = 0; + + QMutex mutex; + mutex.lock(); + +// size = this->irisQueue.size(); + + mutex.unlock(); + + return size; +} +bool ProMemory::isIrisQueueEmpty() +{ + bool empty = true; + + QMutex mutex; + mutex.lock(); + +// empty = this->irisQueue.isEmpty(); + + mutex.unlock(); + + return empty; +} +void ProMemory::clearIrisQueue() +{ + QMutex mutex; + mutex.lock(); + +// QStack empty; +// std::swap(empty, irisQueue); + + mutex.unlock(); +} + + +void ProMemory::initIrisFeatures(QString personId) +{ +// irisRegistPro->sendDataToExract(QByteArray(QString("[-u]").append(personId).toLocal8Bit())); +} diff --git a/ProMemory.h b/ProMemory.h new file mode 100644 index 0000000..2ecd653 --- /dev/null +++ b/ProMemory.h @@ -0,0 +1,52 @@ +#ifndef PROMEMORY_H +#define PROMEMORY_H + +#include +#include + +#include "AppConstants.h" +//#include "casic/iris/CasicIrisInfo.h" +#include "dao/IrisDataDao.h" + +#include "device/IrisCameraController.h" +//#include "device/iris/IrisRegistProcess.h" +//#include "device/iris/IrisRecogProcess.h" + +class IrisCameraController; +class IrisRegistProcess; +class IrisRecogProcess; + +class ProMemory +{ +public: + ~ProMemory(); + ProMemory(const ProMemory&)=delete; + ProMemory& operator=(const ProMemory&)=delete; + + static ProMemory& getInstance() { + static ProMemory instance; + return instance; + } + +// void pushCasicIris(CasicIrisInfo irisInfo); +// CasicIrisInfo popCasicIris(); + int getIrisQueueSize(); + bool isIrisQueueEmpty(); + void clearIrisQueue(); + + volatile int widgeFrame = 0; // 当前显示的界面 + volatile int appState = 0; // 当前程序所处的状态 + + void initIrisFeatures(QString personId = ""); // 初始化虹膜特征值集合 + + IrisCameraController * irisCam; + IrisRecogProcess * irisRecogPro; + +private: + ProMemory(); + +// QStack irisQueue; // 虹膜信息队列 + QVector irisFeatures; // 虹膜特征值集合 +}; + +#endif // PROMEMORY_H diff --git a/conf/config.ini b/conf/config.ini new file mode 100644 index 0000000..66e46ad --- /dev/null +++ b/conf/config.ini @@ -0,0 +1,67 @@ +[recognize] +#最大允许识别时间(ms) +maxMatchTime=10000 +#识别成功界面停留时间(ms) +successTipsLast=5000 +#识别失败界面停留时间(ms) +failureTipsLast=3000 +#人脸识别最大尝试次数 +maxFaceTryCount=20 +#持续没找到人脸的最大次数 +maxFaceNotFoundCount=500 +#注册时最小人脸 +minFaceRegist=240 +#识别时最小人脸 +minFaceRecog=100 + +#虹膜识别最大尝试次数 +maxIrisTryCount=10 +#虹膜识别持续没有找到眼的最大次数 +maxEyeNotFoundCount=50 + +#识别方式[1=人脸;2=虹膜;3=双认证;4=任意] +recogType=4 + +[window] +#界面窗口宽(px) +width=600 +#界面窗口高(px) +height=1024 +#统一背景色 +backgroundColor="#FFFFFF" +#标题 +title="虹膜识别终端" + +[work] +#工作状态检测时最小人脸范围 +minFaceSize=160 +#人脸范围最小横坐标 +minFacePosX=320 +#人脸范围最大横坐标 +maxFacePosX=960 +#人脸范围最小纵坐标 +minFacePosY=180 +#人脸范围最大纵坐标 +maxFacePosY=540 +#人脸太近阈值 +faceCloseSize=360 +#人脸太远阈值 +faceFarSize=480 + +[camera] +#虹膜相机取一幅画面的时间间隔(ms) +irisFrameInterval=100 +#虹膜相机拍摄宽度 +irisFrameWidth=1440 +#虹膜相机拍摄高度 +irisFrameHeight=1080 +#虹膜图像高度 +irisWidth=640 +#虹膜图像高度 +irisHeight=480 + +[log] +#日志文件位置 +logFile="d://irisLogs//casic_log.txt" +#日志级别 +logLevel="trace" diff --git a/dao/BaseDao.cpp b/dao/BaseDao.cpp new file mode 100644 index 0000000..f51c144 --- /dev/null +++ b/dao/BaseDao.cpp @@ -0,0 +1,12 @@ +#include "BaseDao.h" +#include "dao/util/ConnectionManager.h" + +BaseDao::BaseDao(QObject *parent) : QObject(parent) +{ + +} + +BaseDao::~BaseDao() +{ + +} diff --git a/dao/BaseDao.h b/dao/BaseDao.h new file mode 100644 index 0000000..1693c88 --- /dev/null +++ b/dao/BaseDao.h @@ -0,0 +1,32 @@ +#ifndef BASEDAO_H +#define BASEDAO_H + +#include +#include +#include +#include + +#include "dao/util/ConnectionManager.h" +#include "utils/UtilInclude.h" + +class BaseDao : public QObject +{ + Q_OBJECT +public: + explicit BaseDao(QObject *parent = nullptr); + ~BaseDao(); + + virtual QVector findAllRecord() = 0; + virtual QVariantMap findRecordById(QString id) = 0; + + virtual QString save(QVariantMap object) = 0; + virtual bool edit(QVariantMap newObject, QString id) = 0; + virtual bool dele(QString id) = 0; + +private: + +signals: + +}; + +#endif // BASEDAO_H diff --git a/dao/IrisDataDao.cpp b/dao/IrisDataDao.cpp new file mode 100644 index 0000000..37a0ed6 --- /dev/null +++ b/dao/IrisDataDao.cpp @@ -0,0 +1,204 @@ +#include "IrisDataDao.h" + +IrisDataDao::IrisDataDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector IrisDataDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM IRIS_DATA"; + query.prepare(sql); + + // 执行查询 + query.exec(); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + item.insert("id", query.value("id").toString()); + item.insert("person_id", query.value("person_id").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("left_iris_code1", query.value("left_iris_code1")); + item.insert("left_iris_code2", query.value("left_iris_code2")); + item.insert("left_iris_code3", query.value("left_iris_code3")); + item.insert("right_iris_code1", query.value("right_iris_code1")); + item.insert("right_iris_code2", query.value("right_iris_code2")); + item.insert("right_iris_code3", query.value("right_iris_code3")); + + result.append(item); + } + +// LOG_DEBUG(QString("查询IRIS_DATA表的所有记录[结果数:%1]").arg(result.size()).toStdString()); + return result; +} + +QVariantMap IrisDataDao::findRecordById(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM IRIS_DATA WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + // 获取结果 + if (query.next()) + { + result.insert("id", query.value("id").toString()); + result.insert("person_id", query.value("person_id").toLongLong()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("left_iris_code1", query.value("left_iris_code1")); + result.insert("left_iris_code2", query.value("left_iris_code2")); + result.insert("left_iris_code3", query.value("left_iris_code3")); + result.insert("right_iris_code1", query.value("right_iris_code1")); + result.insert("right_iris_code2", query.value("right_iris_code2")); + result.insert("right_iris_code3", query.value("right_iris_code3")); + } + +// LOG_DEBUG(QString("根据id查询IRIS_DATA表的记录[id=%1]").arg(id).toStdString()); + return result; +} + +QVariantMap IrisDataDao::findRecordByPersonId(QString personId) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM IRIS_DATA WHERE PERSON_ID = :personId"); + query.prepare(sql); + query.bindValue(":personId", personId); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + if (query.next()) + { + result.insert("id", query.value("id").toString()); + result.insert("person_id", query.value("person_id").toLongLong()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("left_iris_code1", query.value("left_iris_code1")); + result.insert("left_iris_code2", query.value("left_iris_code2")); + result.insert("left_iris_code3", query.value("left_iris_code3")); + result.insert("right_iris_code1", query.value("right_iris_code1")); + result.insert("right_iris_code2", query.value("right_iris_code2")); + result.insert("right_iris_code3", query.value("right_iris_code3")); + } + +// LOG_DEBUG(QString("根据personId查询IRIS_DATA表的记录[personId=%1]").arg(personId).toStdString()); + return result; +} + + +QString IrisDataDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + + // INSERT语句 + QString sql = QString("INSERT INTO IRIS_DATA (ID, PERSON_ID, ID_CARD_NO, LEFT_IRIS_CODE1, RIGHT_IRIS_CODE1) VALUES (:id, :personId, :idCardNo, :left1, :right1)"); + + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":personId", object.value("person_id").toString()); + query.bindValue(":idCardNo", object.value("id_card_no").toString()); + query.bindValue(":left1", object.value("left_iris_code1")); + query.bindValue(":right1", object.value("right_iris_code1")); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(); + +// LOG_DEBUG(QString("保存虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool IrisDataDao::edit(QVariantMap newObject, QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // UPDATE语句 + if (!newObject.contains("left_iris_code1") || !newObject.contains("right_iris_code1")){ + return false; + } + QString sql = QString("UPDATE IRIS_DATA SET LEFT_IRIS_CODE1 = :left1, RIGHT_IRIS_CODE1 = :right1 WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":left1", newObject.value("left_iris_code1")); + query.bindValue(":right1", newObject.value("right_iris_code1")); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(); + +// LOG_DEBUG(QString("编辑虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; +} + + +bool IrisDataDao::dele(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + QString sql = QString("DELETE FROM IRIS_DATA WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(); + +// LOG_DEBUG(QString("删除虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; +} diff --git a/AppConstants.h b/AppConstants.h new file mode 100644 index 0000000..296c53f --- /dev/null +++ b/AppConstants.h @@ -0,0 +1,28 @@ +#ifndef APPCONSTANTS_H +#define APPCONSTANTS_H + +class AppConstants +{ +public: + enum WidgeFrameName + { + MAIN_PAGE = 0, // 主页面 + PERSON_LIST_FORM = 1, // 人员列表页面 + ADD_PERSON_FORM = 2, // 添加人员页面 + ADD_PERSON_CAPTURE_FACE = 21, // 添加/编辑人员时进行人脸拍图 + ADD_PERSON_CAPTURE_IRIS = 22, // 添加/编辑人员时进行虹膜拍图 + SETTING_FORM = 3, // 设置页面 + RECOGNIZE_RESULT_FORM = 4, // 识别结果界面 + IDENTIFY_FORM = 5, // 识别界面 含识别中 和 识别结果 + LOCKSCREEN_FORM = 6 // 锁屏待机界面 + }; + + enum ApplicationState + { + STATE_WAIT = 0, // 待机 + STATE_WORKING = 1, // 工作状态 + STATE_IDENTIFYING = 2, // 识别中 + }; +}; + +#endif // APPCONSTANTS_H diff --git a/CasicIrisIdentify.pro b/CasicIrisIdentify.pro index 5d7fea6..575ce3d 100644 --- a/CasicIrisIdentify.pro +++ b/CasicIrisIdentify.pro @@ -1,4 +1,4 @@ -QT += core gui +QT += core gui sql network texttospeech greaterThan(QT_MAJOR_VERSION, 4): QT += widgets @@ -15,20 +15,46 @@ # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 -SOURCES += \ - main.cpp \ - IdentifyForm.cpp +include("dao/dao.pri") +include("device/device.pri") +include("utils/utils.pri") -HEADERS += \ - IdentifyForm.h +SOURCES += main.cpp +SOURCES += ProMemory.cpp +SOURCES += MainWindowForm.cpp +SOURCES += IdentifyForm.cpp +SOURCES += LockScreenForm.cpp -FORMS += \ - IdentifyForm.ui +HEADERS += AppConstants.h +HEADERS += ProMemory.h +HEADERS += MainWindowForm.h +HEADERS += IdentifyForm.h +HEADERS += LockScreenForm.h -TRANSLATIONS += \ - CasicIrisIdentify_zh_CN.ts +FORMS += MainWindowForm.ui +FORMS += IdentifyForm.ui +FORMS += LockScreenForm.ui + +RESOURCES += resource.qrc + +DISTFILES += conf/config.ini + +#TRANSLATIONS += CasicIrisIdentify_zh_CN.ts + +#INCLUDEPATH += include/spdlog +#DEPENDPATH += include/spdlog # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target + + +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lopencv_world420 +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lGxIAPICPPEx + +INCLUDEPATH += $$PWD/include/daheng +DEPENDPATH += $$PWD/include/daheng + +INCLUDEPATH += $$PWD/include +DEPENDPATH += $$PWD/include diff --git a/CasicIrisIdentify_zh_CN.ts b/CasicIrisIdentify_zh_CN.ts index 5526fe4..81900df 100644 --- a/CasicIrisIdentify_zh_CN.ts +++ b/CasicIrisIdentify_zh_CN.ts @@ -1,3 +1,12 @@ - + + + IdentifyForm + + + IdentifyForm + + + + diff --git a/IdentifyForm.cpp b/IdentifyForm.cpp index 348a897..ba1f251 100644 --- a/IdentifyForm.cpp +++ b/IdentifyForm.cpp @@ -1,4 +1,4 @@ -#include "IdentifyForm.h" +#include "IdentifyForm.h" #include "ui_IdentifyForm.h" IdentifyForm::IdentifyForm(QWidget *parent) @@ -6,6 +6,12 @@ , ui(new Ui::IdentifyForm) { ui->setupUi(this); + + // 初始化更新界面的定时器 + // 每秒执行一次 + connect(TimeCounterUtil::getInstance().clockCounter, &QTimer::timeout, this, &IdentifyForm::updateDateAndTime); + + TimeCounterUtil::getInstance().clockCounter->start(1000); } IdentifyForm::~IdentifyForm() @@ -13,3 +19,16 @@ delete ui; } +void IdentifyForm::drawIrisImageOnFrame(QImage image) +{ + // 只在识别界面才显示画面 + if (ui->wgtStacked->currentIndex() == 0) { + ui->labelVideo->setPixmap(QPixmap::fromImage(image)); + } +} + + +void IdentifyForm::updateDateAndTime() +{ + ui->labelTime->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd dddd HH:mm:ss")); +} diff --git a/IdentifyForm.h b/IdentifyForm.h index fc857a1..ae1cd22 100644 --- a/IdentifyForm.h +++ b/IdentifyForm.h @@ -1,7 +1,10 @@ -#ifndef IDENTIFYFORM_H +#ifndef IDENTIFYFORM_H #define IDENTIFYFORM_H #include +#include + +#include "utils/UtilInclude.h" QT_BEGIN_NAMESPACE namespace Ui { class IdentifyForm; } @@ -15,7 +18,14 @@ IdentifyForm(QWidget *parent = nullptr); ~IdentifyForm(); +public slots: + void drawIrisImageOnFrame(QImage image); + private: Ui::IdentifyForm *ui; + +private slots: + void updateDateAndTime(); + }; #endif // IDENTIFYFORM_H diff --git a/IdentifyForm.ui b/IdentifyForm.ui index c72a36f..879dc9a 100644 --- a/IdentifyForm.ui +++ b/IdentifyForm.ui @@ -6,13 +6,59 @@ 0 0 - 800 + 600 600 IdentifyForm + + + + 0 + 40 + 600 + 450 + + + + 0 + + + + + + 100 + 10 + 400 + 300 + + + + + + + + + + + + + + 0 + 0 + 600 + 40 + + + + TextLabel + + + Qt::AlignCenter + + diff --git a/LockScreenForm.cpp b/LockScreenForm.cpp new file mode 100644 index 0000000..58dc54b --- /dev/null +++ b/LockScreenForm.cpp @@ -0,0 +1,14 @@ +#include "LockScreenForm.h" +#include "ui_LockScreenForm.h" + +LockScreenForm::LockScreenForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::LockScreenForm) +{ + ui->setupUi(this); +} + +LockScreenForm::~LockScreenForm() +{ + delete ui; +} diff --git a/LockScreenForm.h b/LockScreenForm.h new file mode 100644 index 0000000..b5ded48 --- /dev/null +++ b/LockScreenForm.h @@ -0,0 +1,25 @@ +#ifndef LOCKSCREENFORM_H +#define LOCKSCREENFORM_H + +#include +#include + +#include "utils/UtilInclude.h" + +namespace Ui { +class LockScreenForm; +} + +class LockScreenForm : public QWidget +{ + Q_OBJECT + +public: + explicit LockScreenForm(QWidget *parent = nullptr); + ~LockScreenForm(); + +private: + Ui::LockScreenForm *ui; +}; + +#endif // LOCKSCREENFORM_H diff --git a/LockScreenForm.ui b/LockScreenForm.ui new file mode 100644 index 0000000..7f2a6db --- /dev/null +++ b/LockScreenForm.ui @@ -0,0 +1,45 @@ + + + LockScreenForm + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + 180 + 100 + 54 + 12 + + + + TextLabel + + + + + + 180 + 160 + 54 + 12 + + + + TextLabel + + + + + + diff --git a/MainWindowForm.cpp b/MainWindowForm.cpp new file mode 100644 index 0000000..84f8159 --- /dev/null +++ b/MainWindowForm.cpp @@ -0,0 +1,86 @@ +#include "MainWindowForm.h" +#include "ui_MainWindowForm.h" +#include + +MainWindowForm::MainWindowForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::MainWindowForm) +{ + ui->setupUi(this); + + // 设置窗口透明和大小、位置 + this->setWindowFlags(Qt::FramelessWindowHint); + this->move(1400, 15); + this->resize(SettingConfig::getInstance().WINDOW_WIDTH, SettingConfig::getInstance().WINDOW_HEIGHT); + + // 通过调色板的颜色来设置窗口的统一背景色 + qApp->setPalette(QPalette(QColor(SettingConfig::getInstance().WINDOW_BACKGROUND_COLOR))); + + // 加载css文件设置控件样式 + QFile file(QApplication::applicationDirPath() + "/qss/main.css"); + if (file.open(QFile::ReadOnly)) + { + QString qssStr = QLatin1String(file.readAll()); + this->setStyleSheet(qssStr); + file.close(); + } + + initFormsPtr(); + + // 设置标题文字 + ui->labelTitle->setText(SettingConfig::getInstance().WINDOW_TITLE); + ui->labelCopyright->setText(SettingConfig::getInstance().WINDOW_RIGHTS); + ui->labelVersion->setText(SettingConfig::getInstance().WINDOW_VERSION); + + // 初始化虹膜相机控制 + ProMemory::getInstance().irisCam = new IrisCameraController(this); + ProMemory::getInstance().irisCam->initIrisCamera(); + ProMemory::getInstance().irisCam->openIrisCamera(); + connect(ProMemory::getInstance().irisCam->irisCamHandler, &IrisCameraCapEventHandler::sendIrisFrameToDraw, identifyForm, &IdentifyForm::drawIrisImageOnFrame); + +// LOG_INFO(QString("应用程序启动成功[Application Startup Success]").toStdString()); + qDebug() << "应用程序启动成功[Application Startup Success]"; + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::IDENTIFY_FORM; + ui->wdgtStatced->setCurrentWidget(identifyForm); + + // 开始虹膜相机拍图 + ProMemory::getInstance().irisCam->startCapture(); +} + +MainWindowForm::~MainWindowForm() +{ + delete ui; +} + +void MainWindowForm::lockScreen() +{ + ui->wdgtStatced->setCurrentWidget(lockScreenForm); + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::LOCKSCREEN_FORM; + ProMemory::getInstance().appState = AppConstants::ApplicationState::STATE_WAIT; +} + +void MainWindowForm::keyPressEvent(QKeyEvent *event) +{ + switch (event->key()) { + case Qt::Key_Escape: + QTimer::singleShot(100, qApp, [=](){ + QApplication::quit(); + }); + + default: + QWidget::keyPressEvent(event); + } +} + +void MainWindowForm::initFormsPtr() +{ + // 初始化各个form + lockScreenForm = new LockScreenForm(this); + identifyForm = new IdentifyForm(this); + + // 将form添加到statcked widget中 + ui->wdgtStatced->addWidget(identifyForm); + ui->wdgtStatced->addWidget(lockScreenForm); + + // 绑定按钮函数 +} diff --git a/MainWindowForm.h b/MainWindowForm.h new file mode 100644 index 0000000..7fb2d89 --- /dev/null +++ b/MainWindowForm.h @@ -0,0 +1,38 @@ +#ifndef MAINWINDOWFORM_H +#define MAINWINDOWFORM_H + +#include +#include +#include + +#include "utils/UtilInclude.h" +#include "ProMemory.h" +#include "LockScreenForm.h" +#include "IdentifyForm.h" + +namespace Ui { +class MainWindowForm; +} + +class MainWindowForm : public QWidget +{ + Q_OBJECT + +public: + explicit MainWindowForm(QWidget *parent = nullptr); + ~MainWindowForm(); + +public slots: + void lockScreen(); + +private: + Ui::MainWindowForm *ui; + LockScreenForm * lockScreenForm; + IdentifyForm * identifyForm; + + void keyPressEvent(QKeyEvent *event); + + void initFormsPtr(); +}; + +#endif // MAINWINDOWFORM_H diff --git a/MainWindowForm.ui b/MainWindowForm.ui new file mode 100644 index 0000000..e793ebf --- /dev/null +++ b/MainWindowForm.ui @@ -0,0 +1,85 @@ + + + MainWindowForm + + + + 0 + 0 + 600 + 1024 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + 0 + 0 + 600 + 84 + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + + + + TextLabel + + + Qt::AlignBottom|Qt::AlignHCenter + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + diff --git a/ProMemory.cpp b/ProMemory.cpp new file mode 100644 index 0000000..19e7403 --- /dev/null +++ b/ProMemory.cpp @@ -0,0 +1,84 @@ +#include "ProMemory.h" + +ProMemory::ProMemory() +{ + +} + +ProMemory::~ProMemory() +{ + +} + +/* +void ProMemory::pushCasicIris(CasicIrisInfo irisInfo) +{ + QMutex mutex; + mutex.lock(); + if (this->irisQueue.size() > 30) + { + QStack empty; + std::swap(empty, irisQueue); + } + + irisQueue.push(irisInfo); + mutex.unlock(); +} +CasicIrisInfo ProMemory::popCasicIris() +{ + CasicIrisInfo result; + + QMutex mutex; + mutex.lock(); + if (this->irisQueue.size() > 0) + { + result = irisQueue.pop(); + } + + mutex.unlock(); + + return result; +} +*/ +int ProMemory::getIrisQueueSize() +{ + int size = 0; + + QMutex mutex; + mutex.lock(); + +// size = this->irisQueue.size(); + + mutex.unlock(); + + return size; +} +bool ProMemory::isIrisQueueEmpty() +{ + bool empty = true; + + QMutex mutex; + mutex.lock(); + +// empty = this->irisQueue.isEmpty(); + + mutex.unlock(); + + return empty; +} +void ProMemory::clearIrisQueue() +{ + QMutex mutex; + mutex.lock(); + +// QStack empty; +// std::swap(empty, irisQueue); + + mutex.unlock(); +} + + +void ProMemory::initIrisFeatures(QString personId) +{ +// irisRegistPro->sendDataToExract(QByteArray(QString("[-u]").append(personId).toLocal8Bit())); +} diff --git a/ProMemory.h b/ProMemory.h new file mode 100644 index 0000000..2ecd653 --- /dev/null +++ b/ProMemory.h @@ -0,0 +1,52 @@ +#ifndef PROMEMORY_H +#define PROMEMORY_H + +#include +#include + +#include "AppConstants.h" +//#include "casic/iris/CasicIrisInfo.h" +#include "dao/IrisDataDao.h" + +#include "device/IrisCameraController.h" +//#include "device/iris/IrisRegistProcess.h" +//#include "device/iris/IrisRecogProcess.h" + +class IrisCameraController; +class IrisRegistProcess; +class IrisRecogProcess; + +class ProMemory +{ +public: + ~ProMemory(); + ProMemory(const ProMemory&)=delete; + ProMemory& operator=(const ProMemory&)=delete; + + static ProMemory& getInstance() { + static ProMemory instance; + return instance; + } + +// void pushCasicIris(CasicIrisInfo irisInfo); +// CasicIrisInfo popCasicIris(); + int getIrisQueueSize(); + bool isIrisQueueEmpty(); + void clearIrisQueue(); + + volatile int widgeFrame = 0; // 当前显示的界面 + volatile int appState = 0; // 当前程序所处的状态 + + void initIrisFeatures(QString personId = ""); // 初始化虹膜特征值集合 + + IrisCameraController * irisCam; + IrisRecogProcess * irisRecogPro; + +private: + ProMemory(); + +// QStack irisQueue; // 虹膜信息队列 + QVector irisFeatures; // 虹膜特征值集合 +}; + +#endif // PROMEMORY_H diff --git a/conf/config.ini b/conf/config.ini new file mode 100644 index 0000000..66e46ad --- /dev/null +++ b/conf/config.ini @@ -0,0 +1,67 @@ +[recognize] +#最大允许识别时间(ms) +maxMatchTime=10000 +#识别成功界面停留时间(ms) +successTipsLast=5000 +#识别失败界面停留时间(ms) +failureTipsLast=3000 +#人脸识别最大尝试次数 +maxFaceTryCount=20 +#持续没找到人脸的最大次数 +maxFaceNotFoundCount=500 +#注册时最小人脸 +minFaceRegist=240 +#识别时最小人脸 +minFaceRecog=100 + +#虹膜识别最大尝试次数 +maxIrisTryCount=10 +#虹膜识别持续没有找到眼的最大次数 +maxEyeNotFoundCount=50 + +#识别方式[1=人脸;2=虹膜;3=双认证;4=任意] +recogType=4 + +[window] +#界面窗口宽(px) +width=600 +#界面窗口高(px) +height=1024 +#统一背景色 +backgroundColor="#FFFFFF" +#标题 +title="虹膜识别终端" + +[work] +#工作状态检测时最小人脸范围 +minFaceSize=160 +#人脸范围最小横坐标 +minFacePosX=320 +#人脸范围最大横坐标 +maxFacePosX=960 +#人脸范围最小纵坐标 +minFacePosY=180 +#人脸范围最大纵坐标 +maxFacePosY=540 +#人脸太近阈值 +faceCloseSize=360 +#人脸太远阈值 +faceFarSize=480 + +[camera] +#虹膜相机取一幅画面的时间间隔(ms) +irisFrameInterval=100 +#虹膜相机拍摄宽度 +irisFrameWidth=1440 +#虹膜相机拍摄高度 +irisFrameHeight=1080 +#虹膜图像高度 +irisWidth=640 +#虹膜图像高度 +irisHeight=480 + +[log] +#日志文件位置 +logFile="d://irisLogs//casic_log.txt" +#日志级别 +logLevel="trace" diff --git a/dao/BaseDao.cpp b/dao/BaseDao.cpp new file mode 100644 index 0000000..f51c144 --- /dev/null +++ b/dao/BaseDao.cpp @@ -0,0 +1,12 @@ +#include "BaseDao.h" +#include "dao/util/ConnectionManager.h" + +BaseDao::BaseDao(QObject *parent) : QObject(parent) +{ + +} + +BaseDao::~BaseDao() +{ + +} diff --git a/dao/BaseDao.h b/dao/BaseDao.h new file mode 100644 index 0000000..1693c88 --- /dev/null +++ b/dao/BaseDao.h @@ -0,0 +1,32 @@ +#ifndef BASEDAO_H +#define BASEDAO_H + +#include +#include +#include +#include + +#include "dao/util/ConnectionManager.h" +#include "utils/UtilInclude.h" + +class BaseDao : public QObject +{ + Q_OBJECT +public: + explicit BaseDao(QObject *parent = nullptr); + ~BaseDao(); + + virtual QVector findAllRecord() = 0; + virtual QVariantMap findRecordById(QString id) = 0; + + virtual QString save(QVariantMap object) = 0; + virtual bool edit(QVariantMap newObject, QString id) = 0; + virtual bool dele(QString id) = 0; + +private: + +signals: + +}; + +#endif // BASEDAO_H diff --git a/dao/IrisDataDao.cpp b/dao/IrisDataDao.cpp new file mode 100644 index 0000000..37a0ed6 --- /dev/null +++ b/dao/IrisDataDao.cpp @@ -0,0 +1,204 @@ +#include "IrisDataDao.h" + +IrisDataDao::IrisDataDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector IrisDataDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM IRIS_DATA"; + query.prepare(sql); + + // 执行查询 + query.exec(); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + item.insert("id", query.value("id").toString()); + item.insert("person_id", query.value("person_id").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("left_iris_code1", query.value("left_iris_code1")); + item.insert("left_iris_code2", query.value("left_iris_code2")); + item.insert("left_iris_code3", query.value("left_iris_code3")); + item.insert("right_iris_code1", query.value("right_iris_code1")); + item.insert("right_iris_code2", query.value("right_iris_code2")); + item.insert("right_iris_code3", query.value("right_iris_code3")); + + result.append(item); + } + +// LOG_DEBUG(QString("查询IRIS_DATA表的所有记录[结果数:%1]").arg(result.size()).toStdString()); + return result; +} + +QVariantMap IrisDataDao::findRecordById(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM IRIS_DATA WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + // 获取结果 + if (query.next()) + { + result.insert("id", query.value("id").toString()); + result.insert("person_id", query.value("person_id").toLongLong()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("left_iris_code1", query.value("left_iris_code1")); + result.insert("left_iris_code2", query.value("left_iris_code2")); + result.insert("left_iris_code3", query.value("left_iris_code3")); + result.insert("right_iris_code1", query.value("right_iris_code1")); + result.insert("right_iris_code2", query.value("right_iris_code2")); + result.insert("right_iris_code3", query.value("right_iris_code3")); + } + +// LOG_DEBUG(QString("根据id查询IRIS_DATA表的记录[id=%1]").arg(id).toStdString()); + return result; +} + +QVariantMap IrisDataDao::findRecordByPersonId(QString personId) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM IRIS_DATA WHERE PERSON_ID = :personId"); + query.prepare(sql); + query.bindValue(":personId", personId); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + if (query.next()) + { + result.insert("id", query.value("id").toString()); + result.insert("person_id", query.value("person_id").toLongLong()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("left_iris_code1", query.value("left_iris_code1")); + result.insert("left_iris_code2", query.value("left_iris_code2")); + result.insert("left_iris_code3", query.value("left_iris_code3")); + result.insert("right_iris_code1", query.value("right_iris_code1")); + result.insert("right_iris_code2", query.value("right_iris_code2")); + result.insert("right_iris_code3", query.value("right_iris_code3")); + } + +// LOG_DEBUG(QString("根据personId查询IRIS_DATA表的记录[personId=%1]").arg(personId).toStdString()); + return result; +} + + +QString IrisDataDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + + // INSERT语句 + QString sql = QString("INSERT INTO IRIS_DATA (ID, PERSON_ID, ID_CARD_NO, LEFT_IRIS_CODE1, RIGHT_IRIS_CODE1) VALUES (:id, :personId, :idCardNo, :left1, :right1)"); + + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":personId", object.value("person_id").toString()); + query.bindValue(":idCardNo", object.value("id_card_no").toString()); + query.bindValue(":left1", object.value("left_iris_code1")); + query.bindValue(":right1", object.value("right_iris_code1")); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(); + +// LOG_DEBUG(QString("保存虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool IrisDataDao::edit(QVariantMap newObject, QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // UPDATE语句 + if (!newObject.contains("left_iris_code1") || !newObject.contains("right_iris_code1")){ + return false; + } + QString sql = QString("UPDATE IRIS_DATA SET LEFT_IRIS_CODE1 = :left1, RIGHT_IRIS_CODE1 = :right1 WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":left1", newObject.value("left_iris_code1")); + query.bindValue(":right1", newObject.value("right_iris_code1")); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(); + +// LOG_DEBUG(QString("编辑虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; +} + + +bool IrisDataDao::dele(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + QString sql = QString("DELETE FROM IRIS_DATA WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(); + +// LOG_DEBUG(QString("删除虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; +} diff --git a/dao/IrisDataDao.h b/dao/IrisDataDao.h new file mode 100644 index 0000000..c74dbbd --- /dev/null +++ b/dao/IrisDataDao.h @@ -0,0 +1,25 @@ +#ifndef IRISDATADAO_H +#define IRISDATADAO_H + +#include +#include "BaseDao.h" + +class IrisDataDao : public BaseDao +{ + Q_OBJECT +public: + explicit IrisDataDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + QVariantMap findRecordByPersonId(QString personId); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +signals: + +}; + +#endif // IRISDATADAO_H diff --git a/AppConstants.h b/AppConstants.h new file mode 100644 index 0000000..296c53f --- /dev/null +++ b/AppConstants.h @@ -0,0 +1,28 @@ +#ifndef APPCONSTANTS_H +#define APPCONSTANTS_H + +class AppConstants +{ +public: + enum WidgeFrameName + { + MAIN_PAGE = 0, // 主页面 + PERSON_LIST_FORM = 1, // 人员列表页面 + ADD_PERSON_FORM = 2, // 添加人员页面 + ADD_PERSON_CAPTURE_FACE = 21, // 添加/编辑人员时进行人脸拍图 + ADD_PERSON_CAPTURE_IRIS = 22, // 添加/编辑人员时进行虹膜拍图 + SETTING_FORM = 3, // 设置页面 + RECOGNIZE_RESULT_FORM = 4, // 识别结果界面 + IDENTIFY_FORM = 5, // 识别界面 含识别中 和 识别结果 + LOCKSCREEN_FORM = 6 // 锁屏待机界面 + }; + + enum ApplicationState + { + STATE_WAIT = 0, // 待机 + STATE_WORKING = 1, // 工作状态 + STATE_IDENTIFYING = 2, // 识别中 + }; +}; + +#endif // APPCONSTANTS_H diff --git a/CasicIrisIdentify.pro b/CasicIrisIdentify.pro index 5d7fea6..575ce3d 100644 --- a/CasicIrisIdentify.pro +++ b/CasicIrisIdentify.pro @@ -1,4 +1,4 @@ -QT += core gui +QT += core gui sql network texttospeech greaterThan(QT_MAJOR_VERSION, 4): QT += widgets @@ -15,20 +15,46 @@ # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 -SOURCES += \ - main.cpp \ - IdentifyForm.cpp +include("dao/dao.pri") +include("device/device.pri") +include("utils/utils.pri") -HEADERS += \ - IdentifyForm.h +SOURCES += main.cpp +SOURCES += ProMemory.cpp +SOURCES += MainWindowForm.cpp +SOURCES += IdentifyForm.cpp +SOURCES += LockScreenForm.cpp -FORMS += \ - IdentifyForm.ui +HEADERS += AppConstants.h +HEADERS += ProMemory.h +HEADERS += MainWindowForm.h +HEADERS += IdentifyForm.h +HEADERS += LockScreenForm.h -TRANSLATIONS += \ - CasicIrisIdentify_zh_CN.ts +FORMS += MainWindowForm.ui +FORMS += IdentifyForm.ui +FORMS += LockScreenForm.ui + +RESOURCES += resource.qrc + +DISTFILES += conf/config.ini + +#TRANSLATIONS += CasicIrisIdentify_zh_CN.ts + +#INCLUDEPATH += include/spdlog +#DEPENDPATH += include/spdlog # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target + + +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lopencv_world420 +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lGxIAPICPPEx + +INCLUDEPATH += $$PWD/include/daheng +DEPENDPATH += $$PWD/include/daheng + +INCLUDEPATH += $$PWD/include +DEPENDPATH += $$PWD/include diff --git a/CasicIrisIdentify_zh_CN.ts b/CasicIrisIdentify_zh_CN.ts index 5526fe4..81900df 100644 --- a/CasicIrisIdentify_zh_CN.ts +++ b/CasicIrisIdentify_zh_CN.ts @@ -1,3 +1,12 @@ - + + + IdentifyForm + + + IdentifyForm + + + + diff --git a/IdentifyForm.cpp b/IdentifyForm.cpp index 348a897..ba1f251 100644 --- a/IdentifyForm.cpp +++ b/IdentifyForm.cpp @@ -1,4 +1,4 @@ -#include "IdentifyForm.h" +#include "IdentifyForm.h" #include "ui_IdentifyForm.h" IdentifyForm::IdentifyForm(QWidget *parent) @@ -6,6 +6,12 @@ , ui(new Ui::IdentifyForm) { ui->setupUi(this); + + // 初始化更新界面的定时器 + // 每秒执行一次 + connect(TimeCounterUtil::getInstance().clockCounter, &QTimer::timeout, this, &IdentifyForm::updateDateAndTime); + + TimeCounterUtil::getInstance().clockCounter->start(1000); } IdentifyForm::~IdentifyForm() @@ -13,3 +19,16 @@ delete ui; } +void IdentifyForm::drawIrisImageOnFrame(QImage image) +{ + // 只在识别界面才显示画面 + if (ui->wgtStacked->currentIndex() == 0) { + ui->labelVideo->setPixmap(QPixmap::fromImage(image)); + } +} + + +void IdentifyForm::updateDateAndTime() +{ + ui->labelTime->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd dddd HH:mm:ss")); +} diff --git a/IdentifyForm.h b/IdentifyForm.h index fc857a1..ae1cd22 100644 --- a/IdentifyForm.h +++ b/IdentifyForm.h @@ -1,7 +1,10 @@ -#ifndef IDENTIFYFORM_H +#ifndef IDENTIFYFORM_H #define IDENTIFYFORM_H #include +#include + +#include "utils/UtilInclude.h" QT_BEGIN_NAMESPACE namespace Ui { class IdentifyForm; } @@ -15,7 +18,14 @@ IdentifyForm(QWidget *parent = nullptr); ~IdentifyForm(); +public slots: + void drawIrisImageOnFrame(QImage image); + private: Ui::IdentifyForm *ui; + +private slots: + void updateDateAndTime(); + }; #endif // IDENTIFYFORM_H diff --git a/IdentifyForm.ui b/IdentifyForm.ui index c72a36f..879dc9a 100644 --- a/IdentifyForm.ui +++ b/IdentifyForm.ui @@ -6,13 +6,59 @@ 0 0 - 800 + 600 600 IdentifyForm + + + + 0 + 40 + 600 + 450 + + + + 0 + + + + + + 100 + 10 + 400 + 300 + + + + + + + + + + + + + + 0 + 0 + 600 + 40 + + + + TextLabel + + + Qt::AlignCenter + + diff --git a/LockScreenForm.cpp b/LockScreenForm.cpp new file mode 100644 index 0000000..58dc54b --- /dev/null +++ b/LockScreenForm.cpp @@ -0,0 +1,14 @@ +#include "LockScreenForm.h" +#include "ui_LockScreenForm.h" + +LockScreenForm::LockScreenForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::LockScreenForm) +{ + ui->setupUi(this); +} + +LockScreenForm::~LockScreenForm() +{ + delete ui; +} diff --git a/LockScreenForm.h b/LockScreenForm.h new file mode 100644 index 0000000..b5ded48 --- /dev/null +++ b/LockScreenForm.h @@ -0,0 +1,25 @@ +#ifndef LOCKSCREENFORM_H +#define LOCKSCREENFORM_H + +#include +#include + +#include "utils/UtilInclude.h" + +namespace Ui { +class LockScreenForm; +} + +class LockScreenForm : public QWidget +{ + Q_OBJECT + +public: + explicit LockScreenForm(QWidget *parent = nullptr); + ~LockScreenForm(); + +private: + Ui::LockScreenForm *ui; +}; + +#endif // LOCKSCREENFORM_H diff --git a/LockScreenForm.ui b/LockScreenForm.ui new file mode 100644 index 0000000..7f2a6db --- /dev/null +++ b/LockScreenForm.ui @@ -0,0 +1,45 @@ + + + LockScreenForm + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + 180 + 100 + 54 + 12 + + + + TextLabel + + + + + + 180 + 160 + 54 + 12 + + + + TextLabel + + + + + + diff --git a/MainWindowForm.cpp b/MainWindowForm.cpp new file mode 100644 index 0000000..84f8159 --- /dev/null +++ b/MainWindowForm.cpp @@ -0,0 +1,86 @@ +#include "MainWindowForm.h" +#include "ui_MainWindowForm.h" +#include + +MainWindowForm::MainWindowForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::MainWindowForm) +{ + ui->setupUi(this); + + // 设置窗口透明和大小、位置 + this->setWindowFlags(Qt::FramelessWindowHint); + this->move(1400, 15); + this->resize(SettingConfig::getInstance().WINDOW_WIDTH, SettingConfig::getInstance().WINDOW_HEIGHT); + + // 通过调色板的颜色来设置窗口的统一背景色 + qApp->setPalette(QPalette(QColor(SettingConfig::getInstance().WINDOW_BACKGROUND_COLOR))); + + // 加载css文件设置控件样式 + QFile file(QApplication::applicationDirPath() + "/qss/main.css"); + if (file.open(QFile::ReadOnly)) + { + QString qssStr = QLatin1String(file.readAll()); + this->setStyleSheet(qssStr); + file.close(); + } + + initFormsPtr(); + + // 设置标题文字 + ui->labelTitle->setText(SettingConfig::getInstance().WINDOW_TITLE); + ui->labelCopyright->setText(SettingConfig::getInstance().WINDOW_RIGHTS); + ui->labelVersion->setText(SettingConfig::getInstance().WINDOW_VERSION); + + // 初始化虹膜相机控制 + ProMemory::getInstance().irisCam = new IrisCameraController(this); + ProMemory::getInstance().irisCam->initIrisCamera(); + ProMemory::getInstance().irisCam->openIrisCamera(); + connect(ProMemory::getInstance().irisCam->irisCamHandler, &IrisCameraCapEventHandler::sendIrisFrameToDraw, identifyForm, &IdentifyForm::drawIrisImageOnFrame); + +// LOG_INFO(QString("应用程序启动成功[Application Startup Success]").toStdString()); + qDebug() << "应用程序启动成功[Application Startup Success]"; + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::IDENTIFY_FORM; + ui->wdgtStatced->setCurrentWidget(identifyForm); + + // 开始虹膜相机拍图 + ProMemory::getInstance().irisCam->startCapture(); +} + +MainWindowForm::~MainWindowForm() +{ + delete ui; +} + +void MainWindowForm::lockScreen() +{ + ui->wdgtStatced->setCurrentWidget(lockScreenForm); + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::LOCKSCREEN_FORM; + ProMemory::getInstance().appState = AppConstants::ApplicationState::STATE_WAIT; +} + +void MainWindowForm::keyPressEvent(QKeyEvent *event) +{ + switch (event->key()) { + case Qt::Key_Escape: + QTimer::singleShot(100, qApp, [=](){ + QApplication::quit(); + }); + + default: + QWidget::keyPressEvent(event); + } +} + +void MainWindowForm::initFormsPtr() +{ + // 初始化各个form + lockScreenForm = new LockScreenForm(this); + identifyForm = new IdentifyForm(this); + + // 将form添加到statcked widget中 + ui->wdgtStatced->addWidget(identifyForm); + ui->wdgtStatced->addWidget(lockScreenForm); + + // 绑定按钮函数 +} diff --git a/MainWindowForm.h b/MainWindowForm.h new file mode 100644 index 0000000..7fb2d89 --- /dev/null +++ b/MainWindowForm.h @@ -0,0 +1,38 @@ +#ifndef MAINWINDOWFORM_H +#define MAINWINDOWFORM_H + +#include +#include +#include + +#include "utils/UtilInclude.h" +#include "ProMemory.h" +#include "LockScreenForm.h" +#include "IdentifyForm.h" + +namespace Ui { +class MainWindowForm; +} + +class MainWindowForm : public QWidget +{ + Q_OBJECT + +public: + explicit MainWindowForm(QWidget *parent = nullptr); + ~MainWindowForm(); + +public slots: + void lockScreen(); + +private: + Ui::MainWindowForm *ui; + LockScreenForm * lockScreenForm; + IdentifyForm * identifyForm; + + void keyPressEvent(QKeyEvent *event); + + void initFormsPtr(); +}; + +#endif // MAINWINDOWFORM_H diff --git a/MainWindowForm.ui b/MainWindowForm.ui new file mode 100644 index 0000000..e793ebf --- /dev/null +++ b/MainWindowForm.ui @@ -0,0 +1,85 @@ + + + MainWindowForm + + + + 0 + 0 + 600 + 1024 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + 0 + 0 + 600 + 84 + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + + + + TextLabel + + + Qt::AlignBottom|Qt::AlignHCenter + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + diff --git a/ProMemory.cpp b/ProMemory.cpp new file mode 100644 index 0000000..19e7403 --- /dev/null +++ b/ProMemory.cpp @@ -0,0 +1,84 @@ +#include "ProMemory.h" + +ProMemory::ProMemory() +{ + +} + +ProMemory::~ProMemory() +{ + +} + +/* +void ProMemory::pushCasicIris(CasicIrisInfo irisInfo) +{ + QMutex mutex; + mutex.lock(); + if (this->irisQueue.size() > 30) + { + QStack empty; + std::swap(empty, irisQueue); + } + + irisQueue.push(irisInfo); + mutex.unlock(); +} +CasicIrisInfo ProMemory::popCasicIris() +{ + CasicIrisInfo result; + + QMutex mutex; + mutex.lock(); + if (this->irisQueue.size() > 0) + { + result = irisQueue.pop(); + } + + mutex.unlock(); + + return result; +} +*/ +int ProMemory::getIrisQueueSize() +{ + int size = 0; + + QMutex mutex; + mutex.lock(); + +// size = this->irisQueue.size(); + + mutex.unlock(); + + return size; +} +bool ProMemory::isIrisQueueEmpty() +{ + bool empty = true; + + QMutex mutex; + mutex.lock(); + +// empty = this->irisQueue.isEmpty(); + + mutex.unlock(); + + return empty; +} +void ProMemory::clearIrisQueue() +{ + QMutex mutex; + mutex.lock(); + +// QStack empty; +// std::swap(empty, irisQueue); + + mutex.unlock(); +} + + +void ProMemory::initIrisFeatures(QString personId) +{ +// irisRegistPro->sendDataToExract(QByteArray(QString("[-u]").append(personId).toLocal8Bit())); +} diff --git a/ProMemory.h b/ProMemory.h new file mode 100644 index 0000000..2ecd653 --- /dev/null +++ b/ProMemory.h @@ -0,0 +1,52 @@ +#ifndef PROMEMORY_H +#define PROMEMORY_H + +#include +#include + +#include "AppConstants.h" +//#include "casic/iris/CasicIrisInfo.h" +#include "dao/IrisDataDao.h" + +#include "device/IrisCameraController.h" +//#include "device/iris/IrisRegistProcess.h" +//#include "device/iris/IrisRecogProcess.h" + +class IrisCameraController; +class IrisRegistProcess; +class IrisRecogProcess; + +class ProMemory +{ +public: + ~ProMemory(); + ProMemory(const ProMemory&)=delete; + ProMemory& operator=(const ProMemory&)=delete; + + static ProMemory& getInstance() { + static ProMemory instance; + return instance; + } + +// void pushCasicIris(CasicIrisInfo irisInfo); +// CasicIrisInfo popCasicIris(); + int getIrisQueueSize(); + bool isIrisQueueEmpty(); + void clearIrisQueue(); + + volatile int widgeFrame = 0; // 当前显示的界面 + volatile int appState = 0; // 当前程序所处的状态 + + void initIrisFeatures(QString personId = ""); // 初始化虹膜特征值集合 + + IrisCameraController * irisCam; + IrisRecogProcess * irisRecogPro; + +private: + ProMemory(); + +// QStack irisQueue; // 虹膜信息队列 + QVector irisFeatures; // 虹膜特征值集合 +}; + +#endif // PROMEMORY_H diff --git a/conf/config.ini b/conf/config.ini new file mode 100644 index 0000000..66e46ad --- /dev/null +++ b/conf/config.ini @@ -0,0 +1,67 @@ +[recognize] +#最大允许识别时间(ms) +maxMatchTime=10000 +#识别成功界面停留时间(ms) +successTipsLast=5000 +#识别失败界面停留时间(ms) +failureTipsLast=3000 +#人脸识别最大尝试次数 +maxFaceTryCount=20 +#持续没找到人脸的最大次数 +maxFaceNotFoundCount=500 +#注册时最小人脸 +minFaceRegist=240 +#识别时最小人脸 +minFaceRecog=100 + +#虹膜识别最大尝试次数 +maxIrisTryCount=10 +#虹膜识别持续没有找到眼的最大次数 +maxEyeNotFoundCount=50 + +#识别方式[1=人脸;2=虹膜;3=双认证;4=任意] +recogType=4 + +[window] +#界面窗口宽(px) +width=600 +#界面窗口高(px) +height=1024 +#统一背景色 +backgroundColor="#FFFFFF" +#标题 +title="虹膜识别终端" + +[work] +#工作状态检测时最小人脸范围 +minFaceSize=160 +#人脸范围最小横坐标 +minFacePosX=320 +#人脸范围最大横坐标 +maxFacePosX=960 +#人脸范围最小纵坐标 +minFacePosY=180 +#人脸范围最大纵坐标 +maxFacePosY=540 +#人脸太近阈值 +faceCloseSize=360 +#人脸太远阈值 +faceFarSize=480 + +[camera] +#虹膜相机取一幅画面的时间间隔(ms) +irisFrameInterval=100 +#虹膜相机拍摄宽度 +irisFrameWidth=1440 +#虹膜相机拍摄高度 +irisFrameHeight=1080 +#虹膜图像高度 +irisWidth=640 +#虹膜图像高度 +irisHeight=480 + +[log] +#日志文件位置 +logFile="d://irisLogs//casic_log.txt" +#日志级别 +logLevel="trace" diff --git a/dao/BaseDao.cpp b/dao/BaseDao.cpp new file mode 100644 index 0000000..f51c144 --- /dev/null +++ b/dao/BaseDao.cpp @@ -0,0 +1,12 @@ +#include "BaseDao.h" +#include "dao/util/ConnectionManager.h" + +BaseDao::BaseDao(QObject *parent) : QObject(parent) +{ + +} + +BaseDao::~BaseDao() +{ + +} diff --git a/dao/BaseDao.h b/dao/BaseDao.h new file mode 100644 index 0000000..1693c88 --- /dev/null +++ b/dao/BaseDao.h @@ -0,0 +1,32 @@ +#ifndef BASEDAO_H +#define BASEDAO_H + +#include +#include +#include +#include + +#include "dao/util/ConnectionManager.h" +#include "utils/UtilInclude.h" + +class BaseDao : public QObject +{ + Q_OBJECT +public: + explicit BaseDao(QObject *parent = nullptr); + ~BaseDao(); + + virtual QVector findAllRecord() = 0; + virtual QVariantMap findRecordById(QString id) = 0; + + virtual QString save(QVariantMap object) = 0; + virtual bool edit(QVariantMap newObject, QString id) = 0; + virtual bool dele(QString id) = 0; + +private: + +signals: + +}; + +#endif // BASEDAO_H diff --git a/dao/IrisDataDao.cpp b/dao/IrisDataDao.cpp new file mode 100644 index 0000000..37a0ed6 --- /dev/null +++ b/dao/IrisDataDao.cpp @@ -0,0 +1,204 @@ +#include "IrisDataDao.h" + +IrisDataDao::IrisDataDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector IrisDataDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM IRIS_DATA"; + query.prepare(sql); + + // 执行查询 + query.exec(); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + item.insert("id", query.value("id").toString()); + item.insert("person_id", query.value("person_id").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("left_iris_code1", query.value("left_iris_code1")); + item.insert("left_iris_code2", query.value("left_iris_code2")); + item.insert("left_iris_code3", query.value("left_iris_code3")); + item.insert("right_iris_code1", query.value("right_iris_code1")); + item.insert("right_iris_code2", query.value("right_iris_code2")); + item.insert("right_iris_code3", query.value("right_iris_code3")); + + result.append(item); + } + +// LOG_DEBUG(QString("查询IRIS_DATA表的所有记录[结果数:%1]").arg(result.size()).toStdString()); + return result; +} + +QVariantMap IrisDataDao::findRecordById(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM IRIS_DATA WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + // 获取结果 + if (query.next()) + { + result.insert("id", query.value("id").toString()); + result.insert("person_id", query.value("person_id").toLongLong()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("left_iris_code1", query.value("left_iris_code1")); + result.insert("left_iris_code2", query.value("left_iris_code2")); + result.insert("left_iris_code3", query.value("left_iris_code3")); + result.insert("right_iris_code1", query.value("right_iris_code1")); + result.insert("right_iris_code2", query.value("right_iris_code2")); + result.insert("right_iris_code3", query.value("right_iris_code3")); + } + +// LOG_DEBUG(QString("根据id查询IRIS_DATA表的记录[id=%1]").arg(id).toStdString()); + return result; +} + +QVariantMap IrisDataDao::findRecordByPersonId(QString personId) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM IRIS_DATA WHERE PERSON_ID = :personId"); + query.prepare(sql); + query.bindValue(":personId", personId); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + if (query.next()) + { + result.insert("id", query.value("id").toString()); + result.insert("person_id", query.value("person_id").toLongLong()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("left_iris_code1", query.value("left_iris_code1")); + result.insert("left_iris_code2", query.value("left_iris_code2")); + result.insert("left_iris_code3", query.value("left_iris_code3")); + result.insert("right_iris_code1", query.value("right_iris_code1")); + result.insert("right_iris_code2", query.value("right_iris_code2")); + result.insert("right_iris_code3", query.value("right_iris_code3")); + } + +// LOG_DEBUG(QString("根据personId查询IRIS_DATA表的记录[personId=%1]").arg(personId).toStdString()); + return result; +} + + +QString IrisDataDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + + // INSERT语句 + QString sql = QString("INSERT INTO IRIS_DATA (ID, PERSON_ID, ID_CARD_NO, LEFT_IRIS_CODE1, RIGHT_IRIS_CODE1) VALUES (:id, :personId, :idCardNo, :left1, :right1)"); + + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":personId", object.value("person_id").toString()); + query.bindValue(":idCardNo", object.value("id_card_no").toString()); + query.bindValue(":left1", object.value("left_iris_code1")); + query.bindValue(":right1", object.value("right_iris_code1")); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(); + +// LOG_DEBUG(QString("保存虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool IrisDataDao::edit(QVariantMap newObject, QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // UPDATE语句 + if (!newObject.contains("left_iris_code1") || !newObject.contains("right_iris_code1")){ + return false; + } + QString sql = QString("UPDATE IRIS_DATA SET LEFT_IRIS_CODE1 = :left1, RIGHT_IRIS_CODE1 = :right1 WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":left1", newObject.value("left_iris_code1")); + query.bindValue(":right1", newObject.value("right_iris_code1")); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(); + +// LOG_DEBUG(QString("编辑虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; +} + + +bool IrisDataDao::dele(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + QString sql = QString("DELETE FROM IRIS_DATA WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(); + +// LOG_DEBUG(QString("删除虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; +} diff --git a/dao/IrisDataDao.h b/dao/IrisDataDao.h new file mode 100644 index 0000000..c74dbbd --- /dev/null +++ b/dao/IrisDataDao.h @@ -0,0 +1,25 @@ +#ifndef IRISDATADAO_H +#define IRISDATADAO_H + +#include +#include "BaseDao.h" + +class IrisDataDao : public BaseDao +{ + Q_OBJECT +public: + explicit IrisDataDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + QVariantMap findRecordByPersonId(QString personId); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +signals: + +}; + +#endif // IRISDATADAO_H diff --git a/dao/RecognitionRecordsDao.cpp b/dao/RecognitionRecordsDao.cpp new file mode 100644 index 0000000..40db453 --- /dev/null +++ b/dao/RecognitionRecordsDao.cpp @@ -0,0 +1,100 @@ +#include "RecognitionRecordsDao.h" + +RecognitionRecordsDao::RecognitionRecordsDao(QObject *parent) : BaseDao(parent) +{ + +} + + +QVector RecognitionRecordsDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM RECOGNITION_RECORDS"; + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + item.insert("id", query.value("id").toLongLong()); + result.append(item); + } + +// LOG_DEBUG(QString("查询RECOGNITION_RECORDS表的所有记录[记录数:%1]").arg(result.size()).toStdString()); + return result; +} + +QVariantMap RecognitionRecordsDao::findRecordById(QString id) +{ + QVariantMap item; + return item; +} + +QString RecognitionRecordsDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + + // INSERT语句 + QString sql = QString("INSERT INTO RECOGNITION_RECORDS (ID, PERSON_ID, DATETIME, REC_TYPE, DEV_CODE, DOOR_CODE, INOUT_TYPE) " + "VALUES (:id, :personId, :datetime, :recType, :devCode, :doorCode, :inoutType)"); + + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":personId", object.value("person_id").toString()); + query.bindValue(":datetime", object.value("date_time").toString()); + query.bindValue(":recType", object.value("rec_type").toString()); + query.bindValue(":devCode", object.value("dev_code").toString()); + query.bindValue(":doorCode", object.value("door_code").toString()); + query.bindValue(":inoutType", object.value("inout_type").toString()); + +// LOG_DEBUG(sql.toStdString()); + + // 插入识别的log日志 + QString logStr = QString("INSERT INTO RECOGNITION_LOGS (ID, LOG_INFO) VALUES (:id, :logInfo)"); + + QSqlQuery logQuery(ConnectionManager::getInstance()->getConnection()); + logQuery.prepare(logStr); + logQuery.bindValue(":id", id); + logQuery.bindValue(":logInfo", object.value("debug_info").toString()); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(); + logQuery.exec(); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool RecognitionRecordsDao::edit(QVariantMap newObject, QString id) +{ + return false; +} + +bool RecognitionRecordsDao::dele(QString id) +{ + return false; +} diff --git a/AppConstants.h b/AppConstants.h new file mode 100644 index 0000000..296c53f --- /dev/null +++ b/AppConstants.h @@ -0,0 +1,28 @@ +#ifndef APPCONSTANTS_H +#define APPCONSTANTS_H + +class AppConstants +{ +public: + enum WidgeFrameName + { + MAIN_PAGE = 0, // 主页面 + PERSON_LIST_FORM = 1, // 人员列表页面 + ADD_PERSON_FORM = 2, // 添加人员页面 + ADD_PERSON_CAPTURE_FACE = 21, // 添加/编辑人员时进行人脸拍图 + ADD_PERSON_CAPTURE_IRIS = 22, // 添加/编辑人员时进行虹膜拍图 + SETTING_FORM = 3, // 设置页面 + RECOGNIZE_RESULT_FORM = 4, // 识别结果界面 + IDENTIFY_FORM = 5, // 识别界面 含识别中 和 识别结果 + LOCKSCREEN_FORM = 6 // 锁屏待机界面 + }; + + enum ApplicationState + { + STATE_WAIT = 0, // 待机 + STATE_WORKING = 1, // 工作状态 + STATE_IDENTIFYING = 2, // 识别中 + }; +}; + +#endif // APPCONSTANTS_H diff --git a/CasicIrisIdentify.pro b/CasicIrisIdentify.pro index 5d7fea6..575ce3d 100644 --- a/CasicIrisIdentify.pro +++ b/CasicIrisIdentify.pro @@ -1,4 +1,4 @@ -QT += core gui +QT += core gui sql network texttospeech greaterThan(QT_MAJOR_VERSION, 4): QT += widgets @@ -15,20 +15,46 @@ # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 -SOURCES += \ - main.cpp \ - IdentifyForm.cpp +include("dao/dao.pri") +include("device/device.pri") +include("utils/utils.pri") -HEADERS += \ - IdentifyForm.h +SOURCES += main.cpp +SOURCES += ProMemory.cpp +SOURCES += MainWindowForm.cpp +SOURCES += IdentifyForm.cpp +SOURCES += LockScreenForm.cpp -FORMS += \ - IdentifyForm.ui +HEADERS += AppConstants.h +HEADERS += ProMemory.h +HEADERS += MainWindowForm.h +HEADERS += IdentifyForm.h +HEADERS += LockScreenForm.h -TRANSLATIONS += \ - CasicIrisIdentify_zh_CN.ts +FORMS += MainWindowForm.ui +FORMS += IdentifyForm.ui +FORMS += LockScreenForm.ui + +RESOURCES += resource.qrc + +DISTFILES += conf/config.ini + +#TRANSLATIONS += CasicIrisIdentify_zh_CN.ts + +#INCLUDEPATH += include/spdlog +#DEPENDPATH += include/spdlog # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target + + +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lopencv_world420 +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lGxIAPICPPEx + +INCLUDEPATH += $$PWD/include/daheng +DEPENDPATH += $$PWD/include/daheng + +INCLUDEPATH += $$PWD/include +DEPENDPATH += $$PWD/include diff --git a/CasicIrisIdentify_zh_CN.ts b/CasicIrisIdentify_zh_CN.ts index 5526fe4..81900df 100644 --- a/CasicIrisIdentify_zh_CN.ts +++ b/CasicIrisIdentify_zh_CN.ts @@ -1,3 +1,12 @@ - + + + IdentifyForm + + + IdentifyForm + + + + diff --git a/IdentifyForm.cpp b/IdentifyForm.cpp index 348a897..ba1f251 100644 --- a/IdentifyForm.cpp +++ b/IdentifyForm.cpp @@ -1,4 +1,4 @@ -#include "IdentifyForm.h" +#include "IdentifyForm.h" #include "ui_IdentifyForm.h" IdentifyForm::IdentifyForm(QWidget *parent) @@ -6,6 +6,12 @@ , ui(new Ui::IdentifyForm) { ui->setupUi(this); + + // 初始化更新界面的定时器 + // 每秒执行一次 + connect(TimeCounterUtil::getInstance().clockCounter, &QTimer::timeout, this, &IdentifyForm::updateDateAndTime); + + TimeCounterUtil::getInstance().clockCounter->start(1000); } IdentifyForm::~IdentifyForm() @@ -13,3 +19,16 @@ delete ui; } +void IdentifyForm::drawIrisImageOnFrame(QImage image) +{ + // 只在识别界面才显示画面 + if (ui->wgtStacked->currentIndex() == 0) { + ui->labelVideo->setPixmap(QPixmap::fromImage(image)); + } +} + + +void IdentifyForm::updateDateAndTime() +{ + ui->labelTime->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd dddd HH:mm:ss")); +} diff --git a/IdentifyForm.h b/IdentifyForm.h index fc857a1..ae1cd22 100644 --- a/IdentifyForm.h +++ b/IdentifyForm.h @@ -1,7 +1,10 @@ -#ifndef IDENTIFYFORM_H +#ifndef IDENTIFYFORM_H #define IDENTIFYFORM_H #include +#include + +#include "utils/UtilInclude.h" QT_BEGIN_NAMESPACE namespace Ui { class IdentifyForm; } @@ -15,7 +18,14 @@ IdentifyForm(QWidget *parent = nullptr); ~IdentifyForm(); +public slots: + void drawIrisImageOnFrame(QImage image); + private: Ui::IdentifyForm *ui; + +private slots: + void updateDateAndTime(); + }; #endif // IDENTIFYFORM_H diff --git a/IdentifyForm.ui b/IdentifyForm.ui index c72a36f..879dc9a 100644 --- a/IdentifyForm.ui +++ b/IdentifyForm.ui @@ -6,13 +6,59 @@ 0 0 - 800 + 600 600 IdentifyForm + + + + 0 + 40 + 600 + 450 + + + + 0 + + + + + + 100 + 10 + 400 + 300 + + + + + + + + + + + + + + 0 + 0 + 600 + 40 + + + + TextLabel + + + Qt::AlignCenter + + diff --git a/LockScreenForm.cpp b/LockScreenForm.cpp new file mode 100644 index 0000000..58dc54b --- /dev/null +++ b/LockScreenForm.cpp @@ -0,0 +1,14 @@ +#include "LockScreenForm.h" +#include "ui_LockScreenForm.h" + +LockScreenForm::LockScreenForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::LockScreenForm) +{ + ui->setupUi(this); +} + +LockScreenForm::~LockScreenForm() +{ + delete ui; +} diff --git a/LockScreenForm.h b/LockScreenForm.h new file mode 100644 index 0000000..b5ded48 --- /dev/null +++ b/LockScreenForm.h @@ -0,0 +1,25 @@ +#ifndef LOCKSCREENFORM_H +#define LOCKSCREENFORM_H + +#include +#include + +#include "utils/UtilInclude.h" + +namespace Ui { +class LockScreenForm; +} + +class LockScreenForm : public QWidget +{ + Q_OBJECT + +public: + explicit LockScreenForm(QWidget *parent = nullptr); + ~LockScreenForm(); + +private: + Ui::LockScreenForm *ui; +}; + +#endif // LOCKSCREENFORM_H diff --git a/LockScreenForm.ui b/LockScreenForm.ui new file mode 100644 index 0000000..7f2a6db --- /dev/null +++ b/LockScreenForm.ui @@ -0,0 +1,45 @@ + + + LockScreenForm + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + 180 + 100 + 54 + 12 + + + + TextLabel + + + + + + 180 + 160 + 54 + 12 + + + + TextLabel + + + + + + diff --git a/MainWindowForm.cpp b/MainWindowForm.cpp new file mode 100644 index 0000000..84f8159 --- /dev/null +++ b/MainWindowForm.cpp @@ -0,0 +1,86 @@ +#include "MainWindowForm.h" +#include "ui_MainWindowForm.h" +#include + +MainWindowForm::MainWindowForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::MainWindowForm) +{ + ui->setupUi(this); + + // 设置窗口透明和大小、位置 + this->setWindowFlags(Qt::FramelessWindowHint); + this->move(1400, 15); + this->resize(SettingConfig::getInstance().WINDOW_WIDTH, SettingConfig::getInstance().WINDOW_HEIGHT); + + // 通过调色板的颜色来设置窗口的统一背景色 + qApp->setPalette(QPalette(QColor(SettingConfig::getInstance().WINDOW_BACKGROUND_COLOR))); + + // 加载css文件设置控件样式 + QFile file(QApplication::applicationDirPath() + "/qss/main.css"); + if (file.open(QFile::ReadOnly)) + { + QString qssStr = QLatin1String(file.readAll()); + this->setStyleSheet(qssStr); + file.close(); + } + + initFormsPtr(); + + // 设置标题文字 + ui->labelTitle->setText(SettingConfig::getInstance().WINDOW_TITLE); + ui->labelCopyright->setText(SettingConfig::getInstance().WINDOW_RIGHTS); + ui->labelVersion->setText(SettingConfig::getInstance().WINDOW_VERSION); + + // 初始化虹膜相机控制 + ProMemory::getInstance().irisCam = new IrisCameraController(this); + ProMemory::getInstance().irisCam->initIrisCamera(); + ProMemory::getInstance().irisCam->openIrisCamera(); + connect(ProMemory::getInstance().irisCam->irisCamHandler, &IrisCameraCapEventHandler::sendIrisFrameToDraw, identifyForm, &IdentifyForm::drawIrisImageOnFrame); + +// LOG_INFO(QString("应用程序启动成功[Application Startup Success]").toStdString()); + qDebug() << "应用程序启动成功[Application Startup Success]"; + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::IDENTIFY_FORM; + ui->wdgtStatced->setCurrentWidget(identifyForm); + + // 开始虹膜相机拍图 + ProMemory::getInstance().irisCam->startCapture(); +} + +MainWindowForm::~MainWindowForm() +{ + delete ui; +} + +void MainWindowForm::lockScreen() +{ + ui->wdgtStatced->setCurrentWidget(lockScreenForm); + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::LOCKSCREEN_FORM; + ProMemory::getInstance().appState = AppConstants::ApplicationState::STATE_WAIT; +} + +void MainWindowForm::keyPressEvent(QKeyEvent *event) +{ + switch (event->key()) { + case Qt::Key_Escape: + QTimer::singleShot(100, qApp, [=](){ + QApplication::quit(); + }); + + default: + QWidget::keyPressEvent(event); + } +} + +void MainWindowForm::initFormsPtr() +{ + // 初始化各个form + lockScreenForm = new LockScreenForm(this); + identifyForm = new IdentifyForm(this); + + // 将form添加到statcked widget中 + ui->wdgtStatced->addWidget(identifyForm); + ui->wdgtStatced->addWidget(lockScreenForm); + + // 绑定按钮函数 +} diff --git a/MainWindowForm.h b/MainWindowForm.h new file mode 100644 index 0000000..7fb2d89 --- /dev/null +++ b/MainWindowForm.h @@ -0,0 +1,38 @@ +#ifndef MAINWINDOWFORM_H +#define MAINWINDOWFORM_H + +#include +#include +#include + +#include "utils/UtilInclude.h" +#include "ProMemory.h" +#include "LockScreenForm.h" +#include "IdentifyForm.h" + +namespace Ui { +class MainWindowForm; +} + +class MainWindowForm : public QWidget +{ + Q_OBJECT + +public: + explicit MainWindowForm(QWidget *parent = nullptr); + ~MainWindowForm(); + +public slots: + void lockScreen(); + +private: + Ui::MainWindowForm *ui; + LockScreenForm * lockScreenForm; + IdentifyForm * identifyForm; + + void keyPressEvent(QKeyEvent *event); + + void initFormsPtr(); +}; + +#endif // MAINWINDOWFORM_H diff --git a/MainWindowForm.ui b/MainWindowForm.ui new file mode 100644 index 0000000..e793ebf --- /dev/null +++ b/MainWindowForm.ui @@ -0,0 +1,85 @@ + + + MainWindowForm + + + + 0 + 0 + 600 + 1024 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + 0 + 0 + 600 + 84 + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + + + + TextLabel + + + Qt::AlignBottom|Qt::AlignHCenter + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + diff --git a/ProMemory.cpp b/ProMemory.cpp new file mode 100644 index 0000000..19e7403 --- /dev/null +++ b/ProMemory.cpp @@ -0,0 +1,84 @@ +#include "ProMemory.h" + +ProMemory::ProMemory() +{ + +} + +ProMemory::~ProMemory() +{ + +} + +/* +void ProMemory::pushCasicIris(CasicIrisInfo irisInfo) +{ + QMutex mutex; + mutex.lock(); + if (this->irisQueue.size() > 30) + { + QStack empty; + std::swap(empty, irisQueue); + } + + irisQueue.push(irisInfo); + mutex.unlock(); +} +CasicIrisInfo ProMemory::popCasicIris() +{ + CasicIrisInfo result; + + QMutex mutex; + mutex.lock(); + if (this->irisQueue.size() > 0) + { + result = irisQueue.pop(); + } + + mutex.unlock(); + + return result; +} +*/ +int ProMemory::getIrisQueueSize() +{ + int size = 0; + + QMutex mutex; + mutex.lock(); + +// size = this->irisQueue.size(); + + mutex.unlock(); + + return size; +} +bool ProMemory::isIrisQueueEmpty() +{ + bool empty = true; + + QMutex mutex; + mutex.lock(); + +// empty = this->irisQueue.isEmpty(); + + mutex.unlock(); + + return empty; +} +void ProMemory::clearIrisQueue() +{ + QMutex mutex; + mutex.lock(); + +// QStack empty; +// std::swap(empty, irisQueue); + + mutex.unlock(); +} + + +void ProMemory::initIrisFeatures(QString personId) +{ +// irisRegistPro->sendDataToExract(QByteArray(QString("[-u]").append(personId).toLocal8Bit())); +} diff --git a/ProMemory.h b/ProMemory.h new file mode 100644 index 0000000..2ecd653 --- /dev/null +++ b/ProMemory.h @@ -0,0 +1,52 @@ +#ifndef PROMEMORY_H +#define PROMEMORY_H + +#include +#include + +#include "AppConstants.h" +//#include "casic/iris/CasicIrisInfo.h" +#include "dao/IrisDataDao.h" + +#include "device/IrisCameraController.h" +//#include "device/iris/IrisRegistProcess.h" +//#include "device/iris/IrisRecogProcess.h" + +class IrisCameraController; +class IrisRegistProcess; +class IrisRecogProcess; + +class ProMemory +{ +public: + ~ProMemory(); + ProMemory(const ProMemory&)=delete; + ProMemory& operator=(const ProMemory&)=delete; + + static ProMemory& getInstance() { + static ProMemory instance; + return instance; + } + +// void pushCasicIris(CasicIrisInfo irisInfo); +// CasicIrisInfo popCasicIris(); + int getIrisQueueSize(); + bool isIrisQueueEmpty(); + void clearIrisQueue(); + + volatile int widgeFrame = 0; // 当前显示的界面 + volatile int appState = 0; // 当前程序所处的状态 + + void initIrisFeatures(QString personId = ""); // 初始化虹膜特征值集合 + + IrisCameraController * irisCam; + IrisRecogProcess * irisRecogPro; + +private: + ProMemory(); + +// QStack irisQueue; // 虹膜信息队列 + QVector irisFeatures; // 虹膜特征值集合 +}; + +#endif // PROMEMORY_H diff --git a/conf/config.ini b/conf/config.ini new file mode 100644 index 0000000..66e46ad --- /dev/null +++ b/conf/config.ini @@ -0,0 +1,67 @@ +[recognize] +#最大允许识别时间(ms) +maxMatchTime=10000 +#识别成功界面停留时间(ms) +successTipsLast=5000 +#识别失败界面停留时间(ms) +failureTipsLast=3000 +#人脸识别最大尝试次数 +maxFaceTryCount=20 +#持续没找到人脸的最大次数 +maxFaceNotFoundCount=500 +#注册时最小人脸 +minFaceRegist=240 +#识别时最小人脸 +minFaceRecog=100 + +#虹膜识别最大尝试次数 +maxIrisTryCount=10 +#虹膜识别持续没有找到眼的最大次数 +maxEyeNotFoundCount=50 + +#识别方式[1=人脸;2=虹膜;3=双认证;4=任意] +recogType=4 + +[window] +#界面窗口宽(px) +width=600 +#界面窗口高(px) +height=1024 +#统一背景色 +backgroundColor="#FFFFFF" +#标题 +title="虹膜识别终端" + +[work] +#工作状态检测时最小人脸范围 +minFaceSize=160 +#人脸范围最小横坐标 +minFacePosX=320 +#人脸范围最大横坐标 +maxFacePosX=960 +#人脸范围最小纵坐标 +minFacePosY=180 +#人脸范围最大纵坐标 +maxFacePosY=540 +#人脸太近阈值 +faceCloseSize=360 +#人脸太远阈值 +faceFarSize=480 + +[camera] +#虹膜相机取一幅画面的时间间隔(ms) +irisFrameInterval=100 +#虹膜相机拍摄宽度 +irisFrameWidth=1440 +#虹膜相机拍摄高度 +irisFrameHeight=1080 +#虹膜图像高度 +irisWidth=640 +#虹膜图像高度 +irisHeight=480 + +[log] +#日志文件位置 +logFile="d://irisLogs//casic_log.txt" +#日志级别 +logLevel="trace" diff --git a/dao/BaseDao.cpp b/dao/BaseDao.cpp new file mode 100644 index 0000000..f51c144 --- /dev/null +++ b/dao/BaseDao.cpp @@ -0,0 +1,12 @@ +#include "BaseDao.h" +#include "dao/util/ConnectionManager.h" + +BaseDao::BaseDao(QObject *parent) : QObject(parent) +{ + +} + +BaseDao::~BaseDao() +{ + +} diff --git a/dao/BaseDao.h b/dao/BaseDao.h new file mode 100644 index 0000000..1693c88 --- /dev/null +++ b/dao/BaseDao.h @@ -0,0 +1,32 @@ +#ifndef BASEDAO_H +#define BASEDAO_H + +#include +#include +#include +#include + +#include "dao/util/ConnectionManager.h" +#include "utils/UtilInclude.h" + +class BaseDao : public QObject +{ + Q_OBJECT +public: + explicit BaseDao(QObject *parent = nullptr); + ~BaseDao(); + + virtual QVector findAllRecord() = 0; + virtual QVariantMap findRecordById(QString id) = 0; + + virtual QString save(QVariantMap object) = 0; + virtual bool edit(QVariantMap newObject, QString id) = 0; + virtual bool dele(QString id) = 0; + +private: + +signals: + +}; + +#endif // BASEDAO_H diff --git a/dao/IrisDataDao.cpp b/dao/IrisDataDao.cpp new file mode 100644 index 0000000..37a0ed6 --- /dev/null +++ b/dao/IrisDataDao.cpp @@ -0,0 +1,204 @@ +#include "IrisDataDao.h" + +IrisDataDao::IrisDataDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector IrisDataDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM IRIS_DATA"; + query.prepare(sql); + + // 执行查询 + query.exec(); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + item.insert("id", query.value("id").toString()); + item.insert("person_id", query.value("person_id").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("left_iris_code1", query.value("left_iris_code1")); + item.insert("left_iris_code2", query.value("left_iris_code2")); + item.insert("left_iris_code3", query.value("left_iris_code3")); + item.insert("right_iris_code1", query.value("right_iris_code1")); + item.insert("right_iris_code2", query.value("right_iris_code2")); + item.insert("right_iris_code3", query.value("right_iris_code3")); + + result.append(item); + } + +// LOG_DEBUG(QString("查询IRIS_DATA表的所有记录[结果数:%1]").arg(result.size()).toStdString()); + return result; +} + +QVariantMap IrisDataDao::findRecordById(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM IRIS_DATA WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + // 获取结果 + if (query.next()) + { + result.insert("id", query.value("id").toString()); + result.insert("person_id", query.value("person_id").toLongLong()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("left_iris_code1", query.value("left_iris_code1")); + result.insert("left_iris_code2", query.value("left_iris_code2")); + result.insert("left_iris_code3", query.value("left_iris_code3")); + result.insert("right_iris_code1", query.value("right_iris_code1")); + result.insert("right_iris_code2", query.value("right_iris_code2")); + result.insert("right_iris_code3", query.value("right_iris_code3")); + } + +// LOG_DEBUG(QString("根据id查询IRIS_DATA表的记录[id=%1]").arg(id).toStdString()); + return result; +} + +QVariantMap IrisDataDao::findRecordByPersonId(QString personId) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM IRIS_DATA WHERE PERSON_ID = :personId"); + query.prepare(sql); + query.bindValue(":personId", personId); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + if (query.next()) + { + result.insert("id", query.value("id").toString()); + result.insert("person_id", query.value("person_id").toLongLong()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("left_iris_code1", query.value("left_iris_code1")); + result.insert("left_iris_code2", query.value("left_iris_code2")); + result.insert("left_iris_code3", query.value("left_iris_code3")); + result.insert("right_iris_code1", query.value("right_iris_code1")); + result.insert("right_iris_code2", query.value("right_iris_code2")); + result.insert("right_iris_code3", query.value("right_iris_code3")); + } + +// LOG_DEBUG(QString("根据personId查询IRIS_DATA表的记录[personId=%1]").arg(personId).toStdString()); + return result; +} + + +QString IrisDataDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + + // INSERT语句 + QString sql = QString("INSERT INTO IRIS_DATA (ID, PERSON_ID, ID_CARD_NO, LEFT_IRIS_CODE1, RIGHT_IRIS_CODE1) VALUES (:id, :personId, :idCardNo, :left1, :right1)"); + + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":personId", object.value("person_id").toString()); + query.bindValue(":idCardNo", object.value("id_card_no").toString()); + query.bindValue(":left1", object.value("left_iris_code1")); + query.bindValue(":right1", object.value("right_iris_code1")); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(); + +// LOG_DEBUG(QString("保存虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool IrisDataDao::edit(QVariantMap newObject, QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // UPDATE语句 + if (!newObject.contains("left_iris_code1") || !newObject.contains("right_iris_code1")){ + return false; + } + QString sql = QString("UPDATE IRIS_DATA SET LEFT_IRIS_CODE1 = :left1, RIGHT_IRIS_CODE1 = :right1 WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":left1", newObject.value("left_iris_code1")); + query.bindValue(":right1", newObject.value("right_iris_code1")); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(); + +// LOG_DEBUG(QString("编辑虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; +} + + +bool IrisDataDao::dele(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + QString sql = QString("DELETE FROM IRIS_DATA WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(); + +// LOG_DEBUG(QString("删除虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; +} diff --git a/dao/IrisDataDao.h b/dao/IrisDataDao.h new file mode 100644 index 0000000..c74dbbd --- /dev/null +++ b/dao/IrisDataDao.h @@ -0,0 +1,25 @@ +#ifndef IRISDATADAO_H +#define IRISDATADAO_H + +#include +#include "BaseDao.h" + +class IrisDataDao : public BaseDao +{ + Q_OBJECT +public: + explicit IrisDataDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + QVariantMap findRecordByPersonId(QString personId); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +signals: + +}; + +#endif // IRISDATADAO_H diff --git a/dao/RecognitionRecordsDao.cpp b/dao/RecognitionRecordsDao.cpp new file mode 100644 index 0000000..40db453 --- /dev/null +++ b/dao/RecognitionRecordsDao.cpp @@ -0,0 +1,100 @@ +#include "RecognitionRecordsDao.h" + +RecognitionRecordsDao::RecognitionRecordsDao(QObject *parent) : BaseDao(parent) +{ + +} + + +QVector RecognitionRecordsDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM RECOGNITION_RECORDS"; + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + item.insert("id", query.value("id").toLongLong()); + result.append(item); + } + +// LOG_DEBUG(QString("查询RECOGNITION_RECORDS表的所有记录[记录数:%1]").arg(result.size()).toStdString()); + return result; +} + +QVariantMap RecognitionRecordsDao::findRecordById(QString id) +{ + QVariantMap item; + return item; +} + +QString RecognitionRecordsDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + + // INSERT语句 + QString sql = QString("INSERT INTO RECOGNITION_RECORDS (ID, PERSON_ID, DATETIME, REC_TYPE, DEV_CODE, DOOR_CODE, INOUT_TYPE) " + "VALUES (:id, :personId, :datetime, :recType, :devCode, :doorCode, :inoutType)"); + + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":personId", object.value("person_id").toString()); + query.bindValue(":datetime", object.value("date_time").toString()); + query.bindValue(":recType", object.value("rec_type").toString()); + query.bindValue(":devCode", object.value("dev_code").toString()); + query.bindValue(":doorCode", object.value("door_code").toString()); + query.bindValue(":inoutType", object.value("inout_type").toString()); + +// LOG_DEBUG(sql.toStdString()); + + // 插入识别的log日志 + QString logStr = QString("INSERT INTO RECOGNITION_LOGS (ID, LOG_INFO) VALUES (:id, :logInfo)"); + + QSqlQuery logQuery(ConnectionManager::getInstance()->getConnection()); + logQuery.prepare(logStr); + logQuery.bindValue(":id", id); + logQuery.bindValue(":logInfo", object.value("debug_info").toString()); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(); + logQuery.exec(); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool RecognitionRecordsDao::edit(QVariantMap newObject, QString id) +{ + return false; +} + +bool RecognitionRecordsDao::dele(QString id) +{ + return false; +} diff --git a/dao/RecognitionRecordsDao.h b/dao/RecognitionRecordsDao.h new file mode 100644 index 0000000..38de7c9 --- /dev/null +++ b/dao/RecognitionRecordsDao.h @@ -0,0 +1,23 @@ +#ifndef RECOGNITIONRECORDSDAO_H +#define RECOGNITIONRECORDSDAO_H + +#include +#include "BaseDao.h" +class RecognitionRecordsDao: public BaseDao +{ + Q_OBJECT +public: + explicit RecognitionRecordsDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +signals: + +}; + +#endif // RECOGNITIONRECORDSDAO_H diff --git a/AppConstants.h b/AppConstants.h new file mode 100644 index 0000000..296c53f --- /dev/null +++ b/AppConstants.h @@ -0,0 +1,28 @@ +#ifndef APPCONSTANTS_H +#define APPCONSTANTS_H + +class AppConstants +{ +public: + enum WidgeFrameName + { + MAIN_PAGE = 0, // 主页面 + PERSON_LIST_FORM = 1, // 人员列表页面 + ADD_PERSON_FORM = 2, // 添加人员页面 + ADD_PERSON_CAPTURE_FACE = 21, // 添加/编辑人员时进行人脸拍图 + ADD_PERSON_CAPTURE_IRIS = 22, // 添加/编辑人员时进行虹膜拍图 + SETTING_FORM = 3, // 设置页面 + RECOGNIZE_RESULT_FORM = 4, // 识别结果界面 + IDENTIFY_FORM = 5, // 识别界面 含识别中 和 识别结果 + LOCKSCREEN_FORM = 6 // 锁屏待机界面 + }; + + enum ApplicationState + { + STATE_WAIT = 0, // 待机 + STATE_WORKING = 1, // 工作状态 + STATE_IDENTIFYING = 2, // 识别中 + }; +}; + +#endif // APPCONSTANTS_H diff --git a/CasicIrisIdentify.pro b/CasicIrisIdentify.pro index 5d7fea6..575ce3d 100644 --- a/CasicIrisIdentify.pro +++ b/CasicIrisIdentify.pro @@ -1,4 +1,4 @@ -QT += core gui +QT += core gui sql network texttospeech greaterThan(QT_MAJOR_VERSION, 4): QT += widgets @@ -15,20 +15,46 @@ # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 -SOURCES += \ - main.cpp \ - IdentifyForm.cpp +include("dao/dao.pri") +include("device/device.pri") +include("utils/utils.pri") -HEADERS += \ - IdentifyForm.h +SOURCES += main.cpp +SOURCES += ProMemory.cpp +SOURCES += MainWindowForm.cpp +SOURCES += IdentifyForm.cpp +SOURCES += LockScreenForm.cpp -FORMS += \ - IdentifyForm.ui +HEADERS += AppConstants.h +HEADERS += ProMemory.h +HEADERS += MainWindowForm.h +HEADERS += IdentifyForm.h +HEADERS += LockScreenForm.h -TRANSLATIONS += \ - CasicIrisIdentify_zh_CN.ts +FORMS += MainWindowForm.ui +FORMS += IdentifyForm.ui +FORMS += LockScreenForm.ui + +RESOURCES += resource.qrc + +DISTFILES += conf/config.ini + +#TRANSLATIONS += CasicIrisIdentify_zh_CN.ts + +#INCLUDEPATH += include/spdlog +#DEPENDPATH += include/spdlog # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target + + +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lopencv_world420 +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lGxIAPICPPEx + +INCLUDEPATH += $$PWD/include/daheng +DEPENDPATH += $$PWD/include/daheng + +INCLUDEPATH += $$PWD/include +DEPENDPATH += $$PWD/include diff --git a/CasicIrisIdentify_zh_CN.ts b/CasicIrisIdentify_zh_CN.ts index 5526fe4..81900df 100644 --- a/CasicIrisIdentify_zh_CN.ts +++ b/CasicIrisIdentify_zh_CN.ts @@ -1,3 +1,12 @@ - + + + IdentifyForm + + + IdentifyForm + + + + diff --git a/IdentifyForm.cpp b/IdentifyForm.cpp index 348a897..ba1f251 100644 --- a/IdentifyForm.cpp +++ b/IdentifyForm.cpp @@ -1,4 +1,4 @@ -#include "IdentifyForm.h" +#include "IdentifyForm.h" #include "ui_IdentifyForm.h" IdentifyForm::IdentifyForm(QWidget *parent) @@ -6,6 +6,12 @@ , ui(new Ui::IdentifyForm) { ui->setupUi(this); + + // 初始化更新界面的定时器 + // 每秒执行一次 + connect(TimeCounterUtil::getInstance().clockCounter, &QTimer::timeout, this, &IdentifyForm::updateDateAndTime); + + TimeCounterUtil::getInstance().clockCounter->start(1000); } IdentifyForm::~IdentifyForm() @@ -13,3 +19,16 @@ delete ui; } +void IdentifyForm::drawIrisImageOnFrame(QImage image) +{ + // 只在识别界面才显示画面 + if (ui->wgtStacked->currentIndex() == 0) { + ui->labelVideo->setPixmap(QPixmap::fromImage(image)); + } +} + + +void IdentifyForm::updateDateAndTime() +{ + ui->labelTime->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd dddd HH:mm:ss")); +} diff --git a/IdentifyForm.h b/IdentifyForm.h index fc857a1..ae1cd22 100644 --- a/IdentifyForm.h +++ b/IdentifyForm.h @@ -1,7 +1,10 @@ -#ifndef IDENTIFYFORM_H +#ifndef IDENTIFYFORM_H #define IDENTIFYFORM_H #include +#include + +#include "utils/UtilInclude.h" QT_BEGIN_NAMESPACE namespace Ui { class IdentifyForm; } @@ -15,7 +18,14 @@ IdentifyForm(QWidget *parent = nullptr); ~IdentifyForm(); +public slots: + void drawIrisImageOnFrame(QImage image); + private: Ui::IdentifyForm *ui; + +private slots: + void updateDateAndTime(); + }; #endif // IDENTIFYFORM_H diff --git a/IdentifyForm.ui b/IdentifyForm.ui index c72a36f..879dc9a 100644 --- a/IdentifyForm.ui +++ b/IdentifyForm.ui @@ -6,13 +6,59 @@ 0 0 - 800 + 600 600 IdentifyForm + + + + 0 + 40 + 600 + 450 + + + + 0 + + + + + + 100 + 10 + 400 + 300 + + + + + + + + + + + + + + 0 + 0 + 600 + 40 + + + + TextLabel + + + Qt::AlignCenter + + diff --git a/LockScreenForm.cpp b/LockScreenForm.cpp new file mode 100644 index 0000000..58dc54b --- /dev/null +++ b/LockScreenForm.cpp @@ -0,0 +1,14 @@ +#include "LockScreenForm.h" +#include "ui_LockScreenForm.h" + +LockScreenForm::LockScreenForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::LockScreenForm) +{ + ui->setupUi(this); +} + +LockScreenForm::~LockScreenForm() +{ + delete ui; +} diff --git a/LockScreenForm.h b/LockScreenForm.h new file mode 100644 index 0000000..b5ded48 --- /dev/null +++ b/LockScreenForm.h @@ -0,0 +1,25 @@ +#ifndef LOCKSCREENFORM_H +#define LOCKSCREENFORM_H + +#include +#include + +#include "utils/UtilInclude.h" + +namespace Ui { +class LockScreenForm; +} + +class LockScreenForm : public QWidget +{ + Q_OBJECT + +public: + explicit LockScreenForm(QWidget *parent = nullptr); + ~LockScreenForm(); + +private: + Ui::LockScreenForm *ui; +}; + +#endif // LOCKSCREENFORM_H diff --git a/LockScreenForm.ui b/LockScreenForm.ui new file mode 100644 index 0000000..7f2a6db --- /dev/null +++ b/LockScreenForm.ui @@ -0,0 +1,45 @@ + + + LockScreenForm + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + 180 + 100 + 54 + 12 + + + + TextLabel + + + + + + 180 + 160 + 54 + 12 + + + + TextLabel + + + + + + diff --git a/MainWindowForm.cpp b/MainWindowForm.cpp new file mode 100644 index 0000000..84f8159 --- /dev/null +++ b/MainWindowForm.cpp @@ -0,0 +1,86 @@ +#include "MainWindowForm.h" +#include "ui_MainWindowForm.h" +#include + +MainWindowForm::MainWindowForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::MainWindowForm) +{ + ui->setupUi(this); + + // 设置窗口透明和大小、位置 + this->setWindowFlags(Qt::FramelessWindowHint); + this->move(1400, 15); + this->resize(SettingConfig::getInstance().WINDOW_WIDTH, SettingConfig::getInstance().WINDOW_HEIGHT); + + // 通过调色板的颜色来设置窗口的统一背景色 + qApp->setPalette(QPalette(QColor(SettingConfig::getInstance().WINDOW_BACKGROUND_COLOR))); + + // 加载css文件设置控件样式 + QFile file(QApplication::applicationDirPath() + "/qss/main.css"); + if (file.open(QFile::ReadOnly)) + { + QString qssStr = QLatin1String(file.readAll()); + this->setStyleSheet(qssStr); + file.close(); + } + + initFormsPtr(); + + // 设置标题文字 + ui->labelTitle->setText(SettingConfig::getInstance().WINDOW_TITLE); + ui->labelCopyright->setText(SettingConfig::getInstance().WINDOW_RIGHTS); + ui->labelVersion->setText(SettingConfig::getInstance().WINDOW_VERSION); + + // 初始化虹膜相机控制 + ProMemory::getInstance().irisCam = new IrisCameraController(this); + ProMemory::getInstance().irisCam->initIrisCamera(); + ProMemory::getInstance().irisCam->openIrisCamera(); + connect(ProMemory::getInstance().irisCam->irisCamHandler, &IrisCameraCapEventHandler::sendIrisFrameToDraw, identifyForm, &IdentifyForm::drawIrisImageOnFrame); + +// LOG_INFO(QString("应用程序启动成功[Application Startup Success]").toStdString()); + qDebug() << "应用程序启动成功[Application Startup Success]"; + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::IDENTIFY_FORM; + ui->wdgtStatced->setCurrentWidget(identifyForm); + + // 开始虹膜相机拍图 + ProMemory::getInstance().irisCam->startCapture(); +} + +MainWindowForm::~MainWindowForm() +{ + delete ui; +} + +void MainWindowForm::lockScreen() +{ + ui->wdgtStatced->setCurrentWidget(lockScreenForm); + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::LOCKSCREEN_FORM; + ProMemory::getInstance().appState = AppConstants::ApplicationState::STATE_WAIT; +} + +void MainWindowForm::keyPressEvent(QKeyEvent *event) +{ + switch (event->key()) { + case Qt::Key_Escape: + QTimer::singleShot(100, qApp, [=](){ + QApplication::quit(); + }); + + default: + QWidget::keyPressEvent(event); + } +} + +void MainWindowForm::initFormsPtr() +{ + // 初始化各个form + lockScreenForm = new LockScreenForm(this); + identifyForm = new IdentifyForm(this); + + // 将form添加到statcked widget中 + ui->wdgtStatced->addWidget(identifyForm); + ui->wdgtStatced->addWidget(lockScreenForm); + + // 绑定按钮函数 +} diff --git a/MainWindowForm.h b/MainWindowForm.h new file mode 100644 index 0000000..7fb2d89 --- /dev/null +++ b/MainWindowForm.h @@ -0,0 +1,38 @@ +#ifndef MAINWINDOWFORM_H +#define MAINWINDOWFORM_H + +#include +#include +#include + +#include "utils/UtilInclude.h" +#include "ProMemory.h" +#include "LockScreenForm.h" +#include "IdentifyForm.h" + +namespace Ui { +class MainWindowForm; +} + +class MainWindowForm : public QWidget +{ + Q_OBJECT + +public: + explicit MainWindowForm(QWidget *parent = nullptr); + ~MainWindowForm(); + +public slots: + void lockScreen(); + +private: + Ui::MainWindowForm *ui; + LockScreenForm * lockScreenForm; + IdentifyForm * identifyForm; + + void keyPressEvent(QKeyEvent *event); + + void initFormsPtr(); +}; + +#endif // MAINWINDOWFORM_H diff --git a/MainWindowForm.ui b/MainWindowForm.ui new file mode 100644 index 0000000..e793ebf --- /dev/null +++ b/MainWindowForm.ui @@ -0,0 +1,85 @@ + + + MainWindowForm + + + + 0 + 0 + 600 + 1024 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + 0 + 0 + 600 + 84 + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + + + + TextLabel + + + Qt::AlignBottom|Qt::AlignHCenter + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + diff --git a/ProMemory.cpp b/ProMemory.cpp new file mode 100644 index 0000000..19e7403 --- /dev/null +++ b/ProMemory.cpp @@ -0,0 +1,84 @@ +#include "ProMemory.h" + +ProMemory::ProMemory() +{ + +} + +ProMemory::~ProMemory() +{ + +} + +/* +void ProMemory::pushCasicIris(CasicIrisInfo irisInfo) +{ + QMutex mutex; + mutex.lock(); + if (this->irisQueue.size() > 30) + { + QStack empty; + std::swap(empty, irisQueue); + } + + irisQueue.push(irisInfo); + mutex.unlock(); +} +CasicIrisInfo ProMemory::popCasicIris() +{ + CasicIrisInfo result; + + QMutex mutex; + mutex.lock(); + if (this->irisQueue.size() > 0) + { + result = irisQueue.pop(); + } + + mutex.unlock(); + + return result; +} +*/ +int ProMemory::getIrisQueueSize() +{ + int size = 0; + + QMutex mutex; + mutex.lock(); + +// size = this->irisQueue.size(); + + mutex.unlock(); + + return size; +} +bool ProMemory::isIrisQueueEmpty() +{ + bool empty = true; + + QMutex mutex; + mutex.lock(); + +// empty = this->irisQueue.isEmpty(); + + mutex.unlock(); + + return empty; +} +void ProMemory::clearIrisQueue() +{ + QMutex mutex; + mutex.lock(); + +// QStack empty; +// std::swap(empty, irisQueue); + + mutex.unlock(); +} + + +void ProMemory::initIrisFeatures(QString personId) +{ +// irisRegistPro->sendDataToExract(QByteArray(QString("[-u]").append(personId).toLocal8Bit())); +} diff --git a/ProMemory.h b/ProMemory.h new file mode 100644 index 0000000..2ecd653 --- /dev/null +++ b/ProMemory.h @@ -0,0 +1,52 @@ +#ifndef PROMEMORY_H +#define PROMEMORY_H + +#include +#include + +#include "AppConstants.h" +//#include "casic/iris/CasicIrisInfo.h" +#include "dao/IrisDataDao.h" + +#include "device/IrisCameraController.h" +//#include "device/iris/IrisRegistProcess.h" +//#include "device/iris/IrisRecogProcess.h" + +class IrisCameraController; +class IrisRegistProcess; +class IrisRecogProcess; + +class ProMemory +{ +public: + ~ProMemory(); + ProMemory(const ProMemory&)=delete; + ProMemory& operator=(const ProMemory&)=delete; + + static ProMemory& getInstance() { + static ProMemory instance; + return instance; + } + +// void pushCasicIris(CasicIrisInfo irisInfo); +// CasicIrisInfo popCasicIris(); + int getIrisQueueSize(); + bool isIrisQueueEmpty(); + void clearIrisQueue(); + + volatile int widgeFrame = 0; // 当前显示的界面 + volatile int appState = 0; // 当前程序所处的状态 + + void initIrisFeatures(QString personId = ""); // 初始化虹膜特征值集合 + + IrisCameraController * irisCam; + IrisRecogProcess * irisRecogPro; + +private: + ProMemory(); + +// QStack irisQueue; // 虹膜信息队列 + QVector irisFeatures; // 虹膜特征值集合 +}; + +#endif // PROMEMORY_H diff --git a/conf/config.ini b/conf/config.ini new file mode 100644 index 0000000..66e46ad --- /dev/null +++ b/conf/config.ini @@ -0,0 +1,67 @@ +[recognize] +#最大允许识别时间(ms) +maxMatchTime=10000 +#识别成功界面停留时间(ms) +successTipsLast=5000 +#识别失败界面停留时间(ms) +failureTipsLast=3000 +#人脸识别最大尝试次数 +maxFaceTryCount=20 +#持续没找到人脸的最大次数 +maxFaceNotFoundCount=500 +#注册时最小人脸 +minFaceRegist=240 +#识别时最小人脸 +minFaceRecog=100 + +#虹膜识别最大尝试次数 +maxIrisTryCount=10 +#虹膜识别持续没有找到眼的最大次数 +maxEyeNotFoundCount=50 + +#识别方式[1=人脸;2=虹膜;3=双认证;4=任意] +recogType=4 + +[window] +#界面窗口宽(px) +width=600 +#界面窗口高(px) +height=1024 +#统一背景色 +backgroundColor="#FFFFFF" +#标题 +title="虹膜识别终端" + +[work] +#工作状态检测时最小人脸范围 +minFaceSize=160 +#人脸范围最小横坐标 +minFacePosX=320 +#人脸范围最大横坐标 +maxFacePosX=960 +#人脸范围最小纵坐标 +minFacePosY=180 +#人脸范围最大纵坐标 +maxFacePosY=540 +#人脸太近阈值 +faceCloseSize=360 +#人脸太远阈值 +faceFarSize=480 + +[camera] +#虹膜相机取一幅画面的时间间隔(ms) +irisFrameInterval=100 +#虹膜相机拍摄宽度 +irisFrameWidth=1440 +#虹膜相机拍摄高度 +irisFrameHeight=1080 +#虹膜图像高度 +irisWidth=640 +#虹膜图像高度 +irisHeight=480 + +[log] +#日志文件位置 +logFile="d://irisLogs//casic_log.txt" +#日志级别 +logLevel="trace" diff --git a/dao/BaseDao.cpp b/dao/BaseDao.cpp new file mode 100644 index 0000000..f51c144 --- /dev/null +++ b/dao/BaseDao.cpp @@ -0,0 +1,12 @@ +#include "BaseDao.h" +#include "dao/util/ConnectionManager.h" + +BaseDao::BaseDao(QObject *parent) : QObject(parent) +{ + +} + +BaseDao::~BaseDao() +{ + +} diff --git a/dao/BaseDao.h b/dao/BaseDao.h new file mode 100644 index 0000000..1693c88 --- /dev/null +++ b/dao/BaseDao.h @@ -0,0 +1,32 @@ +#ifndef BASEDAO_H +#define BASEDAO_H + +#include +#include +#include +#include + +#include "dao/util/ConnectionManager.h" +#include "utils/UtilInclude.h" + +class BaseDao : public QObject +{ + Q_OBJECT +public: + explicit BaseDao(QObject *parent = nullptr); + ~BaseDao(); + + virtual QVector findAllRecord() = 0; + virtual QVariantMap findRecordById(QString id) = 0; + + virtual QString save(QVariantMap object) = 0; + virtual bool edit(QVariantMap newObject, QString id) = 0; + virtual bool dele(QString id) = 0; + +private: + +signals: + +}; + +#endif // BASEDAO_H diff --git a/dao/IrisDataDao.cpp b/dao/IrisDataDao.cpp new file mode 100644 index 0000000..37a0ed6 --- /dev/null +++ b/dao/IrisDataDao.cpp @@ -0,0 +1,204 @@ +#include "IrisDataDao.h" + +IrisDataDao::IrisDataDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector IrisDataDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM IRIS_DATA"; + query.prepare(sql); + + // 执行查询 + query.exec(); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + item.insert("id", query.value("id").toString()); + item.insert("person_id", query.value("person_id").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("left_iris_code1", query.value("left_iris_code1")); + item.insert("left_iris_code2", query.value("left_iris_code2")); + item.insert("left_iris_code3", query.value("left_iris_code3")); + item.insert("right_iris_code1", query.value("right_iris_code1")); + item.insert("right_iris_code2", query.value("right_iris_code2")); + item.insert("right_iris_code3", query.value("right_iris_code3")); + + result.append(item); + } + +// LOG_DEBUG(QString("查询IRIS_DATA表的所有记录[结果数:%1]").arg(result.size()).toStdString()); + return result; +} + +QVariantMap IrisDataDao::findRecordById(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM IRIS_DATA WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + // 获取结果 + if (query.next()) + { + result.insert("id", query.value("id").toString()); + result.insert("person_id", query.value("person_id").toLongLong()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("left_iris_code1", query.value("left_iris_code1")); + result.insert("left_iris_code2", query.value("left_iris_code2")); + result.insert("left_iris_code3", query.value("left_iris_code3")); + result.insert("right_iris_code1", query.value("right_iris_code1")); + result.insert("right_iris_code2", query.value("right_iris_code2")); + result.insert("right_iris_code3", query.value("right_iris_code3")); + } + +// LOG_DEBUG(QString("根据id查询IRIS_DATA表的记录[id=%1]").arg(id).toStdString()); + return result; +} + +QVariantMap IrisDataDao::findRecordByPersonId(QString personId) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM IRIS_DATA WHERE PERSON_ID = :personId"); + query.prepare(sql); + query.bindValue(":personId", personId); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + if (query.next()) + { + result.insert("id", query.value("id").toString()); + result.insert("person_id", query.value("person_id").toLongLong()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("left_iris_code1", query.value("left_iris_code1")); + result.insert("left_iris_code2", query.value("left_iris_code2")); + result.insert("left_iris_code3", query.value("left_iris_code3")); + result.insert("right_iris_code1", query.value("right_iris_code1")); + result.insert("right_iris_code2", query.value("right_iris_code2")); + result.insert("right_iris_code3", query.value("right_iris_code3")); + } + +// LOG_DEBUG(QString("根据personId查询IRIS_DATA表的记录[personId=%1]").arg(personId).toStdString()); + return result; +} + + +QString IrisDataDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + + // INSERT语句 + QString sql = QString("INSERT INTO IRIS_DATA (ID, PERSON_ID, ID_CARD_NO, LEFT_IRIS_CODE1, RIGHT_IRIS_CODE1) VALUES (:id, :personId, :idCardNo, :left1, :right1)"); + + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":personId", object.value("person_id").toString()); + query.bindValue(":idCardNo", object.value("id_card_no").toString()); + query.bindValue(":left1", object.value("left_iris_code1")); + query.bindValue(":right1", object.value("right_iris_code1")); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(); + +// LOG_DEBUG(QString("保存虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool IrisDataDao::edit(QVariantMap newObject, QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // UPDATE语句 + if (!newObject.contains("left_iris_code1") || !newObject.contains("right_iris_code1")){ + return false; + } + QString sql = QString("UPDATE IRIS_DATA SET LEFT_IRIS_CODE1 = :left1, RIGHT_IRIS_CODE1 = :right1 WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":left1", newObject.value("left_iris_code1")); + query.bindValue(":right1", newObject.value("right_iris_code1")); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(); + +// LOG_DEBUG(QString("编辑虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; +} + + +bool IrisDataDao::dele(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + QString sql = QString("DELETE FROM IRIS_DATA WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(); + +// LOG_DEBUG(QString("删除虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; +} diff --git a/dao/IrisDataDao.h b/dao/IrisDataDao.h new file mode 100644 index 0000000..c74dbbd --- /dev/null +++ b/dao/IrisDataDao.h @@ -0,0 +1,25 @@ +#ifndef IRISDATADAO_H +#define IRISDATADAO_H + +#include +#include "BaseDao.h" + +class IrisDataDao : public BaseDao +{ + Q_OBJECT +public: + explicit IrisDataDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + QVariantMap findRecordByPersonId(QString personId); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +signals: + +}; + +#endif // IRISDATADAO_H diff --git a/dao/RecognitionRecordsDao.cpp b/dao/RecognitionRecordsDao.cpp new file mode 100644 index 0000000..40db453 --- /dev/null +++ b/dao/RecognitionRecordsDao.cpp @@ -0,0 +1,100 @@ +#include "RecognitionRecordsDao.h" + +RecognitionRecordsDao::RecognitionRecordsDao(QObject *parent) : BaseDao(parent) +{ + +} + + +QVector RecognitionRecordsDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM RECOGNITION_RECORDS"; + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + item.insert("id", query.value("id").toLongLong()); + result.append(item); + } + +// LOG_DEBUG(QString("查询RECOGNITION_RECORDS表的所有记录[记录数:%1]").arg(result.size()).toStdString()); + return result; +} + +QVariantMap RecognitionRecordsDao::findRecordById(QString id) +{ + QVariantMap item; + return item; +} + +QString RecognitionRecordsDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + + // INSERT语句 + QString sql = QString("INSERT INTO RECOGNITION_RECORDS (ID, PERSON_ID, DATETIME, REC_TYPE, DEV_CODE, DOOR_CODE, INOUT_TYPE) " + "VALUES (:id, :personId, :datetime, :recType, :devCode, :doorCode, :inoutType)"); + + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":personId", object.value("person_id").toString()); + query.bindValue(":datetime", object.value("date_time").toString()); + query.bindValue(":recType", object.value("rec_type").toString()); + query.bindValue(":devCode", object.value("dev_code").toString()); + query.bindValue(":doorCode", object.value("door_code").toString()); + query.bindValue(":inoutType", object.value("inout_type").toString()); + +// LOG_DEBUG(sql.toStdString()); + + // 插入识别的log日志 + QString logStr = QString("INSERT INTO RECOGNITION_LOGS (ID, LOG_INFO) VALUES (:id, :logInfo)"); + + QSqlQuery logQuery(ConnectionManager::getInstance()->getConnection()); + logQuery.prepare(logStr); + logQuery.bindValue(":id", id); + logQuery.bindValue(":logInfo", object.value("debug_info").toString()); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(); + logQuery.exec(); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool RecognitionRecordsDao::edit(QVariantMap newObject, QString id) +{ + return false; +} + +bool RecognitionRecordsDao::dele(QString id) +{ + return false; +} diff --git a/dao/RecognitionRecordsDao.h b/dao/RecognitionRecordsDao.h new file mode 100644 index 0000000..38de7c9 --- /dev/null +++ b/dao/RecognitionRecordsDao.h @@ -0,0 +1,23 @@ +#ifndef RECOGNITIONRECORDSDAO_H +#define RECOGNITIONRECORDSDAO_H + +#include +#include "BaseDao.h" +class RecognitionRecordsDao: public BaseDao +{ + Q_OBJECT +public: + explicit RecognitionRecordsDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +signals: + +}; + +#endif // RECOGNITIONRECORDSDAO_H diff --git a/dao/SysDeptDao.cpp b/dao/SysDeptDao.cpp new file mode 100644 index 0000000..22f9946 --- /dev/null +++ b/dao/SysDeptDao.cpp @@ -0,0 +1,88 @@ +#include "SysDeptDao.h" + +SysDeptDao::SysDeptDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector SysDeptDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_DEPT WHERE PID != '-1' ORDER BY PID, NUM"; + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + item.insert("id", query.value("id").toString()); + item.insert("pid", query.value("pid").toString()); + item.insert("pids", query.value("pids").toString()); + item.insert("simplename", query.value("simplename").toString()); + item.insert("fullname", query.value("fullname").toString()); + } + +// LOG_TRACE(QString("查询表[SYS_DEPT]的所有记录[%1][%2]").arg(result.size()).arg(sql).toStdString()); + + return result; +} + +QVariantMap SysDeptDao::findRecordById(QString id) +{ + QVariantMap item; + return item; + + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM SYS_DEPT WHERE SYS_DEPT.ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + // 获取结果集的大小 + query.last(); + int count = query.at() + 1; + + if (count >=1) + { + query.first(); + + result.insert("id", query.value("id").toString()); + result.insert("pid", query.value("pid").toString()); + result.insert("pids", query.value("pids").toString()); + result.insert("simplename", query.value("simplename").toString()); + result.insert("fullname", query.value("fullname").toString()); + } + +// LOG_TRACE(QString("根据id查询SYS_DEPT表的记录[ID=%1][%2]").arg(id).arg(sql).toStdString()); + + return result; +} + + +QString SysDeptDao::save(QVariantMap object) +{ + return "0"; +} +bool SysDeptDao::edit(QVariantMap newObject, QString id) +{ + return true; +} +bool SysDeptDao::dele(QString id) +{ + return true; +} diff --git a/AppConstants.h b/AppConstants.h new file mode 100644 index 0000000..296c53f --- /dev/null +++ b/AppConstants.h @@ -0,0 +1,28 @@ +#ifndef APPCONSTANTS_H +#define APPCONSTANTS_H + +class AppConstants +{ +public: + enum WidgeFrameName + { + MAIN_PAGE = 0, // 主页面 + PERSON_LIST_FORM = 1, // 人员列表页面 + ADD_PERSON_FORM = 2, // 添加人员页面 + ADD_PERSON_CAPTURE_FACE = 21, // 添加/编辑人员时进行人脸拍图 + ADD_PERSON_CAPTURE_IRIS = 22, // 添加/编辑人员时进行虹膜拍图 + SETTING_FORM = 3, // 设置页面 + RECOGNIZE_RESULT_FORM = 4, // 识别结果界面 + IDENTIFY_FORM = 5, // 识别界面 含识别中 和 识别结果 + LOCKSCREEN_FORM = 6 // 锁屏待机界面 + }; + + enum ApplicationState + { + STATE_WAIT = 0, // 待机 + STATE_WORKING = 1, // 工作状态 + STATE_IDENTIFYING = 2, // 识别中 + }; +}; + +#endif // APPCONSTANTS_H diff --git a/CasicIrisIdentify.pro b/CasicIrisIdentify.pro index 5d7fea6..575ce3d 100644 --- a/CasicIrisIdentify.pro +++ b/CasicIrisIdentify.pro @@ -1,4 +1,4 @@ -QT += core gui +QT += core gui sql network texttospeech greaterThan(QT_MAJOR_VERSION, 4): QT += widgets @@ -15,20 +15,46 @@ # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 -SOURCES += \ - main.cpp \ - IdentifyForm.cpp +include("dao/dao.pri") +include("device/device.pri") +include("utils/utils.pri") -HEADERS += \ - IdentifyForm.h +SOURCES += main.cpp +SOURCES += ProMemory.cpp +SOURCES += MainWindowForm.cpp +SOURCES += IdentifyForm.cpp +SOURCES += LockScreenForm.cpp -FORMS += \ - IdentifyForm.ui +HEADERS += AppConstants.h +HEADERS += ProMemory.h +HEADERS += MainWindowForm.h +HEADERS += IdentifyForm.h +HEADERS += LockScreenForm.h -TRANSLATIONS += \ - CasicIrisIdentify_zh_CN.ts +FORMS += MainWindowForm.ui +FORMS += IdentifyForm.ui +FORMS += LockScreenForm.ui + +RESOURCES += resource.qrc + +DISTFILES += conf/config.ini + +#TRANSLATIONS += CasicIrisIdentify_zh_CN.ts + +#INCLUDEPATH += include/spdlog +#DEPENDPATH += include/spdlog # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target + + +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lopencv_world420 +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lGxIAPICPPEx + +INCLUDEPATH += $$PWD/include/daheng +DEPENDPATH += $$PWD/include/daheng + +INCLUDEPATH += $$PWD/include +DEPENDPATH += $$PWD/include diff --git a/CasicIrisIdentify_zh_CN.ts b/CasicIrisIdentify_zh_CN.ts index 5526fe4..81900df 100644 --- a/CasicIrisIdentify_zh_CN.ts +++ b/CasicIrisIdentify_zh_CN.ts @@ -1,3 +1,12 @@ - + + + IdentifyForm + + + IdentifyForm + + + + diff --git a/IdentifyForm.cpp b/IdentifyForm.cpp index 348a897..ba1f251 100644 --- a/IdentifyForm.cpp +++ b/IdentifyForm.cpp @@ -1,4 +1,4 @@ -#include "IdentifyForm.h" +#include "IdentifyForm.h" #include "ui_IdentifyForm.h" IdentifyForm::IdentifyForm(QWidget *parent) @@ -6,6 +6,12 @@ , ui(new Ui::IdentifyForm) { ui->setupUi(this); + + // 初始化更新界面的定时器 + // 每秒执行一次 + connect(TimeCounterUtil::getInstance().clockCounter, &QTimer::timeout, this, &IdentifyForm::updateDateAndTime); + + TimeCounterUtil::getInstance().clockCounter->start(1000); } IdentifyForm::~IdentifyForm() @@ -13,3 +19,16 @@ delete ui; } +void IdentifyForm::drawIrisImageOnFrame(QImage image) +{ + // 只在识别界面才显示画面 + if (ui->wgtStacked->currentIndex() == 0) { + ui->labelVideo->setPixmap(QPixmap::fromImage(image)); + } +} + + +void IdentifyForm::updateDateAndTime() +{ + ui->labelTime->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd dddd HH:mm:ss")); +} diff --git a/IdentifyForm.h b/IdentifyForm.h index fc857a1..ae1cd22 100644 --- a/IdentifyForm.h +++ b/IdentifyForm.h @@ -1,7 +1,10 @@ -#ifndef IDENTIFYFORM_H +#ifndef IDENTIFYFORM_H #define IDENTIFYFORM_H #include +#include + +#include "utils/UtilInclude.h" QT_BEGIN_NAMESPACE namespace Ui { class IdentifyForm; } @@ -15,7 +18,14 @@ IdentifyForm(QWidget *parent = nullptr); ~IdentifyForm(); +public slots: + void drawIrisImageOnFrame(QImage image); + private: Ui::IdentifyForm *ui; + +private slots: + void updateDateAndTime(); + }; #endif // IDENTIFYFORM_H diff --git a/IdentifyForm.ui b/IdentifyForm.ui index c72a36f..879dc9a 100644 --- a/IdentifyForm.ui +++ b/IdentifyForm.ui @@ -6,13 +6,59 @@ 0 0 - 800 + 600 600 IdentifyForm + + + + 0 + 40 + 600 + 450 + + + + 0 + + + + + + 100 + 10 + 400 + 300 + + + + + + + + + + + + + + 0 + 0 + 600 + 40 + + + + TextLabel + + + Qt::AlignCenter + + diff --git a/LockScreenForm.cpp b/LockScreenForm.cpp new file mode 100644 index 0000000..58dc54b --- /dev/null +++ b/LockScreenForm.cpp @@ -0,0 +1,14 @@ +#include "LockScreenForm.h" +#include "ui_LockScreenForm.h" + +LockScreenForm::LockScreenForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::LockScreenForm) +{ + ui->setupUi(this); +} + +LockScreenForm::~LockScreenForm() +{ + delete ui; +} diff --git a/LockScreenForm.h b/LockScreenForm.h new file mode 100644 index 0000000..b5ded48 --- /dev/null +++ b/LockScreenForm.h @@ -0,0 +1,25 @@ +#ifndef LOCKSCREENFORM_H +#define LOCKSCREENFORM_H + +#include +#include + +#include "utils/UtilInclude.h" + +namespace Ui { +class LockScreenForm; +} + +class LockScreenForm : public QWidget +{ + Q_OBJECT + +public: + explicit LockScreenForm(QWidget *parent = nullptr); + ~LockScreenForm(); + +private: + Ui::LockScreenForm *ui; +}; + +#endif // LOCKSCREENFORM_H diff --git a/LockScreenForm.ui b/LockScreenForm.ui new file mode 100644 index 0000000..7f2a6db --- /dev/null +++ b/LockScreenForm.ui @@ -0,0 +1,45 @@ + + + LockScreenForm + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + 180 + 100 + 54 + 12 + + + + TextLabel + + + + + + 180 + 160 + 54 + 12 + + + + TextLabel + + + + + + diff --git a/MainWindowForm.cpp b/MainWindowForm.cpp new file mode 100644 index 0000000..84f8159 --- /dev/null +++ b/MainWindowForm.cpp @@ -0,0 +1,86 @@ +#include "MainWindowForm.h" +#include "ui_MainWindowForm.h" +#include + +MainWindowForm::MainWindowForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::MainWindowForm) +{ + ui->setupUi(this); + + // 设置窗口透明和大小、位置 + this->setWindowFlags(Qt::FramelessWindowHint); + this->move(1400, 15); + this->resize(SettingConfig::getInstance().WINDOW_WIDTH, SettingConfig::getInstance().WINDOW_HEIGHT); + + // 通过调色板的颜色来设置窗口的统一背景色 + qApp->setPalette(QPalette(QColor(SettingConfig::getInstance().WINDOW_BACKGROUND_COLOR))); + + // 加载css文件设置控件样式 + QFile file(QApplication::applicationDirPath() + "/qss/main.css"); + if (file.open(QFile::ReadOnly)) + { + QString qssStr = QLatin1String(file.readAll()); + this->setStyleSheet(qssStr); + file.close(); + } + + initFormsPtr(); + + // 设置标题文字 + ui->labelTitle->setText(SettingConfig::getInstance().WINDOW_TITLE); + ui->labelCopyright->setText(SettingConfig::getInstance().WINDOW_RIGHTS); + ui->labelVersion->setText(SettingConfig::getInstance().WINDOW_VERSION); + + // 初始化虹膜相机控制 + ProMemory::getInstance().irisCam = new IrisCameraController(this); + ProMemory::getInstance().irisCam->initIrisCamera(); + ProMemory::getInstance().irisCam->openIrisCamera(); + connect(ProMemory::getInstance().irisCam->irisCamHandler, &IrisCameraCapEventHandler::sendIrisFrameToDraw, identifyForm, &IdentifyForm::drawIrisImageOnFrame); + +// LOG_INFO(QString("应用程序启动成功[Application Startup Success]").toStdString()); + qDebug() << "应用程序启动成功[Application Startup Success]"; + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::IDENTIFY_FORM; + ui->wdgtStatced->setCurrentWidget(identifyForm); + + // 开始虹膜相机拍图 + ProMemory::getInstance().irisCam->startCapture(); +} + +MainWindowForm::~MainWindowForm() +{ + delete ui; +} + +void MainWindowForm::lockScreen() +{ + ui->wdgtStatced->setCurrentWidget(lockScreenForm); + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::LOCKSCREEN_FORM; + ProMemory::getInstance().appState = AppConstants::ApplicationState::STATE_WAIT; +} + +void MainWindowForm::keyPressEvent(QKeyEvent *event) +{ + switch (event->key()) { + case Qt::Key_Escape: + QTimer::singleShot(100, qApp, [=](){ + QApplication::quit(); + }); + + default: + QWidget::keyPressEvent(event); + } +} + +void MainWindowForm::initFormsPtr() +{ + // 初始化各个form + lockScreenForm = new LockScreenForm(this); + identifyForm = new IdentifyForm(this); + + // 将form添加到statcked widget中 + ui->wdgtStatced->addWidget(identifyForm); + ui->wdgtStatced->addWidget(lockScreenForm); + + // 绑定按钮函数 +} diff --git a/MainWindowForm.h b/MainWindowForm.h new file mode 100644 index 0000000..7fb2d89 --- /dev/null +++ b/MainWindowForm.h @@ -0,0 +1,38 @@ +#ifndef MAINWINDOWFORM_H +#define MAINWINDOWFORM_H + +#include +#include +#include + +#include "utils/UtilInclude.h" +#include "ProMemory.h" +#include "LockScreenForm.h" +#include "IdentifyForm.h" + +namespace Ui { +class MainWindowForm; +} + +class MainWindowForm : public QWidget +{ + Q_OBJECT + +public: + explicit MainWindowForm(QWidget *parent = nullptr); + ~MainWindowForm(); + +public slots: + void lockScreen(); + +private: + Ui::MainWindowForm *ui; + LockScreenForm * lockScreenForm; + IdentifyForm * identifyForm; + + void keyPressEvent(QKeyEvent *event); + + void initFormsPtr(); +}; + +#endif // MAINWINDOWFORM_H diff --git a/MainWindowForm.ui b/MainWindowForm.ui new file mode 100644 index 0000000..e793ebf --- /dev/null +++ b/MainWindowForm.ui @@ -0,0 +1,85 @@ + + + MainWindowForm + + + + 0 + 0 + 600 + 1024 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + 0 + 0 + 600 + 84 + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + + + + TextLabel + + + Qt::AlignBottom|Qt::AlignHCenter + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + diff --git a/ProMemory.cpp b/ProMemory.cpp new file mode 100644 index 0000000..19e7403 --- /dev/null +++ b/ProMemory.cpp @@ -0,0 +1,84 @@ +#include "ProMemory.h" + +ProMemory::ProMemory() +{ + +} + +ProMemory::~ProMemory() +{ + +} + +/* +void ProMemory::pushCasicIris(CasicIrisInfo irisInfo) +{ + QMutex mutex; + mutex.lock(); + if (this->irisQueue.size() > 30) + { + QStack empty; + std::swap(empty, irisQueue); + } + + irisQueue.push(irisInfo); + mutex.unlock(); +} +CasicIrisInfo ProMemory::popCasicIris() +{ + CasicIrisInfo result; + + QMutex mutex; + mutex.lock(); + if (this->irisQueue.size() > 0) + { + result = irisQueue.pop(); + } + + mutex.unlock(); + + return result; +} +*/ +int ProMemory::getIrisQueueSize() +{ + int size = 0; + + QMutex mutex; + mutex.lock(); + +// size = this->irisQueue.size(); + + mutex.unlock(); + + return size; +} +bool ProMemory::isIrisQueueEmpty() +{ + bool empty = true; + + QMutex mutex; + mutex.lock(); + +// empty = this->irisQueue.isEmpty(); + + mutex.unlock(); + + return empty; +} +void ProMemory::clearIrisQueue() +{ + QMutex mutex; + mutex.lock(); + +// QStack empty; +// std::swap(empty, irisQueue); + + mutex.unlock(); +} + + +void ProMemory::initIrisFeatures(QString personId) +{ +// irisRegistPro->sendDataToExract(QByteArray(QString("[-u]").append(personId).toLocal8Bit())); +} diff --git a/ProMemory.h b/ProMemory.h new file mode 100644 index 0000000..2ecd653 --- /dev/null +++ b/ProMemory.h @@ -0,0 +1,52 @@ +#ifndef PROMEMORY_H +#define PROMEMORY_H + +#include +#include + +#include "AppConstants.h" +//#include "casic/iris/CasicIrisInfo.h" +#include "dao/IrisDataDao.h" + +#include "device/IrisCameraController.h" +//#include "device/iris/IrisRegistProcess.h" +//#include "device/iris/IrisRecogProcess.h" + +class IrisCameraController; +class IrisRegistProcess; +class IrisRecogProcess; + +class ProMemory +{ +public: + ~ProMemory(); + ProMemory(const ProMemory&)=delete; + ProMemory& operator=(const ProMemory&)=delete; + + static ProMemory& getInstance() { + static ProMemory instance; + return instance; + } + +// void pushCasicIris(CasicIrisInfo irisInfo); +// CasicIrisInfo popCasicIris(); + int getIrisQueueSize(); + bool isIrisQueueEmpty(); + void clearIrisQueue(); + + volatile int widgeFrame = 0; // 当前显示的界面 + volatile int appState = 0; // 当前程序所处的状态 + + void initIrisFeatures(QString personId = ""); // 初始化虹膜特征值集合 + + IrisCameraController * irisCam; + IrisRecogProcess * irisRecogPro; + +private: + ProMemory(); + +// QStack irisQueue; // 虹膜信息队列 + QVector irisFeatures; // 虹膜特征值集合 +}; + +#endif // PROMEMORY_H diff --git a/conf/config.ini b/conf/config.ini new file mode 100644 index 0000000..66e46ad --- /dev/null +++ b/conf/config.ini @@ -0,0 +1,67 @@ +[recognize] +#最大允许识别时间(ms) +maxMatchTime=10000 +#识别成功界面停留时间(ms) +successTipsLast=5000 +#识别失败界面停留时间(ms) +failureTipsLast=3000 +#人脸识别最大尝试次数 +maxFaceTryCount=20 +#持续没找到人脸的最大次数 +maxFaceNotFoundCount=500 +#注册时最小人脸 +minFaceRegist=240 +#识别时最小人脸 +minFaceRecog=100 + +#虹膜识别最大尝试次数 +maxIrisTryCount=10 +#虹膜识别持续没有找到眼的最大次数 +maxEyeNotFoundCount=50 + +#识别方式[1=人脸;2=虹膜;3=双认证;4=任意] +recogType=4 + +[window] +#界面窗口宽(px) +width=600 +#界面窗口高(px) +height=1024 +#统一背景色 +backgroundColor="#FFFFFF" +#标题 +title="虹膜识别终端" + +[work] +#工作状态检测时最小人脸范围 +minFaceSize=160 +#人脸范围最小横坐标 +minFacePosX=320 +#人脸范围最大横坐标 +maxFacePosX=960 +#人脸范围最小纵坐标 +minFacePosY=180 +#人脸范围最大纵坐标 +maxFacePosY=540 +#人脸太近阈值 +faceCloseSize=360 +#人脸太远阈值 +faceFarSize=480 + +[camera] +#虹膜相机取一幅画面的时间间隔(ms) +irisFrameInterval=100 +#虹膜相机拍摄宽度 +irisFrameWidth=1440 +#虹膜相机拍摄高度 +irisFrameHeight=1080 +#虹膜图像高度 +irisWidth=640 +#虹膜图像高度 +irisHeight=480 + +[log] +#日志文件位置 +logFile="d://irisLogs//casic_log.txt" +#日志级别 +logLevel="trace" diff --git a/dao/BaseDao.cpp b/dao/BaseDao.cpp new file mode 100644 index 0000000..f51c144 --- /dev/null +++ b/dao/BaseDao.cpp @@ -0,0 +1,12 @@ +#include "BaseDao.h" +#include "dao/util/ConnectionManager.h" + +BaseDao::BaseDao(QObject *parent) : QObject(parent) +{ + +} + +BaseDao::~BaseDao() +{ + +} diff --git a/dao/BaseDao.h b/dao/BaseDao.h new file mode 100644 index 0000000..1693c88 --- /dev/null +++ b/dao/BaseDao.h @@ -0,0 +1,32 @@ +#ifndef BASEDAO_H +#define BASEDAO_H + +#include +#include +#include +#include + +#include "dao/util/ConnectionManager.h" +#include "utils/UtilInclude.h" + +class BaseDao : public QObject +{ + Q_OBJECT +public: + explicit BaseDao(QObject *parent = nullptr); + ~BaseDao(); + + virtual QVector findAllRecord() = 0; + virtual QVariantMap findRecordById(QString id) = 0; + + virtual QString save(QVariantMap object) = 0; + virtual bool edit(QVariantMap newObject, QString id) = 0; + virtual bool dele(QString id) = 0; + +private: + +signals: + +}; + +#endif // BASEDAO_H diff --git a/dao/IrisDataDao.cpp b/dao/IrisDataDao.cpp new file mode 100644 index 0000000..37a0ed6 --- /dev/null +++ b/dao/IrisDataDao.cpp @@ -0,0 +1,204 @@ +#include "IrisDataDao.h" + +IrisDataDao::IrisDataDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector IrisDataDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM IRIS_DATA"; + query.prepare(sql); + + // 执行查询 + query.exec(); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + item.insert("id", query.value("id").toString()); + item.insert("person_id", query.value("person_id").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("left_iris_code1", query.value("left_iris_code1")); + item.insert("left_iris_code2", query.value("left_iris_code2")); + item.insert("left_iris_code3", query.value("left_iris_code3")); + item.insert("right_iris_code1", query.value("right_iris_code1")); + item.insert("right_iris_code2", query.value("right_iris_code2")); + item.insert("right_iris_code3", query.value("right_iris_code3")); + + result.append(item); + } + +// LOG_DEBUG(QString("查询IRIS_DATA表的所有记录[结果数:%1]").arg(result.size()).toStdString()); + return result; +} + +QVariantMap IrisDataDao::findRecordById(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM IRIS_DATA WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + // 获取结果 + if (query.next()) + { + result.insert("id", query.value("id").toString()); + result.insert("person_id", query.value("person_id").toLongLong()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("left_iris_code1", query.value("left_iris_code1")); + result.insert("left_iris_code2", query.value("left_iris_code2")); + result.insert("left_iris_code3", query.value("left_iris_code3")); + result.insert("right_iris_code1", query.value("right_iris_code1")); + result.insert("right_iris_code2", query.value("right_iris_code2")); + result.insert("right_iris_code3", query.value("right_iris_code3")); + } + +// LOG_DEBUG(QString("根据id查询IRIS_DATA表的记录[id=%1]").arg(id).toStdString()); + return result; +} + +QVariantMap IrisDataDao::findRecordByPersonId(QString personId) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM IRIS_DATA WHERE PERSON_ID = :personId"); + query.prepare(sql); + query.bindValue(":personId", personId); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + if (query.next()) + { + result.insert("id", query.value("id").toString()); + result.insert("person_id", query.value("person_id").toLongLong()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("left_iris_code1", query.value("left_iris_code1")); + result.insert("left_iris_code2", query.value("left_iris_code2")); + result.insert("left_iris_code3", query.value("left_iris_code3")); + result.insert("right_iris_code1", query.value("right_iris_code1")); + result.insert("right_iris_code2", query.value("right_iris_code2")); + result.insert("right_iris_code3", query.value("right_iris_code3")); + } + +// LOG_DEBUG(QString("根据personId查询IRIS_DATA表的记录[personId=%1]").arg(personId).toStdString()); + return result; +} + + +QString IrisDataDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + + // INSERT语句 + QString sql = QString("INSERT INTO IRIS_DATA (ID, PERSON_ID, ID_CARD_NO, LEFT_IRIS_CODE1, RIGHT_IRIS_CODE1) VALUES (:id, :personId, :idCardNo, :left1, :right1)"); + + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":personId", object.value("person_id").toString()); + query.bindValue(":idCardNo", object.value("id_card_no").toString()); + query.bindValue(":left1", object.value("left_iris_code1")); + query.bindValue(":right1", object.value("right_iris_code1")); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(); + +// LOG_DEBUG(QString("保存虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool IrisDataDao::edit(QVariantMap newObject, QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // UPDATE语句 + if (!newObject.contains("left_iris_code1") || !newObject.contains("right_iris_code1")){ + return false; + } + QString sql = QString("UPDATE IRIS_DATA SET LEFT_IRIS_CODE1 = :left1, RIGHT_IRIS_CODE1 = :right1 WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":left1", newObject.value("left_iris_code1")); + query.bindValue(":right1", newObject.value("right_iris_code1")); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(); + +// LOG_DEBUG(QString("编辑虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; +} + + +bool IrisDataDao::dele(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + QString sql = QString("DELETE FROM IRIS_DATA WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(); + +// LOG_DEBUG(QString("删除虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; +} diff --git a/dao/IrisDataDao.h b/dao/IrisDataDao.h new file mode 100644 index 0000000..c74dbbd --- /dev/null +++ b/dao/IrisDataDao.h @@ -0,0 +1,25 @@ +#ifndef IRISDATADAO_H +#define IRISDATADAO_H + +#include +#include "BaseDao.h" + +class IrisDataDao : public BaseDao +{ + Q_OBJECT +public: + explicit IrisDataDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + QVariantMap findRecordByPersonId(QString personId); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +signals: + +}; + +#endif // IRISDATADAO_H diff --git a/dao/RecognitionRecordsDao.cpp b/dao/RecognitionRecordsDao.cpp new file mode 100644 index 0000000..40db453 --- /dev/null +++ b/dao/RecognitionRecordsDao.cpp @@ -0,0 +1,100 @@ +#include "RecognitionRecordsDao.h" + +RecognitionRecordsDao::RecognitionRecordsDao(QObject *parent) : BaseDao(parent) +{ + +} + + +QVector RecognitionRecordsDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM RECOGNITION_RECORDS"; + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + item.insert("id", query.value("id").toLongLong()); + result.append(item); + } + +// LOG_DEBUG(QString("查询RECOGNITION_RECORDS表的所有记录[记录数:%1]").arg(result.size()).toStdString()); + return result; +} + +QVariantMap RecognitionRecordsDao::findRecordById(QString id) +{ + QVariantMap item; + return item; +} + +QString RecognitionRecordsDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + + // INSERT语句 + QString sql = QString("INSERT INTO RECOGNITION_RECORDS (ID, PERSON_ID, DATETIME, REC_TYPE, DEV_CODE, DOOR_CODE, INOUT_TYPE) " + "VALUES (:id, :personId, :datetime, :recType, :devCode, :doorCode, :inoutType)"); + + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":personId", object.value("person_id").toString()); + query.bindValue(":datetime", object.value("date_time").toString()); + query.bindValue(":recType", object.value("rec_type").toString()); + query.bindValue(":devCode", object.value("dev_code").toString()); + query.bindValue(":doorCode", object.value("door_code").toString()); + query.bindValue(":inoutType", object.value("inout_type").toString()); + +// LOG_DEBUG(sql.toStdString()); + + // 插入识别的log日志 + QString logStr = QString("INSERT INTO RECOGNITION_LOGS (ID, LOG_INFO) VALUES (:id, :logInfo)"); + + QSqlQuery logQuery(ConnectionManager::getInstance()->getConnection()); + logQuery.prepare(logStr); + logQuery.bindValue(":id", id); + logQuery.bindValue(":logInfo", object.value("debug_info").toString()); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(); + logQuery.exec(); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool RecognitionRecordsDao::edit(QVariantMap newObject, QString id) +{ + return false; +} + +bool RecognitionRecordsDao::dele(QString id) +{ + return false; +} diff --git a/dao/RecognitionRecordsDao.h b/dao/RecognitionRecordsDao.h new file mode 100644 index 0000000..38de7c9 --- /dev/null +++ b/dao/RecognitionRecordsDao.h @@ -0,0 +1,23 @@ +#ifndef RECOGNITIONRECORDSDAO_H +#define RECOGNITIONRECORDSDAO_H + +#include +#include "BaseDao.h" +class RecognitionRecordsDao: public BaseDao +{ + Q_OBJECT +public: + explicit RecognitionRecordsDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +signals: + +}; + +#endif // RECOGNITIONRECORDSDAO_H diff --git a/dao/SysDeptDao.cpp b/dao/SysDeptDao.cpp new file mode 100644 index 0000000..22f9946 --- /dev/null +++ b/dao/SysDeptDao.cpp @@ -0,0 +1,88 @@ +#include "SysDeptDao.h" + +SysDeptDao::SysDeptDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector SysDeptDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_DEPT WHERE PID != '-1' ORDER BY PID, NUM"; + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + item.insert("id", query.value("id").toString()); + item.insert("pid", query.value("pid").toString()); + item.insert("pids", query.value("pids").toString()); + item.insert("simplename", query.value("simplename").toString()); + item.insert("fullname", query.value("fullname").toString()); + } + +// LOG_TRACE(QString("查询表[SYS_DEPT]的所有记录[%1][%2]").arg(result.size()).arg(sql).toStdString()); + + return result; +} + +QVariantMap SysDeptDao::findRecordById(QString id) +{ + QVariantMap item; + return item; + + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM SYS_DEPT WHERE SYS_DEPT.ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + // 获取结果集的大小 + query.last(); + int count = query.at() + 1; + + if (count >=1) + { + query.first(); + + result.insert("id", query.value("id").toString()); + result.insert("pid", query.value("pid").toString()); + result.insert("pids", query.value("pids").toString()); + result.insert("simplename", query.value("simplename").toString()); + result.insert("fullname", query.value("fullname").toString()); + } + +// LOG_TRACE(QString("根据id查询SYS_DEPT表的记录[ID=%1][%2]").arg(id).arg(sql).toStdString()); + + return result; +} + + +QString SysDeptDao::save(QVariantMap object) +{ + return "0"; +} +bool SysDeptDao::edit(QVariantMap newObject, QString id) +{ + return true; +} +bool SysDeptDao::dele(QString id) +{ + return true; +} diff --git a/dao/SysDeptDao.h b/dao/SysDeptDao.h new file mode 100644 index 0000000..e07a09f --- /dev/null +++ b/dao/SysDeptDao.h @@ -0,0 +1,24 @@ +#ifndef SYSDEPTDAO_H +#define SYSDEPTDAO_H + +#include +#include "BaseDao.h" + +class SysDeptDao : public BaseDao +{ + Q_OBJECT +public: + explicit SysDeptDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +private: + +}; + +#endif // SYSDEPTDAO_H diff --git a/AppConstants.h b/AppConstants.h new file mode 100644 index 0000000..296c53f --- /dev/null +++ b/AppConstants.h @@ -0,0 +1,28 @@ +#ifndef APPCONSTANTS_H +#define APPCONSTANTS_H + +class AppConstants +{ +public: + enum WidgeFrameName + { + MAIN_PAGE = 0, // 主页面 + PERSON_LIST_FORM = 1, // 人员列表页面 + ADD_PERSON_FORM = 2, // 添加人员页面 + ADD_PERSON_CAPTURE_FACE = 21, // 添加/编辑人员时进行人脸拍图 + ADD_PERSON_CAPTURE_IRIS = 22, // 添加/编辑人员时进行虹膜拍图 + SETTING_FORM = 3, // 设置页面 + RECOGNIZE_RESULT_FORM = 4, // 识别结果界面 + IDENTIFY_FORM = 5, // 识别界面 含识别中 和 识别结果 + LOCKSCREEN_FORM = 6 // 锁屏待机界面 + }; + + enum ApplicationState + { + STATE_WAIT = 0, // 待机 + STATE_WORKING = 1, // 工作状态 + STATE_IDENTIFYING = 2, // 识别中 + }; +}; + +#endif // APPCONSTANTS_H diff --git a/CasicIrisIdentify.pro b/CasicIrisIdentify.pro index 5d7fea6..575ce3d 100644 --- a/CasicIrisIdentify.pro +++ b/CasicIrisIdentify.pro @@ -1,4 +1,4 @@ -QT += core gui +QT += core gui sql network texttospeech greaterThan(QT_MAJOR_VERSION, 4): QT += widgets @@ -15,20 +15,46 @@ # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 -SOURCES += \ - main.cpp \ - IdentifyForm.cpp +include("dao/dao.pri") +include("device/device.pri") +include("utils/utils.pri") -HEADERS += \ - IdentifyForm.h +SOURCES += main.cpp +SOURCES += ProMemory.cpp +SOURCES += MainWindowForm.cpp +SOURCES += IdentifyForm.cpp +SOURCES += LockScreenForm.cpp -FORMS += \ - IdentifyForm.ui +HEADERS += AppConstants.h +HEADERS += ProMemory.h +HEADERS += MainWindowForm.h +HEADERS += IdentifyForm.h +HEADERS += LockScreenForm.h -TRANSLATIONS += \ - CasicIrisIdentify_zh_CN.ts +FORMS += MainWindowForm.ui +FORMS += IdentifyForm.ui +FORMS += LockScreenForm.ui + +RESOURCES += resource.qrc + +DISTFILES += conf/config.ini + +#TRANSLATIONS += CasicIrisIdentify_zh_CN.ts + +#INCLUDEPATH += include/spdlog +#DEPENDPATH += include/spdlog # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target + + +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lopencv_world420 +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lGxIAPICPPEx + +INCLUDEPATH += $$PWD/include/daheng +DEPENDPATH += $$PWD/include/daheng + +INCLUDEPATH += $$PWD/include +DEPENDPATH += $$PWD/include diff --git a/CasicIrisIdentify_zh_CN.ts b/CasicIrisIdentify_zh_CN.ts index 5526fe4..81900df 100644 --- a/CasicIrisIdentify_zh_CN.ts +++ b/CasicIrisIdentify_zh_CN.ts @@ -1,3 +1,12 @@ - + + + IdentifyForm + + + IdentifyForm + + + + diff --git a/IdentifyForm.cpp b/IdentifyForm.cpp index 348a897..ba1f251 100644 --- a/IdentifyForm.cpp +++ b/IdentifyForm.cpp @@ -1,4 +1,4 @@ -#include "IdentifyForm.h" +#include "IdentifyForm.h" #include "ui_IdentifyForm.h" IdentifyForm::IdentifyForm(QWidget *parent) @@ -6,6 +6,12 @@ , ui(new Ui::IdentifyForm) { ui->setupUi(this); + + // 初始化更新界面的定时器 + // 每秒执行一次 + connect(TimeCounterUtil::getInstance().clockCounter, &QTimer::timeout, this, &IdentifyForm::updateDateAndTime); + + TimeCounterUtil::getInstance().clockCounter->start(1000); } IdentifyForm::~IdentifyForm() @@ -13,3 +19,16 @@ delete ui; } +void IdentifyForm::drawIrisImageOnFrame(QImage image) +{ + // 只在识别界面才显示画面 + if (ui->wgtStacked->currentIndex() == 0) { + ui->labelVideo->setPixmap(QPixmap::fromImage(image)); + } +} + + +void IdentifyForm::updateDateAndTime() +{ + ui->labelTime->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd dddd HH:mm:ss")); +} diff --git a/IdentifyForm.h b/IdentifyForm.h index fc857a1..ae1cd22 100644 --- a/IdentifyForm.h +++ b/IdentifyForm.h @@ -1,7 +1,10 @@ -#ifndef IDENTIFYFORM_H +#ifndef IDENTIFYFORM_H #define IDENTIFYFORM_H #include +#include + +#include "utils/UtilInclude.h" QT_BEGIN_NAMESPACE namespace Ui { class IdentifyForm; } @@ -15,7 +18,14 @@ IdentifyForm(QWidget *parent = nullptr); ~IdentifyForm(); +public slots: + void drawIrisImageOnFrame(QImage image); + private: Ui::IdentifyForm *ui; + +private slots: + void updateDateAndTime(); + }; #endif // IDENTIFYFORM_H diff --git a/IdentifyForm.ui b/IdentifyForm.ui index c72a36f..879dc9a 100644 --- a/IdentifyForm.ui +++ b/IdentifyForm.ui @@ -6,13 +6,59 @@ 0 0 - 800 + 600 600 IdentifyForm + + + + 0 + 40 + 600 + 450 + + + + 0 + + + + + + 100 + 10 + 400 + 300 + + + + + + + + + + + + + + 0 + 0 + 600 + 40 + + + + TextLabel + + + Qt::AlignCenter + + diff --git a/LockScreenForm.cpp b/LockScreenForm.cpp new file mode 100644 index 0000000..58dc54b --- /dev/null +++ b/LockScreenForm.cpp @@ -0,0 +1,14 @@ +#include "LockScreenForm.h" +#include "ui_LockScreenForm.h" + +LockScreenForm::LockScreenForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::LockScreenForm) +{ + ui->setupUi(this); +} + +LockScreenForm::~LockScreenForm() +{ + delete ui; +} diff --git a/LockScreenForm.h b/LockScreenForm.h new file mode 100644 index 0000000..b5ded48 --- /dev/null +++ b/LockScreenForm.h @@ -0,0 +1,25 @@ +#ifndef LOCKSCREENFORM_H +#define LOCKSCREENFORM_H + +#include +#include + +#include "utils/UtilInclude.h" + +namespace Ui { +class LockScreenForm; +} + +class LockScreenForm : public QWidget +{ + Q_OBJECT + +public: + explicit LockScreenForm(QWidget *parent = nullptr); + ~LockScreenForm(); + +private: + Ui::LockScreenForm *ui; +}; + +#endif // LOCKSCREENFORM_H diff --git a/LockScreenForm.ui b/LockScreenForm.ui new file mode 100644 index 0000000..7f2a6db --- /dev/null +++ b/LockScreenForm.ui @@ -0,0 +1,45 @@ + + + LockScreenForm + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + 180 + 100 + 54 + 12 + + + + TextLabel + + + + + + 180 + 160 + 54 + 12 + + + + TextLabel + + + + + + diff --git a/MainWindowForm.cpp b/MainWindowForm.cpp new file mode 100644 index 0000000..84f8159 --- /dev/null +++ b/MainWindowForm.cpp @@ -0,0 +1,86 @@ +#include "MainWindowForm.h" +#include "ui_MainWindowForm.h" +#include + +MainWindowForm::MainWindowForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::MainWindowForm) +{ + ui->setupUi(this); + + // 设置窗口透明和大小、位置 + this->setWindowFlags(Qt::FramelessWindowHint); + this->move(1400, 15); + this->resize(SettingConfig::getInstance().WINDOW_WIDTH, SettingConfig::getInstance().WINDOW_HEIGHT); + + // 通过调色板的颜色来设置窗口的统一背景色 + qApp->setPalette(QPalette(QColor(SettingConfig::getInstance().WINDOW_BACKGROUND_COLOR))); + + // 加载css文件设置控件样式 + QFile file(QApplication::applicationDirPath() + "/qss/main.css"); + if (file.open(QFile::ReadOnly)) + { + QString qssStr = QLatin1String(file.readAll()); + this->setStyleSheet(qssStr); + file.close(); + } + + initFormsPtr(); + + // 设置标题文字 + ui->labelTitle->setText(SettingConfig::getInstance().WINDOW_TITLE); + ui->labelCopyright->setText(SettingConfig::getInstance().WINDOW_RIGHTS); + ui->labelVersion->setText(SettingConfig::getInstance().WINDOW_VERSION); + + // 初始化虹膜相机控制 + ProMemory::getInstance().irisCam = new IrisCameraController(this); + ProMemory::getInstance().irisCam->initIrisCamera(); + ProMemory::getInstance().irisCam->openIrisCamera(); + connect(ProMemory::getInstance().irisCam->irisCamHandler, &IrisCameraCapEventHandler::sendIrisFrameToDraw, identifyForm, &IdentifyForm::drawIrisImageOnFrame); + +// LOG_INFO(QString("应用程序启动成功[Application Startup Success]").toStdString()); + qDebug() << "应用程序启动成功[Application Startup Success]"; + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::IDENTIFY_FORM; + ui->wdgtStatced->setCurrentWidget(identifyForm); + + // 开始虹膜相机拍图 + ProMemory::getInstance().irisCam->startCapture(); +} + +MainWindowForm::~MainWindowForm() +{ + delete ui; +} + +void MainWindowForm::lockScreen() +{ + ui->wdgtStatced->setCurrentWidget(lockScreenForm); + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::LOCKSCREEN_FORM; + ProMemory::getInstance().appState = AppConstants::ApplicationState::STATE_WAIT; +} + +void MainWindowForm::keyPressEvent(QKeyEvent *event) +{ + switch (event->key()) { + case Qt::Key_Escape: + QTimer::singleShot(100, qApp, [=](){ + QApplication::quit(); + }); + + default: + QWidget::keyPressEvent(event); + } +} + +void MainWindowForm::initFormsPtr() +{ + // 初始化各个form + lockScreenForm = new LockScreenForm(this); + identifyForm = new IdentifyForm(this); + + // 将form添加到statcked widget中 + ui->wdgtStatced->addWidget(identifyForm); + ui->wdgtStatced->addWidget(lockScreenForm); + + // 绑定按钮函数 +} diff --git a/MainWindowForm.h b/MainWindowForm.h new file mode 100644 index 0000000..7fb2d89 --- /dev/null +++ b/MainWindowForm.h @@ -0,0 +1,38 @@ +#ifndef MAINWINDOWFORM_H +#define MAINWINDOWFORM_H + +#include +#include +#include + +#include "utils/UtilInclude.h" +#include "ProMemory.h" +#include "LockScreenForm.h" +#include "IdentifyForm.h" + +namespace Ui { +class MainWindowForm; +} + +class MainWindowForm : public QWidget +{ + Q_OBJECT + +public: + explicit MainWindowForm(QWidget *parent = nullptr); + ~MainWindowForm(); + +public slots: + void lockScreen(); + +private: + Ui::MainWindowForm *ui; + LockScreenForm * lockScreenForm; + IdentifyForm * identifyForm; + + void keyPressEvent(QKeyEvent *event); + + void initFormsPtr(); +}; + +#endif // MAINWINDOWFORM_H diff --git a/MainWindowForm.ui b/MainWindowForm.ui new file mode 100644 index 0000000..e793ebf --- /dev/null +++ b/MainWindowForm.ui @@ -0,0 +1,85 @@ + + + MainWindowForm + + + + 0 + 0 + 600 + 1024 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + 0 + 0 + 600 + 84 + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + + + + TextLabel + + + Qt::AlignBottom|Qt::AlignHCenter + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + diff --git a/ProMemory.cpp b/ProMemory.cpp new file mode 100644 index 0000000..19e7403 --- /dev/null +++ b/ProMemory.cpp @@ -0,0 +1,84 @@ +#include "ProMemory.h" + +ProMemory::ProMemory() +{ + +} + +ProMemory::~ProMemory() +{ + +} + +/* +void ProMemory::pushCasicIris(CasicIrisInfo irisInfo) +{ + QMutex mutex; + mutex.lock(); + if (this->irisQueue.size() > 30) + { + QStack empty; + std::swap(empty, irisQueue); + } + + irisQueue.push(irisInfo); + mutex.unlock(); +} +CasicIrisInfo ProMemory::popCasicIris() +{ + CasicIrisInfo result; + + QMutex mutex; + mutex.lock(); + if (this->irisQueue.size() > 0) + { + result = irisQueue.pop(); + } + + mutex.unlock(); + + return result; +} +*/ +int ProMemory::getIrisQueueSize() +{ + int size = 0; + + QMutex mutex; + mutex.lock(); + +// size = this->irisQueue.size(); + + mutex.unlock(); + + return size; +} +bool ProMemory::isIrisQueueEmpty() +{ + bool empty = true; + + QMutex mutex; + mutex.lock(); + +// empty = this->irisQueue.isEmpty(); + + mutex.unlock(); + + return empty; +} +void ProMemory::clearIrisQueue() +{ + QMutex mutex; + mutex.lock(); + +// QStack empty; +// std::swap(empty, irisQueue); + + mutex.unlock(); +} + + +void ProMemory::initIrisFeatures(QString personId) +{ +// irisRegistPro->sendDataToExract(QByteArray(QString("[-u]").append(personId).toLocal8Bit())); +} diff --git a/ProMemory.h b/ProMemory.h new file mode 100644 index 0000000..2ecd653 --- /dev/null +++ b/ProMemory.h @@ -0,0 +1,52 @@ +#ifndef PROMEMORY_H +#define PROMEMORY_H + +#include +#include + +#include "AppConstants.h" +//#include "casic/iris/CasicIrisInfo.h" +#include "dao/IrisDataDao.h" + +#include "device/IrisCameraController.h" +//#include "device/iris/IrisRegistProcess.h" +//#include "device/iris/IrisRecogProcess.h" + +class IrisCameraController; +class IrisRegistProcess; +class IrisRecogProcess; + +class ProMemory +{ +public: + ~ProMemory(); + ProMemory(const ProMemory&)=delete; + ProMemory& operator=(const ProMemory&)=delete; + + static ProMemory& getInstance() { + static ProMemory instance; + return instance; + } + +// void pushCasicIris(CasicIrisInfo irisInfo); +// CasicIrisInfo popCasicIris(); + int getIrisQueueSize(); + bool isIrisQueueEmpty(); + void clearIrisQueue(); + + volatile int widgeFrame = 0; // 当前显示的界面 + volatile int appState = 0; // 当前程序所处的状态 + + void initIrisFeatures(QString personId = ""); // 初始化虹膜特征值集合 + + IrisCameraController * irisCam; + IrisRecogProcess * irisRecogPro; + +private: + ProMemory(); + +// QStack irisQueue; // 虹膜信息队列 + QVector irisFeatures; // 虹膜特征值集合 +}; + +#endif // PROMEMORY_H diff --git a/conf/config.ini b/conf/config.ini new file mode 100644 index 0000000..66e46ad --- /dev/null +++ b/conf/config.ini @@ -0,0 +1,67 @@ +[recognize] +#最大允许识别时间(ms) +maxMatchTime=10000 +#识别成功界面停留时间(ms) +successTipsLast=5000 +#识别失败界面停留时间(ms) +failureTipsLast=3000 +#人脸识别最大尝试次数 +maxFaceTryCount=20 +#持续没找到人脸的最大次数 +maxFaceNotFoundCount=500 +#注册时最小人脸 +minFaceRegist=240 +#识别时最小人脸 +minFaceRecog=100 + +#虹膜识别最大尝试次数 +maxIrisTryCount=10 +#虹膜识别持续没有找到眼的最大次数 +maxEyeNotFoundCount=50 + +#识别方式[1=人脸;2=虹膜;3=双认证;4=任意] +recogType=4 + +[window] +#界面窗口宽(px) +width=600 +#界面窗口高(px) +height=1024 +#统一背景色 +backgroundColor="#FFFFFF" +#标题 +title="虹膜识别终端" + +[work] +#工作状态检测时最小人脸范围 +minFaceSize=160 +#人脸范围最小横坐标 +minFacePosX=320 +#人脸范围最大横坐标 +maxFacePosX=960 +#人脸范围最小纵坐标 +minFacePosY=180 +#人脸范围最大纵坐标 +maxFacePosY=540 +#人脸太近阈值 +faceCloseSize=360 +#人脸太远阈值 +faceFarSize=480 + +[camera] +#虹膜相机取一幅画面的时间间隔(ms) +irisFrameInterval=100 +#虹膜相机拍摄宽度 +irisFrameWidth=1440 +#虹膜相机拍摄高度 +irisFrameHeight=1080 +#虹膜图像高度 +irisWidth=640 +#虹膜图像高度 +irisHeight=480 + +[log] +#日志文件位置 +logFile="d://irisLogs//casic_log.txt" +#日志级别 +logLevel="trace" diff --git a/dao/BaseDao.cpp b/dao/BaseDao.cpp new file mode 100644 index 0000000..f51c144 --- /dev/null +++ b/dao/BaseDao.cpp @@ -0,0 +1,12 @@ +#include "BaseDao.h" +#include "dao/util/ConnectionManager.h" + +BaseDao::BaseDao(QObject *parent) : QObject(parent) +{ + +} + +BaseDao::~BaseDao() +{ + +} diff --git a/dao/BaseDao.h b/dao/BaseDao.h new file mode 100644 index 0000000..1693c88 --- /dev/null +++ b/dao/BaseDao.h @@ -0,0 +1,32 @@ +#ifndef BASEDAO_H +#define BASEDAO_H + +#include +#include +#include +#include + +#include "dao/util/ConnectionManager.h" +#include "utils/UtilInclude.h" + +class BaseDao : public QObject +{ + Q_OBJECT +public: + explicit BaseDao(QObject *parent = nullptr); + ~BaseDao(); + + virtual QVector findAllRecord() = 0; + virtual QVariantMap findRecordById(QString id) = 0; + + virtual QString save(QVariantMap object) = 0; + virtual bool edit(QVariantMap newObject, QString id) = 0; + virtual bool dele(QString id) = 0; + +private: + +signals: + +}; + +#endif // BASEDAO_H diff --git a/dao/IrisDataDao.cpp b/dao/IrisDataDao.cpp new file mode 100644 index 0000000..37a0ed6 --- /dev/null +++ b/dao/IrisDataDao.cpp @@ -0,0 +1,204 @@ +#include "IrisDataDao.h" + +IrisDataDao::IrisDataDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector IrisDataDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM IRIS_DATA"; + query.prepare(sql); + + // 执行查询 + query.exec(); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + item.insert("id", query.value("id").toString()); + item.insert("person_id", query.value("person_id").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("left_iris_code1", query.value("left_iris_code1")); + item.insert("left_iris_code2", query.value("left_iris_code2")); + item.insert("left_iris_code3", query.value("left_iris_code3")); + item.insert("right_iris_code1", query.value("right_iris_code1")); + item.insert("right_iris_code2", query.value("right_iris_code2")); + item.insert("right_iris_code3", query.value("right_iris_code3")); + + result.append(item); + } + +// LOG_DEBUG(QString("查询IRIS_DATA表的所有记录[结果数:%1]").arg(result.size()).toStdString()); + return result; +} + +QVariantMap IrisDataDao::findRecordById(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM IRIS_DATA WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + // 获取结果 + if (query.next()) + { + result.insert("id", query.value("id").toString()); + result.insert("person_id", query.value("person_id").toLongLong()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("left_iris_code1", query.value("left_iris_code1")); + result.insert("left_iris_code2", query.value("left_iris_code2")); + result.insert("left_iris_code3", query.value("left_iris_code3")); + result.insert("right_iris_code1", query.value("right_iris_code1")); + result.insert("right_iris_code2", query.value("right_iris_code2")); + result.insert("right_iris_code3", query.value("right_iris_code3")); + } + +// LOG_DEBUG(QString("根据id查询IRIS_DATA表的记录[id=%1]").arg(id).toStdString()); + return result; +} + +QVariantMap IrisDataDao::findRecordByPersonId(QString personId) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM IRIS_DATA WHERE PERSON_ID = :personId"); + query.prepare(sql); + query.bindValue(":personId", personId); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + if (query.next()) + { + result.insert("id", query.value("id").toString()); + result.insert("person_id", query.value("person_id").toLongLong()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("left_iris_code1", query.value("left_iris_code1")); + result.insert("left_iris_code2", query.value("left_iris_code2")); + result.insert("left_iris_code3", query.value("left_iris_code3")); + result.insert("right_iris_code1", query.value("right_iris_code1")); + result.insert("right_iris_code2", query.value("right_iris_code2")); + result.insert("right_iris_code3", query.value("right_iris_code3")); + } + +// LOG_DEBUG(QString("根据personId查询IRIS_DATA表的记录[personId=%1]").arg(personId).toStdString()); + return result; +} + + +QString IrisDataDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + + // INSERT语句 + QString sql = QString("INSERT INTO IRIS_DATA (ID, PERSON_ID, ID_CARD_NO, LEFT_IRIS_CODE1, RIGHT_IRIS_CODE1) VALUES (:id, :personId, :idCardNo, :left1, :right1)"); + + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":personId", object.value("person_id").toString()); + query.bindValue(":idCardNo", object.value("id_card_no").toString()); + query.bindValue(":left1", object.value("left_iris_code1")); + query.bindValue(":right1", object.value("right_iris_code1")); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(); + +// LOG_DEBUG(QString("保存虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool IrisDataDao::edit(QVariantMap newObject, QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // UPDATE语句 + if (!newObject.contains("left_iris_code1") || !newObject.contains("right_iris_code1")){ + return false; + } + QString sql = QString("UPDATE IRIS_DATA SET LEFT_IRIS_CODE1 = :left1, RIGHT_IRIS_CODE1 = :right1 WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":left1", newObject.value("left_iris_code1")); + query.bindValue(":right1", newObject.value("right_iris_code1")); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(); + +// LOG_DEBUG(QString("编辑虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; +} + + +bool IrisDataDao::dele(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + QString sql = QString("DELETE FROM IRIS_DATA WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(); + +// LOG_DEBUG(QString("删除虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; +} diff --git a/dao/IrisDataDao.h b/dao/IrisDataDao.h new file mode 100644 index 0000000..c74dbbd --- /dev/null +++ b/dao/IrisDataDao.h @@ -0,0 +1,25 @@ +#ifndef IRISDATADAO_H +#define IRISDATADAO_H + +#include +#include "BaseDao.h" + +class IrisDataDao : public BaseDao +{ + Q_OBJECT +public: + explicit IrisDataDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + QVariantMap findRecordByPersonId(QString personId); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +signals: + +}; + +#endif // IRISDATADAO_H diff --git a/dao/RecognitionRecordsDao.cpp b/dao/RecognitionRecordsDao.cpp new file mode 100644 index 0000000..40db453 --- /dev/null +++ b/dao/RecognitionRecordsDao.cpp @@ -0,0 +1,100 @@ +#include "RecognitionRecordsDao.h" + +RecognitionRecordsDao::RecognitionRecordsDao(QObject *parent) : BaseDao(parent) +{ + +} + + +QVector RecognitionRecordsDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM RECOGNITION_RECORDS"; + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + item.insert("id", query.value("id").toLongLong()); + result.append(item); + } + +// LOG_DEBUG(QString("查询RECOGNITION_RECORDS表的所有记录[记录数:%1]").arg(result.size()).toStdString()); + return result; +} + +QVariantMap RecognitionRecordsDao::findRecordById(QString id) +{ + QVariantMap item; + return item; +} + +QString RecognitionRecordsDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + + // INSERT语句 + QString sql = QString("INSERT INTO RECOGNITION_RECORDS (ID, PERSON_ID, DATETIME, REC_TYPE, DEV_CODE, DOOR_CODE, INOUT_TYPE) " + "VALUES (:id, :personId, :datetime, :recType, :devCode, :doorCode, :inoutType)"); + + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":personId", object.value("person_id").toString()); + query.bindValue(":datetime", object.value("date_time").toString()); + query.bindValue(":recType", object.value("rec_type").toString()); + query.bindValue(":devCode", object.value("dev_code").toString()); + query.bindValue(":doorCode", object.value("door_code").toString()); + query.bindValue(":inoutType", object.value("inout_type").toString()); + +// LOG_DEBUG(sql.toStdString()); + + // 插入识别的log日志 + QString logStr = QString("INSERT INTO RECOGNITION_LOGS (ID, LOG_INFO) VALUES (:id, :logInfo)"); + + QSqlQuery logQuery(ConnectionManager::getInstance()->getConnection()); + logQuery.prepare(logStr); + logQuery.bindValue(":id", id); + logQuery.bindValue(":logInfo", object.value("debug_info").toString()); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(); + logQuery.exec(); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool RecognitionRecordsDao::edit(QVariantMap newObject, QString id) +{ + return false; +} + +bool RecognitionRecordsDao::dele(QString id) +{ + return false; +} diff --git a/dao/RecognitionRecordsDao.h b/dao/RecognitionRecordsDao.h new file mode 100644 index 0000000..38de7c9 --- /dev/null +++ b/dao/RecognitionRecordsDao.h @@ -0,0 +1,23 @@ +#ifndef RECOGNITIONRECORDSDAO_H +#define RECOGNITIONRECORDSDAO_H + +#include +#include "BaseDao.h" +class RecognitionRecordsDao: public BaseDao +{ + Q_OBJECT +public: + explicit RecognitionRecordsDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +signals: + +}; + +#endif // RECOGNITIONRECORDSDAO_H diff --git a/dao/SysDeptDao.cpp b/dao/SysDeptDao.cpp new file mode 100644 index 0000000..22f9946 --- /dev/null +++ b/dao/SysDeptDao.cpp @@ -0,0 +1,88 @@ +#include "SysDeptDao.h" + +SysDeptDao::SysDeptDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector SysDeptDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_DEPT WHERE PID != '-1' ORDER BY PID, NUM"; + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + item.insert("id", query.value("id").toString()); + item.insert("pid", query.value("pid").toString()); + item.insert("pids", query.value("pids").toString()); + item.insert("simplename", query.value("simplename").toString()); + item.insert("fullname", query.value("fullname").toString()); + } + +// LOG_TRACE(QString("查询表[SYS_DEPT]的所有记录[%1][%2]").arg(result.size()).arg(sql).toStdString()); + + return result; +} + +QVariantMap SysDeptDao::findRecordById(QString id) +{ + QVariantMap item; + return item; + + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM SYS_DEPT WHERE SYS_DEPT.ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + // 获取结果集的大小 + query.last(); + int count = query.at() + 1; + + if (count >=1) + { + query.first(); + + result.insert("id", query.value("id").toString()); + result.insert("pid", query.value("pid").toString()); + result.insert("pids", query.value("pids").toString()); + result.insert("simplename", query.value("simplename").toString()); + result.insert("fullname", query.value("fullname").toString()); + } + +// LOG_TRACE(QString("根据id查询SYS_DEPT表的记录[ID=%1][%2]").arg(id).arg(sql).toStdString()); + + return result; +} + + +QString SysDeptDao::save(QVariantMap object) +{ + return "0"; +} +bool SysDeptDao::edit(QVariantMap newObject, QString id) +{ + return true; +} +bool SysDeptDao::dele(QString id) +{ + return true; +} diff --git a/dao/SysDeptDao.h b/dao/SysDeptDao.h new file mode 100644 index 0000000..e07a09f --- /dev/null +++ b/dao/SysDeptDao.h @@ -0,0 +1,24 @@ +#ifndef SYSDEPTDAO_H +#define SYSDEPTDAO_H + +#include +#include "BaseDao.h" + +class SysDeptDao : public BaseDao +{ + Q_OBJECT +public: + explicit SysDeptDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +private: + +}; + +#endif // SYSDEPTDAO_H diff --git a/dao/SysPersonDao.cpp b/dao/SysPersonDao.cpp new file mode 100644 index 0000000..dd9480f --- /dev/null +++ b/dao/SysPersonDao.cpp @@ -0,0 +1,371 @@ +#include "SysPersonDao.h" + + +SysPersonDao::SysPersonDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector SysPersonDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0'"; + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + count++; + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + result.append(item); + } + +// LOG(TRACE) << QString("查询SYS_PERSON表的所有记录[%1]").arg(count).toStdString(); +// LOG_TRACE(QString("查询SYS_PERSON表的所有记录[%1]").arg(count).toStdString()); + + return result; +} + +QVariantMap SysPersonDao::findRecordById(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0' AND SYS_PERSON.ID = '%1'").arg(id); + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVariantMap result; + + // 获取结果集的大小 + query.last(); + int count = query.at() + 1; + + if (count >=1) + { + query.first(); + + result.insert("id", query.value("id").toString()); + result.insert("delflag", query.value("delflag").toString()); + result.insert("createtime", query.value("createtime").toString()); + result.insert("updatetime", query.value("updatetime").toString()); + result.insert("name", query.value("name").toString()); + result.insert("gender", query.value("gender").toString()); + result.insert("deptid", query.value("deptid").toString()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("remarks", query.value("remarks").toString()); + result.insert("person_code", query.value("person_code").toString()); + result.insert("deptname", query.value("fullname").toString()); + result.insert("sync_id", query.value("sync_id").toString()); + result.insert("hasFace", query.value("face_valid").toString()); + result.insert("hasIris", query.value("iris_valid").toString()); + } + +// LOG(TRACE) << QString("根据id查询SYS_PERSON表的记录[id=%1][%2]").arg(id).arg(sql).toStdString(); +// LOG_TRACE(QString("根据id查询SYS_PERSON表的记录[id=%1][%2]").arg(id).arg(sql).toStdString()); + + return result; +} + +int SysPersonDao::findRecordCountByNameAndDept(QString name, QString dept) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT COUNT(P.ID) AS RECCT FROM SYS_PERSON P LEFT JOIN SYS_DEPT D ON P.DEPTID = D.ID WHERE P.DELFLAG = '0'"; + if (name.isEmpty() == false) + { + sql += " AND P.NAME LIKE '%" + name + "%'"; + } + if (dept.isEmpty() == false && dept.indexOf("-1") < 0) + { + sql += QString(" AND ((P.DEPTID = '%1') OR (D.PIDS LIKE '%,%1,%'))").arg(dept); + } + + // 执行查询 + query.exec(sql); + + // 返回结果 + int result; + + // 遍历查询结果 + if (query.next()) { + result = query.value("RECCT").toInt(); + } + +// LOG(TRACE) << QString("根据姓名和部门查询SYS_PERSON记录总数[%1][%2]").arg(result).arg(sql).toStdString(); +// LOG_TRACE(QString("根据姓名和部门查询SYS_PERSON记录总数[%1][%2]").arg(result).arg(sql).toStdString()); + + return result; +} + +QVector SysPersonDao::findRecordsByNameAndDept(QString name, QString dept, qint8 limit, qint16 offset) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON P LEFT JOIN SYS_DEPT D ON P.DEPTID = D.ID WHERE P.DELFLAG = '0'"; + if (name.isEmpty() == false) + { + sql += " AND P.NAME LIKE '%" + name + "%'"; + } + if (dept.isEmpty() == false && dept.indexOf("-1") < 0) + { + sql += QString(" AND ((P.DEPTID = '%1') OR (D.PIDS LIKE '%,%1,%'))").arg(dept); + } + + sql += QString(" LIMIT %1 OFFSET %2").arg(limit).arg(offset); + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + count++; + + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + + result.append(item); + } + +// LOG(TRACE) << QString("根据姓名和部门分页查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString(); +// LOG_TRACE(QString("根据姓名和部门分页查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString()); + + return result; +} + +QVector SysPersonDao::findRecordsByProperties(QVariantMap conditions) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0'"; + QVariantMap::iterator it; + for (it = conditions.begin(); it != conditions.end(); it++) + { + sql += QString(" AND SYS_PERSON.%1 = %2").arg(it.key()).arg(it.value().toString()); + } + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + count++; + + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + + result.append(item); + } + +// LOG(TRACE) << QString("根据属性值查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString(); +// LOG_TRACE(QString("根据属性值查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString()); + + return result; +} + +QString SysPersonDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + + // INSERT语句 + QString sql = QString("INSERT INTO SYS_PERSON " + "(ID, DELFLAG, CREATETIME, UPDATETIME, " + "NAME, GENDER, DEPTID, ID_CARD_NO, " + "REMARKS, PERSON_CODE, SYNC_ID, FACE_VALID, IRIS_VALID) " + "VALUES ('%1', '0', '%2', '%2', '%3', '%4', '%5', '%6', '%7', '%8', '%9', 0, 0)") + .arg(id).arg(tm) + .arg(object.value("name").toString()) + .arg(object.value("gender").toString()) + .arg(object.value("deptid").toString()) + .arg(object.value("id_card_no").toString()) + .arg(object.value("remarks").toString()) + .arg(object.value("person_code").toString()) + .arg(object.value("sync_id").toString()); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(sql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { +// LOG(DEBUG) << QString("保存SYS_PERSON记录成功[ID = %1][%2]").arg(id).arg(sql).toStdString(); +// LOG_DEBUG(QString("保存SYS_PERSON记录成功[ID = %1][%2]").arg(id).arg(sql).toStdString()); + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool SysPersonDao::edit(QVariantMap newObject, QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + + // UPDATE语句 + QString sql = QString("UPDATE SYS_PERSON SET UPDATETIME = '%1'").arg(tm); + if (newObject.contains("name")) + { + sql.append(QString(", NAME = '%1'").arg(newObject.value("name").toString())); + } + if (newObject.contains("gender")) + { + sql.append(QString(", GENDER = '%1'").arg(newObject.value("gender").toString())); + } + if (newObject.contains("deptid")) + { + sql.append(QString(", DEPTID = '%1'").arg(newObject.value("deptid").toString())); + } + if (newObject.contains("person_code")) + { + sql.append(QString(", PERSON_CODE = '%1'").arg(newObject.value("person_code").toString())); + } + if (newObject.contains("face_valid")) + { + sql.append(QString(", FACE_VALID = '%1'").arg(newObject.value("face_valid").toString())); + } + if (newObject.contains("iris_valid")) + { + sql.append(QString(", IRIS_VALID = '%1'").arg(newObject.value("iris_valid").toString())); + } + + sql.append(QString(" WHERE ID = '%1'").arg(id)); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(sql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + +// LOG(DEBUG) << QString("编辑人员[ID=%1][%2]").arg(id).arg(sql).toStdString(); +// LOG_DEBUG(QString("编辑人员[ID=%1][%2]").arg(id).arg(sql).toStdString()); + + // 返回结果 + return success; +} + +bool SysPersonDao::dele(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + QSqlQuery irisDel(ConnectionManager::getInstance()->getConnection()); + + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + qint64 tmms = QDateTime::currentDateTime().toMSecsSinceEpoch(); + + // UPDATE语句 + QString sql = QString("UPDATE SYS_PERSON SET UPDATETIME = :updateTime, DELFLAG = :flag WHERE ID = :id").arg(tm).arg(tmms).arg(id); + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":updateTime", tm); + query.bindValue(":flag", tmms); + + // 物理删除人员的人脸和虹膜数据 + QString delIrisSql = QString("DELETE FROM IRIS_DATA WHERE PERSON_ID = :personId"); + irisDel.prepare(delIrisSql); + irisDel.bindValue(":personId", id); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(sql); + query.exec(delIrisSql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + +// LOG_DEBUG(QString("删除人员SYS_PERSON[ID=%1][%2]").arg(id).arg(success).toStdString()); + + // 返回结果 + return success; +} diff --git a/AppConstants.h b/AppConstants.h new file mode 100644 index 0000000..296c53f --- /dev/null +++ b/AppConstants.h @@ -0,0 +1,28 @@ +#ifndef APPCONSTANTS_H +#define APPCONSTANTS_H + +class AppConstants +{ +public: + enum WidgeFrameName + { + MAIN_PAGE = 0, // 主页面 + PERSON_LIST_FORM = 1, // 人员列表页面 + ADD_PERSON_FORM = 2, // 添加人员页面 + ADD_PERSON_CAPTURE_FACE = 21, // 添加/编辑人员时进行人脸拍图 + ADD_PERSON_CAPTURE_IRIS = 22, // 添加/编辑人员时进行虹膜拍图 + SETTING_FORM = 3, // 设置页面 + RECOGNIZE_RESULT_FORM = 4, // 识别结果界面 + IDENTIFY_FORM = 5, // 识别界面 含识别中 和 识别结果 + LOCKSCREEN_FORM = 6 // 锁屏待机界面 + }; + + enum ApplicationState + { + STATE_WAIT = 0, // 待机 + STATE_WORKING = 1, // 工作状态 + STATE_IDENTIFYING = 2, // 识别中 + }; +}; + +#endif // APPCONSTANTS_H diff --git a/CasicIrisIdentify.pro b/CasicIrisIdentify.pro index 5d7fea6..575ce3d 100644 --- a/CasicIrisIdentify.pro +++ b/CasicIrisIdentify.pro @@ -1,4 +1,4 @@ -QT += core gui +QT += core gui sql network texttospeech greaterThan(QT_MAJOR_VERSION, 4): QT += widgets @@ -15,20 +15,46 @@ # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 -SOURCES += \ - main.cpp \ - IdentifyForm.cpp +include("dao/dao.pri") +include("device/device.pri") +include("utils/utils.pri") -HEADERS += \ - IdentifyForm.h +SOURCES += main.cpp +SOURCES += ProMemory.cpp +SOURCES += MainWindowForm.cpp +SOURCES += IdentifyForm.cpp +SOURCES += LockScreenForm.cpp -FORMS += \ - IdentifyForm.ui +HEADERS += AppConstants.h +HEADERS += ProMemory.h +HEADERS += MainWindowForm.h +HEADERS += IdentifyForm.h +HEADERS += LockScreenForm.h -TRANSLATIONS += \ - CasicIrisIdentify_zh_CN.ts +FORMS += MainWindowForm.ui +FORMS += IdentifyForm.ui +FORMS += LockScreenForm.ui + +RESOURCES += resource.qrc + +DISTFILES += conf/config.ini + +#TRANSLATIONS += CasicIrisIdentify_zh_CN.ts + +#INCLUDEPATH += include/spdlog +#DEPENDPATH += include/spdlog # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target + + +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lopencv_world420 +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lGxIAPICPPEx + +INCLUDEPATH += $$PWD/include/daheng +DEPENDPATH += $$PWD/include/daheng + +INCLUDEPATH += $$PWD/include +DEPENDPATH += $$PWD/include diff --git a/CasicIrisIdentify_zh_CN.ts b/CasicIrisIdentify_zh_CN.ts index 5526fe4..81900df 100644 --- a/CasicIrisIdentify_zh_CN.ts +++ b/CasicIrisIdentify_zh_CN.ts @@ -1,3 +1,12 @@ - + + + IdentifyForm + + + IdentifyForm + + + + diff --git a/IdentifyForm.cpp b/IdentifyForm.cpp index 348a897..ba1f251 100644 --- a/IdentifyForm.cpp +++ b/IdentifyForm.cpp @@ -1,4 +1,4 @@ -#include "IdentifyForm.h" +#include "IdentifyForm.h" #include "ui_IdentifyForm.h" IdentifyForm::IdentifyForm(QWidget *parent) @@ -6,6 +6,12 @@ , ui(new Ui::IdentifyForm) { ui->setupUi(this); + + // 初始化更新界面的定时器 + // 每秒执行一次 + connect(TimeCounterUtil::getInstance().clockCounter, &QTimer::timeout, this, &IdentifyForm::updateDateAndTime); + + TimeCounterUtil::getInstance().clockCounter->start(1000); } IdentifyForm::~IdentifyForm() @@ -13,3 +19,16 @@ delete ui; } +void IdentifyForm::drawIrisImageOnFrame(QImage image) +{ + // 只在识别界面才显示画面 + if (ui->wgtStacked->currentIndex() == 0) { + ui->labelVideo->setPixmap(QPixmap::fromImage(image)); + } +} + + +void IdentifyForm::updateDateAndTime() +{ + ui->labelTime->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd dddd HH:mm:ss")); +} diff --git a/IdentifyForm.h b/IdentifyForm.h index fc857a1..ae1cd22 100644 --- a/IdentifyForm.h +++ b/IdentifyForm.h @@ -1,7 +1,10 @@ -#ifndef IDENTIFYFORM_H +#ifndef IDENTIFYFORM_H #define IDENTIFYFORM_H #include +#include + +#include "utils/UtilInclude.h" QT_BEGIN_NAMESPACE namespace Ui { class IdentifyForm; } @@ -15,7 +18,14 @@ IdentifyForm(QWidget *parent = nullptr); ~IdentifyForm(); +public slots: + void drawIrisImageOnFrame(QImage image); + private: Ui::IdentifyForm *ui; + +private slots: + void updateDateAndTime(); + }; #endif // IDENTIFYFORM_H diff --git a/IdentifyForm.ui b/IdentifyForm.ui index c72a36f..879dc9a 100644 --- a/IdentifyForm.ui +++ b/IdentifyForm.ui @@ -6,13 +6,59 @@ 0 0 - 800 + 600 600 IdentifyForm + + + + 0 + 40 + 600 + 450 + + + + 0 + + + + + + 100 + 10 + 400 + 300 + + + + + + + + + + + + + + 0 + 0 + 600 + 40 + + + + TextLabel + + + Qt::AlignCenter + + diff --git a/LockScreenForm.cpp b/LockScreenForm.cpp new file mode 100644 index 0000000..58dc54b --- /dev/null +++ b/LockScreenForm.cpp @@ -0,0 +1,14 @@ +#include "LockScreenForm.h" +#include "ui_LockScreenForm.h" + +LockScreenForm::LockScreenForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::LockScreenForm) +{ + ui->setupUi(this); +} + +LockScreenForm::~LockScreenForm() +{ + delete ui; +} diff --git a/LockScreenForm.h b/LockScreenForm.h new file mode 100644 index 0000000..b5ded48 --- /dev/null +++ b/LockScreenForm.h @@ -0,0 +1,25 @@ +#ifndef LOCKSCREENFORM_H +#define LOCKSCREENFORM_H + +#include +#include + +#include "utils/UtilInclude.h" + +namespace Ui { +class LockScreenForm; +} + +class LockScreenForm : public QWidget +{ + Q_OBJECT + +public: + explicit LockScreenForm(QWidget *parent = nullptr); + ~LockScreenForm(); + +private: + Ui::LockScreenForm *ui; +}; + +#endif // LOCKSCREENFORM_H diff --git a/LockScreenForm.ui b/LockScreenForm.ui new file mode 100644 index 0000000..7f2a6db --- /dev/null +++ b/LockScreenForm.ui @@ -0,0 +1,45 @@ + + + LockScreenForm + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + 180 + 100 + 54 + 12 + + + + TextLabel + + + + + + 180 + 160 + 54 + 12 + + + + TextLabel + + + + + + diff --git a/MainWindowForm.cpp b/MainWindowForm.cpp new file mode 100644 index 0000000..84f8159 --- /dev/null +++ b/MainWindowForm.cpp @@ -0,0 +1,86 @@ +#include "MainWindowForm.h" +#include "ui_MainWindowForm.h" +#include + +MainWindowForm::MainWindowForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::MainWindowForm) +{ + ui->setupUi(this); + + // 设置窗口透明和大小、位置 + this->setWindowFlags(Qt::FramelessWindowHint); + this->move(1400, 15); + this->resize(SettingConfig::getInstance().WINDOW_WIDTH, SettingConfig::getInstance().WINDOW_HEIGHT); + + // 通过调色板的颜色来设置窗口的统一背景色 + qApp->setPalette(QPalette(QColor(SettingConfig::getInstance().WINDOW_BACKGROUND_COLOR))); + + // 加载css文件设置控件样式 + QFile file(QApplication::applicationDirPath() + "/qss/main.css"); + if (file.open(QFile::ReadOnly)) + { + QString qssStr = QLatin1String(file.readAll()); + this->setStyleSheet(qssStr); + file.close(); + } + + initFormsPtr(); + + // 设置标题文字 + ui->labelTitle->setText(SettingConfig::getInstance().WINDOW_TITLE); + ui->labelCopyright->setText(SettingConfig::getInstance().WINDOW_RIGHTS); + ui->labelVersion->setText(SettingConfig::getInstance().WINDOW_VERSION); + + // 初始化虹膜相机控制 + ProMemory::getInstance().irisCam = new IrisCameraController(this); + ProMemory::getInstance().irisCam->initIrisCamera(); + ProMemory::getInstance().irisCam->openIrisCamera(); + connect(ProMemory::getInstance().irisCam->irisCamHandler, &IrisCameraCapEventHandler::sendIrisFrameToDraw, identifyForm, &IdentifyForm::drawIrisImageOnFrame); + +// LOG_INFO(QString("应用程序启动成功[Application Startup Success]").toStdString()); + qDebug() << "应用程序启动成功[Application Startup Success]"; + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::IDENTIFY_FORM; + ui->wdgtStatced->setCurrentWidget(identifyForm); + + // 开始虹膜相机拍图 + ProMemory::getInstance().irisCam->startCapture(); +} + +MainWindowForm::~MainWindowForm() +{ + delete ui; +} + +void MainWindowForm::lockScreen() +{ + ui->wdgtStatced->setCurrentWidget(lockScreenForm); + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::LOCKSCREEN_FORM; + ProMemory::getInstance().appState = AppConstants::ApplicationState::STATE_WAIT; +} + +void MainWindowForm::keyPressEvent(QKeyEvent *event) +{ + switch (event->key()) { + case Qt::Key_Escape: + QTimer::singleShot(100, qApp, [=](){ + QApplication::quit(); + }); + + default: + QWidget::keyPressEvent(event); + } +} + +void MainWindowForm::initFormsPtr() +{ + // 初始化各个form + lockScreenForm = new LockScreenForm(this); + identifyForm = new IdentifyForm(this); + + // 将form添加到statcked widget中 + ui->wdgtStatced->addWidget(identifyForm); + ui->wdgtStatced->addWidget(lockScreenForm); + + // 绑定按钮函数 +} diff --git a/MainWindowForm.h b/MainWindowForm.h new file mode 100644 index 0000000..7fb2d89 --- /dev/null +++ b/MainWindowForm.h @@ -0,0 +1,38 @@ +#ifndef MAINWINDOWFORM_H +#define MAINWINDOWFORM_H + +#include +#include +#include + +#include "utils/UtilInclude.h" +#include "ProMemory.h" +#include "LockScreenForm.h" +#include "IdentifyForm.h" + +namespace Ui { +class MainWindowForm; +} + +class MainWindowForm : public QWidget +{ + Q_OBJECT + +public: + explicit MainWindowForm(QWidget *parent = nullptr); + ~MainWindowForm(); + +public slots: + void lockScreen(); + +private: + Ui::MainWindowForm *ui; + LockScreenForm * lockScreenForm; + IdentifyForm * identifyForm; + + void keyPressEvent(QKeyEvent *event); + + void initFormsPtr(); +}; + +#endif // MAINWINDOWFORM_H diff --git a/MainWindowForm.ui b/MainWindowForm.ui new file mode 100644 index 0000000..e793ebf --- /dev/null +++ b/MainWindowForm.ui @@ -0,0 +1,85 @@ + + + MainWindowForm + + + + 0 + 0 + 600 + 1024 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + 0 + 0 + 600 + 84 + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + + + + TextLabel + + + Qt::AlignBottom|Qt::AlignHCenter + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + diff --git a/ProMemory.cpp b/ProMemory.cpp new file mode 100644 index 0000000..19e7403 --- /dev/null +++ b/ProMemory.cpp @@ -0,0 +1,84 @@ +#include "ProMemory.h" + +ProMemory::ProMemory() +{ + +} + +ProMemory::~ProMemory() +{ + +} + +/* +void ProMemory::pushCasicIris(CasicIrisInfo irisInfo) +{ + QMutex mutex; + mutex.lock(); + if (this->irisQueue.size() > 30) + { + QStack empty; + std::swap(empty, irisQueue); + } + + irisQueue.push(irisInfo); + mutex.unlock(); +} +CasicIrisInfo ProMemory::popCasicIris() +{ + CasicIrisInfo result; + + QMutex mutex; + mutex.lock(); + if (this->irisQueue.size() > 0) + { + result = irisQueue.pop(); + } + + mutex.unlock(); + + return result; +} +*/ +int ProMemory::getIrisQueueSize() +{ + int size = 0; + + QMutex mutex; + mutex.lock(); + +// size = this->irisQueue.size(); + + mutex.unlock(); + + return size; +} +bool ProMemory::isIrisQueueEmpty() +{ + bool empty = true; + + QMutex mutex; + mutex.lock(); + +// empty = this->irisQueue.isEmpty(); + + mutex.unlock(); + + return empty; +} +void ProMemory::clearIrisQueue() +{ + QMutex mutex; + mutex.lock(); + +// QStack empty; +// std::swap(empty, irisQueue); + + mutex.unlock(); +} + + +void ProMemory::initIrisFeatures(QString personId) +{ +// irisRegistPro->sendDataToExract(QByteArray(QString("[-u]").append(personId).toLocal8Bit())); +} diff --git a/ProMemory.h b/ProMemory.h new file mode 100644 index 0000000..2ecd653 --- /dev/null +++ b/ProMemory.h @@ -0,0 +1,52 @@ +#ifndef PROMEMORY_H +#define PROMEMORY_H + +#include +#include + +#include "AppConstants.h" +//#include "casic/iris/CasicIrisInfo.h" +#include "dao/IrisDataDao.h" + +#include "device/IrisCameraController.h" +//#include "device/iris/IrisRegistProcess.h" +//#include "device/iris/IrisRecogProcess.h" + +class IrisCameraController; +class IrisRegistProcess; +class IrisRecogProcess; + +class ProMemory +{ +public: + ~ProMemory(); + ProMemory(const ProMemory&)=delete; + ProMemory& operator=(const ProMemory&)=delete; + + static ProMemory& getInstance() { + static ProMemory instance; + return instance; + } + +// void pushCasicIris(CasicIrisInfo irisInfo); +// CasicIrisInfo popCasicIris(); + int getIrisQueueSize(); + bool isIrisQueueEmpty(); + void clearIrisQueue(); + + volatile int widgeFrame = 0; // 当前显示的界面 + volatile int appState = 0; // 当前程序所处的状态 + + void initIrisFeatures(QString personId = ""); // 初始化虹膜特征值集合 + + IrisCameraController * irisCam; + IrisRecogProcess * irisRecogPro; + +private: + ProMemory(); + +// QStack irisQueue; // 虹膜信息队列 + QVector irisFeatures; // 虹膜特征值集合 +}; + +#endif // PROMEMORY_H diff --git a/conf/config.ini b/conf/config.ini new file mode 100644 index 0000000..66e46ad --- /dev/null +++ b/conf/config.ini @@ -0,0 +1,67 @@ +[recognize] +#最大允许识别时间(ms) +maxMatchTime=10000 +#识别成功界面停留时间(ms) +successTipsLast=5000 +#识别失败界面停留时间(ms) +failureTipsLast=3000 +#人脸识别最大尝试次数 +maxFaceTryCount=20 +#持续没找到人脸的最大次数 +maxFaceNotFoundCount=500 +#注册时最小人脸 +minFaceRegist=240 +#识别时最小人脸 +minFaceRecog=100 + +#虹膜识别最大尝试次数 +maxIrisTryCount=10 +#虹膜识别持续没有找到眼的最大次数 +maxEyeNotFoundCount=50 + +#识别方式[1=人脸;2=虹膜;3=双认证;4=任意] +recogType=4 + +[window] +#界面窗口宽(px) +width=600 +#界面窗口高(px) +height=1024 +#统一背景色 +backgroundColor="#FFFFFF" +#标题 +title="虹膜识别终端" + +[work] +#工作状态检测时最小人脸范围 +minFaceSize=160 +#人脸范围最小横坐标 +minFacePosX=320 +#人脸范围最大横坐标 +maxFacePosX=960 +#人脸范围最小纵坐标 +minFacePosY=180 +#人脸范围最大纵坐标 +maxFacePosY=540 +#人脸太近阈值 +faceCloseSize=360 +#人脸太远阈值 +faceFarSize=480 + +[camera] +#虹膜相机取一幅画面的时间间隔(ms) +irisFrameInterval=100 +#虹膜相机拍摄宽度 +irisFrameWidth=1440 +#虹膜相机拍摄高度 +irisFrameHeight=1080 +#虹膜图像高度 +irisWidth=640 +#虹膜图像高度 +irisHeight=480 + +[log] +#日志文件位置 +logFile="d://irisLogs//casic_log.txt" +#日志级别 +logLevel="trace" diff --git a/dao/BaseDao.cpp b/dao/BaseDao.cpp new file mode 100644 index 0000000..f51c144 --- /dev/null +++ b/dao/BaseDao.cpp @@ -0,0 +1,12 @@ +#include "BaseDao.h" +#include "dao/util/ConnectionManager.h" + +BaseDao::BaseDao(QObject *parent) : QObject(parent) +{ + +} + +BaseDao::~BaseDao() +{ + +} diff --git a/dao/BaseDao.h b/dao/BaseDao.h new file mode 100644 index 0000000..1693c88 --- /dev/null +++ b/dao/BaseDao.h @@ -0,0 +1,32 @@ +#ifndef BASEDAO_H +#define BASEDAO_H + +#include +#include +#include +#include + +#include "dao/util/ConnectionManager.h" +#include "utils/UtilInclude.h" + +class BaseDao : public QObject +{ + Q_OBJECT +public: + explicit BaseDao(QObject *parent = nullptr); + ~BaseDao(); + + virtual QVector findAllRecord() = 0; + virtual QVariantMap findRecordById(QString id) = 0; + + virtual QString save(QVariantMap object) = 0; + virtual bool edit(QVariantMap newObject, QString id) = 0; + virtual bool dele(QString id) = 0; + +private: + +signals: + +}; + +#endif // BASEDAO_H diff --git a/dao/IrisDataDao.cpp b/dao/IrisDataDao.cpp new file mode 100644 index 0000000..37a0ed6 --- /dev/null +++ b/dao/IrisDataDao.cpp @@ -0,0 +1,204 @@ +#include "IrisDataDao.h" + +IrisDataDao::IrisDataDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector IrisDataDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM IRIS_DATA"; + query.prepare(sql); + + // 执行查询 + query.exec(); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + item.insert("id", query.value("id").toString()); + item.insert("person_id", query.value("person_id").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("left_iris_code1", query.value("left_iris_code1")); + item.insert("left_iris_code2", query.value("left_iris_code2")); + item.insert("left_iris_code3", query.value("left_iris_code3")); + item.insert("right_iris_code1", query.value("right_iris_code1")); + item.insert("right_iris_code2", query.value("right_iris_code2")); + item.insert("right_iris_code3", query.value("right_iris_code3")); + + result.append(item); + } + +// LOG_DEBUG(QString("查询IRIS_DATA表的所有记录[结果数:%1]").arg(result.size()).toStdString()); + return result; +} + +QVariantMap IrisDataDao::findRecordById(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM IRIS_DATA WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + // 获取结果 + if (query.next()) + { + result.insert("id", query.value("id").toString()); + result.insert("person_id", query.value("person_id").toLongLong()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("left_iris_code1", query.value("left_iris_code1")); + result.insert("left_iris_code2", query.value("left_iris_code2")); + result.insert("left_iris_code3", query.value("left_iris_code3")); + result.insert("right_iris_code1", query.value("right_iris_code1")); + result.insert("right_iris_code2", query.value("right_iris_code2")); + result.insert("right_iris_code3", query.value("right_iris_code3")); + } + +// LOG_DEBUG(QString("根据id查询IRIS_DATA表的记录[id=%1]").arg(id).toStdString()); + return result; +} + +QVariantMap IrisDataDao::findRecordByPersonId(QString personId) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM IRIS_DATA WHERE PERSON_ID = :personId"); + query.prepare(sql); + query.bindValue(":personId", personId); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + if (query.next()) + { + result.insert("id", query.value("id").toString()); + result.insert("person_id", query.value("person_id").toLongLong()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("left_iris_code1", query.value("left_iris_code1")); + result.insert("left_iris_code2", query.value("left_iris_code2")); + result.insert("left_iris_code3", query.value("left_iris_code3")); + result.insert("right_iris_code1", query.value("right_iris_code1")); + result.insert("right_iris_code2", query.value("right_iris_code2")); + result.insert("right_iris_code3", query.value("right_iris_code3")); + } + +// LOG_DEBUG(QString("根据personId查询IRIS_DATA表的记录[personId=%1]").arg(personId).toStdString()); + return result; +} + + +QString IrisDataDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + + // INSERT语句 + QString sql = QString("INSERT INTO IRIS_DATA (ID, PERSON_ID, ID_CARD_NO, LEFT_IRIS_CODE1, RIGHT_IRIS_CODE1) VALUES (:id, :personId, :idCardNo, :left1, :right1)"); + + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":personId", object.value("person_id").toString()); + query.bindValue(":idCardNo", object.value("id_card_no").toString()); + query.bindValue(":left1", object.value("left_iris_code1")); + query.bindValue(":right1", object.value("right_iris_code1")); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(); + +// LOG_DEBUG(QString("保存虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool IrisDataDao::edit(QVariantMap newObject, QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // UPDATE语句 + if (!newObject.contains("left_iris_code1") || !newObject.contains("right_iris_code1")){ + return false; + } + QString sql = QString("UPDATE IRIS_DATA SET LEFT_IRIS_CODE1 = :left1, RIGHT_IRIS_CODE1 = :right1 WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":left1", newObject.value("left_iris_code1")); + query.bindValue(":right1", newObject.value("right_iris_code1")); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(); + +// LOG_DEBUG(QString("编辑虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; +} + + +bool IrisDataDao::dele(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + QString sql = QString("DELETE FROM IRIS_DATA WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(); + +// LOG_DEBUG(QString("删除虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; +} diff --git a/dao/IrisDataDao.h b/dao/IrisDataDao.h new file mode 100644 index 0000000..c74dbbd --- /dev/null +++ b/dao/IrisDataDao.h @@ -0,0 +1,25 @@ +#ifndef IRISDATADAO_H +#define IRISDATADAO_H + +#include +#include "BaseDao.h" + +class IrisDataDao : public BaseDao +{ + Q_OBJECT +public: + explicit IrisDataDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + QVariantMap findRecordByPersonId(QString personId); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +signals: + +}; + +#endif // IRISDATADAO_H diff --git a/dao/RecognitionRecordsDao.cpp b/dao/RecognitionRecordsDao.cpp new file mode 100644 index 0000000..40db453 --- /dev/null +++ b/dao/RecognitionRecordsDao.cpp @@ -0,0 +1,100 @@ +#include "RecognitionRecordsDao.h" + +RecognitionRecordsDao::RecognitionRecordsDao(QObject *parent) : BaseDao(parent) +{ + +} + + +QVector RecognitionRecordsDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM RECOGNITION_RECORDS"; + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + item.insert("id", query.value("id").toLongLong()); + result.append(item); + } + +// LOG_DEBUG(QString("查询RECOGNITION_RECORDS表的所有记录[记录数:%1]").arg(result.size()).toStdString()); + return result; +} + +QVariantMap RecognitionRecordsDao::findRecordById(QString id) +{ + QVariantMap item; + return item; +} + +QString RecognitionRecordsDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + + // INSERT语句 + QString sql = QString("INSERT INTO RECOGNITION_RECORDS (ID, PERSON_ID, DATETIME, REC_TYPE, DEV_CODE, DOOR_CODE, INOUT_TYPE) " + "VALUES (:id, :personId, :datetime, :recType, :devCode, :doorCode, :inoutType)"); + + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":personId", object.value("person_id").toString()); + query.bindValue(":datetime", object.value("date_time").toString()); + query.bindValue(":recType", object.value("rec_type").toString()); + query.bindValue(":devCode", object.value("dev_code").toString()); + query.bindValue(":doorCode", object.value("door_code").toString()); + query.bindValue(":inoutType", object.value("inout_type").toString()); + +// LOG_DEBUG(sql.toStdString()); + + // 插入识别的log日志 + QString logStr = QString("INSERT INTO RECOGNITION_LOGS (ID, LOG_INFO) VALUES (:id, :logInfo)"); + + QSqlQuery logQuery(ConnectionManager::getInstance()->getConnection()); + logQuery.prepare(logStr); + logQuery.bindValue(":id", id); + logQuery.bindValue(":logInfo", object.value("debug_info").toString()); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(); + logQuery.exec(); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool RecognitionRecordsDao::edit(QVariantMap newObject, QString id) +{ + return false; +} + +bool RecognitionRecordsDao::dele(QString id) +{ + return false; +} diff --git a/dao/RecognitionRecordsDao.h b/dao/RecognitionRecordsDao.h new file mode 100644 index 0000000..38de7c9 --- /dev/null +++ b/dao/RecognitionRecordsDao.h @@ -0,0 +1,23 @@ +#ifndef RECOGNITIONRECORDSDAO_H +#define RECOGNITIONRECORDSDAO_H + +#include +#include "BaseDao.h" +class RecognitionRecordsDao: public BaseDao +{ + Q_OBJECT +public: + explicit RecognitionRecordsDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +signals: + +}; + +#endif // RECOGNITIONRECORDSDAO_H diff --git a/dao/SysDeptDao.cpp b/dao/SysDeptDao.cpp new file mode 100644 index 0000000..22f9946 --- /dev/null +++ b/dao/SysDeptDao.cpp @@ -0,0 +1,88 @@ +#include "SysDeptDao.h" + +SysDeptDao::SysDeptDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector SysDeptDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_DEPT WHERE PID != '-1' ORDER BY PID, NUM"; + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + item.insert("id", query.value("id").toString()); + item.insert("pid", query.value("pid").toString()); + item.insert("pids", query.value("pids").toString()); + item.insert("simplename", query.value("simplename").toString()); + item.insert("fullname", query.value("fullname").toString()); + } + +// LOG_TRACE(QString("查询表[SYS_DEPT]的所有记录[%1][%2]").arg(result.size()).arg(sql).toStdString()); + + return result; +} + +QVariantMap SysDeptDao::findRecordById(QString id) +{ + QVariantMap item; + return item; + + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM SYS_DEPT WHERE SYS_DEPT.ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + // 获取结果集的大小 + query.last(); + int count = query.at() + 1; + + if (count >=1) + { + query.first(); + + result.insert("id", query.value("id").toString()); + result.insert("pid", query.value("pid").toString()); + result.insert("pids", query.value("pids").toString()); + result.insert("simplename", query.value("simplename").toString()); + result.insert("fullname", query.value("fullname").toString()); + } + +// LOG_TRACE(QString("根据id查询SYS_DEPT表的记录[ID=%1][%2]").arg(id).arg(sql).toStdString()); + + return result; +} + + +QString SysDeptDao::save(QVariantMap object) +{ + return "0"; +} +bool SysDeptDao::edit(QVariantMap newObject, QString id) +{ + return true; +} +bool SysDeptDao::dele(QString id) +{ + return true; +} diff --git a/dao/SysDeptDao.h b/dao/SysDeptDao.h new file mode 100644 index 0000000..e07a09f --- /dev/null +++ b/dao/SysDeptDao.h @@ -0,0 +1,24 @@ +#ifndef SYSDEPTDAO_H +#define SYSDEPTDAO_H + +#include +#include "BaseDao.h" + +class SysDeptDao : public BaseDao +{ + Q_OBJECT +public: + explicit SysDeptDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +private: + +}; + +#endif // SYSDEPTDAO_H diff --git a/dao/SysPersonDao.cpp b/dao/SysPersonDao.cpp new file mode 100644 index 0000000..dd9480f --- /dev/null +++ b/dao/SysPersonDao.cpp @@ -0,0 +1,371 @@ +#include "SysPersonDao.h" + + +SysPersonDao::SysPersonDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector SysPersonDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0'"; + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + count++; + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + result.append(item); + } + +// LOG(TRACE) << QString("查询SYS_PERSON表的所有记录[%1]").arg(count).toStdString(); +// LOG_TRACE(QString("查询SYS_PERSON表的所有记录[%1]").arg(count).toStdString()); + + return result; +} + +QVariantMap SysPersonDao::findRecordById(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0' AND SYS_PERSON.ID = '%1'").arg(id); + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVariantMap result; + + // 获取结果集的大小 + query.last(); + int count = query.at() + 1; + + if (count >=1) + { + query.first(); + + result.insert("id", query.value("id").toString()); + result.insert("delflag", query.value("delflag").toString()); + result.insert("createtime", query.value("createtime").toString()); + result.insert("updatetime", query.value("updatetime").toString()); + result.insert("name", query.value("name").toString()); + result.insert("gender", query.value("gender").toString()); + result.insert("deptid", query.value("deptid").toString()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("remarks", query.value("remarks").toString()); + result.insert("person_code", query.value("person_code").toString()); + result.insert("deptname", query.value("fullname").toString()); + result.insert("sync_id", query.value("sync_id").toString()); + result.insert("hasFace", query.value("face_valid").toString()); + result.insert("hasIris", query.value("iris_valid").toString()); + } + +// LOG(TRACE) << QString("根据id查询SYS_PERSON表的记录[id=%1][%2]").arg(id).arg(sql).toStdString(); +// LOG_TRACE(QString("根据id查询SYS_PERSON表的记录[id=%1][%2]").arg(id).arg(sql).toStdString()); + + return result; +} + +int SysPersonDao::findRecordCountByNameAndDept(QString name, QString dept) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT COUNT(P.ID) AS RECCT FROM SYS_PERSON P LEFT JOIN SYS_DEPT D ON P.DEPTID = D.ID WHERE P.DELFLAG = '0'"; + if (name.isEmpty() == false) + { + sql += " AND P.NAME LIKE '%" + name + "%'"; + } + if (dept.isEmpty() == false && dept.indexOf("-1") < 0) + { + sql += QString(" AND ((P.DEPTID = '%1') OR (D.PIDS LIKE '%,%1,%'))").arg(dept); + } + + // 执行查询 + query.exec(sql); + + // 返回结果 + int result; + + // 遍历查询结果 + if (query.next()) { + result = query.value("RECCT").toInt(); + } + +// LOG(TRACE) << QString("根据姓名和部门查询SYS_PERSON记录总数[%1][%2]").arg(result).arg(sql).toStdString(); +// LOG_TRACE(QString("根据姓名和部门查询SYS_PERSON记录总数[%1][%2]").arg(result).arg(sql).toStdString()); + + return result; +} + +QVector SysPersonDao::findRecordsByNameAndDept(QString name, QString dept, qint8 limit, qint16 offset) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON P LEFT JOIN SYS_DEPT D ON P.DEPTID = D.ID WHERE P.DELFLAG = '0'"; + if (name.isEmpty() == false) + { + sql += " AND P.NAME LIKE '%" + name + "%'"; + } + if (dept.isEmpty() == false && dept.indexOf("-1") < 0) + { + sql += QString(" AND ((P.DEPTID = '%1') OR (D.PIDS LIKE '%,%1,%'))").arg(dept); + } + + sql += QString(" LIMIT %1 OFFSET %2").arg(limit).arg(offset); + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + count++; + + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + + result.append(item); + } + +// LOG(TRACE) << QString("根据姓名和部门分页查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString(); +// LOG_TRACE(QString("根据姓名和部门分页查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString()); + + return result; +} + +QVector SysPersonDao::findRecordsByProperties(QVariantMap conditions) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0'"; + QVariantMap::iterator it; + for (it = conditions.begin(); it != conditions.end(); it++) + { + sql += QString(" AND SYS_PERSON.%1 = %2").arg(it.key()).arg(it.value().toString()); + } + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + count++; + + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + + result.append(item); + } + +// LOG(TRACE) << QString("根据属性值查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString(); +// LOG_TRACE(QString("根据属性值查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString()); + + return result; +} + +QString SysPersonDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + + // INSERT语句 + QString sql = QString("INSERT INTO SYS_PERSON " + "(ID, DELFLAG, CREATETIME, UPDATETIME, " + "NAME, GENDER, DEPTID, ID_CARD_NO, " + "REMARKS, PERSON_CODE, SYNC_ID, FACE_VALID, IRIS_VALID) " + "VALUES ('%1', '0', '%2', '%2', '%3', '%4', '%5', '%6', '%7', '%8', '%9', 0, 0)") + .arg(id).arg(tm) + .arg(object.value("name").toString()) + .arg(object.value("gender").toString()) + .arg(object.value("deptid").toString()) + .arg(object.value("id_card_no").toString()) + .arg(object.value("remarks").toString()) + .arg(object.value("person_code").toString()) + .arg(object.value("sync_id").toString()); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(sql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { +// LOG(DEBUG) << QString("保存SYS_PERSON记录成功[ID = %1][%2]").arg(id).arg(sql).toStdString(); +// LOG_DEBUG(QString("保存SYS_PERSON记录成功[ID = %1][%2]").arg(id).arg(sql).toStdString()); + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool SysPersonDao::edit(QVariantMap newObject, QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + + // UPDATE语句 + QString sql = QString("UPDATE SYS_PERSON SET UPDATETIME = '%1'").arg(tm); + if (newObject.contains("name")) + { + sql.append(QString(", NAME = '%1'").arg(newObject.value("name").toString())); + } + if (newObject.contains("gender")) + { + sql.append(QString(", GENDER = '%1'").arg(newObject.value("gender").toString())); + } + if (newObject.contains("deptid")) + { + sql.append(QString(", DEPTID = '%1'").arg(newObject.value("deptid").toString())); + } + if (newObject.contains("person_code")) + { + sql.append(QString(", PERSON_CODE = '%1'").arg(newObject.value("person_code").toString())); + } + if (newObject.contains("face_valid")) + { + sql.append(QString(", FACE_VALID = '%1'").arg(newObject.value("face_valid").toString())); + } + if (newObject.contains("iris_valid")) + { + sql.append(QString(", IRIS_VALID = '%1'").arg(newObject.value("iris_valid").toString())); + } + + sql.append(QString(" WHERE ID = '%1'").arg(id)); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(sql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + +// LOG(DEBUG) << QString("编辑人员[ID=%1][%2]").arg(id).arg(sql).toStdString(); +// LOG_DEBUG(QString("编辑人员[ID=%1][%2]").arg(id).arg(sql).toStdString()); + + // 返回结果 + return success; +} + +bool SysPersonDao::dele(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + QSqlQuery irisDel(ConnectionManager::getInstance()->getConnection()); + + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + qint64 tmms = QDateTime::currentDateTime().toMSecsSinceEpoch(); + + // UPDATE语句 + QString sql = QString("UPDATE SYS_PERSON SET UPDATETIME = :updateTime, DELFLAG = :flag WHERE ID = :id").arg(tm).arg(tmms).arg(id); + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":updateTime", tm); + query.bindValue(":flag", tmms); + + // 物理删除人员的人脸和虹膜数据 + QString delIrisSql = QString("DELETE FROM IRIS_DATA WHERE PERSON_ID = :personId"); + irisDel.prepare(delIrisSql); + irisDel.bindValue(":personId", id); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(sql); + query.exec(delIrisSql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + +// LOG_DEBUG(QString("删除人员SYS_PERSON[ID=%1][%2]").arg(id).arg(success).toStdString()); + + // 返回结果 + return success; +} diff --git a/dao/SysPersonDao.h b/dao/SysPersonDao.h new file mode 100644 index 0000000..e02e5ba --- /dev/null +++ b/dao/SysPersonDao.h @@ -0,0 +1,27 @@ +#ifndef SYSPERSONDAO_H +#define SYSPERSONDAO_H + +#include +#include "BaseDao.h" + +class SysPersonDao : public BaseDao +{ + Q_OBJECT +public: + explicit SysPersonDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + int findRecordCountByNameAndDept(QString name, QString dept); + QVector findRecordsByNameAndDept(QString name, QString dept, qint8 limit, qint16 offset); + QVector findRecordsByProperties(QVariantMap conditions); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); +signals: + +}; + +#endif // SYSPERSONDAO_H diff --git a/AppConstants.h b/AppConstants.h new file mode 100644 index 0000000..296c53f --- /dev/null +++ b/AppConstants.h @@ -0,0 +1,28 @@ +#ifndef APPCONSTANTS_H +#define APPCONSTANTS_H + +class AppConstants +{ +public: + enum WidgeFrameName + { + MAIN_PAGE = 0, // 主页面 + PERSON_LIST_FORM = 1, // 人员列表页面 + ADD_PERSON_FORM = 2, // 添加人员页面 + ADD_PERSON_CAPTURE_FACE = 21, // 添加/编辑人员时进行人脸拍图 + ADD_PERSON_CAPTURE_IRIS = 22, // 添加/编辑人员时进行虹膜拍图 + SETTING_FORM = 3, // 设置页面 + RECOGNIZE_RESULT_FORM = 4, // 识别结果界面 + IDENTIFY_FORM = 5, // 识别界面 含识别中 和 识别结果 + LOCKSCREEN_FORM = 6 // 锁屏待机界面 + }; + + enum ApplicationState + { + STATE_WAIT = 0, // 待机 + STATE_WORKING = 1, // 工作状态 + STATE_IDENTIFYING = 2, // 识别中 + }; +}; + +#endif // APPCONSTANTS_H diff --git a/CasicIrisIdentify.pro b/CasicIrisIdentify.pro index 5d7fea6..575ce3d 100644 --- a/CasicIrisIdentify.pro +++ b/CasicIrisIdentify.pro @@ -1,4 +1,4 @@ -QT += core gui +QT += core gui sql network texttospeech greaterThan(QT_MAJOR_VERSION, 4): QT += widgets @@ -15,20 +15,46 @@ # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 -SOURCES += \ - main.cpp \ - IdentifyForm.cpp +include("dao/dao.pri") +include("device/device.pri") +include("utils/utils.pri") -HEADERS += \ - IdentifyForm.h +SOURCES += main.cpp +SOURCES += ProMemory.cpp +SOURCES += MainWindowForm.cpp +SOURCES += IdentifyForm.cpp +SOURCES += LockScreenForm.cpp -FORMS += \ - IdentifyForm.ui +HEADERS += AppConstants.h +HEADERS += ProMemory.h +HEADERS += MainWindowForm.h +HEADERS += IdentifyForm.h +HEADERS += LockScreenForm.h -TRANSLATIONS += \ - CasicIrisIdentify_zh_CN.ts +FORMS += MainWindowForm.ui +FORMS += IdentifyForm.ui +FORMS += LockScreenForm.ui + +RESOURCES += resource.qrc + +DISTFILES += conf/config.ini + +#TRANSLATIONS += CasicIrisIdentify_zh_CN.ts + +#INCLUDEPATH += include/spdlog +#DEPENDPATH += include/spdlog # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target + + +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lopencv_world420 +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lGxIAPICPPEx + +INCLUDEPATH += $$PWD/include/daheng +DEPENDPATH += $$PWD/include/daheng + +INCLUDEPATH += $$PWD/include +DEPENDPATH += $$PWD/include diff --git a/CasicIrisIdentify_zh_CN.ts b/CasicIrisIdentify_zh_CN.ts index 5526fe4..81900df 100644 --- a/CasicIrisIdentify_zh_CN.ts +++ b/CasicIrisIdentify_zh_CN.ts @@ -1,3 +1,12 @@ - + + + IdentifyForm + + + IdentifyForm + + + + diff --git a/IdentifyForm.cpp b/IdentifyForm.cpp index 348a897..ba1f251 100644 --- a/IdentifyForm.cpp +++ b/IdentifyForm.cpp @@ -1,4 +1,4 @@ -#include "IdentifyForm.h" +#include "IdentifyForm.h" #include "ui_IdentifyForm.h" IdentifyForm::IdentifyForm(QWidget *parent) @@ -6,6 +6,12 @@ , ui(new Ui::IdentifyForm) { ui->setupUi(this); + + // 初始化更新界面的定时器 + // 每秒执行一次 + connect(TimeCounterUtil::getInstance().clockCounter, &QTimer::timeout, this, &IdentifyForm::updateDateAndTime); + + TimeCounterUtil::getInstance().clockCounter->start(1000); } IdentifyForm::~IdentifyForm() @@ -13,3 +19,16 @@ delete ui; } +void IdentifyForm::drawIrisImageOnFrame(QImage image) +{ + // 只在识别界面才显示画面 + if (ui->wgtStacked->currentIndex() == 0) { + ui->labelVideo->setPixmap(QPixmap::fromImage(image)); + } +} + + +void IdentifyForm::updateDateAndTime() +{ + ui->labelTime->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd dddd HH:mm:ss")); +} diff --git a/IdentifyForm.h b/IdentifyForm.h index fc857a1..ae1cd22 100644 --- a/IdentifyForm.h +++ b/IdentifyForm.h @@ -1,7 +1,10 @@ -#ifndef IDENTIFYFORM_H +#ifndef IDENTIFYFORM_H #define IDENTIFYFORM_H #include +#include + +#include "utils/UtilInclude.h" QT_BEGIN_NAMESPACE namespace Ui { class IdentifyForm; } @@ -15,7 +18,14 @@ IdentifyForm(QWidget *parent = nullptr); ~IdentifyForm(); +public slots: + void drawIrisImageOnFrame(QImage image); + private: Ui::IdentifyForm *ui; + +private slots: + void updateDateAndTime(); + }; #endif // IDENTIFYFORM_H diff --git a/IdentifyForm.ui b/IdentifyForm.ui index c72a36f..879dc9a 100644 --- a/IdentifyForm.ui +++ b/IdentifyForm.ui @@ -6,13 +6,59 @@ 0 0 - 800 + 600 600 IdentifyForm + + + + 0 + 40 + 600 + 450 + + + + 0 + + + + + + 100 + 10 + 400 + 300 + + + + + + + + + + + + + + 0 + 0 + 600 + 40 + + + + TextLabel + + + Qt::AlignCenter + + diff --git a/LockScreenForm.cpp b/LockScreenForm.cpp new file mode 100644 index 0000000..58dc54b --- /dev/null +++ b/LockScreenForm.cpp @@ -0,0 +1,14 @@ +#include "LockScreenForm.h" +#include "ui_LockScreenForm.h" + +LockScreenForm::LockScreenForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::LockScreenForm) +{ + ui->setupUi(this); +} + +LockScreenForm::~LockScreenForm() +{ + delete ui; +} diff --git a/LockScreenForm.h b/LockScreenForm.h new file mode 100644 index 0000000..b5ded48 --- /dev/null +++ b/LockScreenForm.h @@ -0,0 +1,25 @@ +#ifndef LOCKSCREENFORM_H +#define LOCKSCREENFORM_H + +#include +#include + +#include "utils/UtilInclude.h" + +namespace Ui { +class LockScreenForm; +} + +class LockScreenForm : public QWidget +{ + Q_OBJECT + +public: + explicit LockScreenForm(QWidget *parent = nullptr); + ~LockScreenForm(); + +private: + Ui::LockScreenForm *ui; +}; + +#endif // LOCKSCREENFORM_H diff --git a/LockScreenForm.ui b/LockScreenForm.ui new file mode 100644 index 0000000..7f2a6db --- /dev/null +++ b/LockScreenForm.ui @@ -0,0 +1,45 @@ + + + LockScreenForm + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + 180 + 100 + 54 + 12 + + + + TextLabel + + + + + + 180 + 160 + 54 + 12 + + + + TextLabel + + + + + + diff --git a/MainWindowForm.cpp b/MainWindowForm.cpp new file mode 100644 index 0000000..84f8159 --- /dev/null +++ b/MainWindowForm.cpp @@ -0,0 +1,86 @@ +#include "MainWindowForm.h" +#include "ui_MainWindowForm.h" +#include + +MainWindowForm::MainWindowForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::MainWindowForm) +{ + ui->setupUi(this); + + // 设置窗口透明和大小、位置 + this->setWindowFlags(Qt::FramelessWindowHint); + this->move(1400, 15); + this->resize(SettingConfig::getInstance().WINDOW_WIDTH, SettingConfig::getInstance().WINDOW_HEIGHT); + + // 通过调色板的颜色来设置窗口的统一背景色 + qApp->setPalette(QPalette(QColor(SettingConfig::getInstance().WINDOW_BACKGROUND_COLOR))); + + // 加载css文件设置控件样式 + QFile file(QApplication::applicationDirPath() + "/qss/main.css"); + if (file.open(QFile::ReadOnly)) + { + QString qssStr = QLatin1String(file.readAll()); + this->setStyleSheet(qssStr); + file.close(); + } + + initFormsPtr(); + + // 设置标题文字 + ui->labelTitle->setText(SettingConfig::getInstance().WINDOW_TITLE); + ui->labelCopyright->setText(SettingConfig::getInstance().WINDOW_RIGHTS); + ui->labelVersion->setText(SettingConfig::getInstance().WINDOW_VERSION); + + // 初始化虹膜相机控制 + ProMemory::getInstance().irisCam = new IrisCameraController(this); + ProMemory::getInstance().irisCam->initIrisCamera(); + ProMemory::getInstance().irisCam->openIrisCamera(); + connect(ProMemory::getInstance().irisCam->irisCamHandler, &IrisCameraCapEventHandler::sendIrisFrameToDraw, identifyForm, &IdentifyForm::drawIrisImageOnFrame); + +// LOG_INFO(QString("应用程序启动成功[Application Startup Success]").toStdString()); + qDebug() << "应用程序启动成功[Application Startup Success]"; + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::IDENTIFY_FORM; + ui->wdgtStatced->setCurrentWidget(identifyForm); + + // 开始虹膜相机拍图 + ProMemory::getInstance().irisCam->startCapture(); +} + +MainWindowForm::~MainWindowForm() +{ + delete ui; +} + +void MainWindowForm::lockScreen() +{ + ui->wdgtStatced->setCurrentWidget(lockScreenForm); + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::LOCKSCREEN_FORM; + ProMemory::getInstance().appState = AppConstants::ApplicationState::STATE_WAIT; +} + +void MainWindowForm::keyPressEvent(QKeyEvent *event) +{ + switch (event->key()) { + case Qt::Key_Escape: + QTimer::singleShot(100, qApp, [=](){ + QApplication::quit(); + }); + + default: + QWidget::keyPressEvent(event); + } +} + +void MainWindowForm::initFormsPtr() +{ + // 初始化各个form + lockScreenForm = new LockScreenForm(this); + identifyForm = new IdentifyForm(this); + + // 将form添加到statcked widget中 + ui->wdgtStatced->addWidget(identifyForm); + ui->wdgtStatced->addWidget(lockScreenForm); + + // 绑定按钮函数 +} diff --git a/MainWindowForm.h b/MainWindowForm.h new file mode 100644 index 0000000..7fb2d89 --- /dev/null +++ b/MainWindowForm.h @@ -0,0 +1,38 @@ +#ifndef MAINWINDOWFORM_H +#define MAINWINDOWFORM_H + +#include +#include +#include + +#include "utils/UtilInclude.h" +#include "ProMemory.h" +#include "LockScreenForm.h" +#include "IdentifyForm.h" + +namespace Ui { +class MainWindowForm; +} + +class MainWindowForm : public QWidget +{ + Q_OBJECT + +public: + explicit MainWindowForm(QWidget *parent = nullptr); + ~MainWindowForm(); + +public slots: + void lockScreen(); + +private: + Ui::MainWindowForm *ui; + LockScreenForm * lockScreenForm; + IdentifyForm * identifyForm; + + void keyPressEvent(QKeyEvent *event); + + void initFormsPtr(); +}; + +#endif // MAINWINDOWFORM_H diff --git a/MainWindowForm.ui b/MainWindowForm.ui new file mode 100644 index 0000000..e793ebf --- /dev/null +++ b/MainWindowForm.ui @@ -0,0 +1,85 @@ + + + MainWindowForm + + + + 0 + 0 + 600 + 1024 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + 0 + 0 + 600 + 84 + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + + + + TextLabel + + + Qt::AlignBottom|Qt::AlignHCenter + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + diff --git a/ProMemory.cpp b/ProMemory.cpp new file mode 100644 index 0000000..19e7403 --- /dev/null +++ b/ProMemory.cpp @@ -0,0 +1,84 @@ +#include "ProMemory.h" + +ProMemory::ProMemory() +{ + +} + +ProMemory::~ProMemory() +{ + +} + +/* +void ProMemory::pushCasicIris(CasicIrisInfo irisInfo) +{ + QMutex mutex; + mutex.lock(); + if (this->irisQueue.size() > 30) + { + QStack empty; + std::swap(empty, irisQueue); + } + + irisQueue.push(irisInfo); + mutex.unlock(); +} +CasicIrisInfo ProMemory::popCasicIris() +{ + CasicIrisInfo result; + + QMutex mutex; + mutex.lock(); + if (this->irisQueue.size() > 0) + { + result = irisQueue.pop(); + } + + mutex.unlock(); + + return result; +} +*/ +int ProMemory::getIrisQueueSize() +{ + int size = 0; + + QMutex mutex; + mutex.lock(); + +// size = this->irisQueue.size(); + + mutex.unlock(); + + return size; +} +bool ProMemory::isIrisQueueEmpty() +{ + bool empty = true; + + QMutex mutex; + mutex.lock(); + +// empty = this->irisQueue.isEmpty(); + + mutex.unlock(); + + return empty; +} +void ProMemory::clearIrisQueue() +{ + QMutex mutex; + mutex.lock(); + +// QStack empty; +// std::swap(empty, irisQueue); + + mutex.unlock(); +} + + +void ProMemory::initIrisFeatures(QString personId) +{ +// irisRegistPro->sendDataToExract(QByteArray(QString("[-u]").append(personId).toLocal8Bit())); +} diff --git a/ProMemory.h b/ProMemory.h new file mode 100644 index 0000000..2ecd653 --- /dev/null +++ b/ProMemory.h @@ -0,0 +1,52 @@ +#ifndef PROMEMORY_H +#define PROMEMORY_H + +#include +#include + +#include "AppConstants.h" +//#include "casic/iris/CasicIrisInfo.h" +#include "dao/IrisDataDao.h" + +#include "device/IrisCameraController.h" +//#include "device/iris/IrisRegistProcess.h" +//#include "device/iris/IrisRecogProcess.h" + +class IrisCameraController; +class IrisRegistProcess; +class IrisRecogProcess; + +class ProMemory +{ +public: + ~ProMemory(); + ProMemory(const ProMemory&)=delete; + ProMemory& operator=(const ProMemory&)=delete; + + static ProMemory& getInstance() { + static ProMemory instance; + return instance; + } + +// void pushCasicIris(CasicIrisInfo irisInfo); +// CasicIrisInfo popCasicIris(); + int getIrisQueueSize(); + bool isIrisQueueEmpty(); + void clearIrisQueue(); + + volatile int widgeFrame = 0; // 当前显示的界面 + volatile int appState = 0; // 当前程序所处的状态 + + void initIrisFeatures(QString personId = ""); // 初始化虹膜特征值集合 + + IrisCameraController * irisCam; + IrisRecogProcess * irisRecogPro; + +private: + ProMemory(); + +// QStack irisQueue; // 虹膜信息队列 + QVector irisFeatures; // 虹膜特征值集合 +}; + +#endif // PROMEMORY_H diff --git a/conf/config.ini b/conf/config.ini new file mode 100644 index 0000000..66e46ad --- /dev/null +++ b/conf/config.ini @@ -0,0 +1,67 @@ +[recognize] +#最大允许识别时间(ms) +maxMatchTime=10000 +#识别成功界面停留时间(ms) +successTipsLast=5000 +#识别失败界面停留时间(ms) +failureTipsLast=3000 +#人脸识别最大尝试次数 +maxFaceTryCount=20 +#持续没找到人脸的最大次数 +maxFaceNotFoundCount=500 +#注册时最小人脸 +minFaceRegist=240 +#识别时最小人脸 +minFaceRecog=100 + +#虹膜识别最大尝试次数 +maxIrisTryCount=10 +#虹膜识别持续没有找到眼的最大次数 +maxEyeNotFoundCount=50 + +#识别方式[1=人脸;2=虹膜;3=双认证;4=任意] +recogType=4 + +[window] +#界面窗口宽(px) +width=600 +#界面窗口高(px) +height=1024 +#统一背景色 +backgroundColor="#FFFFFF" +#标题 +title="虹膜识别终端" + +[work] +#工作状态检测时最小人脸范围 +minFaceSize=160 +#人脸范围最小横坐标 +minFacePosX=320 +#人脸范围最大横坐标 +maxFacePosX=960 +#人脸范围最小纵坐标 +minFacePosY=180 +#人脸范围最大纵坐标 +maxFacePosY=540 +#人脸太近阈值 +faceCloseSize=360 +#人脸太远阈值 +faceFarSize=480 + +[camera] +#虹膜相机取一幅画面的时间间隔(ms) +irisFrameInterval=100 +#虹膜相机拍摄宽度 +irisFrameWidth=1440 +#虹膜相机拍摄高度 +irisFrameHeight=1080 +#虹膜图像高度 +irisWidth=640 +#虹膜图像高度 +irisHeight=480 + +[log] +#日志文件位置 +logFile="d://irisLogs//casic_log.txt" +#日志级别 +logLevel="trace" diff --git a/dao/BaseDao.cpp b/dao/BaseDao.cpp new file mode 100644 index 0000000..f51c144 --- /dev/null +++ b/dao/BaseDao.cpp @@ -0,0 +1,12 @@ +#include "BaseDao.h" +#include "dao/util/ConnectionManager.h" + +BaseDao::BaseDao(QObject *parent) : QObject(parent) +{ + +} + +BaseDao::~BaseDao() +{ + +} diff --git a/dao/BaseDao.h b/dao/BaseDao.h new file mode 100644 index 0000000..1693c88 --- /dev/null +++ b/dao/BaseDao.h @@ -0,0 +1,32 @@ +#ifndef BASEDAO_H +#define BASEDAO_H + +#include +#include +#include +#include + +#include "dao/util/ConnectionManager.h" +#include "utils/UtilInclude.h" + +class BaseDao : public QObject +{ + Q_OBJECT +public: + explicit BaseDao(QObject *parent = nullptr); + ~BaseDao(); + + virtual QVector findAllRecord() = 0; + virtual QVariantMap findRecordById(QString id) = 0; + + virtual QString save(QVariantMap object) = 0; + virtual bool edit(QVariantMap newObject, QString id) = 0; + virtual bool dele(QString id) = 0; + +private: + +signals: + +}; + +#endif // BASEDAO_H diff --git a/dao/IrisDataDao.cpp b/dao/IrisDataDao.cpp new file mode 100644 index 0000000..37a0ed6 --- /dev/null +++ b/dao/IrisDataDao.cpp @@ -0,0 +1,204 @@ +#include "IrisDataDao.h" + +IrisDataDao::IrisDataDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector IrisDataDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM IRIS_DATA"; + query.prepare(sql); + + // 执行查询 + query.exec(); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + item.insert("id", query.value("id").toString()); + item.insert("person_id", query.value("person_id").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("left_iris_code1", query.value("left_iris_code1")); + item.insert("left_iris_code2", query.value("left_iris_code2")); + item.insert("left_iris_code3", query.value("left_iris_code3")); + item.insert("right_iris_code1", query.value("right_iris_code1")); + item.insert("right_iris_code2", query.value("right_iris_code2")); + item.insert("right_iris_code3", query.value("right_iris_code3")); + + result.append(item); + } + +// LOG_DEBUG(QString("查询IRIS_DATA表的所有记录[结果数:%1]").arg(result.size()).toStdString()); + return result; +} + +QVariantMap IrisDataDao::findRecordById(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM IRIS_DATA WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + // 获取结果 + if (query.next()) + { + result.insert("id", query.value("id").toString()); + result.insert("person_id", query.value("person_id").toLongLong()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("left_iris_code1", query.value("left_iris_code1")); + result.insert("left_iris_code2", query.value("left_iris_code2")); + result.insert("left_iris_code3", query.value("left_iris_code3")); + result.insert("right_iris_code1", query.value("right_iris_code1")); + result.insert("right_iris_code2", query.value("right_iris_code2")); + result.insert("right_iris_code3", query.value("right_iris_code3")); + } + +// LOG_DEBUG(QString("根据id查询IRIS_DATA表的记录[id=%1]").arg(id).toStdString()); + return result; +} + +QVariantMap IrisDataDao::findRecordByPersonId(QString personId) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM IRIS_DATA WHERE PERSON_ID = :personId"); + query.prepare(sql); + query.bindValue(":personId", personId); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + if (query.next()) + { + result.insert("id", query.value("id").toString()); + result.insert("person_id", query.value("person_id").toLongLong()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("left_iris_code1", query.value("left_iris_code1")); + result.insert("left_iris_code2", query.value("left_iris_code2")); + result.insert("left_iris_code3", query.value("left_iris_code3")); + result.insert("right_iris_code1", query.value("right_iris_code1")); + result.insert("right_iris_code2", query.value("right_iris_code2")); + result.insert("right_iris_code3", query.value("right_iris_code3")); + } + +// LOG_DEBUG(QString("根据personId查询IRIS_DATA表的记录[personId=%1]").arg(personId).toStdString()); + return result; +} + + +QString IrisDataDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + + // INSERT语句 + QString sql = QString("INSERT INTO IRIS_DATA (ID, PERSON_ID, ID_CARD_NO, LEFT_IRIS_CODE1, RIGHT_IRIS_CODE1) VALUES (:id, :personId, :idCardNo, :left1, :right1)"); + + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":personId", object.value("person_id").toString()); + query.bindValue(":idCardNo", object.value("id_card_no").toString()); + query.bindValue(":left1", object.value("left_iris_code1")); + query.bindValue(":right1", object.value("right_iris_code1")); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(); + +// LOG_DEBUG(QString("保存虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool IrisDataDao::edit(QVariantMap newObject, QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // UPDATE语句 + if (!newObject.contains("left_iris_code1") || !newObject.contains("right_iris_code1")){ + return false; + } + QString sql = QString("UPDATE IRIS_DATA SET LEFT_IRIS_CODE1 = :left1, RIGHT_IRIS_CODE1 = :right1 WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":left1", newObject.value("left_iris_code1")); + query.bindValue(":right1", newObject.value("right_iris_code1")); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(); + +// LOG_DEBUG(QString("编辑虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; +} + + +bool IrisDataDao::dele(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + QString sql = QString("DELETE FROM IRIS_DATA WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(); + +// LOG_DEBUG(QString("删除虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; +} diff --git a/dao/IrisDataDao.h b/dao/IrisDataDao.h new file mode 100644 index 0000000..c74dbbd --- /dev/null +++ b/dao/IrisDataDao.h @@ -0,0 +1,25 @@ +#ifndef IRISDATADAO_H +#define IRISDATADAO_H + +#include +#include "BaseDao.h" + +class IrisDataDao : public BaseDao +{ + Q_OBJECT +public: + explicit IrisDataDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + QVariantMap findRecordByPersonId(QString personId); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +signals: + +}; + +#endif // IRISDATADAO_H diff --git a/dao/RecognitionRecordsDao.cpp b/dao/RecognitionRecordsDao.cpp new file mode 100644 index 0000000..40db453 --- /dev/null +++ b/dao/RecognitionRecordsDao.cpp @@ -0,0 +1,100 @@ +#include "RecognitionRecordsDao.h" + +RecognitionRecordsDao::RecognitionRecordsDao(QObject *parent) : BaseDao(parent) +{ + +} + + +QVector RecognitionRecordsDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM RECOGNITION_RECORDS"; + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + item.insert("id", query.value("id").toLongLong()); + result.append(item); + } + +// LOG_DEBUG(QString("查询RECOGNITION_RECORDS表的所有记录[记录数:%1]").arg(result.size()).toStdString()); + return result; +} + +QVariantMap RecognitionRecordsDao::findRecordById(QString id) +{ + QVariantMap item; + return item; +} + +QString RecognitionRecordsDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + + // INSERT语句 + QString sql = QString("INSERT INTO RECOGNITION_RECORDS (ID, PERSON_ID, DATETIME, REC_TYPE, DEV_CODE, DOOR_CODE, INOUT_TYPE) " + "VALUES (:id, :personId, :datetime, :recType, :devCode, :doorCode, :inoutType)"); + + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":personId", object.value("person_id").toString()); + query.bindValue(":datetime", object.value("date_time").toString()); + query.bindValue(":recType", object.value("rec_type").toString()); + query.bindValue(":devCode", object.value("dev_code").toString()); + query.bindValue(":doorCode", object.value("door_code").toString()); + query.bindValue(":inoutType", object.value("inout_type").toString()); + +// LOG_DEBUG(sql.toStdString()); + + // 插入识别的log日志 + QString logStr = QString("INSERT INTO RECOGNITION_LOGS (ID, LOG_INFO) VALUES (:id, :logInfo)"); + + QSqlQuery logQuery(ConnectionManager::getInstance()->getConnection()); + logQuery.prepare(logStr); + logQuery.bindValue(":id", id); + logQuery.bindValue(":logInfo", object.value("debug_info").toString()); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(); + logQuery.exec(); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool RecognitionRecordsDao::edit(QVariantMap newObject, QString id) +{ + return false; +} + +bool RecognitionRecordsDao::dele(QString id) +{ + return false; +} diff --git a/dao/RecognitionRecordsDao.h b/dao/RecognitionRecordsDao.h new file mode 100644 index 0000000..38de7c9 --- /dev/null +++ b/dao/RecognitionRecordsDao.h @@ -0,0 +1,23 @@ +#ifndef RECOGNITIONRECORDSDAO_H +#define RECOGNITIONRECORDSDAO_H + +#include +#include "BaseDao.h" +class RecognitionRecordsDao: public BaseDao +{ + Q_OBJECT +public: + explicit RecognitionRecordsDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +signals: + +}; + +#endif // RECOGNITIONRECORDSDAO_H diff --git a/dao/SysDeptDao.cpp b/dao/SysDeptDao.cpp new file mode 100644 index 0000000..22f9946 --- /dev/null +++ b/dao/SysDeptDao.cpp @@ -0,0 +1,88 @@ +#include "SysDeptDao.h" + +SysDeptDao::SysDeptDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector SysDeptDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_DEPT WHERE PID != '-1' ORDER BY PID, NUM"; + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + item.insert("id", query.value("id").toString()); + item.insert("pid", query.value("pid").toString()); + item.insert("pids", query.value("pids").toString()); + item.insert("simplename", query.value("simplename").toString()); + item.insert("fullname", query.value("fullname").toString()); + } + +// LOG_TRACE(QString("查询表[SYS_DEPT]的所有记录[%1][%2]").arg(result.size()).arg(sql).toStdString()); + + return result; +} + +QVariantMap SysDeptDao::findRecordById(QString id) +{ + QVariantMap item; + return item; + + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM SYS_DEPT WHERE SYS_DEPT.ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + // 获取结果集的大小 + query.last(); + int count = query.at() + 1; + + if (count >=1) + { + query.first(); + + result.insert("id", query.value("id").toString()); + result.insert("pid", query.value("pid").toString()); + result.insert("pids", query.value("pids").toString()); + result.insert("simplename", query.value("simplename").toString()); + result.insert("fullname", query.value("fullname").toString()); + } + +// LOG_TRACE(QString("根据id查询SYS_DEPT表的记录[ID=%1][%2]").arg(id).arg(sql).toStdString()); + + return result; +} + + +QString SysDeptDao::save(QVariantMap object) +{ + return "0"; +} +bool SysDeptDao::edit(QVariantMap newObject, QString id) +{ + return true; +} +bool SysDeptDao::dele(QString id) +{ + return true; +} diff --git a/dao/SysDeptDao.h b/dao/SysDeptDao.h new file mode 100644 index 0000000..e07a09f --- /dev/null +++ b/dao/SysDeptDao.h @@ -0,0 +1,24 @@ +#ifndef SYSDEPTDAO_H +#define SYSDEPTDAO_H + +#include +#include "BaseDao.h" + +class SysDeptDao : public BaseDao +{ + Q_OBJECT +public: + explicit SysDeptDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +private: + +}; + +#endif // SYSDEPTDAO_H diff --git a/dao/SysPersonDao.cpp b/dao/SysPersonDao.cpp new file mode 100644 index 0000000..dd9480f --- /dev/null +++ b/dao/SysPersonDao.cpp @@ -0,0 +1,371 @@ +#include "SysPersonDao.h" + + +SysPersonDao::SysPersonDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector SysPersonDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0'"; + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + count++; + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + result.append(item); + } + +// LOG(TRACE) << QString("查询SYS_PERSON表的所有记录[%1]").arg(count).toStdString(); +// LOG_TRACE(QString("查询SYS_PERSON表的所有记录[%1]").arg(count).toStdString()); + + return result; +} + +QVariantMap SysPersonDao::findRecordById(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0' AND SYS_PERSON.ID = '%1'").arg(id); + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVariantMap result; + + // 获取结果集的大小 + query.last(); + int count = query.at() + 1; + + if (count >=1) + { + query.first(); + + result.insert("id", query.value("id").toString()); + result.insert("delflag", query.value("delflag").toString()); + result.insert("createtime", query.value("createtime").toString()); + result.insert("updatetime", query.value("updatetime").toString()); + result.insert("name", query.value("name").toString()); + result.insert("gender", query.value("gender").toString()); + result.insert("deptid", query.value("deptid").toString()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("remarks", query.value("remarks").toString()); + result.insert("person_code", query.value("person_code").toString()); + result.insert("deptname", query.value("fullname").toString()); + result.insert("sync_id", query.value("sync_id").toString()); + result.insert("hasFace", query.value("face_valid").toString()); + result.insert("hasIris", query.value("iris_valid").toString()); + } + +// LOG(TRACE) << QString("根据id查询SYS_PERSON表的记录[id=%1][%2]").arg(id).arg(sql).toStdString(); +// LOG_TRACE(QString("根据id查询SYS_PERSON表的记录[id=%1][%2]").arg(id).arg(sql).toStdString()); + + return result; +} + +int SysPersonDao::findRecordCountByNameAndDept(QString name, QString dept) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT COUNT(P.ID) AS RECCT FROM SYS_PERSON P LEFT JOIN SYS_DEPT D ON P.DEPTID = D.ID WHERE P.DELFLAG = '0'"; + if (name.isEmpty() == false) + { + sql += " AND P.NAME LIKE '%" + name + "%'"; + } + if (dept.isEmpty() == false && dept.indexOf("-1") < 0) + { + sql += QString(" AND ((P.DEPTID = '%1') OR (D.PIDS LIKE '%,%1,%'))").arg(dept); + } + + // 执行查询 + query.exec(sql); + + // 返回结果 + int result; + + // 遍历查询结果 + if (query.next()) { + result = query.value("RECCT").toInt(); + } + +// LOG(TRACE) << QString("根据姓名和部门查询SYS_PERSON记录总数[%1][%2]").arg(result).arg(sql).toStdString(); +// LOG_TRACE(QString("根据姓名和部门查询SYS_PERSON记录总数[%1][%2]").arg(result).arg(sql).toStdString()); + + return result; +} + +QVector SysPersonDao::findRecordsByNameAndDept(QString name, QString dept, qint8 limit, qint16 offset) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON P LEFT JOIN SYS_DEPT D ON P.DEPTID = D.ID WHERE P.DELFLAG = '0'"; + if (name.isEmpty() == false) + { + sql += " AND P.NAME LIKE '%" + name + "%'"; + } + if (dept.isEmpty() == false && dept.indexOf("-1") < 0) + { + sql += QString(" AND ((P.DEPTID = '%1') OR (D.PIDS LIKE '%,%1,%'))").arg(dept); + } + + sql += QString(" LIMIT %1 OFFSET %2").arg(limit).arg(offset); + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + count++; + + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + + result.append(item); + } + +// LOG(TRACE) << QString("根据姓名和部门分页查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString(); +// LOG_TRACE(QString("根据姓名和部门分页查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString()); + + return result; +} + +QVector SysPersonDao::findRecordsByProperties(QVariantMap conditions) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0'"; + QVariantMap::iterator it; + for (it = conditions.begin(); it != conditions.end(); it++) + { + sql += QString(" AND SYS_PERSON.%1 = %2").arg(it.key()).arg(it.value().toString()); + } + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + count++; + + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + + result.append(item); + } + +// LOG(TRACE) << QString("根据属性值查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString(); +// LOG_TRACE(QString("根据属性值查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString()); + + return result; +} + +QString SysPersonDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + + // INSERT语句 + QString sql = QString("INSERT INTO SYS_PERSON " + "(ID, DELFLAG, CREATETIME, UPDATETIME, " + "NAME, GENDER, DEPTID, ID_CARD_NO, " + "REMARKS, PERSON_CODE, SYNC_ID, FACE_VALID, IRIS_VALID) " + "VALUES ('%1', '0', '%2', '%2', '%3', '%4', '%5', '%6', '%7', '%8', '%9', 0, 0)") + .arg(id).arg(tm) + .arg(object.value("name").toString()) + .arg(object.value("gender").toString()) + .arg(object.value("deptid").toString()) + .arg(object.value("id_card_no").toString()) + .arg(object.value("remarks").toString()) + .arg(object.value("person_code").toString()) + .arg(object.value("sync_id").toString()); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(sql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { +// LOG(DEBUG) << QString("保存SYS_PERSON记录成功[ID = %1][%2]").arg(id).arg(sql).toStdString(); +// LOG_DEBUG(QString("保存SYS_PERSON记录成功[ID = %1][%2]").arg(id).arg(sql).toStdString()); + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool SysPersonDao::edit(QVariantMap newObject, QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + + // UPDATE语句 + QString sql = QString("UPDATE SYS_PERSON SET UPDATETIME = '%1'").arg(tm); + if (newObject.contains("name")) + { + sql.append(QString(", NAME = '%1'").arg(newObject.value("name").toString())); + } + if (newObject.contains("gender")) + { + sql.append(QString(", GENDER = '%1'").arg(newObject.value("gender").toString())); + } + if (newObject.contains("deptid")) + { + sql.append(QString(", DEPTID = '%1'").arg(newObject.value("deptid").toString())); + } + if (newObject.contains("person_code")) + { + sql.append(QString(", PERSON_CODE = '%1'").arg(newObject.value("person_code").toString())); + } + if (newObject.contains("face_valid")) + { + sql.append(QString(", FACE_VALID = '%1'").arg(newObject.value("face_valid").toString())); + } + if (newObject.contains("iris_valid")) + { + sql.append(QString(", IRIS_VALID = '%1'").arg(newObject.value("iris_valid").toString())); + } + + sql.append(QString(" WHERE ID = '%1'").arg(id)); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(sql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + +// LOG(DEBUG) << QString("编辑人员[ID=%1][%2]").arg(id).arg(sql).toStdString(); +// LOG_DEBUG(QString("编辑人员[ID=%1][%2]").arg(id).arg(sql).toStdString()); + + // 返回结果 + return success; +} + +bool SysPersonDao::dele(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + QSqlQuery irisDel(ConnectionManager::getInstance()->getConnection()); + + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + qint64 tmms = QDateTime::currentDateTime().toMSecsSinceEpoch(); + + // UPDATE语句 + QString sql = QString("UPDATE SYS_PERSON SET UPDATETIME = :updateTime, DELFLAG = :flag WHERE ID = :id").arg(tm).arg(tmms).arg(id); + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":updateTime", tm); + query.bindValue(":flag", tmms); + + // 物理删除人员的人脸和虹膜数据 + QString delIrisSql = QString("DELETE FROM IRIS_DATA WHERE PERSON_ID = :personId"); + irisDel.prepare(delIrisSql); + irisDel.bindValue(":personId", id); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(sql); + query.exec(delIrisSql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + +// LOG_DEBUG(QString("删除人员SYS_PERSON[ID=%1][%2]").arg(id).arg(success).toStdString()); + + // 返回结果 + return success; +} diff --git a/dao/SysPersonDao.h b/dao/SysPersonDao.h new file mode 100644 index 0000000..e02e5ba --- /dev/null +++ b/dao/SysPersonDao.h @@ -0,0 +1,27 @@ +#ifndef SYSPERSONDAO_H +#define SYSPERSONDAO_H + +#include +#include "BaseDao.h" + +class SysPersonDao : public BaseDao +{ + Q_OBJECT +public: + explicit SysPersonDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + int findRecordCountByNameAndDept(QString name, QString dept); + QVector findRecordsByNameAndDept(QString name, QString dept, qint8 limit, qint16 offset); + QVector findRecordsByProperties(QVariantMap conditions); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); +signals: + +}; + +#endif // SYSPERSONDAO_H diff --git a/dao/dao.pri b/dao/dao.pri new file mode 100644 index 0000000..1e04ce4 --- /dev/null +++ b/dao/dao.pri @@ -0,0 +1,18 @@ + +HEADERS += $$PWD/BaseDao.h +HEADERS += $$PWD/IrisDataDao.h +HEADERS += $$PWD/RecognitionRecordsDao.h +HEADERS += $$PWD/SysPersonDao.h +HEADERS += $$PWD/SysDeptDao.h + +SOURCES += $$PWD/BaseDao.cpp +SOURCES += $$PWD/IrisDataDao.cpp +SOURCES += $$PWD/RecognitionRecordsDao.cpp +SOURCES += $$PWD/SysPersonDao.cpp +SOURCES += $$PWD/SysDeptDao.cpp + +HEADERS += $$PWD/util/ConnectionManager.h +SOURCES += $$PWD/util/ConnectionManager.cpp +#HEADERS += $$PWD/util/CacheManager.h +#SOURCES += $$PWD/util/CacheManager.cpp + diff --git a/AppConstants.h b/AppConstants.h new file mode 100644 index 0000000..296c53f --- /dev/null +++ b/AppConstants.h @@ -0,0 +1,28 @@ +#ifndef APPCONSTANTS_H +#define APPCONSTANTS_H + +class AppConstants +{ +public: + enum WidgeFrameName + { + MAIN_PAGE = 0, // 主页面 + PERSON_LIST_FORM = 1, // 人员列表页面 + ADD_PERSON_FORM = 2, // 添加人员页面 + ADD_PERSON_CAPTURE_FACE = 21, // 添加/编辑人员时进行人脸拍图 + ADD_PERSON_CAPTURE_IRIS = 22, // 添加/编辑人员时进行虹膜拍图 + SETTING_FORM = 3, // 设置页面 + RECOGNIZE_RESULT_FORM = 4, // 识别结果界面 + IDENTIFY_FORM = 5, // 识别界面 含识别中 和 识别结果 + LOCKSCREEN_FORM = 6 // 锁屏待机界面 + }; + + enum ApplicationState + { + STATE_WAIT = 0, // 待机 + STATE_WORKING = 1, // 工作状态 + STATE_IDENTIFYING = 2, // 识别中 + }; +}; + +#endif // APPCONSTANTS_H diff --git a/CasicIrisIdentify.pro b/CasicIrisIdentify.pro index 5d7fea6..575ce3d 100644 --- a/CasicIrisIdentify.pro +++ b/CasicIrisIdentify.pro @@ -1,4 +1,4 @@ -QT += core gui +QT += core gui sql network texttospeech greaterThan(QT_MAJOR_VERSION, 4): QT += widgets @@ -15,20 +15,46 @@ # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 -SOURCES += \ - main.cpp \ - IdentifyForm.cpp +include("dao/dao.pri") +include("device/device.pri") +include("utils/utils.pri") -HEADERS += \ - IdentifyForm.h +SOURCES += main.cpp +SOURCES += ProMemory.cpp +SOURCES += MainWindowForm.cpp +SOURCES += IdentifyForm.cpp +SOURCES += LockScreenForm.cpp -FORMS += \ - IdentifyForm.ui +HEADERS += AppConstants.h +HEADERS += ProMemory.h +HEADERS += MainWindowForm.h +HEADERS += IdentifyForm.h +HEADERS += LockScreenForm.h -TRANSLATIONS += \ - CasicIrisIdentify_zh_CN.ts +FORMS += MainWindowForm.ui +FORMS += IdentifyForm.ui +FORMS += LockScreenForm.ui + +RESOURCES += resource.qrc + +DISTFILES += conf/config.ini + +#TRANSLATIONS += CasicIrisIdentify_zh_CN.ts + +#INCLUDEPATH += include/spdlog +#DEPENDPATH += include/spdlog # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target + + +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lopencv_world420 +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lGxIAPICPPEx + +INCLUDEPATH += $$PWD/include/daheng +DEPENDPATH += $$PWD/include/daheng + +INCLUDEPATH += $$PWD/include +DEPENDPATH += $$PWD/include diff --git a/CasicIrisIdentify_zh_CN.ts b/CasicIrisIdentify_zh_CN.ts index 5526fe4..81900df 100644 --- a/CasicIrisIdentify_zh_CN.ts +++ b/CasicIrisIdentify_zh_CN.ts @@ -1,3 +1,12 @@ - + + + IdentifyForm + + + IdentifyForm + + + + diff --git a/IdentifyForm.cpp b/IdentifyForm.cpp index 348a897..ba1f251 100644 --- a/IdentifyForm.cpp +++ b/IdentifyForm.cpp @@ -1,4 +1,4 @@ -#include "IdentifyForm.h" +#include "IdentifyForm.h" #include "ui_IdentifyForm.h" IdentifyForm::IdentifyForm(QWidget *parent) @@ -6,6 +6,12 @@ , ui(new Ui::IdentifyForm) { ui->setupUi(this); + + // 初始化更新界面的定时器 + // 每秒执行一次 + connect(TimeCounterUtil::getInstance().clockCounter, &QTimer::timeout, this, &IdentifyForm::updateDateAndTime); + + TimeCounterUtil::getInstance().clockCounter->start(1000); } IdentifyForm::~IdentifyForm() @@ -13,3 +19,16 @@ delete ui; } +void IdentifyForm::drawIrisImageOnFrame(QImage image) +{ + // 只在识别界面才显示画面 + if (ui->wgtStacked->currentIndex() == 0) { + ui->labelVideo->setPixmap(QPixmap::fromImage(image)); + } +} + + +void IdentifyForm::updateDateAndTime() +{ + ui->labelTime->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd dddd HH:mm:ss")); +} diff --git a/IdentifyForm.h b/IdentifyForm.h index fc857a1..ae1cd22 100644 --- a/IdentifyForm.h +++ b/IdentifyForm.h @@ -1,7 +1,10 @@ -#ifndef IDENTIFYFORM_H +#ifndef IDENTIFYFORM_H #define IDENTIFYFORM_H #include +#include + +#include "utils/UtilInclude.h" QT_BEGIN_NAMESPACE namespace Ui { class IdentifyForm; } @@ -15,7 +18,14 @@ IdentifyForm(QWidget *parent = nullptr); ~IdentifyForm(); +public slots: + void drawIrisImageOnFrame(QImage image); + private: Ui::IdentifyForm *ui; + +private slots: + void updateDateAndTime(); + }; #endif // IDENTIFYFORM_H diff --git a/IdentifyForm.ui b/IdentifyForm.ui index c72a36f..879dc9a 100644 --- a/IdentifyForm.ui +++ b/IdentifyForm.ui @@ -6,13 +6,59 @@ 0 0 - 800 + 600 600 IdentifyForm + + + + 0 + 40 + 600 + 450 + + + + 0 + + + + + + 100 + 10 + 400 + 300 + + + + + + + + + + + + + + 0 + 0 + 600 + 40 + + + + TextLabel + + + Qt::AlignCenter + + diff --git a/LockScreenForm.cpp b/LockScreenForm.cpp new file mode 100644 index 0000000..58dc54b --- /dev/null +++ b/LockScreenForm.cpp @@ -0,0 +1,14 @@ +#include "LockScreenForm.h" +#include "ui_LockScreenForm.h" + +LockScreenForm::LockScreenForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::LockScreenForm) +{ + ui->setupUi(this); +} + +LockScreenForm::~LockScreenForm() +{ + delete ui; +} diff --git a/LockScreenForm.h b/LockScreenForm.h new file mode 100644 index 0000000..b5ded48 --- /dev/null +++ b/LockScreenForm.h @@ -0,0 +1,25 @@ +#ifndef LOCKSCREENFORM_H +#define LOCKSCREENFORM_H + +#include +#include + +#include "utils/UtilInclude.h" + +namespace Ui { +class LockScreenForm; +} + +class LockScreenForm : public QWidget +{ + Q_OBJECT + +public: + explicit LockScreenForm(QWidget *parent = nullptr); + ~LockScreenForm(); + +private: + Ui::LockScreenForm *ui; +}; + +#endif // LOCKSCREENFORM_H diff --git a/LockScreenForm.ui b/LockScreenForm.ui new file mode 100644 index 0000000..7f2a6db --- /dev/null +++ b/LockScreenForm.ui @@ -0,0 +1,45 @@ + + + LockScreenForm + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + 180 + 100 + 54 + 12 + + + + TextLabel + + + + + + 180 + 160 + 54 + 12 + + + + TextLabel + + + + + + diff --git a/MainWindowForm.cpp b/MainWindowForm.cpp new file mode 100644 index 0000000..84f8159 --- /dev/null +++ b/MainWindowForm.cpp @@ -0,0 +1,86 @@ +#include "MainWindowForm.h" +#include "ui_MainWindowForm.h" +#include + +MainWindowForm::MainWindowForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::MainWindowForm) +{ + ui->setupUi(this); + + // 设置窗口透明和大小、位置 + this->setWindowFlags(Qt::FramelessWindowHint); + this->move(1400, 15); + this->resize(SettingConfig::getInstance().WINDOW_WIDTH, SettingConfig::getInstance().WINDOW_HEIGHT); + + // 通过调色板的颜色来设置窗口的统一背景色 + qApp->setPalette(QPalette(QColor(SettingConfig::getInstance().WINDOW_BACKGROUND_COLOR))); + + // 加载css文件设置控件样式 + QFile file(QApplication::applicationDirPath() + "/qss/main.css"); + if (file.open(QFile::ReadOnly)) + { + QString qssStr = QLatin1String(file.readAll()); + this->setStyleSheet(qssStr); + file.close(); + } + + initFormsPtr(); + + // 设置标题文字 + ui->labelTitle->setText(SettingConfig::getInstance().WINDOW_TITLE); + ui->labelCopyright->setText(SettingConfig::getInstance().WINDOW_RIGHTS); + ui->labelVersion->setText(SettingConfig::getInstance().WINDOW_VERSION); + + // 初始化虹膜相机控制 + ProMemory::getInstance().irisCam = new IrisCameraController(this); + ProMemory::getInstance().irisCam->initIrisCamera(); + ProMemory::getInstance().irisCam->openIrisCamera(); + connect(ProMemory::getInstance().irisCam->irisCamHandler, &IrisCameraCapEventHandler::sendIrisFrameToDraw, identifyForm, &IdentifyForm::drawIrisImageOnFrame); + +// LOG_INFO(QString("应用程序启动成功[Application Startup Success]").toStdString()); + qDebug() << "应用程序启动成功[Application Startup Success]"; + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::IDENTIFY_FORM; + ui->wdgtStatced->setCurrentWidget(identifyForm); + + // 开始虹膜相机拍图 + ProMemory::getInstance().irisCam->startCapture(); +} + +MainWindowForm::~MainWindowForm() +{ + delete ui; +} + +void MainWindowForm::lockScreen() +{ + ui->wdgtStatced->setCurrentWidget(lockScreenForm); + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::LOCKSCREEN_FORM; + ProMemory::getInstance().appState = AppConstants::ApplicationState::STATE_WAIT; +} + +void MainWindowForm::keyPressEvent(QKeyEvent *event) +{ + switch (event->key()) { + case Qt::Key_Escape: + QTimer::singleShot(100, qApp, [=](){ + QApplication::quit(); + }); + + default: + QWidget::keyPressEvent(event); + } +} + +void MainWindowForm::initFormsPtr() +{ + // 初始化各个form + lockScreenForm = new LockScreenForm(this); + identifyForm = new IdentifyForm(this); + + // 将form添加到statcked widget中 + ui->wdgtStatced->addWidget(identifyForm); + ui->wdgtStatced->addWidget(lockScreenForm); + + // 绑定按钮函数 +} diff --git a/MainWindowForm.h b/MainWindowForm.h new file mode 100644 index 0000000..7fb2d89 --- /dev/null +++ b/MainWindowForm.h @@ -0,0 +1,38 @@ +#ifndef MAINWINDOWFORM_H +#define MAINWINDOWFORM_H + +#include +#include +#include + +#include "utils/UtilInclude.h" +#include "ProMemory.h" +#include "LockScreenForm.h" +#include "IdentifyForm.h" + +namespace Ui { +class MainWindowForm; +} + +class MainWindowForm : public QWidget +{ + Q_OBJECT + +public: + explicit MainWindowForm(QWidget *parent = nullptr); + ~MainWindowForm(); + +public slots: + void lockScreen(); + +private: + Ui::MainWindowForm *ui; + LockScreenForm * lockScreenForm; + IdentifyForm * identifyForm; + + void keyPressEvent(QKeyEvent *event); + + void initFormsPtr(); +}; + +#endif // MAINWINDOWFORM_H diff --git a/MainWindowForm.ui b/MainWindowForm.ui new file mode 100644 index 0000000..e793ebf --- /dev/null +++ b/MainWindowForm.ui @@ -0,0 +1,85 @@ + + + MainWindowForm + + + + 0 + 0 + 600 + 1024 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + 0 + 0 + 600 + 84 + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + + + + TextLabel + + + Qt::AlignBottom|Qt::AlignHCenter + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + diff --git a/ProMemory.cpp b/ProMemory.cpp new file mode 100644 index 0000000..19e7403 --- /dev/null +++ b/ProMemory.cpp @@ -0,0 +1,84 @@ +#include "ProMemory.h" + +ProMemory::ProMemory() +{ + +} + +ProMemory::~ProMemory() +{ + +} + +/* +void ProMemory::pushCasicIris(CasicIrisInfo irisInfo) +{ + QMutex mutex; + mutex.lock(); + if (this->irisQueue.size() > 30) + { + QStack empty; + std::swap(empty, irisQueue); + } + + irisQueue.push(irisInfo); + mutex.unlock(); +} +CasicIrisInfo ProMemory::popCasicIris() +{ + CasicIrisInfo result; + + QMutex mutex; + mutex.lock(); + if (this->irisQueue.size() > 0) + { + result = irisQueue.pop(); + } + + mutex.unlock(); + + return result; +} +*/ +int ProMemory::getIrisQueueSize() +{ + int size = 0; + + QMutex mutex; + mutex.lock(); + +// size = this->irisQueue.size(); + + mutex.unlock(); + + return size; +} +bool ProMemory::isIrisQueueEmpty() +{ + bool empty = true; + + QMutex mutex; + mutex.lock(); + +// empty = this->irisQueue.isEmpty(); + + mutex.unlock(); + + return empty; +} +void ProMemory::clearIrisQueue() +{ + QMutex mutex; + mutex.lock(); + +// QStack empty; +// std::swap(empty, irisQueue); + + mutex.unlock(); +} + + +void ProMemory::initIrisFeatures(QString personId) +{ +// irisRegistPro->sendDataToExract(QByteArray(QString("[-u]").append(personId).toLocal8Bit())); +} diff --git a/ProMemory.h b/ProMemory.h new file mode 100644 index 0000000..2ecd653 --- /dev/null +++ b/ProMemory.h @@ -0,0 +1,52 @@ +#ifndef PROMEMORY_H +#define PROMEMORY_H + +#include +#include + +#include "AppConstants.h" +//#include "casic/iris/CasicIrisInfo.h" +#include "dao/IrisDataDao.h" + +#include "device/IrisCameraController.h" +//#include "device/iris/IrisRegistProcess.h" +//#include "device/iris/IrisRecogProcess.h" + +class IrisCameraController; +class IrisRegistProcess; +class IrisRecogProcess; + +class ProMemory +{ +public: + ~ProMemory(); + ProMemory(const ProMemory&)=delete; + ProMemory& operator=(const ProMemory&)=delete; + + static ProMemory& getInstance() { + static ProMemory instance; + return instance; + } + +// void pushCasicIris(CasicIrisInfo irisInfo); +// CasicIrisInfo popCasicIris(); + int getIrisQueueSize(); + bool isIrisQueueEmpty(); + void clearIrisQueue(); + + volatile int widgeFrame = 0; // 当前显示的界面 + volatile int appState = 0; // 当前程序所处的状态 + + void initIrisFeatures(QString personId = ""); // 初始化虹膜特征值集合 + + IrisCameraController * irisCam; + IrisRecogProcess * irisRecogPro; + +private: + ProMemory(); + +// QStack irisQueue; // 虹膜信息队列 + QVector irisFeatures; // 虹膜特征值集合 +}; + +#endif // PROMEMORY_H diff --git a/conf/config.ini b/conf/config.ini new file mode 100644 index 0000000..66e46ad --- /dev/null +++ b/conf/config.ini @@ -0,0 +1,67 @@ +[recognize] +#最大允许识别时间(ms) +maxMatchTime=10000 +#识别成功界面停留时间(ms) +successTipsLast=5000 +#识别失败界面停留时间(ms) +failureTipsLast=3000 +#人脸识别最大尝试次数 +maxFaceTryCount=20 +#持续没找到人脸的最大次数 +maxFaceNotFoundCount=500 +#注册时最小人脸 +minFaceRegist=240 +#识别时最小人脸 +minFaceRecog=100 + +#虹膜识别最大尝试次数 +maxIrisTryCount=10 +#虹膜识别持续没有找到眼的最大次数 +maxEyeNotFoundCount=50 + +#识别方式[1=人脸;2=虹膜;3=双认证;4=任意] +recogType=4 + +[window] +#界面窗口宽(px) +width=600 +#界面窗口高(px) +height=1024 +#统一背景色 +backgroundColor="#FFFFFF" +#标题 +title="虹膜识别终端" + +[work] +#工作状态检测时最小人脸范围 +minFaceSize=160 +#人脸范围最小横坐标 +minFacePosX=320 +#人脸范围最大横坐标 +maxFacePosX=960 +#人脸范围最小纵坐标 +minFacePosY=180 +#人脸范围最大纵坐标 +maxFacePosY=540 +#人脸太近阈值 +faceCloseSize=360 +#人脸太远阈值 +faceFarSize=480 + +[camera] +#虹膜相机取一幅画面的时间间隔(ms) +irisFrameInterval=100 +#虹膜相机拍摄宽度 +irisFrameWidth=1440 +#虹膜相机拍摄高度 +irisFrameHeight=1080 +#虹膜图像高度 +irisWidth=640 +#虹膜图像高度 +irisHeight=480 + +[log] +#日志文件位置 +logFile="d://irisLogs//casic_log.txt" +#日志级别 +logLevel="trace" diff --git a/dao/BaseDao.cpp b/dao/BaseDao.cpp new file mode 100644 index 0000000..f51c144 --- /dev/null +++ b/dao/BaseDao.cpp @@ -0,0 +1,12 @@ +#include "BaseDao.h" +#include "dao/util/ConnectionManager.h" + +BaseDao::BaseDao(QObject *parent) : QObject(parent) +{ + +} + +BaseDao::~BaseDao() +{ + +} diff --git a/dao/BaseDao.h b/dao/BaseDao.h new file mode 100644 index 0000000..1693c88 --- /dev/null +++ b/dao/BaseDao.h @@ -0,0 +1,32 @@ +#ifndef BASEDAO_H +#define BASEDAO_H + +#include +#include +#include +#include + +#include "dao/util/ConnectionManager.h" +#include "utils/UtilInclude.h" + +class BaseDao : public QObject +{ + Q_OBJECT +public: + explicit BaseDao(QObject *parent = nullptr); + ~BaseDao(); + + virtual QVector findAllRecord() = 0; + virtual QVariantMap findRecordById(QString id) = 0; + + virtual QString save(QVariantMap object) = 0; + virtual bool edit(QVariantMap newObject, QString id) = 0; + virtual bool dele(QString id) = 0; + +private: + +signals: + +}; + +#endif // BASEDAO_H diff --git a/dao/IrisDataDao.cpp b/dao/IrisDataDao.cpp new file mode 100644 index 0000000..37a0ed6 --- /dev/null +++ b/dao/IrisDataDao.cpp @@ -0,0 +1,204 @@ +#include "IrisDataDao.h" + +IrisDataDao::IrisDataDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector IrisDataDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM IRIS_DATA"; + query.prepare(sql); + + // 执行查询 + query.exec(); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + item.insert("id", query.value("id").toString()); + item.insert("person_id", query.value("person_id").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("left_iris_code1", query.value("left_iris_code1")); + item.insert("left_iris_code2", query.value("left_iris_code2")); + item.insert("left_iris_code3", query.value("left_iris_code3")); + item.insert("right_iris_code1", query.value("right_iris_code1")); + item.insert("right_iris_code2", query.value("right_iris_code2")); + item.insert("right_iris_code3", query.value("right_iris_code3")); + + result.append(item); + } + +// LOG_DEBUG(QString("查询IRIS_DATA表的所有记录[结果数:%1]").arg(result.size()).toStdString()); + return result; +} + +QVariantMap IrisDataDao::findRecordById(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM IRIS_DATA WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + // 获取结果 + if (query.next()) + { + result.insert("id", query.value("id").toString()); + result.insert("person_id", query.value("person_id").toLongLong()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("left_iris_code1", query.value("left_iris_code1")); + result.insert("left_iris_code2", query.value("left_iris_code2")); + result.insert("left_iris_code3", query.value("left_iris_code3")); + result.insert("right_iris_code1", query.value("right_iris_code1")); + result.insert("right_iris_code2", query.value("right_iris_code2")); + result.insert("right_iris_code3", query.value("right_iris_code3")); + } + +// LOG_DEBUG(QString("根据id查询IRIS_DATA表的记录[id=%1]").arg(id).toStdString()); + return result; +} + +QVariantMap IrisDataDao::findRecordByPersonId(QString personId) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM IRIS_DATA WHERE PERSON_ID = :personId"); + query.prepare(sql); + query.bindValue(":personId", personId); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + if (query.next()) + { + result.insert("id", query.value("id").toString()); + result.insert("person_id", query.value("person_id").toLongLong()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("left_iris_code1", query.value("left_iris_code1")); + result.insert("left_iris_code2", query.value("left_iris_code2")); + result.insert("left_iris_code3", query.value("left_iris_code3")); + result.insert("right_iris_code1", query.value("right_iris_code1")); + result.insert("right_iris_code2", query.value("right_iris_code2")); + result.insert("right_iris_code3", query.value("right_iris_code3")); + } + +// LOG_DEBUG(QString("根据personId查询IRIS_DATA表的记录[personId=%1]").arg(personId).toStdString()); + return result; +} + + +QString IrisDataDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + + // INSERT语句 + QString sql = QString("INSERT INTO IRIS_DATA (ID, PERSON_ID, ID_CARD_NO, LEFT_IRIS_CODE1, RIGHT_IRIS_CODE1) VALUES (:id, :personId, :idCardNo, :left1, :right1)"); + + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":personId", object.value("person_id").toString()); + query.bindValue(":idCardNo", object.value("id_card_no").toString()); + query.bindValue(":left1", object.value("left_iris_code1")); + query.bindValue(":right1", object.value("right_iris_code1")); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(); + +// LOG_DEBUG(QString("保存虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool IrisDataDao::edit(QVariantMap newObject, QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // UPDATE语句 + if (!newObject.contains("left_iris_code1") || !newObject.contains("right_iris_code1")){ + return false; + } + QString sql = QString("UPDATE IRIS_DATA SET LEFT_IRIS_CODE1 = :left1, RIGHT_IRIS_CODE1 = :right1 WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":left1", newObject.value("left_iris_code1")); + query.bindValue(":right1", newObject.value("right_iris_code1")); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(); + +// LOG_DEBUG(QString("编辑虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; +} + + +bool IrisDataDao::dele(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + QString sql = QString("DELETE FROM IRIS_DATA WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(); + +// LOG_DEBUG(QString("删除虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; +} diff --git a/dao/IrisDataDao.h b/dao/IrisDataDao.h new file mode 100644 index 0000000..c74dbbd --- /dev/null +++ b/dao/IrisDataDao.h @@ -0,0 +1,25 @@ +#ifndef IRISDATADAO_H +#define IRISDATADAO_H + +#include +#include "BaseDao.h" + +class IrisDataDao : public BaseDao +{ + Q_OBJECT +public: + explicit IrisDataDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + QVariantMap findRecordByPersonId(QString personId); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +signals: + +}; + +#endif // IRISDATADAO_H diff --git a/dao/RecognitionRecordsDao.cpp b/dao/RecognitionRecordsDao.cpp new file mode 100644 index 0000000..40db453 --- /dev/null +++ b/dao/RecognitionRecordsDao.cpp @@ -0,0 +1,100 @@ +#include "RecognitionRecordsDao.h" + +RecognitionRecordsDao::RecognitionRecordsDao(QObject *parent) : BaseDao(parent) +{ + +} + + +QVector RecognitionRecordsDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM RECOGNITION_RECORDS"; + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + item.insert("id", query.value("id").toLongLong()); + result.append(item); + } + +// LOG_DEBUG(QString("查询RECOGNITION_RECORDS表的所有记录[记录数:%1]").arg(result.size()).toStdString()); + return result; +} + +QVariantMap RecognitionRecordsDao::findRecordById(QString id) +{ + QVariantMap item; + return item; +} + +QString RecognitionRecordsDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + + // INSERT语句 + QString sql = QString("INSERT INTO RECOGNITION_RECORDS (ID, PERSON_ID, DATETIME, REC_TYPE, DEV_CODE, DOOR_CODE, INOUT_TYPE) " + "VALUES (:id, :personId, :datetime, :recType, :devCode, :doorCode, :inoutType)"); + + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":personId", object.value("person_id").toString()); + query.bindValue(":datetime", object.value("date_time").toString()); + query.bindValue(":recType", object.value("rec_type").toString()); + query.bindValue(":devCode", object.value("dev_code").toString()); + query.bindValue(":doorCode", object.value("door_code").toString()); + query.bindValue(":inoutType", object.value("inout_type").toString()); + +// LOG_DEBUG(sql.toStdString()); + + // 插入识别的log日志 + QString logStr = QString("INSERT INTO RECOGNITION_LOGS (ID, LOG_INFO) VALUES (:id, :logInfo)"); + + QSqlQuery logQuery(ConnectionManager::getInstance()->getConnection()); + logQuery.prepare(logStr); + logQuery.bindValue(":id", id); + logQuery.bindValue(":logInfo", object.value("debug_info").toString()); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(); + logQuery.exec(); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool RecognitionRecordsDao::edit(QVariantMap newObject, QString id) +{ + return false; +} + +bool RecognitionRecordsDao::dele(QString id) +{ + return false; +} diff --git a/dao/RecognitionRecordsDao.h b/dao/RecognitionRecordsDao.h new file mode 100644 index 0000000..38de7c9 --- /dev/null +++ b/dao/RecognitionRecordsDao.h @@ -0,0 +1,23 @@ +#ifndef RECOGNITIONRECORDSDAO_H +#define RECOGNITIONRECORDSDAO_H + +#include +#include "BaseDao.h" +class RecognitionRecordsDao: public BaseDao +{ + Q_OBJECT +public: + explicit RecognitionRecordsDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +signals: + +}; + +#endif // RECOGNITIONRECORDSDAO_H diff --git a/dao/SysDeptDao.cpp b/dao/SysDeptDao.cpp new file mode 100644 index 0000000..22f9946 --- /dev/null +++ b/dao/SysDeptDao.cpp @@ -0,0 +1,88 @@ +#include "SysDeptDao.h" + +SysDeptDao::SysDeptDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector SysDeptDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_DEPT WHERE PID != '-1' ORDER BY PID, NUM"; + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + item.insert("id", query.value("id").toString()); + item.insert("pid", query.value("pid").toString()); + item.insert("pids", query.value("pids").toString()); + item.insert("simplename", query.value("simplename").toString()); + item.insert("fullname", query.value("fullname").toString()); + } + +// LOG_TRACE(QString("查询表[SYS_DEPT]的所有记录[%1][%2]").arg(result.size()).arg(sql).toStdString()); + + return result; +} + +QVariantMap SysDeptDao::findRecordById(QString id) +{ + QVariantMap item; + return item; + + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM SYS_DEPT WHERE SYS_DEPT.ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + // 获取结果集的大小 + query.last(); + int count = query.at() + 1; + + if (count >=1) + { + query.first(); + + result.insert("id", query.value("id").toString()); + result.insert("pid", query.value("pid").toString()); + result.insert("pids", query.value("pids").toString()); + result.insert("simplename", query.value("simplename").toString()); + result.insert("fullname", query.value("fullname").toString()); + } + +// LOG_TRACE(QString("根据id查询SYS_DEPT表的记录[ID=%1][%2]").arg(id).arg(sql).toStdString()); + + return result; +} + + +QString SysDeptDao::save(QVariantMap object) +{ + return "0"; +} +bool SysDeptDao::edit(QVariantMap newObject, QString id) +{ + return true; +} +bool SysDeptDao::dele(QString id) +{ + return true; +} diff --git a/dao/SysDeptDao.h b/dao/SysDeptDao.h new file mode 100644 index 0000000..e07a09f --- /dev/null +++ b/dao/SysDeptDao.h @@ -0,0 +1,24 @@ +#ifndef SYSDEPTDAO_H +#define SYSDEPTDAO_H + +#include +#include "BaseDao.h" + +class SysDeptDao : public BaseDao +{ + Q_OBJECT +public: + explicit SysDeptDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +private: + +}; + +#endif // SYSDEPTDAO_H diff --git a/dao/SysPersonDao.cpp b/dao/SysPersonDao.cpp new file mode 100644 index 0000000..dd9480f --- /dev/null +++ b/dao/SysPersonDao.cpp @@ -0,0 +1,371 @@ +#include "SysPersonDao.h" + + +SysPersonDao::SysPersonDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector SysPersonDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0'"; + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + count++; + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + result.append(item); + } + +// LOG(TRACE) << QString("查询SYS_PERSON表的所有记录[%1]").arg(count).toStdString(); +// LOG_TRACE(QString("查询SYS_PERSON表的所有记录[%1]").arg(count).toStdString()); + + return result; +} + +QVariantMap SysPersonDao::findRecordById(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0' AND SYS_PERSON.ID = '%1'").arg(id); + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVariantMap result; + + // 获取结果集的大小 + query.last(); + int count = query.at() + 1; + + if (count >=1) + { + query.first(); + + result.insert("id", query.value("id").toString()); + result.insert("delflag", query.value("delflag").toString()); + result.insert("createtime", query.value("createtime").toString()); + result.insert("updatetime", query.value("updatetime").toString()); + result.insert("name", query.value("name").toString()); + result.insert("gender", query.value("gender").toString()); + result.insert("deptid", query.value("deptid").toString()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("remarks", query.value("remarks").toString()); + result.insert("person_code", query.value("person_code").toString()); + result.insert("deptname", query.value("fullname").toString()); + result.insert("sync_id", query.value("sync_id").toString()); + result.insert("hasFace", query.value("face_valid").toString()); + result.insert("hasIris", query.value("iris_valid").toString()); + } + +// LOG(TRACE) << QString("根据id查询SYS_PERSON表的记录[id=%1][%2]").arg(id).arg(sql).toStdString(); +// LOG_TRACE(QString("根据id查询SYS_PERSON表的记录[id=%1][%2]").arg(id).arg(sql).toStdString()); + + return result; +} + +int SysPersonDao::findRecordCountByNameAndDept(QString name, QString dept) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT COUNT(P.ID) AS RECCT FROM SYS_PERSON P LEFT JOIN SYS_DEPT D ON P.DEPTID = D.ID WHERE P.DELFLAG = '0'"; + if (name.isEmpty() == false) + { + sql += " AND P.NAME LIKE '%" + name + "%'"; + } + if (dept.isEmpty() == false && dept.indexOf("-1") < 0) + { + sql += QString(" AND ((P.DEPTID = '%1') OR (D.PIDS LIKE '%,%1,%'))").arg(dept); + } + + // 执行查询 + query.exec(sql); + + // 返回结果 + int result; + + // 遍历查询结果 + if (query.next()) { + result = query.value("RECCT").toInt(); + } + +// LOG(TRACE) << QString("根据姓名和部门查询SYS_PERSON记录总数[%1][%2]").arg(result).arg(sql).toStdString(); +// LOG_TRACE(QString("根据姓名和部门查询SYS_PERSON记录总数[%1][%2]").arg(result).arg(sql).toStdString()); + + return result; +} + +QVector SysPersonDao::findRecordsByNameAndDept(QString name, QString dept, qint8 limit, qint16 offset) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON P LEFT JOIN SYS_DEPT D ON P.DEPTID = D.ID WHERE P.DELFLAG = '0'"; + if (name.isEmpty() == false) + { + sql += " AND P.NAME LIKE '%" + name + "%'"; + } + if (dept.isEmpty() == false && dept.indexOf("-1") < 0) + { + sql += QString(" AND ((P.DEPTID = '%1') OR (D.PIDS LIKE '%,%1,%'))").arg(dept); + } + + sql += QString(" LIMIT %1 OFFSET %2").arg(limit).arg(offset); + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + count++; + + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + + result.append(item); + } + +// LOG(TRACE) << QString("根据姓名和部门分页查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString(); +// LOG_TRACE(QString("根据姓名和部门分页查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString()); + + return result; +} + +QVector SysPersonDao::findRecordsByProperties(QVariantMap conditions) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0'"; + QVariantMap::iterator it; + for (it = conditions.begin(); it != conditions.end(); it++) + { + sql += QString(" AND SYS_PERSON.%1 = %2").arg(it.key()).arg(it.value().toString()); + } + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + count++; + + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + + result.append(item); + } + +// LOG(TRACE) << QString("根据属性值查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString(); +// LOG_TRACE(QString("根据属性值查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString()); + + return result; +} + +QString SysPersonDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + + // INSERT语句 + QString sql = QString("INSERT INTO SYS_PERSON " + "(ID, DELFLAG, CREATETIME, UPDATETIME, " + "NAME, GENDER, DEPTID, ID_CARD_NO, " + "REMARKS, PERSON_CODE, SYNC_ID, FACE_VALID, IRIS_VALID) " + "VALUES ('%1', '0', '%2', '%2', '%3', '%4', '%5', '%6', '%7', '%8', '%9', 0, 0)") + .arg(id).arg(tm) + .arg(object.value("name").toString()) + .arg(object.value("gender").toString()) + .arg(object.value("deptid").toString()) + .arg(object.value("id_card_no").toString()) + .arg(object.value("remarks").toString()) + .arg(object.value("person_code").toString()) + .arg(object.value("sync_id").toString()); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(sql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { +// LOG(DEBUG) << QString("保存SYS_PERSON记录成功[ID = %1][%2]").arg(id).arg(sql).toStdString(); +// LOG_DEBUG(QString("保存SYS_PERSON记录成功[ID = %1][%2]").arg(id).arg(sql).toStdString()); + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool SysPersonDao::edit(QVariantMap newObject, QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + + // UPDATE语句 + QString sql = QString("UPDATE SYS_PERSON SET UPDATETIME = '%1'").arg(tm); + if (newObject.contains("name")) + { + sql.append(QString(", NAME = '%1'").arg(newObject.value("name").toString())); + } + if (newObject.contains("gender")) + { + sql.append(QString(", GENDER = '%1'").arg(newObject.value("gender").toString())); + } + if (newObject.contains("deptid")) + { + sql.append(QString(", DEPTID = '%1'").arg(newObject.value("deptid").toString())); + } + if (newObject.contains("person_code")) + { + sql.append(QString(", PERSON_CODE = '%1'").arg(newObject.value("person_code").toString())); + } + if (newObject.contains("face_valid")) + { + sql.append(QString(", FACE_VALID = '%1'").arg(newObject.value("face_valid").toString())); + } + if (newObject.contains("iris_valid")) + { + sql.append(QString(", IRIS_VALID = '%1'").arg(newObject.value("iris_valid").toString())); + } + + sql.append(QString(" WHERE ID = '%1'").arg(id)); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(sql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + +// LOG(DEBUG) << QString("编辑人员[ID=%1][%2]").arg(id).arg(sql).toStdString(); +// LOG_DEBUG(QString("编辑人员[ID=%1][%2]").arg(id).arg(sql).toStdString()); + + // 返回结果 + return success; +} + +bool SysPersonDao::dele(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + QSqlQuery irisDel(ConnectionManager::getInstance()->getConnection()); + + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + qint64 tmms = QDateTime::currentDateTime().toMSecsSinceEpoch(); + + // UPDATE语句 + QString sql = QString("UPDATE SYS_PERSON SET UPDATETIME = :updateTime, DELFLAG = :flag WHERE ID = :id").arg(tm).arg(tmms).arg(id); + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":updateTime", tm); + query.bindValue(":flag", tmms); + + // 物理删除人员的人脸和虹膜数据 + QString delIrisSql = QString("DELETE FROM IRIS_DATA WHERE PERSON_ID = :personId"); + irisDel.prepare(delIrisSql); + irisDel.bindValue(":personId", id); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(sql); + query.exec(delIrisSql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + +// LOG_DEBUG(QString("删除人员SYS_PERSON[ID=%1][%2]").arg(id).arg(success).toStdString()); + + // 返回结果 + return success; +} diff --git a/dao/SysPersonDao.h b/dao/SysPersonDao.h new file mode 100644 index 0000000..e02e5ba --- /dev/null +++ b/dao/SysPersonDao.h @@ -0,0 +1,27 @@ +#ifndef SYSPERSONDAO_H +#define SYSPERSONDAO_H + +#include +#include "BaseDao.h" + +class SysPersonDao : public BaseDao +{ + Q_OBJECT +public: + explicit SysPersonDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + int findRecordCountByNameAndDept(QString name, QString dept); + QVector findRecordsByNameAndDept(QString name, QString dept, qint8 limit, qint16 offset); + QVector findRecordsByProperties(QVariantMap conditions); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); +signals: + +}; + +#endif // SYSPERSONDAO_H diff --git a/dao/dao.pri b/dao/dao.pri new file mode 100644 index 0000000..1e04ce4 --- /dev/null +++ b/dao/dao.pri @@ -0,0 +1,18 @@ + +HEADERS += $$PWD/BaseDao.h +HEADERS += $$PWD/IrisDataDao.h +HEADERS += $$PWD/RecognitionRecordsDao.h +HEADERS += $$PWD/SysPersonDao.h +HEADERS += $$PWD/SysDeptDao.h + +SOURCES += $$PWD/BaseDao.cpp +SOURCES += $$PWD/IrisDataDao.cpp +SOURCES += $$PWD/RecognitionRecordsDao.cpp +SOURCES += $$PWD/SysPersonDao.cpp +SOURCES += $$PWD/SysDeptDao.cpp + +HEADERS += $$PWD/util/ConnectionManager.h +SOURCES += $$PWD/util/ConnectionManager.cpp +#HEADERS += $$PWD/util/CacheManager.h +#SOURCES += $$PWD/util/CacheManager.cpp + diff --git a/dao/util/ConnectionManager.cpp b/dao/util/ConnectionManager.cpp new file mode 100644 index 0000000..84b17be --- /dev/null +++ b/dao/util/ConnectionManager.cpp @@ -0,0 +1,47 @@ +#include "ConnectionManager.h" +#include + +Q_GLOBAL_STATIC(ConnectionManager, cm) + +ConnectionManager::ConnectionManager(QObject *parent) : QObject(parent) +{ + // 初始化数据库连接 + if (QSqlDatabase::contains("qt_sql_dafault_connection")) + { + conn = QSqlDatabase::database("qt_sql_default_connection"); + } + else + { + conn = QSqlDatabase::addDatabase("QSQLITE"); + conn.setDatabaseName(QApplication::applicationDirPath() + "/data/casic.db"); + + bool succ = conn.open(); + if (succ == true) + { +// LOG_INFO(QString("打开数据库操作正常[Open Database Success]").toStdString()); + } else + { +// LOG_ERROR(QString("打开数据库操作失败[Open Database Failed]").toStdString()); + } + } +} + +ConnectionManager::~ConnectionManager() +{ + conn.close(); +} + +ConnectionManager* ConnectionManager::getInstance() +{ + return cm; +} + +QSqlDatabase ConnectionManager::getConnection() +{ + return this->conn; +} + +qint64 ConnectionManager::generateId() +{ + return this->idWorker.nextId(); +} diff --git a/AppConstants.h b/AppConstants.h new file mode 100644 index 0000000..296c53f --- /dev/null +++ b/AppConstants.h @@ -0,0 +1,28 @@ +#ifndef APPCONSTANTS_H +#define APPCONSTANTS_H + +class AppConstants +{ +public: + enum WidgeFrameName + { + MAIN_PAGE = 0, // 主页面 + PERSON_LIST_FORM = 1, // 人员列表页面 + ADD_PERSON_FORM = 2, // 添加人员页面 + ADD_PERSON_CAPTURE_FACE = 21, // 添加/编辑人员时进行人脸拍图 + ADD_PERSON_CAPTURE_IRIS = 22, // 添加/编辑人员时进行虹膜拍图 + SETTING_FORM = 3, // 设置页面 + RECOGNIZE_RESULT_FORM = 4, // 识别结果界面 + IDENTIFY_FORM = 5, // 识别界面 含识别中 和 识别结果 + LOCKSCREEN_FORM = 6 // 锁屏待机界面 + }; + + enum ApplicationState + { + STATE_WAIT = 0, // 待机 + STATE_WORKING = 1, // 工作状态 + STATE_IDENTIFYING = 2, // 识别中 + }; +}; + +#endif // APPCONSTANTS_H diff --git a/CasicIrisIdentify.pro b/CasicIrisIdentify.pro index 5d7fea6..575ce3d 100644 --- a/CasicIrisIdentify.pro +++ b/CasicIrisIdentify.pro @@ -1,4 +1,4 @@ -QT += core gui +QT += core gui sql network texttospeech greaterThan(QT_MAJOR_VERSION, 4): QT += widgets @@ -15,20 +15,46 @@ # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 -SOURCES += \ - main.cpp \ - IdentifyForm.cpp +include("dao/dao.pri") +include("device/device.pri") +include("utils/utils.pri") -HEADERS += \ - IdentifyForm.h +SOURCES += main.cpp +SOURCES += ProMemory.cpp +SOURCES += MainWindowForm.cpp +SOURCES += IdentifyForm.cpp +SOURCES += LockScreenForm.cpp -FORMS += \ - IdentifyForm.ui +HEADERS += AppConstants.h +HEADERS += ProMemory.h +HEADERS += MainWindowForm.h +HEADERS += IdentifyForm.h +HEADERS += LockScreenForm.h -TRANSLATIONS += \ - CasicIrisIdentify_zh_CN.ts +FORMS += MainWindowForm.ui +FORMS += IdentifyForm.ui +FORMS += LockScreenForm.ui + +RESOURCES += resource.qrc + +DISTFILES += conf/config.ini + +#TRANSLATIONS += CasicIrisIdentify_zh_CN.ts + +#INCLUDEPATH += include/spdlog +#DEPENDPATH += include/spdlog # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target + + +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lopencv_world420 +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lGxIAPICPPEx + +INCLUDEPATH += $$PWD/include/daheng +DEPENDPATH += $$PWD/include/daheng + +INCLUDEPATH += $$PWD/include +DEPENDPATH += $$PWD/include diff --git a/CasicIrisIdentify_zh_CN.ts b/CasicIrisIdentify_zh_CN.ts index 5526fe4..81900df 100644 --- a/CasicIrisIdentify_zh_CN.ts +++ b/CasicIrisIdentify_zh_CN.ts @@ -1,3 +1,12 @@ - + + + IdentifyForm + + + IdentifyForm + + + + diff --git a/IdentifyForm.cpp b/IdentifyForm.cpp index 348a897..ba1f251 100644 --- a/IdentifyForm.cpp +++ b/IdentifyForm.cpp @@ -1,4 +1,4 @@ -#include "IdentifyForm.h" +#include "IdentifyForm.h" #include "ui_IdentifyForm.h" IdentifyForm::IdentifyForm(QWidget *parent) @@ -6,6 +6,12 @@ , ui(new Ui::IdentifyForm) { ui->setupUi(this); + + // 初始化更新界面的定时器 + // 每秒执行一次 + connect(TimeCounterUtil::getInstance().clockCounter, &QTimer::timeout, this, &IdentifyForm::updateDateAndTime); + + TimeCounterUtil::getInstance().clockCounter->start(1000); } IdentifyForm::~IdentifyForm() @@ -13,3 +19,16 @@ delete ui; } +void IdentifyForm::drawIrisImageOnFrame(QImage image) +{ + // 只在识别界面才显示画面 + if (ui->wgtStacked->currentIndex() == 0) { + ui->labelVideo->setPixmap(QPixmap::fromImage(image)); + } +} + + +void IdentifyForm::updateDateAndTime() +{ + ui->labelTime->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd dddd HH:mm:ss")); +} diff --git a/IdentifyForm.h b/IdentifyForm.h index fc857a1..ae1cd22 100644 --- a/IdentifyForm.h +++ b/IdentifyForm.h @@ -1,7 +1,10 @@ -#ifndef IDENTIFYFORM_H +#ifndef IDENTIFYFORM_H #define IDENTIFYFORM_H #include +#include + +#include "utils/UtilInclude.h" QT_BEGIN_NAMESPACE namespace Ui { class IdentifyForm; } @@ -15,7 +18,14 @@ IdentifyForm(QWidget *parent = nullptr); ~IdentifyForm(); +public slots: + void drawIrisImageOnFrame(QImage image); + private: Ui::IdentifyForm *ui; + +private slots: + void updateDateAndTime(); + }; #endif // IDENTIFYFORM_H diff --git a/IdentifyForm.ui b/IdentifyForm.ui index c72a36f..879dc9a 100644 --- a/IdentifyForm.ui +++ b/IdentifyForm.ui @@ -6,13 +6,59 @@ 0 0 - 800 + 600 600 IdentifyForm + + + + 0 + 40 + 600 + 450 + + + + 0 + + + + + + 100 + 10 + 400 + 300 + + + + + + + + + + + + + + 0 + 0 + 600 + 40 + + + + TextLabel + + + Qt::AlignCenter + + diff --git a/LockScreenForm.cpp b/LockScreenForm.cpp new file mode 100644 index 0000000..58dc54b --- /dev/null +++ b/LockScreenForm.cpp @@ -0,0 +1,14 @@ +#include "LockScreenForm.h" +#include "ui_LockScreenForm.h" + +LockScreenForm::LockScreenForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::LockScreenForm) +{ + ui->setupUi(this); +} + +LockScreenForm::~LockScreenForm() +{ + delete ui; +} diff --git a/LockScreenForm.h b/LockScreenForm.h new file mode 100644 index 0000000..b5ded48 --- /dev/null +++ b/LockScreenForm.h @@ -0,0 +1,25 @@ +#ifndef LOCKSCREENFORM_H +#define LOCKSCREENFORM_H + +#include +#include + +#include "utils/UtilInclude.h" + +namespace Ui { +class LockScreenForm; +} + +class LockScreenForm : public QWidget +{ + Q_OBJECT + +public: + explicit LockScreenForm(QWidget *parent = nullptr); + ~LockScreenForm(); + +private: + Ui::LockScreenForm *ui; +}; + +#endif // LOCKSCREENFORM_H diff --git a/LockScreenForm.ui b/LockScreenForm.ui new file mode 100644 index 0000000..7f2a6db --- /dev/null +++ b/LockScreenForm.ui @@ -0,0 +1,45 @@ + + + LockScreenForm + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + 180 + 100 + 54 + 12 + + + + TextLabel + + + + + + 180 + 160 + 54 + 12 + + + + TextLabel + + + + + + diff --git a/MainWindowForm.cpp b/MainWindowForm.cpp new file mode 100644 index 0000000..84f8159 --- /dev/null +++ b/MainWindowForm.cpp @@ -0,0 +1,86 @@ +#include "MainWindowForm.h" +#include "ui_MainWindowForm.h" +#include + +MainWindowForm::MainWindowForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::MainWindowForm) +{ + ui->setupUi(this); + + // 设置窗口透明和大小、位置 + this->setWindowFlags(Qt::FramelessWindowHint); + this->move(1400, 15); + this->resize(SettingConfig::getInstance().WINDOW_WIDTH, SettingConfig::getInstance().WINDOW_HEIGHT); + + // 通过调色板的颜色来设置窗口的统一背景色 + qApp->setPalette(QPalette(QColor(SettingConfig::getInstance().WINDOW_BACKGROUND_COLOR))); + + // 加载css文件设置控件样式 + QFile file(QApplication::applicationDirPath() + "/qss/main.css"); + if (file.open(QFile::ReadOnly)) + { + QString qssStr = QLatin1String(file.readAll()); + this->setStyleSheet(qssStr); + file.close(); + } + + initFormsPtr(); + + // 设置标题文字 + ui->labelTitle->setText(SettingConfig::getInstance().WINDOW_TITLE); + ui->labelCopyright->setText(SettingConfig::getInstance().WINDOW_RIGHTS); + ui->labelVersion->setText(SettingConfig::getInstance().WINDOW_VERSION); + + // 初始化虹膜相机控制 + ProMemory::getInstance().irisCam = new IrisCameraController(this); + ProMemory::getInstance().irisCam->initIrisCamera(); + ProMemory::getInstance().irisCam->openIrisCamera(); + connect(ProMemory::getInstance().irisCam->irisCamHandler, &IrisCameraCapEventHandler::sendIrisFrameToDraw, identifyForm, &IdentifyForm::drawIrisImageOnFrame); + +// LOG_INFO(QString("应用程序启动成功[Application Startup Success]").toStdString()); + qDebug() << "应用程序启动成功[Application Startup Success]"; + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::IDENTIFY_FORM; + ui->wdgtStatced->setCurrentWidget(identifyForm); + + // 开始虹膜相机拍图 + ProMemory::getInstance().irisCam->startCapture(); +} + +MainWindowForm::~MainWindowForm() +{ + delete ui; +} + +void MainWindowForm::lockScreen() +{ + ui->wdgtStatced->setCurrentWidget(lockScreenForm); + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::LOCKSCREEN_FORM; + ProMemory::getInstance().appState = AppConstants::ApplicationState::STATE_WAIT; +} + +void MainWindowForm::keyPressEvent(QKeyEvent *event) +{ + switch (event->key()) { + case Qt::Key_Escape: + QTimer::singleShot(100, qApp, [=](){ + QApplication::quit(); + }); + + default: + QWidget::keyPressEvent(event); + } +} + +void MainWindowForm::initFormsPtr() +{ + // 初始化各个form + lockScreenForm = new LockScreenForm(this); + identifyForm = new IdentifyForm(this); + + // 将form添加到statcked widget中 + ui->wdgtStatced->addWidget(identifyForm); + ui->wdgtStatced->addWidget(lockScreenForm); + + // 绑定按钮函数 +} diff --git a/MainWindowForm.h b/MainWindowForm.h new file mode 100644 index 0000000..7fb2d89 --- /dev/null +++ b/MainWindowForm.h @@ -0,0 +1,38 @@ +#ifndef MAINWINDOWFORM_H +#define MAINWINDOWFORM_H + +#include +#include +#include + +#include "utils/UtilInclude.h" +#include "ProMemory.h" +#include "LockScreenForm.h" +#include "IdentifyForm.h" + +namespace Ui { +class MainWindowForm; +} + +class MainWindowForm : public QWidget +{ + Q_OBJECT + +public: + explicit MainWindowForm(QWidget *parent = nullptr); + ~MainWindowForm(); + +public slots: + void lockScreen(); + +private: + Ui::MainWindowForm *ui; + LockScreenForm * lockScreenForm; + IdentifyForm * identifyForm; + + void keyPressEvent(QKeyEvent *event); + + void initFormsPtr(); +}; + +#endif // MAINWINDOWFORM_H diff --git a/MainWindowForm.ui b/MainWindowForm.ui new file mode 100644 index 0000000..e793ebf --- /dev/null +++ b/MainWindowForm.ui @@ -0,0 +1,85 @@ + + + MainWindowForm + + + + 0 + 0 + 600 + 1024 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + 0 + 0 + 600 + 84 + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + + + + TextLabel + + + Qt::AlignBottom|Qt::AlignHCenter + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + diff --git a/ProMemory.cpp b/ProMemory.cpp new file mode 100644 index 0000000..19e7403 --- /dev/null +++ b/ProMemory.cpp @@ -0,0 +1,84 @@ +#include "ProMemory.h" + +ProMemory::ProMemory() +{ + +} + +ProMemory::~ProMemory() +{ + +} + +/* +void ProMemory::pushCasicIris(CasicIrisInfo irisInfo) +{ + QMutex mutex; + mutex.lock(); + if (this->irisQueue.size() > 30) + { + QStack empty; + std::swap(empty, irisQueue); + } + + irisQueue.push(irisInfo); + mutex.unlock(); +} +CasicIrisInfo ProMemory::popCasicIris() +{ + CasicIrisInfo result; + + QMutex mutex; + mutex.lock(); + if (this->irisQueue.size() > 0) + { + result = irisQueue.pop(); + } + + mutex.unlock(); + + return result; +} +*/ +int ProMemory::getIrisQueueSize() +{ + int size = 0; + + QMutex mutex; + mutex.lock(); + +// size = this->irisQueue.size(); + + mutex.unlock(); + + return size; +} +bool ProMemory::isIrisQueueEmpty() +{ + bool empty = true; + + QMutex mutex; + mutex.lock(); + +// empty = this->irisQueue.isEmpty(); + + mutex.unlock(); + + return empty; +} +void ProMemory::clearIrisQueue() +{ + QMutex mutex; + mutex.lock(); + +// QStack empty; +// std::swap(empty, irisQueue); + + mutex.unlock(); +} + + +void ProMemory::initIrisFeatures(QString personId) +{ +// irisRegistPro->sendDataToExract(QByteArray(QString("[-u]").append(personId).toLocal8Bit())); +} diff --git a/ProMemory.h b/ProMemory.h new file mode 100644 index 0000000..2ecd653 --- /dev/null +++ b/ProMemory.h @@ -0,0 +1,52 @@ +#ifndef PROMEMORY_H +#define PROMEMORY_H + +#include +#include + +#include "AppConstants.h" +//#include "casic/iris/CasicIrisInfo.h" +#include "dao/IrisDataDao.h" + +#include "device/IrisCameraController.h" +//#include "device/iris/IrisRegistProcess.h" +//#include "device/iris/IrisRecogProcess.h" + +class IrisCameraController; +class IrisRegistProcess; +class IrisRecogProcess; + +class ProMemory +{ +public: + ~ProMemory(); + ProMemory(const ProMemory&)=delete; + ProMemory& operator=(const ProMemory&)=delete; + + static ProMemory& getInstance() { + static ProMemory instance; + return instance; + } + +// void pushCasicIris(CasicIrisInfo irisInfo); +// CasicIrisInfo popCasicIris(); + int getIrisQueueSize(); + bool isIrisQueueEmpty(); + void clearIrisQueue(); + + volatile int widgeFrame = 0; // 当前显示的界面 + volatile int appState = 0; // 当前程序所处的状态 + + void initIrisFeatures(QString personId = ""); // 初始化虹膜特征值集合 + + IrisCameraController * irisCam; + IrisRecogProcess * irisRecogPro; + +private: + ProMemory(); + +// QStack irisQueue; // 虹膜信息队列 + QVector irisFeatures; // 虹膜特征值集合 +}; + +#endif // PROMEMORY_H diff --git a/conf/config.ini b/conf/config.ini new file mode 100644 index 0000000..66e46ad --- /dev/null +++ b/conf/config.ini @@ -0,0 +1,67 @@ +[recognize] +#最大允许识别时间(ms) +maxMatchTime=10000 +#识别成功界面停留时间(ms) +successTipsLast=5000 +#识别失败界面停留时间(ms) +failureTipsLast=3000 +#人脸识别最大尝试次数 +maxFaceTryCount=20 +#持续没找到人脸的最大次数 +maxFaceNotFoundCount=500 +#注册时最小人脸 +minFaceRegist=240 +#识别时最小人脸 +minFaceRecog=100 + +#虹膜识别最大尝试次数 +maxIrisTryCount=10 +#虹膜识别持续没有找到眼的最大次数 +maxEyeNotFoundCount=50 + +#识别方式[1=人脸;2=虹膜;3=双认证;4=任意] +recogType=4 + +[window] +#界面窗口宽(px) +width=600 +#界面窗口高(px) +height=1024 +#统一背景色 +backgroundColor="#FFFFFF" +#标题 +title="虹膜识别终端" + +[work] +#工作状态检测时最小人脸范围 +minFaceSize=160 +#人脸范围最小横坐标 +minFacePosX=320 +#人脸范围最大横坐标 +maxFacePosX=960 +#人脸范围最小纵坐标 +minFacePosY=180 +#人脸范围最大纵坐标 +maxFacePosY=540 +#人脸太近阈值 +faceCloseSize=360 +#人脸太远阈值 +faceFarSize=480 + +[camera] +#虹膜相机取一幅画面的时间间隔(ms) +irisFrameInterval=100 +#虹膜相机拍摄宽度 +irisFrameWidth=1440 +#虹膜相机拍摄高度 +irisFrameHeight=1080 +#虹膜图像高度 +irisWidth=640 +#虹膜图像高度 +irisHeight=480 + +[log] +#日志文件位置 +logFile="d://irisLogs//casic_log.txt" +#日志级别 +logLevel="trace" diff --git a/dao/BaseDao.cpp b/dao/BaseDao.cpp new file mode 100644 index 0000000..f51c144 --- /dev/null +++ b/dao/BaseDao.cpp @@ -0,0 +1,12 @@ +#include "BaseDao.h" +#include "dao/util/ConnectionManager.h" + +BaseDao::BaseDao(QObject *parent) : QObject(parent) +{ + +} + +BaseDao::~BaseDao() +{ + +} diff --git a/dao/BaseDao.h b/dao/BaseDao.h new file mode 100644 index 0000000..1693c88 --- /dev/null +++ b/dao/BaseDao.h @@ -0,0 +1,32 @@ +#ifndef BASEDAO_H +#define BASEDAO_H + +#include +#include +#include +#include + +#include "dao/util/ConnectionManager.h" +#include "utils/UtilInclude.h" + +class BaseDao : public QObject +{ + Q_OBJECT +public: + explicit BaseDao(QObject *parent = nullptr); + ~BaseDao(); + + virtual QVector findAllRecord() = 0; + virtual QVariantMap findRecordById(QString id) = 0; + + virtual QString save(QVariantMap object) = 0; + virtual bool edit(QVariantMap newObject, QString id) = 0; + virtual bool dele(QString id) = 0; + +private: + +signals: + +}; + +#endif // BASEDAO_H diff --git a/dao/IrisDataDao.cpp b/dao/IrisDataDao.cpp new file mode 100644 index 0000000..37a0ed6 --- /dev/null +++ b/dao/IrisDataDao.cpp @@ -0,0 +1,204 @@ +#include "IrisDataDao.h" + +IrisDataDao::IrisDataDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector IrisDataDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM IRIS_DATA"; + query.prepare(sql); + + // 执行查询 + query.exec(); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + item.insert("id", query.value("id").toString()); + item.insert("person_id", query.value("person_id").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("left_iris_code1", query.value("left_iris_code1")); + item.insert("left_iris_code2", query.value("left_iris_code2")); + item.insert("left_iris_code3", query.value("left_iris_code3")); + item.insert("right_iris_code1", query.value("right_iris_code1")); + item.insert("right_iris_code2", query.value("right_iris_code2")); + item.insert("right_iris_code3", query.value("right_iris_code3")); + + result.append(item); + } + +// LOG_DEBUG(QString("查询IRIS_DATA表的所有记录[结果数:%1]").arg(result.size()).toStdString()); + return result; +} + +QVariantMap IrisDataDao::findRecordById(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM IRIS_DATA WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + // 获取结果 + if (query.next()) + { + result.insert("id", query.value("id").toString()); + result.insert("person_id", query.value("person_id").toLongLong()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("left_iris_code1", query.value("left_iris_code1")); + result.insert("left_iris_code2", query.value("left_iris_code2")); + result.insert("left_iris_code3", query.value("left_iris_code3")); + result.insert("right_iris_code1", query.value("right_iris_code1")); + result.insert("right_iris_code2", query.value("right_iris_code2")); + result.insert("right_iris_code3", query.value("right_iris_code3")); + } + +// LOG_DEBUG(QString("根据id查询IRIS_DATA表的记录[id=%1]").arg(id).toStdString()); + return result; +} + +QVariantMap IrisDataDao::findRecordByPersonId(QString personId) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM IRIS_DATA WHERE PERSON_ID = :personId"); + query.prepare(sql); + query.bindValue(":personId", personId); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + if (query.next()) + { + result.insert("id", query.value("id").toString()); + result.insert("person_id", query.value("person_id").toLongLong()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("left_iris_code1", query.value("left_iris_code1")); + result.insert("left_iris_code2", query.value("left_iris_code2")); + result.insert("left_iris_code3", query.value("left_iris_code3")); + result.insert("right_iris_code1", query.value("right_iris_code1")); + result.insert("right_iris_code2", query.value("right_iris_code2")); + result.insert("right_iris_code3", query.value("right_iris_code3")); + } + +// LOG_DEBUG(QString("根据personId查询IRIS_DATA表的记录[personId=%1]").arg(personId).toStdString()); + return result; +} + + +QString IrisDataDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + + // INSERT语句 + QString sql = QString("INSERT INTO IRIS_DATA (ID, PERSON_ID, ID_CARD_NO, LEFT_IRIS_CODE1, RIGHT_IRIS_CODE1) VALUES (:id, :personId, :idCardNo, :left1, :right1)"); + + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":personId", object.value("person_id").toString()); + query.bindValue(":idCardNo", object.value("id_card_no").toString()); + query.bindValue(":left1", object.value("left_iris_code1")); + query.bindValue(":right1", object.value("right_iris_code1")); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(); + +// LOG_DEBUG(QString("保存虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool IrisDataDao::edit(QVariantMap newObject, QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // UPDATE语句 + if (!newObject.contains("left_iris_code1") || !newObject.contains("right_iris_code1")){ + return false; + } + QString sql = QString("UPDATE IRIS_DATA SET LEFT_IRIS_CODE1 = :left1, RIGHT_IRIS_CODE1 = :right1 WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":left1", newObject.value("left_iris_code1")); + query.bindValue(":right1", newObject.value("right_iris_code1")); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(); + +// LOG_DEBUG(QString("编辑虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; +} + + +bool IrisDataDao::dele(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + QString sql = QString("DELETE FROM IRIS_DATA WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(); + +// LOG_DEBUG(QString("删除虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; +} diff --git a/dao/IrisDataDao.h b/dao/IrisDataDao.h new file mode 100644 index 0000000..c74dbbd --- /dev/null +++ b/dao/IrisDataDao.h @@ -0,0 +1,25 @@ +#ifndef IRISDATADAO_H +#define IRISDATADAO_H + +#include +#include "BaseDao.h" + +class IrisDataDao : public BaseDao +{ + Q_OBJECT +public: + explicit IrisDataDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + QVariantMap findRecordByPersonId(QString personId); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +signals: + +}; + +#endif // IRISDATADAO_H diff --git a/dao/RecognitionRecordsDao.cpp b/dao/RecognitionRecordsDao.cpp new file mode 100644 index 0000000..40db453 --- /dev/null +++ b/dao/RecognitionRecordsDao.cpp @@ -0,0 +1,100 @@ +#include "RecognitionRecordsDao.h" + +RecognitionRecordsDao::RecognitionRecordsDao(QObject *parent) : BaseDao(parent) +{ + +} + + +QVector RecognitionRecordsDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM RECOGNITION_RECORDS"; + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + item.insert("id", query.value("id").toLongLong()); + result.append(item); + } + +// LOG_DEBUG(QString("查询RECOGNITION_RECORDS表的所有记录[记录数:%1]").arg(result.size()).toStdString()); + return result; +} + +QVariantMap RecognitionRecordsDao::findRecordById(QString id) +{ + QVariantMap item; + return item; +} + +QString RecognitionRecordsDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + + // INSERT语句 + QString sql = QString("INSERT INTO RECOGNITION_RECORDS (ID, PERSON_ID, DATETIME, REC_TYPE, DEV_CODE, DOOR_CODE, INOUT_TYPE) " + "VALUES (:id, :personId, :datetime, :recType, :devCode, :doorCode, :inoutType)"); + + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":personId", object.value("person_id").toString()); + query.bindValue(":datetime", object.value("date_time").toString()); + query.bindValue(":recType", object.value("rec_type").toString()); + query.bindValue(":devCode", object.value("dev_code").toString()); + query.bindValue(":doorCode", object.value("door_code").toString()); + query.bindValue(":inoutType", object.value("inout_type").toString()); + +// LOG_DEBUG(sql.toStdString()); + + // 插入识别的log日志 + QString logStr = QString("INSERT INTO RECOGNITION_LOGS (ID, LOG_INFO) VALUES (:id, :logInfo)"); + + QSqlQuery logQuery(ConnectionManager::getInstance()->getConnection()); + logQuery.prepare(logStr); + logQuery.bindValue(":id", id); + logQuery.bindValue(":logInfo", object.value("debug_info").toString()); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(); + logQuery.exec(); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool RecognitionRecordsDao::edit(QVariantMap newObject, QString id) +{ + return false; +} + +bool RecognitionRecordsDao::dele(QString id) +{ + return false; +} diff --git a/dao/RecognitionRecordsDao.h b/dao/RecognitionRecordsDao.h new file mode 100644 index 0000000..38de7c9 --- /dev/null +++ b/dao/RecognitionRecordsDao.h @@ -0,0 +1,23 @@ +#ifndef RECOGNITIONRECORDSDAO_H +#define RECOGNITIONRECORDSDAO_H + +#include +#include "BaseDao.h" +class RecognitionRecordsDao: public BaseDao +{ + Q_OBJECT +public: + explicit RecognitionRecordsDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +signals: + +}; + +#endif // RECOGNITIONRECORDSDAO_H diff --git a/dao/SysDeptDao.cpp b/dao/SysDeptDao.cpp new file mode 100644 index 0000000..22f9946 --- /dev/null +++ b/dao/SysDeptDao.cpp @@ -0,0 +1,88 @@ +#include "SysDeptDao.h" + +SysDeptDao::SysDeptDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector SysDeptDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_DEPT WHERE PID != '-1' ORDER BY PID, NUM"; + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + item.insert("id", query.value("id").toString()); + item.insert("pid", query.value("pid").toString()); + item.insert("pids", query.value("pids").toString()); + item.insert("simplename", query.value("simplename").toString()); + item.insert("fullname", query.value("fullname").toString()); + } + +// LOG_TRACE(QString("查询表[SYS_DEPT]的所有记录[%1][%2]").arg(result.size()).arg(sql).toStdString()); + + return result; +} + +QVariantMap SysDeptDao::findRecordById(QString id) +{ + QVariantMap item; + return item; + + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM SYS_DEPT WHERE SYS_DEPT.ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + // 获取结果集的大小 + query.last(); + int count = query.at() + 1; + + if (count >=1) + { + query.first(); + + result.insert("id", query.value("id").toString()); + result.insert("pid", query.value("pid").toString()); + result.insert("pids", query.value("pids").toString()); + result.insert("simplename", query.value("simplename").toString()); + result.insert("fullname", query.value("fullname").toString()); + } + +// LOG_TRACE(QString("根据id查询SYS_DEPT表的记录[ID=%1][%2]").arg(id).arg(sql).toStdString()); + + return result; +} + + +QString SysDeptDao::save(QVariantMap object) +{ + return "0"; +} +bool SysDeptDao::edit(QVariantMap newObject, QString id) +{ + return true; +} +bool SysDeptDao::dele(QString id) +{ + return true; +} diff --git a/dao/SysDeptDao.h b/dao/SysDeptDao.h new file mode 100644 index 0000000..e07a09f --- /dev/null +++ b/dao/SysDeptDao.h @@ -0,0 +1,24 @@ +#ifndef SYSDEPTDAO_H +#define SYSDEPTDAO_H + +#include +#include "BaseDao.h" + +class SysDeptDao : public BaseDao +{ + Q_OBJECT +public: + explicit SysDeptDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +private: + +}; + +#endif // SYSDEPTDAO_H diff --git a/dao/SysPersonDao.cpp b/dao/SysPersonDao.cpp new file mode 100644 index 0000000..dd9480f --- /dev/null +++ b/dao/SysPersonDao.cpp @@ -0,0 +1,371 @@ +#include "SysPersonDao.h" + + +SysPersonDao::SysPersonDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector SysPersonDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0'"; + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + count++; + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + result.append(item); + } + +// LOG(TRACE) << QString("查询SYS_PERSON表的所有记录[%1]").arg(count).toStdString(); +// LOG_TRACE(QString("查询SYS_PERSON表的所有记录[%1]").arg(count).toStdString()); + + return result; +} + +QVariantMap SysPersonDao::findRecordById(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0' AND SYS_PERSON.ID = '%1'").arg(id); + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVariantMap result; + + // 获取结果集的大小 + query.last(); + int count = query.at() + 1; + + if (count >=1) + { + query.first(); + + result.insert("id", query.value("id").toString()); + result.insert("delflag", query.value("delflag").toString()); + result.insert("createtime", query.value("createtime").toString()); + result.insert("updatetime", query.value("updatetime").toString()); + result.insert("name", query.value("name").toString()); + result.insert("gender", query.value("gender").toString()); + result.insert("deptid", query.value("deptid").toString()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("remarks", query.value("remarks").toString()); + result.insert("person_code", query.value("person_code").toString()); + result.insert("deptname", query.value("fullname").toString()); + result.insert("sync_id", query.value("sync_id").toString()); + result.insert("hasFace", query.value("face_valid").toString()); + result.insert("hasIris", query.value("iris_valid").toString()); + } + +// LOG(TRACE) << QString("根据id查询SYS_PERSON表的记录[id=%1][%2]").arg(id).arg(sql).toStdString(); +// LOG_TRACE(QString("根据id查询SYS_PERSON表的记录[id=%1][%2]").arg(id).arg(sql).toStdString()); + + return result; +} + +int SysPersonDao::findRecordCountByNameAndDept(QString name, QString dept) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT COUNT(P.ID) AS RECCT FROM SYS_PERSON P LEFT JOIN SYS_DEPT D ON P.DEPTID = D.ID WHERE P.DELFLAG = '0'"; + if (name.isEmpty() == false) + { + sql += " AND P.NAME LIKE '%" + name + "%'"; + } + if (dept.isEmpty() == false && dept.indexOf("-1") < 0) + { + sql += QString(" AND ((P.DEPTID = '%1') OR (D.PIDS LIKE '%,%1,%'))").arg(dept); + } + + // 执行查询 + query.exec(sql); + + // 返回结果 + int result; + + // 遍历查询结果 + if (query.next()) { + result = query.value("RECCT").toInt(); + } + +// LOG(TRACE) << QString("根据姓名和部门查询SYS_PERSON记录总数[%1][%2]").arg(result).arg(sql).toStdString(); +// LOG_TRACE(QString("根据姓名和部门查询SYS_PERSON记录总数[%1][%2]").arg(result).arg(sql).toStdString()); + + return result; +} + +QVector SysPersonDao::findRecordsByNameAndDept(QString name, QString dept, qint8 limit, qint16 offset) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON P LEFT JOIN SYS_DEPT D ON P.DEPTID = D.ID WHERE P.DELFLAG = '0'"; + if (name.isEmpty() == false) + { + sql += " AND P.NAME LIKE '%" + name + "%'"; + } + if (dept.isEmpty() == false && dept.indexOf("-1") < 0) + { + sql += QString(" AND ((P.DEPTID = '%1') OR (D.PIDS LIKE '%,%1,%'))").arg(dept); + } + + sql += QString(" LIMIT %1 OFFSET %2").arg(limit).arg(offset); + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + count++; + + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + + result.append(item); + } + +// LOG(TRACE) << QString("根据姓名和部门分页查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString(); +// LOG_TRACE(QString("根据姓名和部门分页查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString()); + + return result; +} + +QVector SysPersonDao::findRecordsByProperties(QVariantMap conditions) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0'"; + QVariantMap::iterator it; + for (it = conditions.begin(); it != conditions.end(); it++) + { + sql += QString(" AND SYS_PERSON.%1 = %2").arg(it.key()).arg(it.value().toString()); + } + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + count++; + + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + + result.append(item); + } + +// LOG(TRACE) << QString("根据属性值查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString(); +// LOG_TRACE(QString("根据属性值查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString()); + + return result; +} + +QString SysPersonDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + + // INSERT语句 + QString sql = QString("INSERT INTO SYS_PERSON " + "(ID, DELFLAG, CREATETIME, UPDATETIME, " + "NAME, GENDER, DEPTID, ID_CARD_NO, " + "REMARKS, PERSON_CODE, SYNC_ID, FACE_VALID, IRIS_VALID) " + "VALUES ('%1', '0', '%2', '%2', '%3', '%4', '%5', '%6', '%7', '%8', '%9', 0, 0)") + .arg(id).arg(tm) + .arg(object.value("name").toString()) + .arg(object.value("gender").toString()) + .arg(object.value("deptid").toString()) + .arg(object.value("id_card_no").toString()) + .arg(object.value("remarks").toString()) + .arg(object.value("person_code").toString()) + .arg(object.value("sync_id").toString()); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(sql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { +// LOG(DEBUG) << QString("保存SYS_PERSON记录成功[ID = %1][%2]").arg(id).arg(sql).toStdString(); +// LOG_DEBUG(QString("保存SYS_PERSON记录成功[ID = %1][%2]").arg(id).arg(sql).toStdString()); + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool SysPersonDao::edit(QVariantMap newObject, QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + + // UPDATE语句 + QString sql = QString("UPDATE SYS_PERSON SET UPDATETIME = '%1'").arg(tm); + if (newObject.contains("name")) + { + sql.append(QString(", NAME = '%1'").arg(newObject.value("name").toString())); + } + if (newObject.contains("gender")) + { + sql.append(QString(", GENDER = '%1'").arg(newObject.value("gender").toString())); + } + if (newObject.contains("deptid")) + { + sql.append(QString(", DEPTID = '%1'").arg(newObject.value("deptid").toString())); + } + if (newObject.contains("person_code")) + { + sql.append(QString(", PERSON_CODE = '%1'").arg(newObject.value("person_code").toString())); + } + if (newObject.contains("face_valid")) + { + sql.append(QString(", FACE_VALID = '%1'").arg(newObject.value("face_valid").toString())); + } + if (newObject.contains("iris_valid")) + { + sql.append(QString(", IRIS_VALID = '%1'").arg(newObject.value("iris_valid").toString())); + } + + sql.append(QString(" WHERE ID = '%1'").arg(id)); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(sql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + +// LOG(DEBUG) << QString("编辑人员[ID=%1][%2]").arg(id).arg(sql).toStdString(); +// LOG_DEBUG(QString("编辑人员[ID=%1][%2]").arg(id).arg(sql).toStdString()); + + // 返回结果 + return success; +} + +bool SysPersonDao::dele(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + QSqlQuery irisDel(ConnectionManager::getInstance()->getConnection()); + + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + qint64 tmms = QDateTime::currentDateTime().toMSecsSinceEpoch(); + + // UPDATE语句 + QString sql = QString("UPDATE SYS_PERSON SET UPDATETIME = :updateTime, DELFLAG = :flag WHERE ID = :id").arg(tm).arg(tmms).arg(id); + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":updateTime", tm); + query.bindValue(":flag", tmms); + + // 物理删除人员的人脸和虹膜数据 + QString delIrisSql = QString("DELETE FROM IRIS_DATA WHERE PERSON_ID = :personId"); + irisDel.prepare(delIrisSql); + irisDel.bindValue(":personId", id); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(sql); + query.exec(delIrisSql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + +// LOG_DEBUG(QString("删除人员SYS_PERSON[ID=%1][%2]").arg(id).arg(success).toStdString()); + + // 返回结果 + return success; +} diff --git a/dao/SysPersonDao.h b/dao/SysPersonDao.h new file mode 100644 index 0000000..e02e5ba --- /dev/null +++ b/dao/SysPersonDao.h @@ -0,0 +1,27 @@ +#ifndef SYSPERSONDAO_H +#define SYSPERSONDAO_H + +#include +#include "BaseDao.h" + +class SysPersonDao : public BaseDao +{ + Q_OBJECT +public: + explicit SysPersonDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + int findRecordCountByNameAndDept(QString name, QString dept); + QVector findRecordsByNameAndDept(QString name, QString dept, qint8 limit, qint16 offset); + QVector findRecordsByProperties(QVariantMap conditions); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); +signals: + +}; + +#endif // SYSPERSONDAO_H diff --git a/dao/dao.pri b/dao/dao.pri new file mode 100644 index 0000000..1e04ce4 --- /dev/null +++ b/dao/dao.pri @@ -0,0 +1,18 @@ + +HEADERS += $$PWD/BaseDao.h +HEADERS += $$PWD/IrisDataDao.h +HEADERS += $$PWD/RecognitionRecordsDao.h +HEADERS += $$PWD/SysPersonDao.h +HEADERS += $$PWD/SysDeptDao.h + +SOURCES += $$PWD/BaseDao.cpp +SOURCES += $$PWD/IrisDataDao.cpp +SOURCES += $$PWD/RecognitionRecordsDao.cpp +SOURCES += $$PWD/SysPersonDao.cpp +SOURCES += $$PWD/SysDeptDao.cpp + +HEADERS += $$PWD/util/ConnectionManager.h +SOURCES += $$PWD/util/ConnectionManager.cpp +#HEADERS += $$PWD/util/CacheManager.h +#SOURCES += $$PWD/util/CacheManager.cpp + diff --git a/dao/util/ConnectionManager.cpp b/dao/util/ConnectionManager.cpp new file mode 100644 index 0000000..84b17be --- /dev/null +++ b/dao/util/ConnectionManager.cpp @@ -0,0 +1,47 @@ +#include "ConnectionManager.h" +#include + +Q_GLOBAL_STATIC(ConnectionManager, cm) + +ConnectionManager::ConnectionManager(QObject *parent) : QObject(parent) +{ + // 初始化数据库连接 + if (QSqlDatabase::contains("qt_sql_dafault_connection")) + { + conn = QSqlDatabase::database("qt_sql_default_connection"); + } + else + { + conn = QSqlDatabase::addDatabase("QSQLITE"); + conn.setDatabaseName(QApplication::applicationDirPath() + "/data/casic.db"); + + bool succ = conn.open(); + if (succ == true) + { +// LOG_INFO(QString("打开数据库操作正常[Open Database Success]").toStdString()); + } else + { +// LOG_ERROR(QString("打开数据库操作失败[Open Database Failed]").toStdString()); + } + } +} + +ConnectionManager::~ConnectionManager() +{ + conn.close(); +} + +ConnectionManager* ConnectionManager::getInstance() +{ + return cm; +} + +QSqlDatabase ConnectionManager::getConnection() +{ + return this->conn; +} + +qint64 ConnectionManager::generateId() +{ + return this->idWorker.nextId(); +} diff --git a/dao/util/ConnectionManager.h b/dao/util/ConnectionManager.h new file mode 100644 index 0000000..84647e3 --- /dev/null +++ b/dao/util/ConnectionManager.h @@ -0,0 +1,34 @@ +#ifndef CONNECTIONMANAGER_H +#define CONNECTIONMANAGER_H + +#include +#include +#include "utils/id/IdWorker.h" +#include "utils/UtilInclude.h" + +using namespace Jiawa::Core; + +class ConnectionManager : public QObject +{ + Q_OBJECT +public: + explicit ConnectionManager(QObject *parent = nullptr); + ~ConnectionManager(); + + static ConnectionManager * getInstance(); + + QSqlDatabase getConnection(); + qint64 generateId(); + +private: + // 数据库连接 + QSqlDatabase conn; + + // 雪花id生成工具 + IdWorker &idWorker = Singleton::instance(); + +signals: + +}; + +#endif // CONNECTIONMANAGER_H diff --git a/AppConstants.h b/AppConstants.h new file mode 100644 index 0000000..296c53f --- /dev/null +++ b/AppConstants.h @@ -0,0 +1,28 @@ +#ifndef APPCONSTANTS_H +#define APPCONSTANTS_H + +class AppConstants +{ +public: + enum WidgeFrameName + { + MAIN_PAGE = 0, // 主页面 + PERSON_LIST_FORM = 1, // 人员列表页面 + ADD_PERSON_FORM = 2, // 添加人员页面 + ADD_PERSON_CAPTURE_FACE = 21, // 添加/编辑人员时进行人脸拍图 + ADD_PERSON_CAPTURE_IRIS = 22, // 添加/编辑人员时进行虹膜拍图 + SETTING_FORM = 3, // 设置页面 + RECOGNIZE_RESULT_FORM = 4, // 识别结果界面 + IDENTIFY_FORM = 5, // 识别界面 含识别中 和 识别结果 + LOCKSCREEN_FORM = 6 // 锁屏待机界面 + }; + + enum ApplicationState + { + STATE_WAIT = 0, // 待机 + STATE_WORKING = 1, // 工作状态 + STATE_IDENTIFYING = 2, // 识别中 + }; +}; + +#endif // APPCONSTANTS_H diff --git a/CasicIrisIdentify.pro b/CasicIrisIdentify.pro index 5d7fea6..575ce3d 100644 --- a/CasicIrisIdentify.pro +++ b/CasicIrisIdentify.pro @@ -1,4 +1,4 @@ -QT += core gui +QT += core gui sql network texttospeech greaterThan(QT_MAJOR_VERSION, 4): QT += widgets @@ -15,20 +15,46 @@ # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 -SOURCES += \ - main.cpp \ - IdentifyForm.cpp +include("dao/dao.pri") +include("device/device.pri") +include("utils/utils.pri") -HEADERS += \ - IdentifyForm.h +SOURCES += main.cpp +SOURCES += ProMemory.cpp +SOURCES += MainWindowForm.cpp +SOURCES += IdentifyForm.cpp +SOURCES += LockScreenForm.cpp -FORMS += \ - IdentifyForm.ui +HEADERS += AppConstants.h +HEADERS += ProMemory.h +HEADERS += MainWindowForm.h +HEADERS += IdentifyForm.h +HEADERS += LockScreenForm.h -TRANSLATIONS += \ - CasicIrisIdentify_zh_CN.ts +FORMS += MainWindowForm.ui +FORMS += IdentifyForm.ui +FORMS += LockScreenForm.ui + +RESOURCES += resource.qrc + +DISTFILES += conf/config.ini + +#TRANSLATIONS += CasicIrisIdentify_zh_CN.ts + +#INCLUDEPATH += include/spdlog +#DEPENDPATH += include/spdlog # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target + + +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lopencv_world420 +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lGxIAPICPPEx + +INCLUDEPATH += $$PWD/include/daheng +DEPENDPATH += $$PWD/include/daheng + +INCLUDEPATH += $$PWD/include +DEPENDPATH += $$PWD/include diff --git a/CasicIrisIdentify_zh_CN.ts b/CasicIrisIdentify_zh_CN.ts index 5526fe4..81900df 100644 --- a/CasicIrisIdentify_zh_CN.ts +++ b/CasicIrisIdentify_zh_CN.ts @@ -1,3 +1,12 @@ - + + + IdentifyForm + + + IdentifyForm + + + + diff --git a/IdentifyForm.cpp b/IdentifyForm.cpp index 348a897..ba1f251 100644 --- a/IdentifyForm.cpp +++ b/IdentifyForm.cpp @@ -1,4 +1,4 @@ -#include "IdentifyForm.h" +#include "IdentifyForm.h" #include "ui_IdentifyForm.h" IdentifyForm::IdentifyForm(QWidget *parent) @@ -6,6 +6,12 @@ , ui(new Ui::IdentifyForm) { ui->setupUi(this); + + // 初始化更新界面的定时器 + // 每秒执行一次 + connect(TimeCounterUtil::getInstance().clockCounter, &QTimer::timeout, this, &IdentifyForm::updateDateAndTime); + + TimeCounterUtil::getInstance().clockCounter->start(1000); } IdentifyForm::~IdentifyForm() @@ -13,3 +19,16 @@ delete ui; } +void IdentifyForm::drawIrisImageOnFrame(QImage image) +{ + // 只在识别界面才显示画面 + if (ui->wgtStacked->currentIndex() == 0) { + ui->labelVideo->setPixmap(QPixmap::fromImage(image)); + } +} + + +void IdentifyForm::updateDateAndTime() +{ + ui->labelTime->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd dddd HH:mm:ss")); +} diff --git a/IdentifyForm.h b/IdentifyForm.h index fc857a1..ae1cd22 100644 --- a/IdentifyForm.h +++ b/IdentifyForm.h @@ -1,7 +1,10 @@ -#ifndef IDENTIFYFORM_H +#ifndef IDENTIFYFORM_H #define IDENTIFYFORM_H #include +#include + +#include "utils/UtilInclude.h" QT_BEGIN_NAMESPACE namespace Ui { class IdentifyForm; } @@ -15,7 +18,14 @@ IdentifyForm(QWidget *parent = nullptr); ~IdentifyForm(); +public slots: + void drawIrisImageOnFrame(QImage image); + private: Ui::IdentifyForm *ui; + +private slots: + void updateDateAndTime(); + }; #endif // IDENTIFYFORM_H diff --git a/IdentifyForm.ui b/IdentifyForm.ui index c72a36f..879dc9a 100644 --- a/IdentifyForm.ui +++ b/IdentifyForm.ui @@ -6,13 +6,59 @@ 0 0 - 800 + 600 600 IdentifyForm + + + + 0 + 40 + 600 + 450 + + + + 0 + + + + + + 100 + 10 + 400 + 300 + + + + + + + + + + + + + + 0 + 0 + 600 + 40 + + + + TextLabel + + + Qt::AlignCenter + + diff --git a/LockScreenForm.cpp b/LockScreenForm.cpp new file mode 100644 index 0000000..58dc54b --- /dev/null +++ b/LockScreenForm.cpp @@ -0,0 +1,14 @@ +#include "LockScreenForm.h" +#include "ui_LockScreenForm.h" + +LockScreenForm::LockScreenForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::LockScreenForm) +{ + ui->setupUi(this); +} + +LockScreenForm::~LockScreenForm() +{ + delete ui; +} diff --git a/LockScreenForm.h b/LockScreenForm.h new file mode 100644 index 0000000..b5ded48 --- /dev/null +++ b/LockScreenForm.h @@ -0,0 +1,25 @@ +#ifndef LOCKSCREENFORM_H +#define LOCKSCREENFORM_H + +#include +#include + +#include "utils/UtilInclude.h" + +namespace Ui { +class LockScreenForm; +} + +class LockScreenForm : public QWidget +{ + Q_OBJECT + +public: + explicit LockScreenForm(QWidget *parent = nullptr); + ~LockScreenForm(); + +private: + Ui::LockScreenForm *ui; +}; + +#endif // LOCKSCREENFORM_H diff --git a/LockScreenForm.ui b/LockScreenForm.ui new file mode 100644 index 0000000..7f2a6db --- /dev/null +++ b/LockScreenForm.ui @@ -0,0 +1,45 @@ + + + LockScreenForm + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + 180 + 100 + 54 + 12 + + + + TextLabel + + + + + + 180 + 160 + 54 + 12 + + + + TextLabel + + + + + + diff --git a/MainWindowForm.cpp b/MainWindowForm.cpp new file mode 100644 index 0000000..84f8159 --- /dev/null +++ b/MainWindowForm.cpp @@ -0,0 +1,86 @@ +#include "MainWindowForm.h" +#include "ui_MainWindowForm.h" +#include + +MainWindowForm::MainWindowForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::MainWindowForm) +{ + ui->setupUi(this); + + // 设置窗口透明和大小、位置 + this->setWindowFlags(Qt::FramelessWindowHint); + this->move(1400, 15); + this->resize(SettingConfig::getInstance().WINDOW_WIDTH, SettingConfig::getInstance().WINDOW_HEIGHT); + + // 通过调色板的颜色来设置窗口的统一背景色 + qApp->setPalette(QPalette(QColor(SettingConfig::getInstance().WINDOW_BACKGROUND_COLOR))); + + // 加载css文件设置控件样式 + QFile file(QApplication::applicationDirPath() + "/qss/main.css"); + if (file.open(QFile::ReadOnly)) + { + QString qssStr = QLatin1String(file.readAll()); + this->setStyleSheet(qssStr); + file.close(); + } + + initFormsPtr(); + + // 设置标题文字 + ui->labelTitle->setText(SettingConfig::getInstance().WINDOW_TITLE); + ui->labelCopyright->setText(SettingConfig::getInstance().WINDOW_RIGHTS); + ui->labelVersion->setText(SettingConfig::getInstance().WINDOW_VERSION); + + // 初始化虹膜相机控制 + ProMemory::getInstance().irisCam = new IrisCameraController(this); + ProMemory::getInstance().irisCam->initIrisCamera(); + ProMemory::getInstance().irisCam->openIrisCamera(); + connect(ProMemory::getInstance().irisCam->irisCamHandler, &IrisCameraCapEventHandler::sendIrisFrameToDraw, identifyForm, &IdentifyForm::drawIrisImageOnFrame); + +// LOG_INFO(QString("应用程序启动成功[Application Startup Success]").toStdString()); + qDebug() << "应用程序启动成功[Application Startup Success]"; + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::IDENTIFY_FORM; + ui->wdgtStatced->setCurrentWidget(identifyForm); + + // 开始虹膜相机拍图 + ProMemory::getInstance().irisCam->startCapture(); +} + +MainWindowForm::~MainWindowForm() +{ + delete ui; +} + +void MainWindowForm::lockScreen() +{ + ui->wdgtStatced->setCurrentWidget(lockScreenForm); + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::LOCKSCREEN_FORM; + ProMemory::getInstance().appState = AppConstants::ApplicationState::STATE_WAIT; +} + +void MainWindowForm::keyPressEvent(QKeyEvent *event) +{ + switch (event->key()) { + case Qt::Key_Escape: + QTimer::singleShot(100, qApp, [=](){ + QApplication::quit(); + }); + + default: + QWidget::keyPressEvent(event); + } +} + +void MainWindowForm::initFormsPtr() +{ + // 初始化各个form + lockScreenForm = new LockScreenForm(this); + identifyForm = new IdentifyForm(this); + + // 将form添加到statcked widget中 + ui->wdgtStatced->addWidget(identifyForm); + ui->wdgtStatced->addWidget(lockScreenForm); + + // 绑定按钮函数 +} diff --git a/MainWindowForm.h b/MainWindowForm.h new file mode 100644 index 0000000..7fb2d89 --- /dev/null +++ b/MainWindowForm.h @@ -0,0 +1,38 @@ +#ifndef MAINWINDOWFORM_H +#define MAINWINDOWFORM_H + +#include +#include +#include + +#include "utils/UtilInclude.h" +#include "ProMemory.h" +#include "LockScreenForm.h" +#include "IdentifyForm.h" + +namespace Ui { +class MainWindowForm; +} + +class MainWindowForm : public QWidget +{ + Q_OBJECT + +public: + explicit MainWindowForm(QWidget *parent = nullptr); + ~MainWindowForm(); + +public slots: + void lockScreen(); + +private: + Ui::MainWindowForm *ui; + LockScreenForm * lockScreenForm; + IdentifyForm * identifyForm; + + void keyPressEvent(QKeyEvent *event); + + void initFormsPtr(); +}; + +#endif // MAINWINDOWFORM_H diff --git a/MainWindowForm.ui b/MainWindowForm.ui new file mode 100644 index 0000000..e793ebf --- /dev/null +++ b/MainWindowForm.ui @@ -0,0 +1,85 @@ + + + MainWindowForm + + + + 0 + 0 + 600 + 1024 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + 0 + 0 + 600 + 84 + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + + + + TextLabel + + + Qt::AlignBottom|Qt::AlignHCenter + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + diff --git a/ProMemory.cpp b/ProMemory.cpp new file mode 100644 index 0000000..19e7403 --- /dev/null +++ b/ProMemory.cpp @@ -0,0 +1,84 @@ +#include "ProMemory.h" + +ProMemory::ProMemory() +{ + +} + +ProMemory::~ProMemory() +{ + +} + +/* +void ProMemory::pushCasicIris(CasicIrisInfo irisInfo) +{ + QMutex mutex; + mutex.lock(); + if (this->irisQueue.size() > 30) + { + QStack empty; + std::swap(empty, irisQueue); + } + + irisQueue.push(irisInfo); + mutex.unlock(); +} +CasicIrisInfo ProMemory::popCasicIris() +{ + CasicIrisInfo result; + + QMutex mutex; + mutex.lock(); + if (this->irisQueue.size() > 0) + { + result = irisQueue.pop(); + } + + mutex.unlock(); + + return result; +} +*/ +int ProMemory::getIrisQueueSize() +{ + int size = 0; + + QMutex mutex; + mutex.lock(); + +// size = this->irisQueue.size(); + + mutex.unlock(); + + return size; +} +bool ProMemory::isIrisQueueEmpty() +{ + bool empty = true; + + QMutex mutex; + mutex.lock(); + +// empty = this->irisQueue.isEmpty(); + + mutex.unlock(); + + return empty; +} +void ProMemory::clearIrisQueue() +{ + QMutex mutex; + mutex.lock(); + +// QStack empty; +// std::swap(empty, irisQueue); + + mutex.unlock(); +} + + +void ProMemory::initIrisFeatures(QString personId) +{ +// irisRegistPro->sendDataToExract(QByteArray(QString("[-u]").append(personId).toLocal8Bit())); +} diff --git a/ProMemory.h b/ProMemory.h new file mode 100644 index 0000000..2ecd653 --- /dev/null +++ b/ProMemory.h @@ -0,0 +1,52 @@ +#ifndef PROMEMORY_H +#define PROMEMORY_H + +#include +#include + +#include "AppConstants.h" +//#include "casic/iris/CasicIrisInfo.h" +#include "dao/IrisDataDao.h" + +#include "device/IrisCameraController.h" +//#include "device/iris/IrisRegistProcess.h" +//#include "device/iris/IrisRecogProcess.h" + +class IrisCameraController; +class IrisRegistProcess; +class IrisRecogProcess; + +class ProMemory +{ +public: + ~ProMemory(); + ProMemory(const ProMemory&)=delete; + ProMemory& operator=(const ProMemory&)=delete; + + static ProMemory& getInstance() { + static ProMemory instance; + return instance; + } + +// void pushCasicIris(CasicIrisInfo irisInfo); +// CasicIrisInfo popCasicIris(); + int getIrisQueueSize(); + bool isIrisQueueEmpty(); + void clearIrisQueue(); + + volatile int widgeFrame = 0; // 当前显示的界面 + volatile int appState = 0; // 当前程序所处的状态 + + void initIrisFeatures(QString personId = ""); // 初始化虹膜特征值集合 + + IrisCameraController * irisCam; + IrisRecogProcess * irisRecogPro; + +private: + ProMemory(); + +// QStack irisQueue; // 虹膜信息队列 + QVector irisFeatures; // 虹膜特征值集合 +}; + +#endif // PROMEMORY_H diff --git a/conf/config.ini b/conf/config.ini new file mode 100644 index 0000000..66e46ad --- /dev/null +++ b/conf/config.ini @@ -0,0 +1,67 @@ +[recognize] +#最大允许识别时间(ms) +maxMatchTime=10000 +#识别成功界面停留时间(ms) +successTipsLast=5000 +#识别失败界面停留时间(ms) +failureTipsLast=3000 +#人脸识别最大尝试次数 +maxFaceTryCount=20 +#持续没找到人脸的最大次数 +maxFaceNotFoundCount=500 +#注册时最小人脸 +minFaceRegist=240 +#识别时最小人脸 +minFaceRecog=100 + +#虹膜识别最大尝试次数 +maxIrisTryCount=10 +#虹膜识别持续没有找到眼的最大次数 +maxEyeNotFoundCount=50 + +#识别方式[1=人脸;2=虹膜;3=双认证;4=任意] +recogType=4 + +[window] +#界面窗口宽(px) +width=600 +#界面窗口高(px) +height=1024 +#统一背景色 +backgroundColor="#FFFFFF" +#标题 +title="虹膜识别终端" + +[work] +#工作状态检测时最小人脸范围 +minFaceSize=160 +#人脸范围最小横坐标 +minFacePosX=320 +#人脸范围最大横坐标 +maxFacePosX=960 +#人脸范围最小纵坐标 +minFacePosY=180 +#人脸范围最大纵坐标 +maxFacePosY=540 +#人脸太近阈值 +faceCloseSize=360 +#人脸太远阈值 +faceFarSize=480 + +[camera] +#虹膜相机取一幅画面的时间间隔(ms) +irisFrameInterval=100 +#虹膜相机拍摄宽度 +irisFrameWidth=1440 +#虹膜相机拍摄高度 +irisFrameHeight=1080 +#虹膜图像高度 +irisWidth=640 +#虹膜图像高度 +irisHeight=480 + +[log] +#日志文件位置 +logFile="d://irisLogs//casic_log.txt" +#日志级别 +logLevel="trace" diff --git a/dao/BaseDao.cpp b/dao/BaseDao.cpp new file mode 100644 index 0000000..f51c144 --- /dev/null +++ b/dao/BaseDao.cpp @@ -0,0 +1,12 @@ +#include "BaseDao.h" +#include "dao/util/ConnectionManager.h" + +BaseDao::BaseDao(QObject *parent) : QObject(parent) +{ + +} + +BaseDao::~BaseDao() +{ + +} diff --git a/dao/BaseDao.h b/dao/BaseDao.h new file mode 100644 index 0000000..1693c88 --- /dev/null +++ b/dao/BaseDao.h @@ -0,0 +1,32 @@ +#ifndef BASEDAO_H +#define BASEDAO_H + +#include +#include +#include +#include + +#include "dao/util/ConnectionManager.h" +#include "utils/UtilInclude.h" + +class BaseDao : public QObject +{ + Q_OBJECT +public: + explicit BaseDao(QObject *parent = nullptr); + ~BaseDao(); + + virtual QVector findAllRecord() = 0; + virtual QVariantMap findRecordById(QString id) = 0; + + virtual QString save(QVariantMap object) = 0; + virtual bool edit(QVariantMap newObject, QString id) = 0; + virtual bool dele(QString id) = 0; + +private: + +signals: + +}; + +#endif // BASEDAO_H diff --git a/dao/IrisDataDao.cpp b/dao/IrisDataDao.cpp new file mode 100644 index 0000000..37a0ed6 --- /dev/null +++ b/dao/IrisDataDao.cpp @@ -0,0 +1,204 @@ +#include "IrisDataDao.h" + +IrisDataDao::IrisDataDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector IrisDataDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM IRIS_DATA"; + query.prepare(sql); + + // 执行查询 + query.exec(); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + item.insert("id", query.value("id").toString()); + item.insert("person_id", query.value("person_id").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("left_iris_code1", query.value("left_iris_code1")); + item.insert("left_iris_code2", query.value("left_iris_code2")); + item.insert("left_iris_code3", query.value("left_iris_code3")); + item.insert("right_iris_code1", query.value("right_iris_code1")); + item.insert("right_iris_code2", query.value("right_iris_code2")); + item.insert("right_iris_code3", query.value("right_iris_code3")); + + result.append(item); + } + +// LOG_DEBUG(QString("查询IRIS_DATA表的所有记录[结果数:%1]").arg(result.size()).toStdString()); + return result; +} + +QVariantMap IrisDataDao::findRecordById(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM IRIS_DATA WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + // 获取结果 + if (query.next()) + { + result.insert("id", query.value("id").toString()); + result.insert("person_id", query.value("person_id").toLongLong()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("left_iris_code1", query.value("left_iris_code1")); + result.insert("left_iris_code2", query.value("left_iris_code2")); + result.insert("left_iris_code3", query.value("left_iris_code3")); + result.insert("right_iris_code1", query.value("right_iris_code1")); + result.insert("right_iris_code2", query.value("right_iris_code2")); + result.insert("right_iris_code3", query.value("right_iris_code3")); + } + +// LOG_DEBUG(QString("根据id查询IRIS_DATA表的记录[id=%1]").arg(id).toStdString()); + return result; +} + +QVariantMap IrisDataDao::findRecordByPersonId(QString personId) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM IRIS_DATA WHERE PERSON_ID = :personId"); + query.prepare(sql); + query.bindValue(":personId", personId); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + if (query.next()) + { + result.insert("id", query.value("id").toString()); + result.insert("person_id", query.value("person_id").toLongLong()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("left_iris_code1", query.value("left_iris_code1")); + result.insert("left_iris_code2", query.value("left_iris_code2")); + result.insert("left_iris_code3", query.value("left_iris_code3")); + result.insert("right_iris_code1", query.value("right_iris_code1")); + result.insert("right_iris_code2", query.value("right_iris_code2")); + result.insert("right_iris_code3", query.value("right_iris_code3")); + } + +// LOG_DEBUG(QString("根据personId查询IRIS_DATA表的记录[personId=%1]").arg(personId).toStdString()); + return result; +} + + +QString IrisDataDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + + // INSERT语句 + QString sql = QString("INSERT INTO IRIS_DATA (ID, PERSON_ID, ID_CARD_NO, LEFT_IRIS_CODE1, RIGHT_IRIS_CODE1) VALUES (:id, :personId, :idCardNo, :left1, :right1)"); + + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":personId", object.value("person_id").toString()); + query.bindValue(":idCardNo", object.value("id_card_no").toString()); + query.bindValue(":left1", object.value("left_iris_code1")); + query.bindValue(":right1", object.value("right_iris_code1")); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(); + +// LOG_DEBUG(QString("保存虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool IrisDataDao::edit(QVariantMap newObject, QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // UPDATE语句 + if (!newObject.contains("left_iris_code1") || !newObject.contains("right_iris_code1")){ + return false; + } + QString sql = QString("UPDATE IRIS_DATA SET LEFT_IRIS_CODE1 = :left1, RIGHT_IRIS_CODE1 = :right1 WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":left1", newObject.value("left_iris_code1")); + query.bindValue(":right1", newObject.value("right_iris_code1")); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(); + +// LOG_DEBUG(QString("编辑虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; +} + + +bool IrisDataDao::dele(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + QString sql = QString("DELETE FROM IRIS_DATA WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(); + +// LOG_DEBUG(QString("删除虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; +} diff --git a/dao/IrisDataDao.h b/dao/IrisDataDao.h new file mode 100644 index 0000000..c74dbbd --- /dev/null +++ b/dao/IrisDataDao.h @@ -0,0 +1,25 @@ +#ifndef IRISDATADAO_H +#define IRISDATADAO_H + +#include +#include "BaseDao.h" + +class IrisDataDao : public BaseDao +{ + Q_OBJECT +public: + explicit IrisDataDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + QVariantMap findRecordByPersonId(QString personId); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +signals: + +}; + +#endif // IRISDATADAO_H diff --git a/dao/RecognitionRecordsDao.cpp b/dao/RecognitionRecordsDao.cpp new file mode 100644 index 0000000..40db453 --- /dev/null +++ b/dao/RecognitionRecordsDao.cpp @@ -0,0 +1,100 @@ +#include "RecognitionRecordsDao.h" + +RecognitionRecordsDao::RecognitionRecordsDao(QObject *parent) : BaseDao(parent) +{ + +} + + +QVector RecognitionRecordsDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM RECOGNITION_RECORDS"; + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + item.insert("id", query.value("id").toLongLong()); + result.append(item); + } + +// LOG_DEBUG(QString("查询RECOGNITION_RECORDS表的所有记录[记录数:%1]").arg(result.size()).toStdString()); + return result; +} + +QVariantMap RecognitionRecordsDao::findRecordById(QString id) +{ + QVariantMap item; + return item; +} + +QString RecognitionRecordsDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + + // INSERT语句 + QString sql = QString("INSERT INTO RECOGNITION_RECORDS (ID, PERSON_ID, DATETIME, REC_TYPE, DEV_CODE, DOOR_CODE, INOUT_TYPE) " + "VALUES (:id, :personId, :datetime, :recType, :devCode, :doorCode, :inoutType)"); + + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":personId", object.value("person_id").toString()); + query.bindValue(":datetime", object.value("date_time").toString()); + query.bindValue(":recType", object.value("rec_type").toString()); + query.bindValue(":devCode", object.value("dev_code").toString()); + query.bindValue(":doorCode", object.value("door_code").toString()); + query.bindValue(":inoutType", object.value("inout_type").toString()); + +// LOG_DEBUG(sql.toStdString()); + + // 插入识别的log日志 + QString logStr = QString("INSERT INTO RECOGNITION_LOGS (ID, LOG_INFO) VALUES (:id, :logInfo)"); + + QSqlQuery logQuery(ConnectionManager::getInstance()->getConnection()); + logQuery.prepare(logStr); + logQuery.bindValue(":id", id); + logQuery.bindValue(":logInfo", object.value("debug_info").toString()); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(); + logQuery.exec(); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool RecognitionRecordsDao::edit(QVariantMap newObject, QString id) +{ + return false; +} + +bool RecognitionRecordsDao::dele(QString id) +{ + return false; +} diff --git a/dao/RecognitionRecordsDao.h b/dao/RecognitionRecordsDao.h new file mode 100644 index 0000000..38de7c9 --- /dev/null +++ b/dao/RecognitionRecordsDao.h @@ -0,0 +1,23 @@ +#ifndef RECOGNITIONRECORDSDAO_H +#define RECOGNITIONRECORDSDAO_H + +#include +#include "BaseDao.h" +class RecognitionRecordsDao: public BaseDao +{ + Q_OBJECT +public: + explicit RecognitionRecordsDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +signals: + +}; + +#endif // RECOGNITIONRECORDSDAO_H diff --git a/dao/SysDeptDao.cpp b/dao/SysDeptDao.cpp new file mode 100644 index 0000000..22f9946 --- /dev/null +++ b/dao/SysDeptDao.cpp @@ -0,0 +1,88 @@ +#include "SysDeptDao.h" + +SysDeptDao::SysDeptDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector SysDeptDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_DEPT WHERE PID != '-1' ORDER BY PID, NUM"; + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + item.insert("id", query.value("id").toString()); + item.insert("pid", query.value("pid").toString()); + item.insert("pids", query.value("pids").toString()); + item.insert("simplename", query.value("simplename").toString()); + item.insert("fullname", query.value("fullname").toString()); + } + +// LOG_TRACE(QString("查询表[SYS_DEPT]的所有记录[%1][%2]").arg(result.size()).arg(sql).toStdString()); + + return result; +} + +QVariantMap SysDeptDao::findRecordById(QString id) +{ + QVariantMap item; + return item; + + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM SYS_DEPT WHERE SYS_DEPT.ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + // 获取结果集的大小 + query.last(); + int count = query.at() + 1; + + if (count >=1) + { + query.first(); + + result.insert("id", query.value("id").toString()); + result.insert("pid", query.value("pid").toString()); + result.insert("pids", query.value("pids").toString()); + result.insert("simplename", query.value("simplename").toString()); + result.insert("fullname", query.value("fullname").toString()); + } + +// LOG_TRACE(QString("根据id查询SYS_DEPT表的记录[ID=%1][%2]").arg(id).arg(sql).toStdString()); + + return result; +} + + +QString SysDeptDao::save(QVariantMap object) +{ + return "0"; +} +bool SysDeptDao::edit(QVariantMap newObject, QString id) +{ + return true; +} +bool SysDeptDao::dele(QString id) +{ + return true; +} diff --git a/dao/SysDeptDao.h b/dao/SysDeptDao.h new file mode 100644 index 0000000..e07a09f --- /dev/null +++ b/dao/SysDeptDao.h @@ -0,0 +1,24 @@ +#ifndef SYSDEPTDAO_H +#define SYSDEPTDAO_H + +#include +#include "BaseDao.h" + +class SysDeptDao : public BaseDao +{ + Q_OBJECT +public: + explicit SysDeptDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +private: + +}; + +#endif // SYSDEPTDAO_H diff --git a/dao/SysPersonDao.cpp b/dao/SysPersonDao.cpp new file mode 100644 index 0000000..dd9480f --- /dev/null +++ b/dao/SysPersonDao.cpp @@ -0,0 +1,371 @@ +#include "SysPersonDao.h" + + +SysPersonDao::SysPersonDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector SysPersonDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0'"; + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + count++; + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + result.append(item); + } + +// LOG(TRACE) << QString("查询SYS_PERSON表的所有记录[%1]").arg(count).toStdString(); +// LOG_TRACE(QString("查询SYS_PERSON表的所有记录[%1]").arg(count).toStdString()); + + return result; +} + +QVariantMap SysPersonDao::findRecordById(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0' AND SYS_PERSON.ID = '%1'").arg(id); + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVariantMap result; + + // 获取结果集的大小 + query.last(); + int count = query.at() + 1; + + if (count >=1) + { + query.first(); + + result.insert("id", query.value("id").toString()); + result.insert("delflag", query.value("delflag").toString()); + result.insert("createtime", query.value("createtime").toString()); + result.insert("updatetime", query.value("updatetime").toString()); + result.insert("name", query.value("name").toString()); + result.insert("gender", query.value("gender").toString()); + result.insert("deptid", query.value("deptid").toString()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("remarks", query.value("remarks").toString()); + result.insert("person_code", query.value("person_code").toString()); + result.insert("deptname", query.value("fullname").toString()); + result.insert("sync_id", query.value("sync_id").toString()); + result.insert("hasFace", query.value("face_valid").toString()); + result.insert("hasIris", query.value("iris_valid").toString()); + } + +// LOG(TRACE) << QString("根据id查询SYS_PERSON表的记录[id=%1][%2]").arg(id).arg(sql).toStdString(); +// LOG_TRACE(QString("根据id查询SYS_PERSON表的记录[id=%1][%2]").arg(id).arg(sql).toStdString()); + + return result; +} + +int SysPersonDao::findRecordCountByNameAndDept(QString name, QString dept) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT COUNT(P.ID) AS RECCT FROM SYS_PERSON P LEFT JOIN SYS_DEPT D ON P.DEPTID = D.ID WHERE P.DELFLAG = '0'"; + if (name.isEmpty() == false) + { + sql += " AND P.NAME LIKE '%" + name + "%'"; + } + if (dept.isEmpty() == false && dept.indexOf("-1") < 0) + { + sql += QString(" AND ((P.DEPTID = '%1') OR (D.PIDS LIKE '%,%1,%'))").arg(dept); + } + + // 执行查询 + query.exec(sql); + + // 返回结果 + int result; + + // 遍历查询结果 + if (query.next()) { + result = query.value("RECCT").toInt(); + } + +// LOG(TRACE) << QString("根据姓名和部门查询SYS_PERSON记录总数[%1][%2]").arg(result).arg(sql).toStdString(); +// LOG_TRACE(QString("根据姓名和部门查询SYS_PERSON记录总数[%1][%2]").arg(result).arg(sql).toStdString()); + + return result; +} + +QVector SysPersonDao::findRecordsByNameAndDept(QString name, QString dept, qint8 limit, qint16 offset) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON P LEFT JOIN SYS_DEPT D ON P.DEPTID = D.ID WHERE P.DELFLAG = '0'"; + if (name.isEmpty() == false) + { + sql += " AND P.NAME LIKE '%" + name + "%'"; + } + if (dept.isEmpty() == false && dept.indexOf("-1") < 0) + { + sql += QString(" AND ((P.DEPTID = '%1') OR (D.PIDS LIKE '%,%1,%'))").arg(dept); + } + + sql += QString(" LIMIT %1 OFFSET %2").arg(limit).arg(offset); + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + count++; + + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + + result.append(item); + } + +// LOG(TRACE) << QString("根据姓名和部门分页查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString(); +// LOG_TRACE(QString("根据姓名和部门分页查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString()); + + return result; +} + +QVector SysPersonDao::findRecordsByProperties(QVariantMap conditions) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0'"; + QVariantMap::iterator it; + for (it = conditions.begin(); it != conditions.end(); it++) + { + sql += QString(" AND SYS_PERSON.%1 = %2").arg(it.key()).arg(it.value().toString()); + } + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + count++; + + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + + result.append(item); + } + +// LOG(TRACE) << QString("根据属性值查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString(); +// LOG_TRACE(QString("根据属性值查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString()); + + return result; +} + +QString SysPersonDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + + // INSERT语句 + QString sql = QString("INSERT INTO SYS_PERSON " + "(ID, DELFLAG, CREATETIME, UPDATETIME, " + "NAME, GENDER, DEPTID, ID_CARD_NO, " + "REMARKS, PERSON_CODE, SYNC_ID, FACE_VALID, IRIS_VALID) " + "VALUES ('%1', '0', '%2', '%2', '%3', '%4', '%5', '%6', '%7', '%8', '%9', 0, 0)") + .arg(id).arg(tm) + .arg(object.value("name").toString()) + .arg(object.value("gender").toString()) + .arg(object.value("deptid").toString()) + .arg(object.value("id_card_no").toString()) + .arg(object.value("remarks").toString()) + .arg(object.value("person_code").toString()) + .arg(object.value("sync_id").toString()); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(sql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { +// LOG(DEBUG) << QString("保存SYS_PERSON记录成功[ID = %1][%2]").arg(id).arg(sql).toStdString(); +// LOG_DEBUG(QString("保存SYS_PERSON记录成功[ID = %1][%2]").arg(id).arg(sql).toStdString()); + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool SysPersonDao::edit(QVariantMap newObject, QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + + // UPDATE语句 + QString sql = QString("UPDATE SYS_PERSON SET UPDATETIME = '%1'").arg(tm); + if (newObject.contains("name")) + { + sql.append(QString(", NAME = '%1'").arg(newObject.value("name").toString())); + } + if (newObject.contains("gender")) + { + sql.append(QString(", GENDER = '%1'").arg(newObject.value("gender").toString())); + } + if (newObject.contains("deptid")) + { + sql.append(QString(", DEPTID = '%1'").arg(newObject.value("deptid").toString())); + } + if (newObject.contains("person_code")) + { + sql.append(QString(", PERSON_CODE = '%1'").arg(newObject.value("person_code").toString())); + } + if (newObject.contains("face_valid")) + { + sql.append(QString(", FACE_VALID = '%1'").arg(newObject.value("face_valid").toString())); + } + if (newObject.contains("iris_valid")) + { + sql.append(QString(", IRIS_VALID = '%1'").arg(newObject.value("iris_valid").toString())); + } + + sql.append(QString(" WHERE ID = '%1'").arg(id)); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(sql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + +// LOG(DEBUG) << QString("编辑人员[ID=%1][%2]").arg(id).arg(sql).toStdString(); +// LOG_DEBUG(QString("编辑人员[ID=%1][%2]").arg(id).arg(sql).toStdString()); + + // 返回结果 + return success; +} + +bool SysPersonDao::dele(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + QSqlQuery irisDel(ConnectionManager::getInstance()->getConnection()); + + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + qint64 tmms = QDateTime::currentDateTime().toMSecsSinceEpoch(); + + // UPDATE语句 + QString sql = QString("UPDATE SYS_PERSON SET UPDATETIME = :updateTime, DELFLAG = :flag WHERE ID = :id").arg(tm).arg(tmms).arg(id); + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":updateTime", tm); + query.bindValue(":flag", tmms); + + // 物理删除人员的人脸和虹膜数据 + QString delIrisSql = QString("DELETE FROM IRIS_DATA WHERE PERSON_ID = :personId"); + irisDel.prepare(delIrisSql); + irisDel.bindValue(":personId", id); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(sql); + query.exec(delIrisSql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + +// LOG_DEBUG(QString("删除人员SYS_PERSON[ID=%1][%2]").arg(id).arg(success).toStdString()); + + // 返回结果 + return success; +} diff --git a/dao/SysPersonDao.h b/dao/SysPersonDao.h new file mode 100644 index 0000000..e02e5ba --- /dev/null +++ b/dao/SysPersonDao.h @@ -0,0 +1,27 @@ +#ifndef SYSPERSONDAO_H +#define SYSPERSONDAO_H + +#include +#include "BaseDao.h" + +class SysPersonDao : public BaseDao +{ + Q_OBJECT +public: + explicit SysPersonDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + int findRecordCountByNameAndDept(QString name, QString dept); + QVector findRecordsByNameAndDept(QString name, QString dept, qint8 limit, qint16 offset); + QVector findRecordsByProperties(QVariantMap conditions); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); +signals: + +}; + +#endif // SYSPERSONDAO_H diff --git a/dao/dao.pri b/dao/dao.pri new file mode 100644 index 0000000..1e04ce4 --- /dev/null +++ b/dao/dao.pri @@ -0,0 +1,18 @@ + +HEADERS += $$PWD/BaseDao.h +HEADERS += $$PWD/IrisDataDao.h +HEADERS += $$PWD/RecognitionRecordsDao.h +HEADERS += $$PWD/SysPersonDao.h +HEADERS += $$PWD/SysDeptDao.h + +SOURCES += $$PWD/BaseDao.cpp +SOURCES += $$PWD/IrisDataDao.cpp +SOURCES += $$PWD/RecognitionRecordsDao.cpp +SOURCES += $$PWD/SysPersonDao.cpp +SOURCES += $$PWD/SysDeptDao.cpp + +HEADERS += $$PWD/util/ConnectionManager.h +SOURCES += $$PWD/util/ConnectionManager.cpp +#HEADERS += $$PWD/util/CacheManager.h +#SOURCES += $$PWD/util/CacheManager.cpp + diff --git a/dao/util/ConnectionManager.cpp b/dao/util/ConnectionManager.cpp new file mode 100644 index 0000000..84b17be --- /dev/null +++ b/dao/util/ConnectionManager.cpp @@ -0,0 +1,47 @@ +#include "ConnectionManager.h" +#include + +Q_GLOBAL_STATIC(ConnectionManager, cm) + +ConnectionManager::ConnectionManager(QObject *parent) : QObject(parent) +{ + // 初始化数据库连接 + if (QSqlDatabase::contains("qt_sql_dafault_connection")) + { + conn = QSqlDatabase::database("qt_sql_default_connection"); + } + else + { + conn = QSqlDatabase::addDatabase("QSQLITE"); + conn.setDatabaseName(QApplication::applicationDirPath() + "/data/casic.db"); + + bool succ = conn.open(); + if (succ == true) + { +// LOG_INFO(QString("打开数据库操作正常[Open Database Success]").toStdString()); + } else + { +// LOG_ERROR(QString("打开数据库操作失败[Open Database Failed]").toStdString()); + } + } +} + +ConnectionManager::~ConnectionManager() +{ + conn.close(); +} + +ConnectionManager* ConnectionManager::getInstance() +{ + return cm; +} + +QSqlDatabase ConnectionManager::getConnection() +{ + return this->conn; +} + +qint64 ConnectionManager::generateId() +{ + return this->idWorker.nextId(); +} diff --git a/dao/util/ConnectionManager.h b/dao/util/ConnectionManager.h new file mode 100644 index 0000000..84647e3 --- /dev/null +++ b/dao/util/ConnectionManager.h @@ -0,0 +1,34 @@ +#ifndef CONNECTIONMANAGER_H +#define CONNECTIONMANAGER_H + +#include +#include +#include "utils/id/IdWorker.h" +#include "utils/UtilInclude.h" + +using namespace Jiawa::Core; + +class ConnectionManager : public QObject +{ + Q_OBJECT +public: + explicit ConnectionManager(QObject *parent = nullptr); + ~ConnectionManager(); + + static ConnectionManager * getInstance(); + + QSqlDatabase getConnection(); + qint64 generateId(); + +private: + // 数据库连接 + QSqlDatabase conn; + + // 雪花id生成工具 + IdWorker &idWorker = Singleton::instance(); + +signals: + +}; + +#endif // CONNECTIONMANAGER_H diff --git a/device/IrisCameraCapEventHandler.cpp b/device/IrisCameraCapEventHandler.cpp new file mode 100644 index 0000000..45df089 --- /dev/null +++ b/device/IrisCameraCapEventHandler.cpp @@ -0,0 +1,103 @@ +#include "IrisCameraCapEventHandler.h" + +IrisCameraCapEventHandler::IrisCameraCapEventHandler(QObject *parent) : QObject(parent) +{ + +} + +void IrisCameraCapEventHandler::DoOnImageCaptured(CImageDataPointer &objImageDataPointer, void *pUserParam) +{ + if (objImageDataPointer.IsNull() == false) + { + CGXDevicePointer* cam = (CGXDevicePointer *) pUserParam; + + auto camName = cam->getPtr()->GetDeviceInfo().GetUserID(); + int width = objImageDataPointer->GetWidth(); + int height = objImageDataPointer->GetHeight(); + size_t leftKeyIndex = camName.find("left"); + size_t rightKeyIndex = camName.find("right"); + + uchar * pBuffer = (BYTE*)objImageDataPointer->GetBuffer(); + + // 相机拍摄下的图像1440*1080, 直接用于算法判断 + QImage img = QImage(pBuffer, width, height, QImage::Format_Grayscale8); // 用于展示 +// QImage imgAlgo = img.copy(0, 0, width, height); + + // 用于显示的图像需要缩小到400 * 300的尺寸 + img = img.scaled(SettingConfig::getInstance().IRIS_DISPLAY_HEIGHT, SettingConfig::getInstance().IRIS_DISPLAY_WIDTH); + img = img.transformed(QTransform().rotate(-90)); // 图像逆时针旋转90度 + + // 发送到界面进行显示 + emit sendIrisFrameToDraw(img); +// cv::Mat irisMat = ImageUtil::QImageToMat(imgAlgo); + +// irisInfo.data = imgAlgo; +// irisInfo.matData = irisMat; + +// // 将图像显示在注册页面的label上 +// // 并将虹膜信息对象存入队列中 +// ProMemory::getInstance().pushCasicIris(irisInfo); + +// if (leftKeyIndex >= 0 && leftKeyIndex < 32) +// { +// emit sendIrisFrameToDraw(img, 0); // 左眼画面 +// } else if (rightKeyIndex >= 0 && rightKeyIndex < 32) +// { +// emit sendIrisFrameToDraw(img, 1); // 右眼画面 +// } +/* + if (pBuffer != NULL) + { + // 创建虹膜信息对象 + CasicIrisInfo irisInfo; + irisInfo.hasEye = false; + if (leftKeyIndex >= 0 && leftKeyIndex < 32) + { + // 左眼相机拍摄的图像 + irisInfo.leftOrRight = "left"; + } else if (rightKeyIndex >= 0 && rightKeyIndex < 32) + { + // 右眼相机 + irisInfo.leftOrRight = "right"; + } + + if (ProMemory::getInstance().widgeFrame == CasicBioRecConst::RECOGNIZE_RESULT_FORM) + { + // 相机拍摄下的图像1280*960, 直接用于算法判断 + QImage imgDisp = QImage(pBuffer, width, height, QImage::Format_Grayscale8); + cv::Mat irisMat = ImageUtil::QImageToMat(imgDisp); + + irisInfo.data = imgDisp; + irisInfo.matData = irisMat; + + ProMemory::getInstance().pushCasicIris(irisInfo); + +// cv::imwrite(QString("D:\\irisLogs\\iristest-%1.bmp").arg(irisInfo.leftOrRight).toStdString(), irisMat); + } else if (ProMemory::getInstance().widgeFrame == CasicBioRecConst::ADD_PERSON_CAPTURE_IRIS) + { + // 相机拍摄下的图像1280*960, 直接用于算法判断 + QImage img = QImage(pBuffer, width, height, QImage::Format_Grayscale8); + QImage imgAlgo = img.copy(0, 0, width, height); + + // 用于显示的图像需要缩小到1/4的尺寸 + img = img.scaled(640, 480); + cv::Mat irisMat = ImageUtil::QImageToMat(imgAlgo); + + irisInfo.data = imgAlgo; + irisInfo.matData = irisMat; + + // 将图像显示在注册页面的label上 + // 并将虹膜信息对象存入队列中 + ProMemory::getInstance().pushCasicIris(irisInfo); + + if (leftKeyIndex >= 0 && leftKeyIndex < 32) + { + emit sendIrisFrameToDraw(img, 0); // 左眼画面 + } else if (rightKeyIndex >= 0 && rightKeyIndex < 32) + { + emit sendIrisFrameToDraw(img, 1); // 右眼画面 + } + } + }*/ + } +} diff --git a/AppConstants.h b/AppConstants.h new file mode 100644 index 0000000..296c53f --- /dev/null +++ b/AppConstants.h @@ -0,0 +1,28 @@ +#ifndef APPCONSTANTS_H +#define APPCONSTANTS_H + +class AppConstants +{ +public: + enum WidgeFrameName + { + MAIN_PAGE = 0, // 主页面 + PERSON_LIST_FORM = 1, // 人员列表页面 + ADD_PERSON_FORM = 2, // 添加人员页面 + ADD_PERSON_CAPTURE_FACE = 21, // 添加/编辑人员时进行人脸拍图 + ADD_PERSON_CAPTURE_IRIS = 22, // 添加/编辑人员时进行虹膜拍图 + SETTING_FORM = 3, // 设置页面 + RECOGNIZE_RESULT_FORM = 4, // 识别结果界面 + IDENTIFY_FORM = 5, // 识别界面 含识别中 和 识别结果 + LOCKSCREEN_FORM = 6 // 锁屏待机界面 + }; + + enum ApplicationState + { + STATE_WAIT = 0, // 待机 + STATE_WORKING = 1, // 工作状态 + STATE_IDENTIFYING = 2, // 识别中 + }; +}; + +#endif // APPCONSTANTS_H diff --git a/CasicIrisIdentify.pro b/CasicIrisIdentify.pro index 5d7fea6..575ce3d 100644 --- a/CasicIrisIdentify.pro +++ b/CasicIrisIdentify.pro @@ -1,4 +1,4 @@ -QT += core gui +QT += core gui sql network texttospeech greaterThan(QT_MAJOR_VERSION, 4): QT += widgets @@ -15,20 +15,46 @@ # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 -SOURCES += \ - main.cpp \ - IdentifyForm.cpp +include("dao/dao.pri") +include("device/device.pri") +include("utils/utils.pri") -HEADERS += \ - IdentifyForm.h +SOURCES += main.cpp +SOURCES += ProMemory.cpp +SOURCES += MainWindowForm.cpp +SOURCES += IdentifyForm.cpp +SOURCES += LockScreenForm.cpp -FORMS += \ - IdentifyForm.ui +HEADERS += AppConstants.h +HEADERS += ProMemory.h +HEADERS += MainWindowForm.h +HEADERS += IdentifyForm.h +HEADERS += LockScreenForm.h -TRANSLATIONS += \ - CasicIrisIdentify_zh_CN.ts +FORMS += MainWindowForm.ui +FORMS += IdentifyForm.ui +FORMS += LockScreenForm.ui + +RESOURCES += resource.qrc + +DISTFILES += conf/config.ini + +#TRANSLATIONS += CasicIrisIdentify_zh_CN.ts + +#INCLUDEPATH += include/spdlog +#DEPENDPATH += include/spdlog # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target + + +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lopencv_world420 +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lGxIAPICPPEx + +INCLUDEPATH += $$PWD/include/daheng +DEPENDPATH += $$PWD/include/daheng + +INCLUDEPATH += $$PWD/include +DEPENDPATH += $$PWD/include diff --git a/CasicIrisIdentify_zh_CN.ts b/CasicIrisIdentify_zh_CN.ts index 5526fe4..81900df 100644 --- a/CasicIrisIdentify_zh_CN.ts +++ b/CasicIrisIdentify_zh_CN.ts @@ -1,3 +1,12 @@ - + + + IdentifyForm + + + IdentifyForm + + + + diff --git a/IdentifyForm.cpp b/IdentifyForm.cpp index 348a897..ba1f251 100644 --- a/IdentifyForm.cpp +++ b/IdentifyForm.cpp @@ -1,4 +1,4 @@ -#include "IdentifyForm.h" +#include "IdentifyForm.h" #include "ui_IdentifyForm.h" IdentifyForm::IdentifyForm(QWidget *parent) @@ -6,6 +6,12 @@ , ui(new Ui::IdentifyForm) { ui->setupUi(this); + + // 初始化更新界面的定时器 + // 每秒执行一次 + connect(TimeCounterUtil::getInstance().clockCounter, &QTimer::timeout, this, &IdentifyForm::updateDateAndTime); + + TimeCounterUtil::getInstance().clockCounter->start(1000); } IdentifyForm::~IdentifyForm() @@ -13,3 +19,16 @@ delete ui; } +void IdentifyForm::drawIrisImageOnFrame(QImage image) +{ + // 只在识别界面才显示画面 + if (ui->wgtStacked->currentIndex() == 0) { + ui->labelVideo->setPixmap(QPixmap::fromImage(image)); + } +} + + +void IdentifyForm::updateDateAndTime() +{ + ui->labelTime->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd dddd HH:mm:ss")); +} diff --git a/IdentifyForm.h b/IdentifyForm.h index fc857a1..ae1cd22 100644 --- a/IdentifyForm.h +++ b/IdentifyForm.h @@ -1,7 +1,10 @@ -#ifndef IDENTIFYFORM_H +#ifndef IDENTIFYFORM_H #define IDENTIFYFORM_H #include +#include + +#include "utils/UtilInclude.h" QT_BEGIN_NAMESPACE namespace Ui { class IdentifyForm; } @@ -15,7 +18,14 @@ IdentifyForm(QWidget *parent = nullptr); ~IdentifyForm(); +public slots: + void drawIrisImageOnFrame(QImage image); + private: Ui::IdentifyForm *ui; + +private slots: + void updateDateAndTime(); + }; #endif // IDENTIFYFORM_H diff --git a/IdentifyForm.ui b/IdentifyForm.ui index c72a36f..879dc9a 100644 --- a/IdentifyForm.ui +++ b/IdentifyForm.ui @@ -6,13 +6,59 @@ 0 0 - 800 + 600 600 IdentifyForm + + + + 0 + 40 + 600 + 450 + + + + 0 + + + + + + 100 + 10 + 400 + 300 + + + + + + + + + + + + + + 0 + 0 + 600 + 40 + + + + TextLabel + + + Qt::AlignCenter + + diff --git a/LockScreenForm.cpp b/LockScreenForm.cpp new file mode 100644 index 0000000..58dc54b --- /dev/null +++ b/LockScreenForm.cpp @@ -0,0 +1,14 @@ +#include "LockScreenForm.h" +#include "ui_LockScreenForm.h" + +LockScreenForm::LockScreenForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::LockScreenForm) +{ + ui->setupUi(this); +} + +LockScreenForm::~LockScreenForm() +{ + delete ui; +} diff --git a/LockScreenForm.h b/LockScreenForm.h new file mode 100644 index 0000000..b5ded48 --- /dev/null +++ b/LockScreenForm.h @@ -0,0 +1,25 @@ +#ifndef LOCKSCREENFORM_H +#define LOCKSCREENFORM_H + +#include +#include + +#include "utils/UtilInclude.h" + +namespace Ui { +class LockScreenForm; +} + +class LockScreenForm : public QWidget +{ + Q_OBJECT + +public: + explicit LockScreenForm(QWidget *parent = nullptr); + ~LockScreenForm(); + +private: + Ui::LockScreenForm *ui; +}; + +#endif // LOCKSCREENFORM_H diff --git a/LockScreenForm.ui b/LockScreenForm.ui new file mode 100644 index 0000000..7f2a6db --- /dev/null +++ b/LockScreenForm.ui @@ -0,0 +1,45 @@ + + + LockScreenForm + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + 180 + 100 + 54 + 12 + + + + TextLabel + + + + + + 180 + 160 + 54 + 12 + + + + TextLabel + + + + + + diff --git a/MainWindowForm.cpp b/MainWindowForm.cpp new file mode 100644 index 0000000..84f8159 --- /dev/null +++ b/MainWindowForm.cpp @@ -0,0 +1,86 @@ +#include "MainWindowForm.h" +#include "ui_MainWindowForm.h" +#include + +MainWindowForm::MainWindowForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::MainWindowForm) +{ + ui->setupUi(this); + + // 设置窗口透明和大小、位置 + this->setWindowFlags(Qt::FramelessWindowHint); + this->move(1400, 15); + this->resize(SettingConfig::getInstance().WINDOW_WIDTH, SettingConfig::getInstance().WINDOW_HEIGHT); + + // 通过调色板的颜色来设置窗口的统一背景色 + qApp->setPalette(QPalette(QColor(SettingConfig::getInstance().WINDOW_BACKGROUND_COLOR))); + + // 加载css文件设置控件样式 + QFile file(QApplication::applicationDirPath() + "/qss/main.css"); + if (file.open(QFile::ReadOnly)) + { + QString qssStr = QLatin1String(file.readAll()); + this->setStyleSheet(qssStr); + file.close(); + } + + initFormsPtr(); + + // 设置标题文字 + ui->labelTitle->setText(SettingConfig::getInstance().WINDOW_TITLE); + ui->labelCopyright->setText(SettingConfig::getInstance().WINDOW_RIGHTS); + ui->labelVersion->setText(SettingConfig::getInstance().WINDOW_VERSION); + + // 初始化虹膜相机控制 + ProMemory::getInstance().irisCam = new IrisCameraController(this); + ProMemory::getInstance().irisCam->initIrisCamera(); + ProMemory::getInstance().irisCam->openIrisCamera(); + connect(ProMemory::getInstance().irisCam->irisCamHandler, &IrisCameraCapEventHandler::sendIrisFrameToDraw, identifyForm, &IdentifyForm::drawIrisImageOnFrame); + +// LOG_INFO(QString("应用程序启动成功[Application Startup Success]").toStdString()); + qDebug() << "应用程序启动成功[Application Startup Success]"; + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::IDENTIFY_FORM; + ui->wdgtStatced->setCurrentWidget(identifyForm); + + // 开始虹膜相机拍图 + ProMemory::getInstance().irisCam->startCapture(); +} + +MainWindowForm::~MainWindowForm() +{ + delete ui; +} + +void MainWindowForm::lockScreen() +{ + ui->wdgtStatced->setCurrentWidget(lockScreenForm); + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::LOCKSCREEN_FORM; + ProMemory::getInstance().appState = AppConstants::ApplicationState::STATE_WAIT; +} + +void MainWindowForm::keyPressEvent(QKeyEvent *event) +{ + switch (event->key()) { + case Qt::Key_Escape: + QTimer::singleShot(100, qApp, [=](){ + QApplication::quit(); + }); + + default: + QWidget::keyPressEvent(event); + } +} + +void MainWindowForm::initFormsPtr() +{ + // 初始化各个form + lockScreenForm = new LockScreenForm(this); + identifyForm = new IdentifyForm(this); + + // 将form添加到statcked widget中 + ui->wdgtStatced->addWidget(identifyForm); + ui->wdgtStatced->addWidget(lockScreenForm); + + // 绑定按钮函数 +} diff --git a/MainWindowForm.h b/MainWindowForm.h new file mode 100644 index 0000000..7fb2d89 --- /dev/null +++ b/MainWindowForm.h @@ -0,0 +1,38 @@ +#ifndef MAINWINDOWFORM_H +#define MAINWINDOWFORM_H + +#include +#include +#include + +#include "utils/UtilInclude.h" +#include "ProMemory.h" +#include "LockScreenForm.h" +#include "IdentifyForm.h" + +namespace Ui { +class MainWindowForm; +} + +class MainWindowForm : public QWidget +{ + Q_OBJECT + +public: + explicit MainWindowForm(QWidget *parent = nullptr); + ~MainWindowForm(); + +public slots: + void lockScreen(); + +private: + Ui::MainWindowForm *ui; + LockScreenForm * lockScreenForm; + IdentifyForm * identifyForm; + + void keyPressEvent(QKeyEvent *event); + + void initFormsPtr(); +}; + +#endif // MAINWINDOWFORM_H diff --git a/MainWindowForm.ui b/MainWindowForm.ui new file mode 100644 index 0000000..e793ebf --- /dev/null +++ b/MainWindowForm.ui @@ -0,0 +1,85 @@ + + + MainWindowForm + + + + 0 + 0 + 600 + 1024 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + 0 + 0 + 600 + 84 + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + + + + TextLabel + + + Qt::AlignBottom|Qt::AlignHCenter + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + diff --git a/ProMemory.cpp b/ProMemory.cpp new file mode 100644 index 0000000..19e7403 --- /dev/null +++ b/ProMemory.cpp @@ -0,0 +1,84 @@ +#include "ProMemory.h" + +ProMemory::ProMemory() +{ + +} + +ProMemory::~ProMemory() +{ + +} + +/* +void ProMemory::pushCasicIris(CasicIrisInfo irisInfo) +{ + QMutex mutex; + mutex.lock(); + if (this->irisQueue.size() > 30) + { + QStack empty; + std::swap(empty, irisQueue); + } + + irisQueue.push(irisInfo); + mutex.unlock(); +} +CasicIrisInfo ProMemory::popCasicIris() +{ + CasicIrisInfo result; + + QMutex mutex; + mutex.lock(); + if (this->irisQueue.size() > 0) + { + result = irisQueue.pop(); + } + + mutex.unlock(); + + return result; +} +*/ +int ProMemory::getIrisQueueSize() +{ + int size = 0; + + QMutex mutex; + mutex.lock(); + +// size = this->irisQueue.size(); + + mutex.unlock(); + + return size; +} +bool ProMemory::isIrisQueueEmpty() +{ + bool empty = true; + + QMutex mutex; + mutex.lock(); + +// empty = this->irisQueue.isEmpty(); + + mutex.unlock(); + + return empty; +} +void ProMemory::clearIrisQueue() +{ + QMutex mutex; + mutex.lock(); + +// QStack empty; +// std::swap(empty, irisQueue); + + mutex.unlock(); +} + + +void ProMemory::initIrisFeatures(QString personId) +{ +// irisRegistPro->sendDataToExract(QByteArray(QString("[-u]").append(personId).toLocal8Bit())); +} diff --git a/ProMemory.h b/ProMemory.h new file mode 100644 index 0000000..2ecd653 --- /dev/null +++ b/ProMemory.h @@ -0,0 +1,52 @@ +#ifndef PROMEMORY_H +#define PROMEMORY_H + +#include +#include + +#include "AppConstants.h" +//#include "casic/iris/CasicIrisInfo.h" +#include "dao/IrisDataDao.h" + +#include "device/IrisCameraController.h" +//#include "device/iris/IrisRegistProcess.h" +//#include "device/iris/IrisRecogProcess.h" + +class IrisCameraController; +class IrisRegistProcess; +class IrisRecogProcess; + +class ProMemory +{ +public: + ~ProMemory(); + ProMemory(const ProMemory&)=delete; + ProMemory& operator=(const ProMemory&)=delete; + + static ProMemory& getInstance() { + static ProMemory instance; + return instance; + } + +// void pushCasicIris(CasicIrisInfo irisInfo); +// CasicIrisInfo popCasicIris(); + int getIrisQueueSize(); + bool isIrisQueueEmpty(); + void clearIrisQueue(); + + volatile int widgeFrame = 0; // 当前显示的界面 + volatile int appState = 0; // 当前程序所处的状态 + + void initIrisFeatures(QString personId = ""); // 初始化虹膜特征值集合 + + IrisCameraController * irisCam; + IrisRecogProcess * irisRecogPro; + +private: + ProMemory(); + +// QStack irisQueue; // 虹膜信息队列 + QVector irisFeatures; // 虹膜特征值集合 +}; + +#endif // PROMEMORY_H diff --git a/conf/config.ini b/conf/config.ini new file mode 100644 index 0000000..66e46ad --- /dev/null +++ b/conf/config.ini @@ -0,0 +1,67 @@ +[recognize] +#最大允许识别时间(ms) +maxMatchTime=10000 +#识别成功界面停留时间(ms) +successTipsLast=5000 +#识别失败界面停留时间(ms) +failureTipsLast=3000 +#人脸识别最大尝试次数 +maxFaceTryCount=20 +#持续没找到人脸的最大次数 +maxFaceNotFoundCount=500 +#注册时最小人脸 +minFaceRegist=240 +#识别时最小人脸 +minFaceRecog=100 + +#虹膜识别最大尝试次数 +maxIrisTryCount=10 +#虹膜识别持续没有找到眼的最大次数 +maxEyeNotFoundCount=50 + +#识别方式[1=人脸;2=虹膜;3=双认证;4=任意] +recogType=4 + +[window] +#界面窗口宽(px) +width=600 +#界面窗口高(px) +height=1024 +#统一背景色 +backgroundColor="#FFFFFF" +#标题 +title="虹膜识别终端" + +[work] +#工作状态检测时最小人脸范围 +minFaceSize=160 +#人脸范围最小横坐标 +minFacePosX=320 +#人脸范围最大横坐标 +maxFacePosX=960 +#人脸范围最小纵坐标 +minFacePosY=180 +#人脸范围最大纵坐标 +maxFacePosY=540 +#人脸太近阈值 +faceCloseSize=360 +#人脸太远阈值 +faceFarSize=480 + +[camera] +#虹膜相机取一幅画面的时间间隔(ms) +irisFrameInterval=100 +#虹膜相机拍摄宽度 +irisFrameWidth=1440 +#虹膜相机拍摄高度 +irisFrameHeight=1080 +#虹膜图像高度 +irisWidth=640 +#虹膜图像高度 +irisHeight=480 + +[log] +#日志文件位置 +logFile="d://irisLogs//casic_log.txt" +#日志级别 +logLevel="trace" diff --git a/dao/BaseDao.cpp b/dao/BaseDao.cpp new file mode 100644 index 0000000..f51c144 --- /dev/null +++ b/dao/BaseDao.cpp @@ -0,0 +1,12 @@ +#include "BaseDao.h" +#include "dao/util/ConnectionManager.h" + +BaseDao::BaseDao(QObject *parent) : QObject(parent) +{ + +} + +BaseDao::~BaseDao() +{ + +} diff --git a/dao/BaseDao.h b/dao/BaseDao.h new file mode 100644 index 0000000..1693c88 --- /dev/null +++ b/dao/BaseDao.h @@ -0,0 +1,32 @@ +#ifndef BASEDAO_H +#define BASEDAO_H + +#include +#include +#include +#include + +#include "dao/util/ConnectionManager.h" +#include "utils/UtilInclude.h" + +class BaseDao : public QObject +{ + Q_OBJECT +public: + explicit BaseDao(QObject *parent = nullptr); + ~BaseDao(); + + virtual QVector findAllRecord() = 0; + virtual QVariantMap findRecordById(QString id) = 0; + + virtual QString save(QVariantMap object) = 0; + virtual bool edit(QVariantMap newObject, QString id) = 0; + virtual bool dele(QString id) = 0; + +private: + +signals: + +}; + +#endif // BASEDAO_H diff --git a/dao/IrisDataDao.cpp b/dao/IrisDataDao.cpp new file mode 100644 index 0000000..37a0ed6 --- /dev/null +++ b/dao/IrisDataDao.cpp @@ -0,0 +1,204 @@ +#include "IrisDataDao.h" + +IrisDataDao::IrisDataDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector IrisDataDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM IRIS_DATA"; + query.prepare(sql); + + // 执行查询 + query.exec(); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + item.insert("id", query.value("id").toString()); + item.insert("person_id", query.value("person_id").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("left_iris_code1", query.value("left_iris_code1")); + item.insert("left_iris_code2", query.value("left_iris_code2")); + item.insert("left_iris_code3", query.value("left_iris_code3")); + item.insert("right_iris_code1", query.value("right_iris_code1")); + item.insert("right_iris_code2", query.value("right_iris_code2")); + item.insert("right_iris_code3", query.value("right_iris_code3")); + + result.append(item); + } + +// LOG_DEBUG(QString("查询IRIS_DATA表的所有记录[结果数:%1]").arg(result.size()).toStdString()); + return result; +} + +QVariantMap IrisDataDao::findRecordById(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM IRIS_DATA WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + // 获取结果 + if (query.next()) + { + result.insert("id", query.value("id").toString()); + result.insert("person_id", query.value("person_id").toLongLong()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("left_iris_code1", query.value("left_iris_code1")); + result.insert("left_iris_code2", query.value("left_iris_code2")); + result.insert("left_iris_code3", query.value("left_iris_code3")); + result.insert("right_iris_code1", query.value("right_iris_code1")); + result.insert("right_iris_code2", query.value("right_iris_code2")); + result.insert("right_iris_code3", query.value("right_iris_code3")); + } + +// LOG_DEBUG(QString("根据id查询IRIS_DATA表的记录[id=%1]").arg(id).toStdString()); + return result; +} + +QVariantMap IrisDataDao::findRecordByPersonId(QString personId) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM IRIS_DATA WHERE PERSON_ID = :personId"); + query.prepare(sql); + query.bindValue(":personId", personId); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + if (query.next()) + { + result.insert("id", query.value("id").toString()); + result.insert("person_id", query.value("person_id").toLongLong()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("left_iris_code1", query.value("left_iris_code1")); + result.insert("left_iris_code2", query.value("left_iris_code2")); + result.insert("left_iris_code3", query.value("left_iris_code3")); + result.insert("right_iris_code1", query.value("right_iris_code1")); + result.insert("right_iris_code2", query.value("right_iris_code2")); + result.insert("right_iris_code3", query.value("right_iris_code3")); + } + +// LOG_DEBUG(QString("根据personId查询IRIS_DATA表的记录[personId=%1]").arg(personId).toStdString()); + return result; +} + + +QString IrisDataDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + + // INSERT语句 + QString sql = QString("INSERT INTO IRIS_DATA (ID, PERSON_ID, ID_CARD_NO, LEFT_IRIS_CODE1, RIGHT_IRIS_CODE1) VALUES (:id, :personId, :idCardNo, :left1, :right1)"); + + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":personId", object.value("person_id").toString()); + query.bindValue(":idCardNo", object.value("id_card_no").toString()); + query.bindValue(":left1", object.value("left_iris_code1")); + query.bindValue(":right1", object.value("right_iris_code1")); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(); + +// LOG_DEBUG(QString("保存虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool IrisDataDao::edit(QVariantMap newObject, QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // UPDATE语句 + if (!newObject.contains("left_iris_code1") || !newObject.contains("right_iris_code1")){ + return false; + } + QString sql = QString("UPDATE IRIS_DATA SET LEFT_IRIS_CODE1 = :left1, RIGHT_IRIS_CODE1 = :right1 WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":left1", newObject.value("left_iris_code1")); + query.bindValue(":right1", newObject.value("right_iris_code1")); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(); + +// LOG_DEBUG(QString("编辑虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; +} + + +bool IrisDataDao::dele(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + QString sql = QString("DELETE FROM IRIS_DATA WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(); + +// LOG_DEBUG(QString("删除虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; +} diff --git a/dao/IrisDataDao.h b/dao/IrisDataDao.h new file mode 100644 index 0000000..c74dbbd --- /dev/null +++ b/dao/IrisDataDao.h @@ -0,0 +1,25 @@ +#ifndef IRISDATADAO_H +#define IRISDATADAO_H + +#include +#include "BaseDao.h" + +class IrisDataDao : public BaseDao +{ + Q_OBJECT +public: + explicit IrisDataDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + QVariantMap findRecordByPersonId(QString personId); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +signals: + +}; + +#endif // IRISDATADAO_H diff --git a/dao/RecognitionRecordsDao.cpp b/dao/RecognitionRecordsDao.cpp new file mode 100644 index 0000000..40db453 --- /dev/null +++ b/dao/RecognitionRecordsDao.cpp @@ -0,0 +1,100 @@ +#include "RecognitionRecordsDao.h" + +RecognitionRecordsDao::RecognitionRecordsDao(QObject *parent) : BaseDao(parent) +{ + +} + + +QVector RecognitionRecordsDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM RECOGNITION_RECORDS"; + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + item.insert("id", query.value("id").toLongLong()); + result.append(item); + } + +// LOG_DEBUG(QString("查询RECOGNITION_RECORDS表的所有记录[记录数:%1]").arg(result.size()).toStdString()); + return result; +} + +QVariantMap RecognitionRecordsDao::findRecordById(QString id) +{ + QVariantMap item; + return item; +} + +QString RecognitionRecordsDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + + // INSERT语句 + QString sql = QString("INSERT INTO RECOGNITION_RECORDS (ID, PERSON_ID, DATETIME, REC_TYPE, DEV_CODE, DOOR_CODE, INOUT_TYPE) " + "VALUES (:id, :personId, :datetime, :recType, :devCode, :doorCode, :inoutType)"); + + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":personId", object.value("person_id").toString()); + query.bindValue(":datetime", object.value("date_time").toString()); + query.bindValue(":recType", object.value("rec_type").toString()); + query.bindValue(":devCode", object.value("dev_code").toString()); + query.bindValue(":doorCode", object.value("door_code").toString()); + query.bindValue(":inoutType", object.value("inout_type").toString()); + +// LOG_DEBUG(sql.toStdString()); + + // 插入识别的log日志 + QString logStr = QString("INSERT INTO RECOGNITION_LOGS (ID, LOG_INFO) VALUES (:id, :logInfo)"); + + QSqlQuery logQuery(ConnectionManager::getInstance()->getConnection()); + logQuery.prepare(logStr); + logQuery.bindValue(":id", id); + logQuery.bindValue(":logInfo", object.value("debug_info").toString()); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(); + logQuery.exec(); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool RecognitionRecordsDao::edit(QVariantMap newObject, QString id) +{ + return false; +} + +bool RecognitionRecordsDao::dele(QString id) +{ + return false; +} diff --git a/dao/RecognitionRecordsDao.h b/dao/RecognitionRecordsDao.h new file mode 100644 index 0000000..38de7c9 --- /dev/null +++ b/dao/RecognitionRecordsDao.h @@ -0,0 +1,23 @@ +#ifndef RECOGNITIONRECORDSDAO_H +#define RECOGNITIONRECORDSDAO_H + +#include +#include "BaseDao.h" +class RecognitionRecordsDao: public BaseDao +{ + Q_OBJECT +public: + explicit RecognitionRecordsDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +signals: + +}; + +#endif // RECOGNITIONRECORDSDAO_H diff --git a/dao/SysDeptDao.cpp b/dao/SysDeptDao.cpp new file mode 100644 index 0000000..22f9946 --- /dev/null +++ b/dao/SysDeptDao.cpp @@ -0,0 +1,88 @@ +#include "SysDeptDao.h" + +SysDeptDao::SysDeptDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector SysDeptDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_DEPT WHERE PID != '-1' ORDER BY PID, NUM"; + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + item.insert("id", query.value("id").toString()); + item.insert("pid", query.value("pid").toString()); + item.insert("pids", query.value("pids").toString()); + item.insert("simplename", query.value("simplename").toString()); + item.insert("fullname", query.value("fullname").toString()); + } + +// LOG_TRACE(QString("查询表[SYS_DEPT]的所有记录[%1][%2]").arg(result.size()).arg(sql).toStdString()); + + return result; +} + +QVariantMap SysDeptDao::findRecordById(QString id) +{ + QVariantMap item; + return item; + + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM SYS_DEPT WHERE SYS_DEPT.ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + // 获取结果集的大小 + query.last(); + int count = query.at() + 1; + + if (count >=1) + { + query.first(); + + result.insert("id", query.value("id").toString()); + result.insert("pid", query.value("pid").toString()); + result.insert("pids", query.value("pids").toString()); + result.insert("simplename", query.value("simplename").toString()); + result.insert("fullname", query.value("fullname").toString()); + } + +// LOG_TRACE(QString("根据id查询SYS_DEPT表的记录[ID=%1][%2]").arg(id).arg(sql).toStdString()); + + return result; +} + + +QString SysDeptDao::save(QVariantMap object) +{ + return "0"; +} +bool SysDeptDao::edit(QVariantMap newObject, QString id) +{ + return true; +} +bool SysDeptDao::dele(QString id) +{ + return true; +} diff --git a/dao/SysDeptDao.h b/dao/SysDeptDao.h new file mode 100644 index 0000000..e07a09f --- /dev/null +++ b/dao/SysDeptDao.h @@ -0,0 +1,24 @@ +#ifndef SYSDEPTDAO_H +#define SYSDEPTDAO_H + +#include +#include "BaseDao.h" + +class SysDeptDao : public BaseDao +{ + Q_OBJECT +public: + explicit SysDeptDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +private: + +}; + +#endif // SYSDEPTDAO_H diff --git a/dao/SysPersonDao.cpp b/dao/SysPersonDao.cpp new file mode 100644 index 0000000..dd9480f --- /dev/null +++ b/dao/SysPersonDao.cpp @@ -0,0 +1,371 @@ +#include "SysPersonDao.h" + + +SysPersonDao::SysPersonDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector SysPersonDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0'"; + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + count++; + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + result.append(item); + } + +// LOG(TRACE) << QString("查询SYS_PERSON表的所有记录[%1]").arg(count).toStdString(); +// LOG_TRACE(QString("查询SYS_PERSON表的所有记录[%1]").arg(count).toStdString()); + + return result; +} + +QVariantMap SysPersonDao::findRecordById(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0' AND SYS_PERSON.ID = '%1'").arg(id); + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVariantMap result; + + // 获取结果集的大小 + query.last(); + int count = query.at() + 1; + + if (count >=1) + { + query.first(); + + result.insert("id", query.value("id").toString()); + result.insert("delflag", query.value("delflag").toString()); + result.insert("createtime", query.value("createtime").toString()); + result.insert("updatetime", query.value("updatetime").toString()); + result.insert("name", query.value("name").toString()); + result.insert("gender", query.value("gender").toString()); + result.insert("deptid", query.value("deptid").toString()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("remarks", query.value("remarks").toString()); + result.insert("person_code", query.value("person_code").toString()); + result.insert("deptname", query.value("fullname").toString()); + result.insert("sync_id", query.value("sync_id").toString()); + result.insert("hasFace", query.value("face_valid").toString()); + result.insert("hasIris", query.value("iris_valid").toString()); + } + +// LOG(TRACE) << QString("根据id查询SYS_PERSON表的记录[id=%1][%2]").arg(id).arg(sql).toStdString(); +// LOG_TRACE(QString("根据id查询SYS_PERSON表的记录[id=%1][%2]").arg(id).arg(sql).toStdString()); + + return result; +} + +int SysPersonDao::findRecordCountByNameAndDept(QString name, QString dept) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT COUNT(P.ID) AS RECCT FROM SYS_PERSON P LEFT JOIN SYS_DEPT D ON P.DEPTID = D.ID WHERE P.DELFLAG = '0'"; + if (name.isEmpty() == false) + { + sql += " AND P.NAME LIKE '%" + name + "%'"; + } + if (dept.isEmpty() == false && dept.indexOf("-1") < 0) + { + sql += QString(" AND ((P.DEPTID = '%1') OR (D.PIDS LIKE '%,%1,%'))").arg(dept); + } + + // 执行查询 + query.exec(sql); + + // 返回结果 + int result; + + // 遍历查询结果 + if (query.next()) { + result = query.value("RECCT").toInt(); + } + +// LOG(TRACE) << QString("根据姓名和部门查询SYS_PERSON记录总数[%1][%2]").arg(result).arg(sql).toStdString(); +// LOG_TRACE(QString("根据姓名和部门查询SYS_PERSON记录总数[%1][%2]").arg(result).arg(sql).toStdString()); + + return result; +} + +QVector SysPersonDao::findRecordsByNameAndDept(QString name, QString dept, qint8 limit, qint16 offset) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON P LEFT JOIN SYS_DEPT D ON P.DEPTID = D.ID WHERE P.DELFLAG = '0'"; + if (name.isEmpty() == false) + { + sql += " AND P.NAME LIKE '%" + name + "%'"; + } + if (dept.isEmpty() == false && dept.indexOf("-1") < 0) + { + sql += QString(" AND ((P.DEPTID = '%1') OR (D.PIDS LIKE '%,%1,%'))").arg(dept); + } + + sql += QString(" LIMIT %1 OFFSET %2").arg(limit).arg(offset); + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + count++; + + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + + result.append(item); + } + +// LOG(TRACE) << QString("根据姓名和部门分页查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString(); +// LOG_TRACE(QString("根据姓名和部门分页查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString()); + + return result; +} + +QVector SysPersonDao::findRecordsByProperties(QVariantMap conditions) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0'"; + QVariantMap::iterator it; + for (it = conditions.begin(); it != conditions.end(); it++) + { + sql += QString(" AND SYS_PERSON.%1 = %2").arg(it.key()).arg(it.value().toString()); + } + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + count++; + + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + + result.append(item); + } + +// LOG(TRACE) << QString("根据属性值查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString(); +// LOG_TRACE(QString("根据属性值查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString()); + + return result; +} + +QString SysPersonDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + + // INSERT语句 + QString sql = QString("INSERT INTO SYS_PERSON " + "(ID, DELFLAG, CREATETIME, UPDATETIME, " + "NAME, GENDER, DEPTID, ID_CARD_NO, " + "REMARKS, PERSON_CODE, SYNC_ID, FACE_VALID, IRIS_VALID) " + "VALUES ('%1', '0', '%2', '%2', '%3', '%4', '%5', '%6', '%7', '%8', '%9', 0, 0)") + .arg(id).arg(tm) + .arg(object.value("name").toString()) + .arg(object.value("gender").toString()) + .arg(object.value("deptid").toString()) + .arg(object.value("id_card_no").toString()) + .arg(object.value("remarks").toString()) + .arg(object.value("person_code").toString()) + .arg(object.value("sync_id").toString()); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(sql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { +// LOG(DEBUG) << QString("保存SYS_PERSON记录成功[ID = %1][%2]").arg(id).arg(sql).toStdString(); +// LOG_DEBUG(QString("保存SYS_PERSON记录成功[ID = %1][%2]").arg(id).arg(sql).toStdString()); + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool SysPersonDao::edit(QVariantMap newObject, QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + + // UPDATE语句 + QString sql = QString("UPDATE SYS_PERSON SET UPDATETIME = '%1'").arg(tm); + if (newObject.contains("name")) + { + sql.append(QString(", NAME = '%1'").arg(newObject.value("name").toString())); + } + if (newObject.contains("gender")) + { + sql.append(QString(", GENDER = '%1'").arg(newObject.value("gender").toString())); + } + if (newObject.contains("deptid")) + { + sql.append(QString(", DEPTID = '%1'").arg(newObject.value("deptid").toString())); + } + if (newObject.contains("person_code")) + { + sql.append(QString(", PERSON_CODE = '%1'").arg(newObject.value("person_code").toString())); + } + if (newObject.contains("face_valid")) + { + sql.append(QString(", FACE_VALID = '%1'").arg(newObject.value("face_valid").toString())); + } + if (newObject.contains("iris_valid")) + { + sql.append(QString(", IRIS_VALID = '%1'").arg(newObject.value("iris_valid").toString())); + } + + sql.append(QString(" WHERE ID = '%1'").arg(id)); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(sql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + +// LOG(DEBUG) << QString("编辑人员[ID=%1][%2]").arg(id).arg(sql).toStdString(); +// LOG_DEBUG(QString("编辑人员[ID=%1][%2]").arg(id).arg(sql).toStdString()); + + // 返回结果 + return success; +} + +bool SysPersonDao::dele(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + QSqlQuery irisDel(ConnectionManager::getInstance()->getConnection()); + + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + qint64 tmms = QDateTime::currentDateTime().toMSecsSinceEpoch(); + + // UPDATE语句 + QString sql = QString("UPDATE SYS_PERSON SET UPDATETIME = :updateTime, DELFLAG = :flag WHERE ID = :id").arg(tm).arg(tmms).arg(id); + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":updateTime", tm); + query.bindValue(":flag", tmms); + + // 物理删除人员的人脸和虹膜数据 + QString delIrisSql = QString("DELETE FROM IRIS_DATA WHERE PERSON_ID = :personId"); + irisDel.prepare(delIrisSql); + irisDel.bindValue(":personId", id); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(sql); + query.exec(delIrisSql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + +// LOG_DEBUG(QString("删除人员SYS_PERSON[ID=%1][%2]").arg(id).arg(success).toStdString()); + + // 返回结果 + return success; +} diff --git a/dao/SysPersonDao.h b/dao/SysPersonDao.h new file mode 100644 index 0000000..e02e5ba --- /dev/null +++ b/dao/SysPersonDao.h @@ -0,0 +1,27 @@ +#ifndef SYSPERSONDAO_H +#define SYSPERSONDAO_H + +#include +#include "BaseDao.h" + +class SysPersonDao : public BaseDao +{ + Q_OBJECT +public: + explicit SysPersonDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + int findRecordCountByNameAndDept(QString name, QString dept); + QVector findRecordsByNameAndDept(QString name, QString dept, qint8 limit, qint16 offset); + QVector findRecordsByProperties(QVariantMap conditions); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); +signals: + +}; + +#endif // SYSPERSONDAO_H diff --git a/dao/dao.pri b/dao/dao.pri new file mode 100644 index 0000000..1e04ce4 --- /dev/null +++ b/dao/dao.pri @@ -0,0 +1,18 @@ + +HEADERS += $$PWD/BaseDao.h +HEADERS += $$PWD/IrisDataDao.h +HEADERS += $$PWD/RecognitionRecordsDao.h +HEADERS += $$PWD/SysPersonDao.h +HEADERS += $$PWD/SysDeptDao.h + +SOURCES += $$PWD/BaseDao.cpp +SOURCES += $$PWD/IrisDataDao.cpp +SOURCES += $$PWD/RecognitionRecordsDao.cpp +SOURCES += $$PWD/SysPersonDao.cpp +SOURCES += $$PWD/SysDeptDao.cpp + +HEADERS += $$PWD/util/ConnectionManager.h +SOURCES += $$PWD/util/ConnectionManager.cpp +#HEADERS += $$PWD/util/CacheManager.h +#SOURCES += $$PWD/util/CacheManager.cpp + diff --git a/dao/util/ConnectionManager.cpp b/dao/util/ConnectionManager.cpp new file mode 100644 index 0000000..84b17be --- /dev/null +++ b/dao/util/ConnectionManager.cpp @@ -0,0 +1,47 @@ +#include "ConnectionManager.h" +#include + +Q_GLOBAL_STATIC(ConnectionManager, cm) + +ConnectionManager::ConnectionManager(QObject *parent) : QObject(parent) +{ + // 初始化数据库连接 + if (QSqlDatabase::contains("qt_sql_dafault_connection")) + { + conn = QSqlDatabase::database("qt_sql_default_connection"); + } + else + { + conn = QSqlDatabase::addDatabase("QSQLITE"); + conn.setDatabaseName(QApplication::applicationDirPath() + "/data/casic.db"); + + bool succ = conn.open(); + if (succ == true) + { +// LOG_INFO(QString("打开数据库操作正常[Open Database Success]").toStdString()); + } else + { +// LOG_ERROR(QString("打开数据库操作失败[Open Database Failed]").toStdString()); + } + } +} + +ConnectionManager::~ConnectionManager() +{ + conn.close(); +} + +ConnectionManager* ConnectionManager::getInstance() +{ + return cm; +} + +QSqlDatabase ConnectionManager::getConnection() +{ + return this->conn; +} + +qint64 ConnectionManager::generateId() +{ + return this->idWorker.nextId(); +} diff --git a/dao/util/ConnectionManager.h b/dao/util/ConnectionManager.h new file mode 100644 index 0000000..84647e3 --- /dev/null +++ b/dao/util/ConnectionManager.h @@ -0,0 +1,34 @@ +#ifndef CONNECTIONMANAGER_H +#define CONNECTIONMANAGER_H + +#include +#include +#include "utils/id/IdWorker.h" +#include "utils/UtilInclude.h" + +using namespace Jiawa::Core; + +class ConnectionManager : public QObject +{ + Q_OBJECT +public: + explicit ConnectionManager(QObject *parent = nullptr); + ~ConnectionManager(); + + static ConnectionManager * getInstance(); + + QSqlDatabase getConnection(); + qint64 generateId(); + +private: + // 数据库连接 + QSqlDatabase conn; + + // 雪花id生成工具 + IdWorker &idWorker = Singleton::instance(); + +signals: + +}; + +#endif // CONNECTIONMANAGER_H diff --git a/device/IrisCameraCapEventHandler.cpp b/device/IrisCameraCapEventHandler.cpp new file mode 100644 index 0000000..45df089 --- /dev/null +++ b/device/IrisCameraCapEventHandler.cpp @@ -0,0 +1,103 @@ +#include "IrisCameraCapEventHandler.h" + +IrisCameraCapEventHandler::IrisCameraCapEventHandler(QObject *parent) : QObject(parent) +{ + +} + +void IrisCameraCapEventHandler::DoOnImageCaptured(CImageDataPointer &objImageDataPointer, void *pUserParam) +{ + if (objImageDataPointer.IsNull() == false) + { + CGXDevicePointer* cam = (CGXDevicePointer *) pUserParam; + + auto camName = cam->getPtr()->GetDeviceInfo().GetUserID(); + int width = objImageDataPointer->GetWidth(); + int height = objImageDataPointer->GetHeight(); + size_t leftKeyIndex = camName.find("left"); + size_t rightKeyIndex = camName.find("right"); + + uchar * pBuffer = (BYTE*)objImageDataPointer->GetBuffer(); + + // 相机拍摄下的图像1440*1080, 直接用于算法判断 + QImage img = QImage(pBuffer, width, height, QImage::Format_Grayscale8); // 用于展示 +// QImage imgAlgo = img.copy(0, 0, width, height); + + // 用于显示的图像需要缩小到400 * 300的尺寸 + img = img.scaled(SettingConfig::getInstance().IRIS_DISPLAY_HEIGHT, SettingConfig::getInstance().IRIS_DISPLAY_WIDTH); + img = img.transformed(QTransform().rotate(-90)); // 图像逆时针旋转90度 + + // 发送到界面进行显示 + emit sendIrisFrameToDraw(img); +// cv::Mat irisMat = ImageUtil::QImageToMat(imgAlgo); + +// irisInfo.data = imgAlgo; +// irisInfo.matData = irisMat; + +// // 将图像显示在注册页面的label上 +// // 并将虹膜信息对象存入队列中 +// ProMemory::getInstance().pushCasicIris(irisInfo); + +// if (leftKeyIndex >= 0 && leftKeyIndex < 32) +// { +// emit sendIrisFrameToDraw(img, 0); // 左眼画面 +// } else if (rightKeyIndex >= 0 && rightKeyIndex < 32) +// { +// emit sendIrisFrameToDraw(img, 1); // 右眼画面 +// } +/* + if (pBuffer != NULL) + { + // 创建虹膜信息对象 + CasicIrisInfo irisInfo; + irisInfo.hasEye = false; + if (leftKeyIndex >= 0 && leftKeyIndex < 32) + { + // 左眼相机拍摄的图像 + irisInfo.leftOrRight = "left"; + } else if (rightKeyIndex >= 0 && rightKeyIndex < 32) + { + // 右眼相机 + irisInfo.leftOrRight = "right"; + } + + if (ProMemory::getInstance().widgeFrame == CasicBioRecConst::RECOGNIZE_RESULT_FORM) + { + // 相机拍摄下的图像1280*960, 直接用于算法判断 + QImage imgDisp = QImage(pBuffer, width, height, QImage::Format_Grayscale8); + cv::Mat irisMat = ImageUtil::QImageToMat(imgDisp); + + irisInfo.data = imgDisp; + irisInfo.matData = irisMat; + + ProMemory::getInstance().pushCasicIris(irisInfo); + +// cv::imwrite(QString("D:\\irisLogs\\iristest-%1.bmp").arg(irisInfo.leftOrRight).toStdString(), irisMat); + } else if (ProMemory::getInstance().widgeFrame == CasicBioRecConst::ADD_PERSON_CAPTURE_IRIS) + { + // 相机拍摄下的图像1280*960, 直接用于算法判断 + QImage img = QImage(pBuffer, width, height, QImage::Format_Grayscale8); + QImage imgAlgo = img.copy(0, 0, width, height); + + // 用于显示的图像需要缩小到1/4的尺寸 + img = img.scaled(640, 480); + cv::Mat irisMat = ImageUtil::QImageToMat(imgAlgo); + + irisInfo.data = imgAlgo; + irisInfo.matData = irisMat; + + // 将图像显示在注册页面的label上 + // 并将虹膜信息对象存入队列中 + ProMemory::getInstance().pushCasicIris(irisInfo); + + if (leftKeyIndex >= 0 && leftKeyIndex < 32) + { + emit sendIrisFrameToDraw(img, 0); // 左眼画面 + } else if (rightKeyIndex >= 0 && rightKeyIndex < 32) + { + emit sendIrisFrameToDraw(img, 1); // 右眼画面 + } + } + }*/ + } +} diff --git a/device/IrisCameraCapEventHandler.h b/device/IrisCameraCapEventHandler.h new file mode 100644 index 0000000..ad75a97 --- /dev/null +++ b/device/IrisCameraCapEventHandler.h @@ -0,0 +1,30 @@ +#ifndef IRISCAMERACAPEVENTHANDLER_H +#define IRISCAMERACAPEVENTHANDLER_H + +#include +#include +#include "include/opencv2/opencv.hpp" +#include "include/daheng/GalaxyIncludes.h" + +//#include "casic/iris/CasicIrisInterface.h" +#include "ProMemory.h" + +#include "utils/UtilInclude.h" + +class IrisCameraCapEventHandler : public QObject, public ICaptureEventHandler +{ + Q_OBJECT +public: + explicit IrisCameraCapEventHandler(QObject *parent = nullptr); + + void DoOnImageCaptured(CImageDataPointer &objImageDataPointer, void *pUserParam); + +private: + unsigned char* pImageBuffer; + +signals: + void sendIrisFrameToDraw(QImage irisImage); + +}; + +#endif // IRISCAMERACAPEVENTHANDLER_H diff --git a/AppConstants.h b/AppConstants.h new file mode 100644 index 0000000..296c53f --- /dev/null +++ b/AppConstants.h @@ -0,0 +1,28 @@ +#ifndef APPCONSTANTS_H +#define APPCONSTANTS_H + +class AppConstants +{ +public: + enum WidgeFrameName + { + MAIN_PAGE = 0, // 主页面 + PERSON_LIST_FORM = 1, // 人员列表页面 + ADD_PERSON_FORM = 2, // 添加人员页面 + ADD_PERSON_CAPTURE_FACE = 21, // 添加/编辑人员时进行人脸拍图 + ADD_PERSON_CAPTURE_IRIS = 22, // 添加/编辑人员时进行虹膜拍图 + SETTING_FORM = 3, // 设置页面 + RECOGNIZE_RESULT_FORM = 4, // 识别结果界面 + IDENTIFY_FORM = 5, // 识别界面 含识别中 和 识别结果 + LOCKSCREEN_FORM = 6 // 锁屏待机界面 + }; + + enum ApplicationState + { + STATE_WAIT = 0, // 待机 + STATE_WORKING = 1, // 工作状态 + STATE_IDENTIFYING = 2, // 识别中 + }; +}; + +#endif // APPCONSTANTS_H diff --git a/CasicIrisIdentify.pro b/CasicIrisIdentify.pro index 5d7fea6..575ce3d 100644 --- a/CasicIrisIdentify.pro +++ b/CasicIrisIdentify.pro @@ -1,4 +1,4 @@ -QT += core gui +QT += core gui sql network texttospeech greaterThan(QT_MAJOR_VERSION, 4): QT += widgets @@ -15,20 +15,46 @@ # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 -SOURCES += \ - main.cpp \ - IdentifyForm.cpp +include("dao/dao.pri") +include("device/device.pri") +include("utils/utils.pri") -HEADERS += \ - IdentifyForm.h +SOURCES += main.cpp +SOURCES += ProMemory.cpp +SOURCES += MainWindowForm.cpp +SOURCES += IdentifyForm.cpp +SOURCES += LockScreenForm.cpp -FORMS += \ - IdentifyForm.ui +HEADERS += AppConstants.h +HEADERS += ProMemory.h +HEADERS += MainWindowForm.h +HEADERS += IdentifyForm.h +HEADERS += LockScreenForm.h -TRANSLATIONS += \ - CasicIrisIdentify_zh_CN.ts +FORMS += MainWindowForm.ui +FORMS += IdentifyForm.ui +FORMS += LockScreenForm.ui + +RESOURCES += resource.qrc + +DISTFILES += conf/config.ini + +#TRANSLATIONS += CasicIrisIdentify_zh_CN.ts + +#INCLUDEPATH += include/spdlog +#DEPENDPATH += include/spdlog # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target + + +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lopencv_world420 +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lGxIAPICPPEx + +INCLUDEPATH += $$PWD/include/daheng +DEPENDPATH += $$PWD/include/daheng + +INCLUDEPATH += $$PWD/include +DEPENDPATH += $$PWD/include diff --git a/CasicIrisIdentify_zh_CN.ts b/CasicIrisIdentify_zh_CN.ts index 5526fe4..81900df 100644 --- a/CasicIrisIdentify_zh_CN.ts +++ b/CasicIrisIdentify_zh_CN.ts @@ -1,3 +1,12 @@ - + + + IdentifyForm + + + IdentifyForm + + + + diff --git a/IdentifyForm.cpp b/IdentifyForm.cpp index 348a897..ba1f251 100644 --- a/IdentifyForm.cpp +++ b/IdentifyForm.cpp @@ -1,4 +1,4 @@ -#include "IdentifyForm.h" +#include "IdentifyForm.h" #include "ui_IdentifyForm.h" IdentifyForm::IdentifyForm(QWidget *parent) @@ -6,6 +6,12 @@ , ui(new Ui::IdentifyForm) { ui->setupUi(this); + + // 初始化更新界面的定时器 + // 每秒执行一次 + connect(TimeCounterUtil::getInstance().clockCounter, &QTimer::timeout, this, &IdentifyForm::updateDateAndTime); + + TimeCounterUtil::getInstance().clockCounter->start(1000); } IdentifyForm::~IdentifyForm() @@ -13,3 +19,16 @@ delete ui; } +void IdentifyForm::drawIrisImageOnFrame(QImage image) +{ + // 只在识别界面才显示画面 + if (ui->wgtStacked->currentIndex() == 0) { + ui->labelVideo->setPixmap(QPixmap::fromImage(image)); + } +} + + +void IdentifyForm::updateDateAndTime() +{ + ui->labelTime->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd dddd HH:mm:ss")); +} diff --git a/IdentifyForm.h b/IdentifyForm.h index fc857a1..ae1cd22 100644 --- a/IdentifyForm.h +++ b/IdentifyForm.h @@ -1,7 +1,10 @@ -#ifndef IDENTIFYFORM_H +#ifndef IDENTIFYFORM_H #define IDENTIFYFORM_H #include +#include + +#include "utils/UtilInclude.h" QT_BEGIN_NAMESPACE namespace Ui { class IdentifyForm; } @@ -15,7 +18,14 @@ IdentifyForm(QWidget *parent = nullptr); ~IdentifyForm(); +public slots: + void drawIrisImageOnFrame(QImage image); + private: Ui::IdentifyForm *ui; + +private slots: + void updateDateAndTime(); + }; #endif // IDENTIFYFORM_H diff --git a/IdentifyForm.ui b/IdentifyForm.ui index c72a36f..879dc9a 100644 --- a/IdentifyForm.ui +++ b/IdentifyForm.ui @@ -6,13 +6,59 @@ 0 0 - 800 + 600 600 IdentifyForm + + + + 0 + 40 + 600 + 450 + + + + 0 + + + + + + 100 + 10 + 400 + 300 + + + + + + + + + + + + + + 0 + 0 + 600 + 40 + + + + TextLabel + + + Qt::AlignCenter + + diff --git a/LockScreenForm.cpp b/LockScreenForm.cpp new file mode 100644 index 0000000..58dc54b --- /dev/null +++ b/LockScreenForm.cpp @@ -0,0 +1,14 @@ +#include "LockScreenForm.h" +#include "ui_LockScreenForm.h" + +LockScreenForm::LockScreenForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::LockScreenForm) +{ + ui->setupUi(this); +} + +LockScreenForm::~LockScreenForm() +{ + delete ui; +} diff --git a/LockScreenForm.h b/LockScreenForm.h new file mode 100644 index 0000000..b5ded48 --- /dev/null +++ b/LockScreenForm.h @@ -0,0 +1,25 @@ +#ifndef LOCKSCREENFORM_H +#define LOCKSCREENFORM_H + +#include +#include + +#include "utils/UtilInclude.h" + +namespace Ui { +class LockScreenForm; +} + +class LockScreenForm : public QWidget +{ + Q_OBJECT + +public: + explicit LockScreenForm(QWidget *parent = nullptr); + ~LockScreenForm(); + +private: + Ui::LockScreenForm *ui; +}; + +#endif // LOCKSCREENFORM_H diff --git a/LockScreenForm.ui b/LockScreenForm.ui new file mode 100644 index 0000000..7f2a6db --- /dev/null +++ b/LockScreenForm.ui @@ -0,0 +1,45 @@ + + + LockScreenForm + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + 180 + 100 + 54 + 12 + + + + TextLabel + + + + + + 180 + 160 + 54 + 12 + + + + TextLabel + + + + + + diff --git a/MainWindowForm.cpp b/MainWindowForm.cpp new file mode 100644 index 0000000..84f8159 --- /dev/null +++ b/MainWindowForm.cpp @@ -0,0 +1,86 @@ +#include "MainWindowForm.h" +#include "ui_MainWindowForm.h" +#include + +MainWindowForm::MainWindowForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::MainWindowForm) +{ + ui->setupUi(this); + + // 设置窗口透明和大小、位置 + this->setWindowFlags(Qt::FramelessWindowHint); + this->move(1400, 15); + this->resize(SettingConfig::getInstance().WINDOW_WIDTH, SettingConfig::getInstance().WINDOW_HEIGHT); + + // 通过调色板的颜色来设置窗口的统一背景色 + qApp->setPalette(QPalette(QColor(SettingConfig::getInstance().WINDOW_BACKGROUND_COLOR))); + + // 加载css文件设置控件样式 + QFile file(QApplication::applicationDirPath() + "/qss/main.css"); + if (file.open(QFile::ReadOnly)) + { + QString qssStr = QLatin1String(file.readAll()); + this->setStyleSheet(qssStr); + file.close(); + } + + initFormsPtr(); + + // 设置标题文字 + ui->labelTitle->setText(SettingConfig::getInstance().WINDOW_TITLE); + ui->labelCopyright->setText(SettingConfig::getInstance().WINDOW_RIGHTS); + ui->labelVersion->setText(SettingConfig::getInstance().WINDOW_VERSION); + + // 初始化虹膜相机控制 + ProMemory::getInstance().irisCam = new IrisCameraController(this); + ProMemory::getInstance().irisCam->initIrisCamera(); + ProMemory::getInstance().irisCam->openIrisCamera(); + connect(ProMemory::getInstance().irisCam->irisCamHandler, &IrisCameraCapEventHandler::sendIrisFrameToDraw, identifyForm, &IdentifyForm::drawIrisImageOnFrame); + +// LOG_INFO(QString("应用程序启动成功[Application Startup Success]").toStdString()); + qDebug() << "应用程序启动成功[Application Startup Success]"; + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::IDENTIFY_FORM; + ui->wdgtStatced->setCurrentWidget(identifyForm); + + // 开始虹膜相机拍图 + ProMemory::getInstance().irisCam->startCapture(); +} + +MainWindowForm::~MainWindowForm() +{ + delete ui; +} + +void MainWindowForm::lockScreen() +{ + ui->wdgtStatced->setCurrentWidget(lockScreenForm); + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::LOCKSCREEN_FORM; + ProMemory::getInstance().appState = AppConstants::ApplicationState::STATE_WAIT; +} + +void MainWindowForm::keyPressEvent(QKeyEvent *event) +{ + switch (event->key()) { + case Qt::Key_Escape: + QTimer::singleShot(100, qApp, [=](){ + QApplication::quit(); + }); + + default: + QWidget::keyPressEvent(event); + } +} + +void MainWindowForm::initFormsPtr() +{ + // 初始化各个form + lockScreenForm = new LockScreenForm(this); + identifyForm = new IdentifyForm(this); + + // 将form添加到statcked widget中 + ui->wdgtStatced->addWidget(identifyForm); + ui->wdgtStatced->addWidget(lockScreenForm); + + // 绑定按钮函数 +} diff --git a/MainWindowForm.h b/MainWindowForm.h new file mode 100644 index 0000000..7fb2d89 --- /dev/null +++ b/MainWindowForm.h @@ -0,0 +1,38 @@ +#ifndef MAINWINDOWFORM_H +#define MAINWINDOWFORM_H + +#include +#include +#include + +#include "utils/UtilInclude.h" +#include "ProMemory.h" +#include "LockScreenForm.h" +#include "IdentifyForm.h" + +namespace Ui { +class MainWindowForm; +} + +class MainWindowForm : public QWidget +{ + Q_OBJECT + +public: + explicit MainWindowForm(QWidget *parent = nullptr); + ~MainWindowForm(); + +public slots: + void lockScreen(); + +private: + Ui::MainWindowForm *ui; + LockScreenForm * lockScreenForm; + IdentifyForm * identifyForm; + + void keyPressEvent(QKeyEvent *event); + + void initFormsPtr(); +}; + +#endif // MAINWINDOWFORM_H diff --git a/MainWindowForm.ui b/MainWindowForm.ui new file mode 100644 index 0000000..e793ebf --- /dev/null +++ b/MainWindowForm.ui @@ -0,0 +1,85 @@ + + + MainWindowForm + + + + 0 + 0 + 600 + 1024 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + 0 + 0 + 600 + 84 + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + + + + TextLabel + + + Qt::AlignBottom|Qt::AlignHCenter + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + diff --git a/ProMemory.cpp b/ProMemory.cpp new file mode 100644 index 0000000..19e7403 --- /dev/null +++ b/ProMemory.cpp @@ -0,0 +1,84 @@ +#include "ProMemory.h" + +ProMemory::ProMemory() +{ + +} + +ProMemory::~ProMemory() +{ + +} + +/* +void ProMemory::pushCasicIris(CasicIrisInfo irisInfo) +{ + QMutex mutex; + mutex.lock(); + if (this->irisQueue.size() > 30) + { + QStack empty; + std::swap(empty, irisQueue); + } + + irisQueue.push(irisInfo); + mutex.unlock(); +} +CasicIrisInfo ProMemory::popCasicIris() +{ + CasicIrisInfo result; + + QMutex mutex; + mutex.lock(); + if (this->irisQueue.size() > 0) + { + result = irisQueue.pop(); + } + + mutex.unlock(); + + return result; +} +*/ +int ProMemory::getIrisQueueSize() +{ + int size = 0; + + QMutex mutex; + mutex.lock(); + +// size = this->irisQueue.size(); + + mutex.unlock(); + + return size; +} +bool ProMemory::isIrisQueueEmpty() +{ + bool empty = true; + + QMutex mutex; + mutex.lock(); + +// empty = this->irisQueue.isEmpty(); + + mutex.unlock(); + + return empty; +} +void ProMemory::clearIrisQueue() +{ + QMutex mutex; + mutex.lock(); + +// QStack empty; +// std::swap(empty, irisQueue); + + mutex.unlock(); +} + + +void ProMemory::initIrisFeatures(QString personId) +{ +// irisRegistPro->sendDataToExract(QByteArray(QString("[-u]").append(personId).toLocal8Bit())); +} diff --git a/ProMemory.h b/ProMemory.h new file mode 100644 index 0000000..2ecd653 --- /dev/null +++ b/ProMemory.h @@ -0,0 +1,52 @@ +#ifndef PROMEMORY_H +#define PROMEMORY_H + +#include +#include + +#include "AppConstants.h" +//#include "casic/iris/CasicIrisInfo.h" +#include "dao/IrisDataDao.h" + +#include "device/IrisCameraController.h" +//#include "device/iris/IrisRegistProcess.h" +//#include "device/iris/IrisRecogProcess.h" + +class IrisCameraController; +class IrisRegistProcess; +class IrisRecogProcess; + +class ProMemory +{ +public: + ~ProMemory(); + ProMemory(const ProMemory&)=delete; + ProMemory& operator=(const ProMemory&)=delete; + + static ProMemory& getInstance() { + static ProMemory instance; + return instance; + } + +// void pushCasicIris(CasicIrisInfo irisInfo); +// CasicIrisInfo popCasicIris(); + int getIrisQueueSize(); + bool isIrisQueueEmpty(); + void clearIrisQueue(); + + volatile int widgeFrame = 0; // 当前显示的界面 + volatile int appState = 0; // 当前程序所处的状态 + + void initIrisFeatures(QString personId = ""); // 初始化虹膜特征值集合 + + IrisCameraController * irisCam; + IrisRecogProcess * irisRecogPro; + +private: + ProMemory(); + +// QStack irisQueue; // 虹膜信息队列 + QVector irisFeatures; // 虹膜特征值集合 +}; + +#endif // PROMEMORY_H diff --git a/conf/config.ini b/conf/config.ini new file mode 100644 index 0000000..66e46ad --- /dev/null +++ b/conf/config.ini @@ -0,0 +1,67 @@ +[recognize] +#最大允许识别时间(ms) +maxMatchTime=10000 +#识别成功界面停留时间(ms) +successTipsLast=5000 +#识别失败界面停留时间(ms) +failureTipsLast=3000 +#人脸识别最大尝试次数 +maxFaceTryCount=20 +#持续没找到人脸的最大次数 +maxFaceNotFoundCount=500 +#注册时最小人脸 +minFaceRegist=240 +#识别时最小人脸 +minFaceRecog=100 + +#虹膜识别最大尝试次数 +maxIrisTryCount=10 +#虹膜识别持续没有找到眼的最大次数 +maxEyeNotFoundCount=50 + +#识别方式[1=人脸;2=虹膜;3=双认证;4=任意] +recogType=4 + +[window] +#界面窗口宽(px) +width=600 +#界面窗口高(px) +height=1024 +#统一背景色 +backgroundColor="#FFFFFF" +#标题 +title="虹膜识别终端" + +[work] +#工作状态检测时最小人脸范围 +minFaceSize=160 +#人脸范围最小横坐标 +minFacePosX=320 +#人脸范围最大横坐标 +maxFacePosX=960 +#人脸范围最小纵坐标 +minFacePosY=180 +#人脸范围最大纵坐标 +maxFacePosY=540 +#人脸太近阈值 +faceCloseSize=360 +#人脸太远阈值 +faceFarSize=480 + +[camera] +#虹膜相机取一幅画面的时间间隔(ms) +irisFrameInterval=100 +#虹膜相机拍摄宽度 +irisFrameWidth=1440 +#虹膜相机拍摄高度 +irisFrameHeight=1080 +#虹膜图像高度 +irisWidth=640 +#虹膜图像高度 +irisHeight=480 + +[log] +#日志文件位置 +logFile="d://irisLogs//casic_log.txt" +#日志级别 +logLevel="trace" diff --git a/dao/BaseDao.cpp b/dao/BaseDao.cpp new file mode 100644 index 0000000..f51c144 --- /dev/null +++ b/dao/BaseDao.cpp @@ -0,0 +1,12 @@ +#include "BaseDao.h" +#include "dao/util/ConnectionManager.h" + +BaseDao::BaseDao(QObject *parent) : QObject(parent) +{ + +} + +BaseDao::~BaseDao() +{ + +} diff --git a/dao/BaseDao.h b/dao/BaseDao.h new file mode 100644 index 0000000..1693c88 --- /dev/null +++ b/dao/BaseDao.h @@ -0,0 +1,32 @@ +#ifndef BASEDAO_H +#define BASEDAO_H + +#include +#include +#include +#include + +#include "dao/util/ConnectionManager.h" +#include "utils/UtilInclude.h" + +class BaseDao : public QObject +{ + Q_OBJECT +public: + explicit BaseDao(QObject *parent = nullptr); + ~BaseDao(); + + virtual QVector findAllRecord() = 0; + virtual QVariantMap findRecordById(QString id) = 0; + + virtual QString save(QVariantMap object) = 0; + virtual bool edit(QVariantMap newObject, QString id) = 0; + virtual bool dele(QString id) = 0; + +private: + +signals: + +}; + +#endif // BASEDAO_H diff --git a/dao/IrisDataDao.cpp b/dao/IrisDataDao.cpp new file mode 100644 index 0000000..37a0ed6 --- /dev/null +++ b/dao/IrisDataDao.cpp @@ -0,0 +1,204 @@ +#include "IrisDataDao.h" + +IrisDataDao::IrisDataDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector IrisDataDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM IRIS_DATA"; + query.prepare(sql); + + // 执行查询 + query.exec(); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + item.insert("id", query.value("id").toString()); + item.insert("person_id", query.value("person_id").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("left_iris_code1", query.value("left_iris_code1")); + item.insert("left_iris_code2", query.value("left_iris_code2")); + item.insert("left_iris_code3", query.value("left_iris_code3")); + item.insert("right_iris_code1", query.value("right_iris_code1")); + item.insert("right_iris_code2", query.value("right_iris_code2")); + item.insert("right_iris_code3", query.value("right_iris_code3")); + + result.append(item); + } + +// LOG_DEBUG(QString("查询IRIS_DATA表的所有记录[结果数:%1]").arg(result.size()).toStdString()); + return result; +} + +QVariantMap IrisDataDao::findRecordById(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM IRIS_DATA WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + // 获取结果 + if (query.next()) + { + result.insert("id", query.value("id").toString()); + result.insert("person_id", query.value("person_id").toLongLong()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("left_iris_code1", query.value("left_iris_code1")); + result.insert("left_iris_code2", query.value("left_iris_code2")); + result.insert("left_iris_code3", query.value("left_iris_code3")); + result.insert("right_iris_code1", query.value("right_iris_code1")); + result.insert("right_iris_code2", query.value("right_iris_code2")); + result.insert("right_iris_code3", query.value("right_iris_code3")); + } + +// LOG_DEBUG(QString("根据id查询IRIS_DATA表的记录[id=%1]").arg(id).toStdString()); + return result; +} + +QVariantMap IrisDataDao::findRecordByPersonId(QString personId) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM IRIS_DATA WHERE PERSON_ID = :personId"); + query.prepare(sql); + query.bindValue(":personId", personId); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + if (query.next()) + { + result.insert("id", query.value("id").toString()); + result.insert("person_id", query.value("person_id").toLongLong()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("left_iris_code1", query.value("left_iris_code1")); + result.insert("left_iris_code2", query.value("left_iris_code2")); + result.insert("left_iris_code3", query.value("left_iris_code3")); + result.insert("right_iris_code1", query.value("right_iris_code1")); + result.insert("right_iris_code2", query.value("right_iris_code2")); + result.insert("right_iris_code3", query.value("right_iris_code3")); + } + +// LOG_DEBUG(QString("根据personId查询IRIS_DATA表的记录[personId=%1]").arg(personId).toStdString()); + return result; +} + + +QString IrisDataDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + + // INSERT语句 + QString sql = QString("INSERT INTO IRIS_DATA (ID, PERSON_ID, ID_CARD_NO, LEFT_IRIS_CODE1, RIGHT_IRIS_CODE1) VALUES (:id, :personId, :idCardNo, :left1, :right1)"); + + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":personId", object.value("person_id").toString()); + query.bindValue(":idCardNo", object.value("id_card_no").toString()); + query.bindValue(":left1", object.value("left_iris_code1")); + query.bindValue(":right1", object.value("right_iris_code1")); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(); + +// LOG_DEBUG(QString("保存虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool IrisDataDao::edit(QVariantMap newObject, QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // UPDATE语句 + if (!newObject.contains("left_iris_code1") || !newObject.contains("right_iris_code1")){ + return false; + } + QString sql = QString("UPDATE IRIS_DATA SET LEFT_IRIS_CODE1 = :left1, RIGHT_IRIS_CODE1 = :right1 WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":left1", newObject.value("left_iris_code1")); + query.bindValue(":right1", newObject.value("right_iris_code1")); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(); + +// LOG_DEBUG(QString("编辑虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; +} + + +bool IrisDataDao::dele(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + QString sql = QString("DELETE FROM IRIS_DATA WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(); + +// LOG_DEBUG(QString("删除虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; +} diff --git a/dao/IrisDataDao.h b/dao/IrisDataDao.h new file mode 100644 index 0000000..c74dbbd --- /dev/null +++ b/dao/IrisDataDao.h @@ -0,0 +1,25 @@ +#ifndef IRISDATADAO_H +#define IRISDATADAO_H + +#include +#include "BaseDao.h" + +class IrisDataDao : public BaseDao +{ + Q_OBJECT +public: + explicit IrisDataDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + QVariantMap findRecordByPersonId(QString personId); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +signals: + +}; + +#endif // IRISDATADAO_H diff --git a/dao/RecognitionRecordsDao.cpp b/dao/RecognitionRecordsDao.cpp new file mode 100644 index 0000000..40db453 --- /dev/null +++ b/dao/RecognitionRecordsDao.cpp @@ -0,0 +1,100 @@ +#include "RecognitionRecordsDao.h" + +RecognitionRecordsDao::RecognitionRecordsDao(QObject *parent) : BaseDao(parent) +{ + +} + + +QVector RecognitionRecordsDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM RECOGNITION_RECORDS"; + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + item.insert("id", query.value("id").toLongLong()); + result.append(item); + } + +// LOG_DEBUG(QString("查询RECOGNITION_RECORDS表的所有记录[记录数:%1]").arg(result.size()).toStdString()); + return result; +} + +QVariantMap RecognitionRecordsDao::findRecordById(QString id) +{ + QVariantMap item; + return item; +} + +QString RecognitionRecordsDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + + // INSERT语句 + QString sql = QString("INSERT INTO RECOGNITION_RECORDS (ID, PERSON_ID, DATETIME, REC_TYPE, DEV_CODE, DOOR_CODE, INOUT_TYPE) " + "VALUES (:id, :personId, :datetime, :recType, :devCode, :doorCode, :inoutType)"); + + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":personId", object.value("person_id").toString()); + query.bindValue(":datetime", object.value("date_time").toString()); + query.bindValue(":recType", object.value("rec_type").toString()); + query.bindValue(":devCode", object.value("dev_code").toString()); + query.bindValue(":doorCode", object.value("door_code").toString()); + query.bindValue(":inoutType", object.value("inout_type").toString()); + +// LOG_DEBUG(sql.toStdString()); + + // 插入识别的log日志 + QString logStr = QString("INSERT INTO RECOGNITION_LOGS (ID, LOG_INFO) VALUES (:id, :logInfo)"); + + QSqlQuery logQuery(ConnectionManager::getInstance()->getConnection()); + logQuery.prepare(logStr); + logQuery.bindValue(":id", id); + logQuery.bindValue(":logInfo", object.value("debug_info").toString()); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(); + logQuery.exec(); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool RecognitionRecordsDao::edit(QVariantMap newObject, QString id) +{ + return false; +} + +bool RecognitionRecordsDao::dele(QString id) +{ + return false; +} diff --git a/dao/RecognitionRecordsDao.h b/dao/RecognitionRecordsDao.h new file mode 100644 index 0000000..38de7c9 --- /dev/null +++ b/dao/RecognitionRecordsDao.h @@ -0,0 +1,23 @@ +#ifndef RECOGNITIONRECORDSDAO_H +#define RECOGNITIONRECORDSDAO_H + +#include +#include "BaseDao.h" +class RecognitionRecordsDao: public BaseDao +{ + Q_OBJECT +public: + explicit RecognitionRecordsDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +signals: + +}; + +#endif // RECOGNITIONRECORDSDAO_H diff --git a/dao/SysDeptDao.cpp b/dao/SysDeptDao.cpp new file mode 100644 index 0000000..22f9946 --- /dev/null +++ b/dao/SysDeptDao.cpp @@ -0,0 +1,88 @@ +#include "SysDeptDao.h" + +SysDeptDao::SysDeptDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector SysDeptDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_DEPT WHERE PID != '-1' ORDER BY PID, NUM"; + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + item.insert("id", query.value("id").toString()); + item.insert("pid", query.value("pid").toString()); + item.insert("pids", query.value("pids").toString()); + item.insert("simplename", query.value("simplename").toString()); + item.insert("fullname", query.value("fullname").toString()); + } + +// LOG_TRACE(QString("查询表[SYS_DEPT]的所有记录[%1][%2]").arg(result.size()).arg(sql).toStdString()); + + return result; +} + +QVariantMap SysDeptDao::findRecordById(QString id) +{ + QVariantMap item; + return item; + + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM SYS_DEPT WHERE SYS_DEPT.ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + // 获取结果集的大小 + query.last(); + int count = query.at() + 1; + + if (count >=1) + { + query.first(); + + result.insert("id", query.value("id").toString()); + result.insert("pid", query.value("pid").toString()); + result.insert("pids", query.value("pids").toString()); + result.insert("simplename", query.value("simplename").toString()); + result.insert("fullname", query.value("fullname").toString()); + } + +// LOG_TRACE(QString("根据id查询SYS_DEPT表的记录[ID=%1][%2]").arg(id).arg(sql).toStdString()); + + return result; +} + + +QString SysDeptDao::save(QVariantMap object) +{ + return "0"; +} +bool SysDeptDao::edit(QVariantMap newObject, QString id) +{ + return true; +} +bool SysDeptDao::dele(QString id) +{ + return true; +} diff --git a/dao/SysDeptDao.h b/dao/SysDeptDao.h new file mode 100644 index 0000000..e07a09f --- /dev/null +++ b/dao/SysDeptDao.h @@ -0,0 +1,24 @@ +#ifndef SYSDEPTDAO_H +#define SYSDEPTDAO_H + +#include +#include "BaseDao.h" + +class SysDeptDao : public BaseDao +{ + Q_OBJECT +public: + explicit SysDeptDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +private: + +}; + +#endif // SYSDEPTDAO_H diff --git a/dao/SysPersonDao.cpp b/dao/SysPersonDao.cpp new file mode 100644 index 0000000..dd9480f --- /dev/null +++ b/dao/SysPersonDao.cpp @@ -0,0 +1,371 @@ +#include "SysPersonDao.h" + + +SysPersonDao::SysPersonDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector SysPersonDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0'"; + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + count++; + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + result.append(item); + } + +// LOG(TRACE) << QString("查询SYS_PERSON表的所有记录[%1]").arg(count).toStdString(); +// LOG_TRACE(QString("查询SYS_PERSON表的所有记录[%1]").arg(count).toStdString()); + + return result; +} + +QVariantMap SysPersonDao::findRecordById(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0' AND SYS_PERSON.ID = '%1'").arg(id); + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVariantMap result; + + // 获取结果集的大小 + query.last(); + int count = query.at() + 1; + + if (count >=1) + { + query.first(); + + result.insert("id", query.value("id").toString()); + result.insert("delflag", query.value("delflag").toString()); + result.insert("createtime", query.value("createtime").toString()); + result.insert("updatetime", query.value("updatetime").toString()); + result.insert("name", query.value("name").toString()); + result.insert("gender", query.value("gender").toString()); + result.insert("deptid", query.value("deptid").toString()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("remarks", query.value("remarks").toString()); + result.insert("person_code", query.value("person_code").toString()); + result.insert("deptname", query.value("fullname").toString()); + result.insert("sync_id", query.value("sync_id").toString()); + result.insert("hasFace", query.value("face_valid").toString()); + result.insert("hasIris", query.value("iris_valid").toString()); + } + +// LOG(TRACE) << QString("根据id查询SYS_PERSON表的记录[id=%1][%2]").arg(id).arg(sql).toStdString(); +// LOG_TRACE(QString("根据id查询SYS_PERSON表的记录[id=%1][%2]").arg(id).arg(sql).toStdString()); + + return result; +} + +int SysPersonDao::findRecordCountByNameAndDept(QString name, QString dept) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT COUNT(P.ID) AS RECCT FROM SYS_PERSON P LEFT JOIN SYS_DEPT D ON P.DEPTID = D.ID WHERE P.DELFLAG = '0'"; + if (name.isEmpty() == false) + { + sql += " AND P.NAME LIKE '%" + name + "%'"; + } + if (dept.isEmpty() == false && dept.indexOf("-1") < 0) + { + sql += QString(" AND ((P.DEPTID = '%1') OR (D.PIDS LIKE '%,%1,%'))").arg(dept); + } + + // 执行查询 + query.exec(sql); + + // 返回结果 + int result; + + // 遍历查询结果 + if (query.next()) { + result = query.value("RECCT").toInt(); + } + +// LOG(TRACE) << QString("根据姓名和部门查询SYS_PERSON记录总数[%1][%2]").arg(result).arg(sql).toStdString(); +// LOG_TRACE(QString("根据姓名和部门查询SYS_PERSON记录总数[%1][%2]").arg(result).arg(sql).toStdString()); + + return result; +} + +QVector SysPersonDao::findRecordsByNameAndDept(QString name, QString dept, qint8 limit, qint16 offset) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON P LEFT JOIN SYS_DEPT D ON P.DEPTID = D.ID WHERE P.DELFLAG = '0'"; + if (name.isEmpty() == false) + { + sql += " AND P.NAME LIKE '%" + name + "%'"; + } + if (dept.isEmpty() == false && dept.indexOf("-1") < 0) + { + sql += QString(" AND ((P.DEPTID = '%1') OR (D.PIDS LIKE '%,%1,%'))").arg(dept); + } + + sql += QString(" LIMIT %1 OFFSET %2").arg(limit).arg(offset); + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + count++; + + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + + result.append(item); + } + +// LOG(TRACE) << QString("根据姓名和部门分页查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString(); +// LOG_TRACE(QString("根据姓名和部门分页查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString()); + + return result; +} + +QVector SysPersonDao::findRecordsByProperties(QVariantMap conditions) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0'"; + QVariantMap::iterator it; + for (it = conditions.begin(); it != conditions.end(); it++) + { + sql += QString(" AND SYS_PERSON.%1 = %2").arg(it.key()).arg(it.value().toString()); + } + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + count++; + + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + + result.append(item); + } + +// LOG(TRACE) << QString("根据属性值查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString(); +// LOG_TRACE(QString("根据属性值查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString()); + + return result; +} + +QString SysPersonDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + + // INSERT语句 + QString sql = QString("INSERT INTO SYS_PERSON " + "(ID, DELFLAG, CREATETIME, UPDATETIME, " + "NAME, GENDER, DEPTID, ID_CARD_NO, " + "REMARKS, PERSON_CODE, SYNC_ID, FACE_VALID, IRIS_VALID) " + "VALUES ('%1', '0', '%2', '%2', '%3', '%4', '%5', '%6', '%7', '%8', '%9', 0, 0)") + .arg(id).arg(tm) + .arg(object.value("name").toString()) + .arg(object.value("gender").toString()) + .arg(object.value("deptid").toString()) + .arg(object.value("id_card_no").toString()) + .arg(object.value("remarks").toString()) + .arg(object.value("person_code").toString()) + .arg(object.value("sync_id").toString()); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(sql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { +// LOG(DEBUG) << QString("保存SYS_PERSON记录成功[ID = %1][%2]").arg(id).arg(sql).toStdString(); +// LOG_DEBUG(QString("保存SYS_PERSON记录成功[ID = %1][%2]").arg(id).arg(sql).toStdString()); + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool SysPersonDao::edit(QVariantMap newObject, QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + + // UPDATE语句 + QString sql = QString("UPDATE SYS_PERSON SET UPDATETIME = '%1'").arg(tm); + if (newObject.contains("name")) + { + sql.append(QString(", NAME = '%1'").arg(newObject.value("name").toString())); + } + if (newObject.contains("gender")) + { + sql.append(QString(", GENDER = '%1'").arg(newObject.value("gender").toString())); + } + if (newObject.contains("deptid")) + { + sql.append(QString(", DEPTID = '%1'").arg(newObject.value("deptid").toString())); + } + if (newObject.contains("person_code")) + { + sql.append(QString(", PERSON_CODE = '%1'").arg(newObject.value("person_code").toString())); + } + if (newObject.contains("face_valid")) + { + sql.append(QString(", FACE_VALID = '%1'").arg(newObject.value("face_valid").toString())); + } + if (newObject.contains("iris_valid")) + { + sql.append(QString(", IRIS_VALID = '%1'").arg(newObject.value("iris_valid").toString())); + } + + sql.append(QString(" WHERE ID = '%1'").arg(id)); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(sql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + +// LOG(DEBUG) << QString("编辑人员[ID=%1][%2]").arg(id).arg(sql).toStdString(); +// LOG_DEBUG(QString("编辑人员[ID=%1][%2]").arg(id).arg(sql).toStdString()); + + // 返回结果 + return success; +} + +bool SysPersonDao::dele(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + QSqlQuery irisDel(ConnectionManager::getInstance()->getConnection()); + + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + qint64 tmms = QDateTime::currentDateTime().toMSecsSinceEpoch(); + + // UPDATE语句 + QString sql = QString("UPDATE SYS_PERSON SET UPDATETIME = :updateTime, DELFLAG = :flag WHERE ID = :id").arg(tm).arg(tmms).arg(id); + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":updateTime", tm); + query.bindValue(":flag", tmms); + + // 物理删除人员的人脸和虹膜数据 + QString delIrisSql = QString("DELETE FROM IRIS_DATA WHERE PERSON_ID = :personId"); + irisDel.prepare(delIrisSql); + irisDel.bindValue(":personId", id); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(sql); + query.exec(delIrisSql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + +// LOG_DEBUG(QString("删除人员SYS_PERSON[ID=%1][%2]").arg(id).arg(success).toStdString()); + + // 返回结果 + return success; +} diff --git a/dao/SysPersonDao.h b/dao/SysPersonDao.h new file mode 100644 index 0000000..e02e5ba --- /dev/null +++ b/dao/SysPersonDao.h @@ -0,0 +1,27 @@ +#ifndef SYSPERSONDAO_H +#define SYSPERSONDAO_H + +#include +#include "BaseDao.h" + +class SysPersonDao : public BaseDao +{ + Q_OBJECT +public: + explicit SysPersonDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + int findRecordCountByNameAndDept(QString name, QString dept); + QVector findRecordsByNameAndDept(QString name, QString dept, qint8 limit, qint16 offset); + QVector findRecordsByProperties(QVariantMap conditions); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); +signals: + +}; + +#endif // SYSPERSONDAO_H diff --git a/dao/dao.pri b/dao/dao.pri new file mode 100644 index 0000000..1e04ce4 --- /dev/null +++ b/dao/dao.pri @@ -0,0 +1,18 @@ + +HEADERS += $$PWD/BaseDao.h +HEADERS += $$PWD/IrisDataDao.h +HEADERS += $$PWD/RecognitionRecordsDao.h +HEADERS += $$PWD/SysPersonDao.h +HEADERS += $$PWD/SysDeptDao.h + +SOURCES += $$PWD/BaseDao.cpp +SOURCES += $$PWD/IrisDataDao.cpp +SOURCES += $$PWD/RecognitionRecordsDao.cpp +SOURCES += $$PWD/SysPersonDao.cpp +SOURCES += $$PWD/SysDeptDao.cpp + +HEADERS += $$PWD/util/ConnectionManager.h +SOURCES += $$PWD/util/ConnectionManager.cpp +#HEADERS += $$PWD/util/CacheManager.h +#SOURCES += $$PWD/util/CacheManager.cpp + diff --git a/dao/util/ConnectionManager.cpp b/dao/util/ConnectionManager.cpp new file mode 100644 index 0000000..84b17be --- /dev/null +++ b/dao/util/ConnectionManager.cpp @@ -0,0 +1,47 @@ +#include "ConnectionManager.h" +#include + +Q_GLOBAL_STATIC(ConnectionManager, cm) + +ConnectionManager::ConnectionManager(QObject *parent) : QObject(parent) +{ + // 初始化数据库连接 + if (QSqlDatabase::contains("qt_sql_dafault_connection")) + { + conn = QSqlDatabase::database("qt_sql_default_connection"); + } + else + { + conn = QSqlDatabase::addDatabase("QSQLITE"); + conn.setDatabaseName(QApplication::applicationDirPath() + "/data/casic.db"); + + bool succ = conn.open(); + if (succ == true) + { +// LOG_INFO(QString("打开数据库操作正常[Open Database Success]").toStdString()); + } else + { +// LOG_ERROR(QString("打开数据库操作失败[Open Database Failed]").toStdString()); + } + } +} + +ConnectionManager::~ConnectionManager() +{ + conn.close(); +} + +ConnectionManager* ConnectionManager::getInstance() +{ + return cm; +} + +QSqlDatabase ConnectionManager::getConnection() +{ + return this->conn; +} + +qint64 ConnectionManager::generateId() +{ + return this->idWorker.nextId(); +} diff --git a/dao/util/ConnectionManager.h b/dao/util/ConnectionManager.h new file mode 100644 index 0000000..84647e3 --- /dev/null +++ b/dao/util/ConnectionManager.h @@ -0,0 +1,34 @@ +#ifndef CONNECTIONMANAGER_H +#define CONNECTIONMANAGER_H + +#include +#include +#include "utils/id/IdWorker.h" +#include "utils/UtilInclude.h" + +using namespace Jiawa::Core; + +class ConnectionManager : public QObject +{ + Q_OBJECT +public: + explicit ConnectionManager(QObject *parent = nullptr); + ~ConnectionManager(); + + static ConnectionManager * getInstance(); + + QSqlDatabase getConnection(); + qint64 generateId(); + +private: + // 数据库连接 + QSqlDatabase conn; + + // 雪花id生成工具 + IdWorker &idWorker = Singleton::instance(); + +signals: + +}; + +#endif // CONNECTIONMANAGER_H diff --git a/device/IrisCameraCapEventHandler.cpp b/device/IrisCameraCapEventHandler.cpp new file mode 100644 index 0000000..45df089 --- /dev/null +++ b/device/IrisCameraCapEventHandler.cpp @@ -0,0 +1,103 @@ +#include "IrisCameraCapEventHandler.h" + +IrisCameraCapEventHandler::IrisCameraCapEventHandler(QObject *parent) : QObject(parent) +{ + +} + +void IrisCameraCapEventHandler::DoOnImageCaptured(CImageDataPointer &objImageDataPointer, void *pUserParam) +{ + if (objImageDataPointer.IsNull() == false) + { + CGXDevicePointer* cam = (CGXDevicePointer *) pUserParam; + + auto camName = cam->getPtr()->GetDeviceInfo().GetUserID(); + int width = objImageDataPointer->GetWidth(); + int height = objImageDataPointer->GetHeight(); + size_t leftKeyIndex = camName.find("left"); + size_t rightKeyIndex = camName.find("right"); + + uchar * pBuffer = (BYTE*)objImageDataPointer->GetBuffer(); + + // 相机拍摄下的图像1440*1080, 直接用于算法判断 + QImage img = QImage(pBuffer, width, height, QImage::Format_Grayscale8); // 用于展示 +// QImage imgAlgo = img.copy(0, 0, width, height); + + // 用于显示的图像需要缩小到400 * 300的尺寸 + img = img.scaled(SettingConfig::getInstance().IRIS_DISPLAY_HEIGHT, SettingConfig::getInstance().IRIS_DISPLAY_WIDTH); + img = img.transformed(QTransform().rotate(-90)); // 图像逆时针旋转90度 + + // 发送到界面进行显示 + emit sendIrisFrameToDraw(img); +// cv::Mat irisMat = ImageUtil::QImageToMat(imgAlgo); + +// irisInfo.data = imgAlgo; +// irisInfo.matData = irisMat; + +// // 将图像显示在注册页面的label上 +// // 并将虹膜信息对象存入队列中 +// ProMemory::getInstance().pushCasicIris(irisInfo); + +// if (leftKeyIndex >= 0 && leftKeyIndex < 32) +// { +// emit sendIrisFrameToDraw(img, 0); // 左眼画面 +// } else if (rightKeyIndex >= 0 && rightKeyIndex < 32) +// { +// emit sendIrisFrameToDraw(img, 1); // 右眼画面 +// } +/* + if (pBuffer != NULL) + { + // 创建虹膜信息对象 + CasicIrisInfo irisInfo; + irisInfo.hasEye = false; + if (leftKeyIndex >= 0 && leftKeyIndex < 32) + { + // 左眼相机拍摄的图像 + irisInfo.leftOrRight = "left"; + } else if (rightKeyIndex >= 0 && rightKeyIndex < 32) + { + // 右眼相机 + irisInfo.leftOrRight = "right"; + } + + if (ProMemory::getInstance().widgeFrame == CasicBioRecConst::RECOGNIZE_RESULT_FORM) + { + // 相机拍摄下的图像1280*960, 直接用于算法判断 + QImage imgDisp = QImage(pBuffer, width, height, QImage::Format_Grayscale8); + cv::Mat irisMat = ImageUtil::QImageToMat(imgDisp); + + irisInfo.data = imgDisp; + irisInfo.matData = irisMat; + + ProMemory::getInstance().pushCasicIris(irisInfo); + +// cv::imwrite(QString("D:\\irisLogs\\iristest-%1.bmp").arg(irisInfo.leftOrRight).toStdString(), irisMat); + } else if (ProMemory::getInstance().widgeFrame == CasicBioRecConst::ADD_PERSON_CAPTURE_IRIS) + { + // 相机拍摄下的图像1280*960, 直接用于算法判断 + QImage img = QImage(pBuffer, width, height, QImage::Format_Grayscale8); + QImage imgAlgo = img.copy(0, 0, width, height); + + // 用于显示的图像需要缩小到1/4的尺寸 + img = img.scaled(640, 480); + cv::Mat irisMat = ImageUtil::QImageToMat(imgAlgo); + + irisInfo.data = imgAlgo; + irisInfo.matData = irisMat; + + // 将图像显示在注册页面的label上 + // 并将虹膜信息对象存入队列中 + ProMemory::getInstance().pushCasicIris(irisInfo); + + if (leftKeyIndex >= 0 && leftKeyIndex < 32) + { + emit sendIrisFrameToDraw(img, 0); // 左眼画面 + } else if (rightKeyIndex >= 0 && rightKeyIndex < 32) + { + emit sendIrisFrameToDraw(img, 1); // 右眼画面 + } + } + }*/ + } +} diff --git a/device/IrisCameraCapEventHandler.h b/device/IrisCameraCapEventHandler.h new file mode 100644 index 0000000..ad75a97 --- /dev/null +++ b/device/IrisCameraCapEventHandler.h @@ -0,0 +1,30 @@ +#ifndef IRISCAMERACAPEVENTHANDLER_H +#define IRISCAMERACAPEVENTHANDLER_H + +#include +#include +#include "include/opencv2/opencv.hpp" +#include "include/daheng/GalaxyIncludes.h" + +//#include "casic/iris/CasicIrisInterface.h" +#include "ProMemory.h" + +#include "utils/UtilInclude.h" + +class IrisCameraCapEventHandler : public QObject, public ICaptureEventHandler +{ + Q_OBJECT +public: + explicit IrisCameraCapEventHandler(QObject *parent = nullptr); + + void DoOnImageCaptured(CImageDataPointer &objImageDataPointer, void *pUserParam); + +private: + unsigned char* pImageBuffer; + +signals: + void sendIrisFrameToDraw(QImage irisImage); + +}; + +#endif // IRISCAMERACAPEVENTHANDLER_H diff --git a/device/IrisCameraController.cpp b/device/IrisCameraController.cpp new file mode 100644 index 0000000..0928176 --- /dev/null +++ b/device/IrisCameraController.cpp @@ -0,0 +1,110 @@ +#include "IrisCameraController.h" + +IrisCameraController::IrisCameraController(QObject *parent) : QObject(parent) +{ + this->irisCamHandler = new IrisCameraCapEventHandler(this); +} +IrisCameraController::~IrisCameraController() +{ + this->closeIrisCamera(); +} + + +void IrisCameraController::initIrisCamera() +{ + IGXFactory::GetInstance().Init(); + + //枚举设备 + IGXFactory::GetInstance().UpdateDeviceList(1000, irisCamList); + + this->OpenDevice(); +} + +void IrisCameraController::openIrisCamera() +{ + //设置Buffer处理模式 + irisStreamFeaturePtr->GetEnumFeature("StreamBufferHandlingMode")->SetValue("OldestFirst"); + + //注册回调函数 + irisStreamPtr->RegisterCaptureCallback(irisCamHandler, &irisCamPtr); + + //开启流层通道 + irisStreamPtr->StartGrab(); + + //发送开采命令 + irisFeaturePtr->GetCommandFeature("AcquisitionStart")->Execute(); + + // 启动定时器 + TimeCounterUtil::getInstance().irisCapCounter->start(SettingConfig::getInstance().IRIS_FRAME_INTERVAL); // 50ms执行一次定时器 +} + +void IrisCameraController::closeIrisCamera() +{ + +} + +void IrisCameraController::startCapture() +{ + // 获取定时器, 绑定定时函数 + connect(TimeCounterUtil::getInstance().irisCapCounter, &QTimer::timeout, this, &IrisCameraController::getOneFaceFrm); +// LOG(DEBUG) << QString("[IrisCameraController][startCapture]虹膜相机拍图").toStdString(); +// LOG_DEBUG(QString("[IrisCameraController][startCapture]虹膜相机拍图").toStdString()); + +} +void IrisCameraController::stopCapture() +{ + // 获取定时器, 绑定定时函数 + disconnect(TimeCounterUtil::getInstance().irisCapCounter, &QTimer::timeout, this, &IrisCameraController::getOneFaceFrm); +// LOG(DEBUG) << QString("[IrisCameraController][stopCapture]虹膜相机停止拍图").toStdString(); +// LOG_DEBUG(QString("[IrisCameraController][stopCapture]虹膜相机停止拍图").toStdString()); + +} + +void IrisCameraController::getOneFaceFrm() +{ + // 发送软触发命令(在触发模式开启时有效) + irisFeaturePtr->GetCommandFeature("TriggerSoftware")->Execute(); +} + +void IrisCameraController::getLeftAndRightEyeFrame() +{ + irisFeaturePtr->GetCommandFeature("TriggerSoftware")->Execute(); +} + +void IrisCameraController::OpenDevice() +{ + auto device = irisCamList.at(0); + + irisCamPtr = IGXFactory::GetInstance().OpenDeviceByUserID(device.GetUserID(), GX_ACCESS_EXCLUSIVE); + irisFeaturePtr = irisCamPtr->GetRemoteFeatureControl(); + + // 判断设备流是否大于零, 如果大于零则打开流 + int nStreamCount = irisCamPtr->GetStreamCount(); + if (nStreamCount > 0) + { + irisStreamPtr = irisCamPtr->OpenStream(0); + irisStreamFeaturePtr = irisStreamPtr->GetFeatureControl(); + } + + // 建议用户在打开网络相机之后, 根据当前网络环境设置相机的流通道包长值, + // 以提高网络相机的采集性能, 设置方法参考以下代码。 + GX_DEVICE_CLASS_LIST objDeviceClass = irisCamPtr->GetDeviceInfo().GetDeviceClass(); + if(GX_DEVICE_CLASS_GEV == objDeviceClass) + { + // 判断设备是否支持流通道数据包功能 + if(true == irisFeaturePtr->IsImplemented("GevSCPSPacketSize")) + { + // 获取当前网络环境的最优包长值 + int nPacketSize = irisStreamPtr->GetOptimalPacketSize(); + // 将最优包长值设置为当前设备的流通道包长值 + irisFeaturePtr->GetIntFeature("GevSCPSPacketSize")->SetValue(nPacketSize); + } + } + + //设置采集模式为连续采集模式 + irisFeaturePtr->GetEnumFeature("AcquisitionMode")->SetValue("Continuous"); + + //设置触发模式关 + irisFeaturePtr->GetEnumFeature("TriggerMode")->SetValue("On"); + irisFeaturePtr->GetEnumFeature("TriggerSource")->SetValue("Software"); +} diff --git a/AppConstants.h b/AppConstants.h new file mode 100644 index 0000000..296c53f --- /dev/null +++ b/AppConstants.h @@ -0,0 +1,28 @@ +#ifndef APPCONSTANTS_H +#define APPCONSTANTS_H + +class AppConstants +{ +public: + enum WidgeFrameName + { + MAIN_PAGE = 0, // 主页面 + PERSON_LIST_FORM = 1, // 人员列表页面 + ADD_PERSON_FORM = 2, // 添加人员页面 + ADD_PERSON_CAPTURE_FACE = 21, // 添加/编辑人员时进行人脸拍图 + ADD_PERSON_CAPTURE_IRIS = 22, // 添加/编辑人员时进行虹膜拍图 + SETTING_FORM = 3, // 设置页面 + RECOGNIZE_RESULT_FORM = 4, // 识别结果界面 + IDENTIFY_FORM = 5, // 识别界面 含识别中 和 识别结果 + LOCKSCREEN_FORM = 6 // 锁屏待机界面 + }; + + enum ApplicationState + { + STATE_WAIT = 0, // 待机 + STATE_WORKING = 1, // 工作状态 + STATE_IDENTIFYING = 2, // 识别中 + }; +}; + +#endif // APPCONSTANTS_H diff --git a/CasicIrisIdentify.pro b/CasicIrisIdentify.pro index 5d7fea6..575ce3d 100644 --- a/CasicIrisIdentify.pro +++ b/CasicIrisIdentify.pro @@ -1,4 +1,4 @@ -QT += core gui +QT += core gui sql network texttospeech greaterThan(QT_MAJOR_VERSION, 4): QT += widgets @@ -15,20 +15,46 @@ # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 -SOURCES += \ - main.cpp \ - IdentifyForm.cpp +include("dao/dao.pri") +include("device/device.pri") +include("utils/utils.pri") -HEADERS += \ - IdentifyForm.h +SOURCES += main.cpp +SOURCES += ProMemory.cpp +SOURCES += MainWindowForm.cpp +SOURCES += IdentifyForm.cpp +SOURCES += LockScreenForm.cpp -FORMS += \ - IdentifyForm.ui +HEADERS += AppConstants.h +HEADERS += ProMemory.h +HEADERS += MainWindowForm.h +HEADERS += IdentifyForm.h +HEADERS += LockScreenForm.h -TRANSLATIONS += \ - CasicIrisIdentify_zh_CN.ts +FORMS += MainWindowForm.ui +FORMS += IdentifyForm.ui +FORMS += LockScreenForm.ui + +RESOURCES += resource.qrc + +DISTFILES += conf/config.ini + +#TRANSLATIONS += CasicIrisIdentify_zh_CN.ts + +#INCLUDEPATH += include/spdlog +#DEPENDPATH += include/spdlog # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target + + +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lopencv_world420 +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lGxIAPICPPEx + +INCLUDEPATH += $$PWD/include/daheng +DEPENDPATH += $$PWD/include/daheng + +INCLUDEPATH += $$PWD/include +DEPENDPATH += $$PWD/include diff --git a/CasicIrisIdentify_zh_CN.ts b/CasicIrisIdentify_zh_CN.ts index 5526fe4..81900df 100644 --- a/CasicIrisIdentify_zh_CN.ts +++ b/CasicIrisIdentify_zh_CN.ts @@ -1,3 +1,12 @@ - + + + IdentifyForm + + + IdentifyForm + + + + diff --git a/IdentifyForm.cpp b/IdentifyForm.cpp index 348a897..ba1f251 100644 --- a/IdentifyForm.cpp +++ b/IdentifyForm.cpp @@ -1,4 +1,4 @@ -#include "IdentifyForm.h" +#include "IdentifyForm.h" #include "ui_IdentifyForm.h" IdentifyForm::IdentifyForm(QWidget *parent) @@ -6,6 +6,12 @@ , ui(new Ui::IdentifyForm) { ui->setupUi(this); + + // 初始化更新界面的定时器 + // 每秒执行一次 + connect(TimeCounterUtil::getInstance().clockCounter, &QTimer::timeout, this, &IdentifyForm::updateDateAndTime); + + TimeCounterUtil::getInstance().clockCounter->start(1000); } IdentifyForm::~IdentifyForm() @@ -13,3 +19,16 @@ delete ui; } +void IdentifyForm::drawIrisImageOnFrame(QImage image) +{ + // 只在识别界面才显示画面 + if (ui->wgtStacked->currentIndex() == 0) { + ui->labelVideo->setPixmap(QPixmap::fromImage(image)); + } +} + + +void IdentifyForm::updateDateAndTime() +{ + ui->labelTime->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd dddd HH:mm:ss")); +} diff --git a/IdentifyForm.h b/IdentifyForm.h index fc857a1..ae1cd22 100644 --- a/IdentifyForm.h +++ b/IdentifyForm.h @@ -1,7 +1,10 @@ -#ifndef IDENTIFYFORM_H +#ifndef IDENTIFYFORM_H #define IDENTIFYFORM_H #include +#include + +#include "utils/UtilInclude.h" QT_BEGIN_NAMESPACE namespace Ui { class IdentifyForm; } @@ -15,7 +18,14 @@ IdentifyForm(QWidget *parent = nullptr); ~IdentifyForm(); +public slots: + void drawIrisImageOnFrame(QImage image); + private: Ui::IdentifyForm *ui; + +private slots: + void updateDateAndTime(); + }; #endif // IDENTIFYFORM_H diff --git a/IdentifyForm.ui b/IdentifyForm.ui index c72a36f..879dc9a 100644 --- a/IdentifyForm.ui +++ b/IdentifyForm.ui @@ -6,13 +6,59 @@ 0 0 - 800 + 600 600 IdentifyForm + + + + 0 + 40 + 600 + 450 + + + + 0 + + + + + + 100 + 10 + 400 + 300 + + + + + + + + + + + + + + 0 + 0 + 600 + 40 + + + + TextLabel + + + Qt::AlignCenter + + diff --git a/LockScreenForm.cpp b/LockScreenForm.cpp new file mode 100644 index 0000000..58dc54b --- /dev/null +++ b/LockScreenForm.cpp @@ -0,0 +1,14 @@ +#include "LockScreenForm.h" +#include "ui_LockScreenForm.h" + +LockScreenForm::LockScreenForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::LockScreenForm) +{ + ui->setupUi(this); +} + +LockScreenForm::~LockScreenForm() +{ + delete ui; +} diff --git a/LockScreenForm.h b/LockScreenForm.h new file mode 100644 index 0000000..b5ded48 --- /dev/null +++ b/LockScreenForm.h @@ -0,0 +1,25 @@ +#ifndef LOCKSCREENFORM_H +#define LOCKSCREENFORM_H + +#include +#include + +#include "utils/UtilInclude.h" + +namespace Ui { +class LockScreenForm; +} + +class LockScreenForm : public QWidget +{ + Q_OBJECT + +public: + explicit LockScreenForm(QWidget *parent = nullptr); + ~LockScreenForm(); + +private: + Ui::LockScreenForm *ui; +}; + +#endif // LOCKSCREENFORM_H diff --git a/LockScreenForm.ui b/LockScreenForm.ui new file mode 100644 index 0000000..7f2a6db --- /dev/null +++ b/LockScreenForm.ui @@ -0,0 +1,45 @@ + + + LockScreenForm + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + 180 + 100 + 54 + 12 + + + + TextLabel + + + + + + 180 + 160 + 54 + 12 + + + + TextLabel + + + + + + diff --git a/MainWindowForm.cpp b/MainWindowForm.cpp new file mode 100644 index 0000000..84f8159 --- /dev/null +++ b/MainWindowForm.cpp @@ -0,0 +1,86 @@ +#include "MainWindowForm.h" +#include "ui_MainWindowForm.h" +#include + +MainWindowForm::MainWindowForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::MainWindowForm) +{ + ui->setupUi(this); + + // 设置窗口透明和大小、位置 + this->setWindowFlags(Qt::FramelessWindowHint); + this->move(1400, 15); + this->resize(SettingConfig::getInstance().WINDOW_WIDTH, SettingConfig::getInstance().WINDOW_HEIGHT); + + // 通过调色板的颜色来设置窗口的统一背景色 + qApp->setPalette(QPalette(QColor(SettingConfig::getInstance().WINDOW_BACKGROUND_COLOR))); + + // 加载css文件设置控件样式 + QFile file(QApplication::applicationDirPath() + "/qss/main.css"); + if (file.open(QFile::ReadOnly)) + { + QString qssStr = QLatin1String(file.readAll()); + this->setStyleSheet(qssStr); + file.close(); + } + + initFormsPtr(); + + // 设置标题文字 + ui->labelTitle->setText(SettingConfig::getInstance().WINDOW_TITLE); + ui->labelCopyright->setText(SettingConfig::getInstance().WINDOW_RIGHTS); + ui->labelVersion->setText(SettingConfig::getInstance().WINDOW_VERSION); + + // 初始化虹膜相机控制 + ProMemory::getInstance().irisCam = new IrisCameraController(this); + ProMemory::getInstance().irisCam->initIrisCamera(); + ProMemory::getInstance().irisCam->openIrisCamera(); + connect(ProMemory::getInstance().irisCam->irisCamHandler, &IrisCameraCapEventHandler::sendIrisFrameToDraw, identifyForm, &IdentifyForm::drawIrisImageOnFrame); + +// LOG_INFO(QString("应用程序启动成功[Application Startup Success]").toStdString()); + qDebug() << "应用程序启动成功[Application Startup Success]"; + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::IDENTIFY_FORM; + ui->wdgtStatced->setCurrentWidget(identifyForm); + + // 开始虹膜相机拍图 + ProMemory::getInstance().irisCam->startCapture(); +} + +MainWindowForm::~MainWindowForm() +{ + delete ui; +} + +void MainWindowForm::lockScreen() +{ + ui->wdgtStatced->setCurrentWidget(lockScreenForm); + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::LOCKSCREEN_FORM; + ProMemory::getInstance().appState = AppConstants::ApplicationState::STATE_WAIT; +} + +void MainWindowForm::keyPressEvent(QKeyEvent *event) +{ + switch (event->key()) { + case Qt::Key_Escape: + QTimer::singleShot(100, qApp, [=](){ + QApplication::quit(); + }); + + default: + QWidget::keyPressEvent(event); + } +} + +void MainWindowForm::initFormsPtr() +{ + // 初始化各个form + lockScreenForm = new LockScreenForm(this); + identifyForm = new IdentifyForm(this); + + // 将form添加到statcked widget中 + ui->wdgtStatced->addWidget(identifyForm); + ui->wdgtStatced->addWidget(lockScreenForm); + + // 绑定按钮函数 +} diff --git a/MainWindowForm.h b/MainWindowForm.h new file mode 100644 index 0000000..7fb2d89 --- /dev/null +++ b/MainWindowForm.h @@ -0,0 +1,38 @@ +#ifndef MAINWINDOWFORM_H +#define MAINWINDOWFORM_H + +#include +#include +#include + +#include "utils/UtilInclude.h" +#include "ProMemory.h" +#include "LockScreenForm.h" +#include "IdentifyForm.h" + +namespace Ui { +class MainWindowForm; +} + +class MainWindowForm : public QWidget +{ + Q_OBJECT + +public: + explicit MainWindowForm(QWidget *parent = nullptr); + ~MainWindowForm(); + +public slots: + void lockScreen(); + +private: + Ui::MainWindowForm *ui; + LockScreenForm * lockScreenForm; + IdentifyForm * identifyForm; + + void keyPressEvent(QKeyEvent *event); + + void initFormsPtr(); +}; + +#endif // MAINWINDOWFORM_H diff --git a/MainWindowForm.ui b/MainWindowForm.ui new file mode 100644 index 0000000..e793ebf --- /dev/null +++ b/MainWindowForm.ui @@ -0,0 +1,85 @@ + + + MainWindowForm + + + + 0 + 0 + 600 + 1024 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + 0 + 0 + 600 + 84 + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + + + + TextLabel + + + Qt::AlignBottom|Qt::AlignHCenter + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + diff --git a/ProMemory.cpp b/ProMemory.cpp new file mode 100644 index 0000000..19e7403 --- /dev/null +++ b/ProMemory.cpp @@ -0,0 +1,84 @@ +#include "ProMemory.h" + +ProMemory::ProMemory() +{ + +} + +ProMemory::~ProMemory() +{ + +} + +/* +void ProMemory::pushCasicIris(CasicIrisInfo irisInfo) +{ + QMutex mutex; + mutex.lock(); + if (this->irisQueue.size() > 30) + { + QStack empty; + std::swap(empty, irisQueue); + } + + irisQueue.push(irisInfo); + mutex.unlock(); +} +CasicIrisInfo ProMemory::popCasicIris() +{ + CasicIrisInfo result; + + QMutex mutex; + mutex.lock(); + if (this->irisQueue.size() > 0) + { + result = irisQueue.pop(); + } + + mutex.unlock(); + + return result; +} +*/ +int ProMemory::getIrisQueueSize() +{ + int size = 0; + + QMutex mutex; + mutex.lock(); + +// size = this->irisQueue.size(); + + mutex.unlock(); + + return size; +} +bool ProMemory::isIrisQueueEmpty() +{ + bool empty = true; + + QMutex mutex; + mutex.lock(); + +// empty = this->irisQueue.isEmpty(); + + mutex.unlock(); + + return empty; +} +void ProMemory::clearIrisQueue() +{ + QMutex mutex; + mutex.lock(); + +// QStack empty; +// std::swap(empty, irisQueue); + + mutex.unlock(); +} + + +void ProMemory::initIrisFeatures(QString personId) +{ +// irisRegistPro->sendDataToExract(QByteArray(QString("[-u]").append(personId).toLocal8Bit())); +} diff --git a/ProMemory.h b/ProMemory.h new file mode 100644 index 0000000..2ecd653 --- /dev/null +++ b/ProMemory.h @@ -0,0 +1,52 @@ +#ifndef PROMEMORY_H +#define PROMEMORY_H + +#include +#include + +#include "AppConstants.h" +//#include "casic/iris/CasicIrisInfo.h" +#include "dao/IrisDataDao.h" + +#include "device/IrisCameraController.h" +//#include "device/iris/IrisRegistProcess.h" +//#include "device/iris/IrisRecogProcess.h" + +class IrisCameraController; +class IrisRegistProcess; +class IrisRecogProcess; + +class ProMemory +{ +public: + ~ProMemory(); + ProMemory(const ProMemory&)=delete; + ProMemory& operator=(const ProMemory&)=delete; + + static ProMemory& getInstance() { + static ProMemory instance; + return instance; + } + +// void pushCasicIris(CasicIrisInfo irisInfo); +// CasicIrisInfo popCasicIris(); + int getIrisQueueSize(); + bool isIrisQueueEmpty(); + void clearIrisQueue(); + + volatile int widgeFrame = 0; // 当前显示的界面 + volatile int appState = 0; // 当前程序所处的状态 + + void initIrisFeatures(QString personId = ""); // 初始化虹膜特征值集合 + + IrisCameraController * irisCam; + IrisRecogProcess * irisRecogPro; + +private: + ProMemory(); + +// QStack irisQueue; // 虹膜信息队列 + QVector irisFeatures; // 虹膜特征值集合 +}; + +#endif // PROMEMORY_H diff --git a/conf/config.ini b/conf/config.ini new file mode 100644 index 0000000..66e46ad --- /dev/null +++ b/conf/config.ini @@ -0,0 +1,67 @@ +[recognize] +#最大允许识别时间(ms) +maxMatchTime=10000 +#识别成功界面停留时间(ms) +successTipsLast=5000 +#识别失败界面停留时间(ms) +failureTipsLast=3000 +#人脸识别最大尝试次数 +maxFaceTryCount=20 +#持续没找到人脸的最大次数 +maxFaceNotFoundCount=500 +#注册时最小人脸 +minFaceRegist=240 +#识别时最小人脸 +minFaceRecog=100 + +#虹膜识别最大尝试次数 +maxIrisTryCount=10 +#虹膜识别持续没有找到眼的最大次数 +maxEyeNotFoundCount=50 + +#识别方式[1=人脸;2=虹膜;3=双认证;4=任意] +recogType=4 + +[window] +#界面窗口宽(px) +width=600 +#界面窗口高(px) +height=1024 +#统一背景色 +backgroundColor="#FFFFFF" +#标题 +title="虹膜识别终端" + +[work] +#工作状态检测时最小人脸范围 +minFaceSize=160 +#人脸范围最小横坐标 +minFacePosX=320 +#人脸范围最大横坐标 +maxFacePosX=960 +#人脸范围最小纵坐标 +minFacePosY=180 +#人脸范围最大纵坐标 +maxFacePosY=540 +#人脸太近阈值 +faceCloseSize=360 +#人脸太远阈值 +faceFarSize=480 + +[camera] +#虹膜相机取一幅画面的时间间隔(ms) +irisFrameInterval=100 +#虹膜相机拍摄宽度 +irisFrameWidth=1440 +#虹膜相机拍摄高度 +irisFrameHeight=1080 +#虹膜图像高度 +irisWidth=640 +#虹膜图像高度 +irisHeight=480 + +[log] +#日志文件位置 +logFile="d://irisLogs//casic_log.txt" +#日志级别 +logLevel="trace" diff --git a/dao/BaseDao.cpp b/dao/BaseDao.cpp new file mode 100644 index 0000000..f51c144 --- /dev/null +++ b/dao/BaseDao.cpp @@ -0,0 +1,12 @@ +#include "BaseDao.h" +#include "dao/util/ConnectionManager.h" + +BaseDao::BaseDao(QObject *parent) : QObject(parent) +{ + +} + +BaseDao::~BaseDao() +{ + +} diff --git a/dao/BaseDao.h b/dao/BaseDao.h new file mode 100644 index 0000000..1693c88 --- /dev/null +++ b/dao/BaseDao.h @@ -0,0 +1,32 @@ +#ifndef BASEDAO_H +#define BASEDAO_H + +#include +#include +#include +#include + +#include "dao/util/ConnectionManager.h" +#include "utils/UtilInclude.h" + +class BaseDao : public QObject +{ + Q_OBJECT +public: + explicit BaseDao(QObject *parent = nullptr); + ~BaseDao(); + + virtual QVector findAllRecord() = 0; + virtual QVariantMap findRecordById(QString id) = 0; + + virtual QString save(QVariantMap object) = 0; + virtual bool edit(QVariantMap newObject, QString id) = 0; + virtual bool dele(QString id) = 0; + +private: + +signals: + +}; + +#endif // BASEDAO_H diff --git a/dao/IrisDataDao.cpp b/dao/IrisDataDao.cpp new file mode 100644 index 0000000..37a0ed6 --- /dev/null +++ b/dao/IrisDataDao.cpp @@ -0,0 +1,204 @@ +#include "IrisDataDao.h" + +IrisDataDao::IrisDataDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector IrisDataDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM IRIS_DATA"; + query.prepare(sql); + + // 执行查询 + query.exec(); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + item.insert("id", query.value("id").toString()); + item.insert("person_id", query.value("person_id").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("left_iris_code1", query.value("left_iris_code1")); + item.insert("left_iris_code2", query.value("left_iris_code2")); + item.insert("left_iris_code3", query.value("left_iris_code3")); + item.insert("right_iris_code1", query.value("right_iris_code1")); + item.insert("right_iris_code2", query.value("right_iris_code2")); + item.insert("right_iris_code3", query.value("right_iris_code3")); + + result.append(item); + } + +// LOG_DEBUG(QString("查询IRIS_DATA表的所有记录[结果数:%1]").arg(result.size()).toStdString()); + return result; +} + +QVariantMap IrisDataDao::findRecordById(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM IRIS_DATA WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + // 获取结果 + if (query.next()) + { + result.insert("id", query.value("id").toString()); + result.insert("person_id", query.value("person_id").toLongLong()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("left_iris_code1", query.value("left_iris_code1")); + result.insert("left_iris_code2", query.value("left_iris_code2")); + result.insert("left_iris_code3", query.value("left_iris_code3")); + result.insert("right_iris_code1", query.value("right_iris_code1")); + result.insert("right_iris_code2", query.value("right_iris_code2")); + result.insert("right_iris_code3", query.value("right_iris_code3")); + } + +// LOG_DEBUG(QString("根据id查询IRIS_DATA表的记录[id=%1]").arg(id).toStdString()); + return result; +} + +QVariantMap IrisDataDao::findRecordByPersonId(QString personId) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM IRIS_DATA WHERE PERSON_ID = :personId"); + query.prepare(sql); + query.bindValue(":personId", personId); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + if (query.next()) + { + result.insert("id", query.value("id").toString()); + result.insert("person_id", query.value("person_id").toLongLong()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("left_iris_code1", query.value("left_iris_code1")); + result.insert("left_iris_code2", query.value("left_iris_code2")); + result.insert("left_iris_code3", query.value("left_iris_code3")); + result.insert("right_iris_code1", query.value("right_iris_code1")); + result.insert("right_iris_code2", query.value("right_iris_code2")); + result.insert("right_iris_code3", query.value("right_iris_code3")); + } + +// LOG_DEBUG(QString("根据personId查询IRIS_DATA表的记录[personId=%1]").arg(personId).toStdString()); + return result; +} + + +QString IrisDataDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + + // INSERT语句 + QString sql = QString("INSERT INTO IRIS_DATA (ID, PERSON_ID, ID_CARD_NO, LEFT_IRIS_CODE1, RIGHT_IRIS_CODE1) VALUES (:id, :personId, :idCardNo, :left1, :right1)"); + + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":personId", object.value("person_id").toString()); + query.bindValue(":idCardNo", object.value("id_card_no").toString()); + query.bindValue(":left1", object.value("left_iris_code1")); + query.bindValue(":right1", object.value("right_iris_code1")); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(); + +// LOG_DEBUG(QString("保存虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool IrisDataDao::edit(QVariantMap newObject, QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // UPDATE语句 + if (!newObject.contains("left_iris_code1") || !newObject.contains("right_iris_code1")){ + return false; + } + QString sql = QString("UPDATE IRIS_DATA SET LEFT_IRIS_CODE1 = :left1, RIGHT_IRIS_CODE1 = :right1 WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":left1", newObject.value("left_iris_code1")); + query.bindValue(":right1", newObject.value("right_iris_code1")); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(); + +// LOG_DEBUG(QString("编辑虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; +} + + +bool IrisDataDao::dele(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + QString sql = QString("DELETE FROM IRIS_DATA WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(); + +// LOG_DEBUG(QString("删除虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; +} diff --git a/dao/IrisDataDao.h b/dao/IrisDataDao.h new file mode 100644 index 0000000..c74dbbd --- /dev/null +++ b/dao/IrisDataDao.h @@ -0,0 +1,25 @@ +#ifndef IRISDATADAO_H +#define IRISDATADAO_H + +#include +#include "BaseDao.h" + +class IrisDataDao : public BaseDao +{ + Q_OBJECT +public: + explicit IrisDataDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + QVariantMap findRecordByPersonId(QString personId); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +signals: + +}; + +#endif // IRISDATADAO_H diff --git a/dao/RecognitionRecordsDao.cpp b/dao/RecognitionRecordsDao.cpp new file mode 100644 index 0000000..40db453 --- /dev/null +++ b/dao/RecognitionRecordsDao.cpp @@ -0,0 +1,100 @@ +#include "RecognitionRecordsDao.h" + +RecognitionRecordsDao::RecognitionRecordsDao(QObject *parent) : BaseDao(parent) +{ + +} + + +QVector RecognitionRecordsDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM RECOGNITION_RECORDS"; + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + item.insert("id", query.value("id").toLongLong()); + result.append(item); + } + +// LOG_DEBUG(QString("查询RECOGNITION_RECORDS表的所有记录[记录数:%1]").arg(result.size()).toStdString()); + return result; +} + +QVariantMap RecognitionRecordsDao::findRecordById(QString id) +{ + QVariantMap item; + return item; +} + +QString RecognitionRecordsDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + + // INSERT语句 + QString sql = QString("INSERT INTO RECOGNITION_RECORDS (ID, PERSON_ID, DATETIME, REC_TYPE, DEV_CODE, DOOR_CODE, INOUT_TYPE) " + "VALUES (:id, :personId, :datetime, :recType, :devCode, :doorCode, :inoutType)"); + + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":personId", object.value("person_id").toString()); + query.bindValue(":datetime", object.value("date_time").toString()); + query.bindValue(":recType", object.value("rec_type").toString()); + query.bindValue(":devCode", object.value("dev_code").toString()); + query.bindValue(":doorCode", object.value("door_code").toString()); + query.bindValue(":inoutType", object.value("inout_type").toString()); + +// LOG_DEBUG(sql.toStdString()); + + // 插入识别的log日志 + QString logStr = QString("INSERT INTO RECOGNITION_LOGS (ID, LOG_INFO) VALUES (:id, :logInfo)"); + + QSqlQuery logQuery(ConnectionManager::getInstance()->getConnection()); + logQuery.prepare(logStr); + logQuery.bindValue(":id", id); + logQuery.bindValue(":logInfo", object.value("debug_info").toString()); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(); + logQuery.exec(); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool RecognitionRecordsDao::edit(QVariantMap newObject, QString id) +{ + return false; +} + +bool RecognitionRecordsDao::dele(QString id) +{ + return false; +} diff --git a/dao/RecognitionRecordsDao.h b/dao/RecognitionRecordsDao.h new file mode 100644 index 0000000..38de7c9 --- /dev/null +++ b/dao/RecognitionRecordsDao.h @@ -0,0 +1,23 @@ +#ifndef RECOGNITIONRECORDSDAO_H +#define RECOGNITIONRECORDSDAO_H + +#include +#include "BaseDao.h" +class RecognitionRecordsDao: public BaseDao +{ + Q_OBJECT +public: + explicit RecognitionRecordsDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +signals: + +}; + +#endif // RECOGNITIONRECORDSDAO_H diff --git a/dao/SysDeptDao.cpp b/dao/SysDeptDao.cpp new file mode 100644 index 0000000..22f9946 --- /dev/null +++ b/dao/SysDeptDao.cpp @@ -0,0 +1,88 @@ +#include "SysDeptDao.h" + +SysDeptDao::SysDeptDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector SysDeptDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_DEPT WHERE PID != '-1' ORDER BY PID, NUM"; + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + item.insert("id", query.value("id").toString()); + item.insert("pid", query.value("pid").toString()); + item.insert("pids", query.value("pids").toString()); + item.insert("simplename", query.value("simplename").toString()); + item.insert("fullname", query.value("fullname").toString()); + } + +// LOG_TRACE(QString("查询表[SYS_DEPT]的所有记录[%1][%2]").arg(result.size()).arg(sql).toStdString()); + + return result; +} + +QVariantMap SysDeptDao::findRecordById(QString id) +{ + QVariantMap item; + return item; + + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM SYS_DEPT WHERE SYS_DEPT.ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + // 获取结果集的大小 + query.last(); + int count = query.at() + 1; + + if (count >=1) + { + query.first(); + + result.insert("id", query.value("id").toString()); + result.insert("pid", query.value("pid").toString()); + result.insert("pids", query.value("pids").toString()); + result.insert("simplename", query.value("simplename").toString()); + result.insert("fullname", query.value("fullname").toString()); + } + +// LOG_TRACE(QString("根据id查询SYS_DEPT表的记录[ID=%1][%2]").arg(id).arg(sql).toStdString()); + + return result; +} + + +QString SysDeptDao::save(QVariantMap object) +{ + return "0"; +} +bool SysDeptDao::edit(QVariantMap newObject, QString id) +{ + return true; +} +bool SysDeptDao::dele(QString id) +{ + return true; +} diff --git a/dao/SysDeptDao.h b/dao/SysDeptDao.h new file mode 100644 index 0000000..e07a09f --- /dev/null +++ b/dao/SysDeptDao.h @@ -0,0 +1,24 @@ +#ifndef SYSDEPTDAO_H +#define SYSDEPTDAO_H + +#include +#include "BaseDao.h" + +class SysDeptDao : public BaseDao +{ + Q_OBJECT +public: + explicit SysDeptDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +private: + +}; + +#endif // SYSDEPTDAO_H diff --git a/dao/SysPersonDao.cpp b/dao/SysPersonDao.cpp new file mode 100644 index 0000000..dd9480f --- /dev/null +++ b/dao/SysPersonDao.cpp @@ -0,0 +1,371 @@ +#include "SysPersonDao.h" + + +SysPersonDao::SysPersonDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector SysPersonDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0'"; + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + count++; + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + result.append(item); + } + +// LOG(TRACE) << QString("查询SYS_PERSON表的所有记录[%1]").arg(count).toStdString(); +// LOG_TRACE(QString("查询SYS_PERSON表的所有记录[%1]").arg(count).toStdString()); + + return result; +} + +QVariantMap SysPersonDao::findRecordById(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0' AND SYS_PERSON.ID = '%1'").arg(id); + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVariantMap result; + + // 获取结果集的大小 + query.last(); + int count = query.at() + 1; + + if (count >=1) + { + query.first(); + + result.insert("id", query.value("id").toString()); + result.insert("delflag", query.value("delflag").toString()); + result.insert("createtime", query.value("createtime").toString()); + result.insert("updatetime", query.value("updatetime").toString()); + result.insert("name", query.value("name").toString()); + result.insert("gender", query.value("gender").toString()); + result.insert("deptid", query.value("deptid").toString()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("remarks", query.value("remarks").toString()); + result.insert("person_code", query.value("person_code").toString()); + result.insert("deptname", query.value("fullname").toString()); + result.insert("sync_id", query.value("sync_id").toString()); + result.insert("hasFace", query.value("face_valid").toString()); + result.insert("hasIris", query.value("iris_valid").toString()); + } + +// LOG(TRACE) << QString("根据id查询SYS_PERSON表的记录[id=%1][%2]").arg(id).arg(sql).toStdString(); +// LOG_TRACE(QString("根据id查询SYS_PERSON表的记录[id=%1][%2]").arg(id).arg(sql).toStdString()); + + return result; +} + +int SysPersonDao::findRecordCountByNameAndDept(QString name, QString dept) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT COUNT(P.ID) AS RECCT FROM SYS_PERSON P LEFT JOIN SYS_DEPT D ON P.DEPTID = D.ID WHERE P.DELFLAG = '0'"; + if (name.isEmpty() == false) + { + sql += " AND P.NAME LIKE '%" + name + "%'"; + } + if (dept.isEmpty() == false && dept.indexOf("-1") < 0) + { + sql += QString(" AND ((P.DEPTID = '%1') OR (D.PIDS LIKE '%,%1,%'))").arg(dept); + } + + // 执行查询 + query.exec(sql); + + // 返回结果 + int result; + + // 遍历查询结果 + if (query.next()) { + result = query.value("RECCT").toInt(); + } + +// LOG(TRACE) << QString("根据姓名和部门查询SYS_PERSON记录总数[%1][%2]").arg(result).arg(sql).toStdString(); +// LOG_TRACE(QString("根据姓名和部门查询SYS_PERSON记录总数[%1][%2]").arg(result).arg(sql).toStdString()); + + return result; +} + +QVector SysPersonDao::findRecordsByNameAndDept(QString name, QString dept, qint8 limit, qint16 offset) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON P LEFT JOIN SYS_DEPT D ON P.DEPTID = D.ID WHERE P.DELFLAG = '0'"; + if (name.isEmpty() == false) + { + sql += " AND P.NAME LIKE '%" + name + "%'"; + } + if (dept.isEmpty() == false && dept.indexOf("-1") < 0) + { + sql += QString(" AND ((P.DEPTID = '%1') OR (D.PIDS LIKE '%,%1,%'))").arg(dept); + } + + sql += QString(" LIMIT %1 OFFSET %2").arg(limit).arg(offset); + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + count++; + + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + + result.append(item); + } + +// LOG(TRACE) << QString("根据姓名和部门分页查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString(); +// LOG_TRACE(QString("根据姓名和部门分页查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString()); + + return result; +} + +QVector SysPersonDao::findRecordsByProperties(QVariantMap conditions) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0'"; + QVariantMap::iterator it; + for (it = conditions.begin(); it != conditions.end(); it++) + { + sql += QString(" AND SYS_PERSON.%1 = %2").arg(it.key()).arg(it.value().toString()); + } + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + count++; + + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + + result.append(item); + } + +// LOG(TRACE) << QString("根据属性值查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString(); +// LOG_TRACE(QString("根据属性值查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString()); + + return result; +} + +QString SysPersonDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + + // INSERT语句 + QString sql = QString("INSERT INTO SYS_PERSON " + "(ID, DELFLAG, CREATETIME, UPDATETIME, " + "NAME, GENDER, DEPTID, ID_CARD_NO, " + "REMARKS, PERSON_CODE, SYNC_ID, FACE_VALID, IRIS_VALID) " + "VALUES ('%1', '0', '%2', '%2', '%3', '%4', '%5', '%6', '%7', '%8', '%9', 0, 0)") + .arg(id).arg(tm) + .arg(object.value("name").toString()) + .arg(object.value("gender").toString()) + .arg(object.value("deptid").toString()) + .arg(object.value("id_card_no").toString()) + .arg(object.value("remarks").toString()) + .arg(object.value("person_code").toString()) + .arg(object.value("sync_id").toString()); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(sql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { +// LOG(DEBUG) << QString("保存SYS_PERSON记录成功[ID = %1][%2]").arg(id).arg(sql).toStdString(); +// LOG_DEBUG(QString("保存SYS_PERSON记录成功[ID = %1][%2]").arg(id).arg(sql).toStdString()); + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool SysPersonDao::edit(QVariantMap newObject, QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + + // UPDATE语句 + QString sql = QString("UPDATE SYS_PERSON SET UPDATETIME = '%1'").arg(tm); + if (newObject.contains("name")) + { + sql.append(QString(", NAME = '%1'").arg(newObject.value("name").toString())); + } + if (newObject.contains("gender")) + { + sql.append(QString(", GENDER = '%1'").arg(newObject.value("gender").toString())); + } + if (newObject.contains("deptid")) + { + sql.append(QString(", DEPTID = '%1'").arg(newObject.value("deptid").toString())); + } + if (newObject.contains("person_code")) + { + sql.append(QString(", PERSON_CODE = '%1'").arg(newObject.value("person_code").toString())); + } + if (newObject.contains("face_valid")) + { + sql.append(QString(", FACE_VALID = '%1'").arg(newObject.value("face_valid").toString())); + } + if (newObject.contains("iris_valid")) + { + sql.append(QString(", IRIS_VALID = '%1'").arg(newObject.value("iris_valid").toString())); + } + + sql.append(QString(" WHERE ID = '%1'").arg(id)); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(sql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + +// LOG(DEBUG) << QString("编辑人员[ID=%1][%2]").arg(id).arg(sql).toStdString(); +// LOG_DEBUG(QString("编辑人员[ID=%1][%2]").arg(id).arg(sql).toStdString()); + + // 返回结果 + return success; +} + +bool SysPersonDao::dele(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + QSqlQuery irisDel(ConnectionManager::getInstance()->getConnection()); + + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + qint64 tmms = QDateTime::currentDateTime().toMSecsSinceEpoch(); + + // UPDATE语句 + QString sql = QString("UPDATE SYS_PERSON SET UPDATETIME = :updateTime, DELFLAG = :flag WHERE ID = :id").arg(tm).arg(tmms).arg(id); + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":updateTime", tm); + query.bindValue(":flag", tmms); + + // 物理删除人员的人脸和虹膜数据 + QString delIrisSql = QString("DELETE FROM IRIS_DATA WHERE PERSON_ID = :personId"); + irisDel.prepare(delIrisSql); + irisDel.bindValue(":personId", id); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(sql); + query.exec(delIrisSql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + +// LOG_DEBUG(QString("删除人员SYS_PERSON[ID=%1][%2]").arg(id).arg(success).toStdString()); + + // 返回结果 + return success; +} diff --git a/dao/SysPersonDao.h b/dao/SysPersonDao.h new file mode 100644 index 0000000..e02e5ba --- /dev/null +++ b/dao/SysPersonDao.h @@ -0,0 +1,27 @@ +#ifndef SYSPERSONDAO_H +#define SYSPERSONDAO_H + +#include +#include "BaseDao.h" + +class SysPersonDao : public BaseDao +{ + Q_OBJECT +public: + explicit SysPersonDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + int findRecordCountByNameAndDept(QString name, QString dept); + QVector findRecordsByNameAndDept(QString name, QString dept, qint8 limit, qint16 offset); + QVector findRecordsByProperties(QVariantMap conditions); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); +signals: + +}; + +#endif // SYSPERSONDAO_H diff --git a/dao/dao.pri b/dao/dao.pri new file mode 100644 index 0000000..1e04ce4 --- /dev/null +++ b/dao/dao.pri @@ -0,0 +1,18 @@ + +HEADERS += $$PWD/BaseDao.h +HEADERS += $$PWD/IrisDataDao.h +HEADERS += $$PWD/RecognitionRecordsDao.h +HEADERS += $$PWD/SysPersonDao.h +HEADERS += $$PWD/SysDeptDao.h + +SOURCES += $$PWD/BaseDao.cpp +SOURCES += $$PWD/IrisDataDao.cpp +SOURCES += $$PWD/RecognitionRecordsDao.cpp +SOURCES += $$PWD/SysPersonDao.cpp +SOURCES += $$PWD/SysDeptDao.cpp + +HEADERS += $$PWD/util/ConnectionManager.h +SOURCES += $$PWD/util/ConnectionManager.cpp +#HEADERS += $$PWD/util/CacheManager.h +#SOURCES += $$PWD/util/CacheManager.cpp + diff --git a/dao/util/ConnectionManager.cpp b/dao/util/ConnectionManager.cpp new file mode 100644 index 0000000..84b17be --- /dev/null +++ b/dao/util/ConnectionManager.cpp @@ -0,0 +1,47 @@ +#include "ConnectionManager.h" +#include + +Q_GLOBAL_STATIC(ConnectionManager, cm) + +ConnectionManager::ConnectionManager(QObject *parent) : QObject(parent) +{ + // 初始化数据库连接 + if (QSqlDatabase::contains("qt_sql_dafault_connection")) + { + conn = QSqlDatabase::database("qt_sql_default_connection"); + } + else + { + conn = QSqlDatabase::addDatabase("QSQLITE"); + conn.setDatabaseName(QApplication::applicationDirPath() + "/data/casic.db"); + + bool succ = conn.open(); + if (succ == true) + { +// LOG_INFO(QString("打开数据库操作正常[Open Database Success]").toStdString()); + } else + { +// LOG_ERROR(QString("打开数据库操作失败[Open Database Failed]").toStdString()); + } + } +} + +ConnectionManager::~ConnectionManager() +{ + conn.close(); +} + +ConnectionManager* ConnectionManager::getInstance() +{ + return cm; +} + +QSqlDatabase ConnectionManager::getConnection() +{ + return this->conn; +} + +qint64 ConnectionManager::generateId() +{ + return this->idWorker.nextId(); +} diff --git a/dao/util/ConnectionManager.h b/dao/util/ConnectionManager.h new file mode 100644 index 0000000..84647e3 --- /dev/null +++ b/dao/util/ConnectionManager.h @@ -0,0 +1,34 @@ +#ifndef CONNECTIONMANAGER_H +#define CONNECTIONMANAGER_H + +#include +#include +#include "utils/id/IdWorker.h" +#include "utils/UtilInclude.h" + +using namespace Jiawa::Core; + +class ConnectionManager : public QObject +{ + Q_OBJECT +public: + explicit ConnectionManager(QObject *parent = nullptr); + ~ConnectionManager(); + + static ConnectionManager * getInstance(); + + QSqlDatabase getConnection(); + qint64 generateId(); + +private: + // 数据库连接 + QSqlDatabase conn; + + // 雪花id生成工具 + IdWorker &idWorker = Singleton::instance(); + +signals: + +}; + +#endif // CONNECTIONMANAGER_H diff --git a/device/IrisCameraCapEventHandler.cpp b/device/IrisCameraCapEventHandler.cpp new file mode 100644 index 0000000..45df089 --- /dev/null +++ b/device/IrisCameraCapEventHandler.cpp @@ -0,0 +1,103 @@ +#include "IrisCameraCapEventHandler.h" + +IrisCameraCapEventHandler::IrisCameraCapEventHandler(QObject *parent) : QObject(parent) +{ + +} + +void IrisCameraCapEventHandler::DoOnImageCaptured(CImageDataPointer &objImageDataPointer, void *pUserParam) +{ + if (objImageDataPointer.IsNull() == false) + { + CGXDevicePointer* cam = (CGXDevicePointer *) pUserParam; + + auto camName = cam->getPtr()->GetDeviceInfo().GetUserID(); + int width = objImageDataPointer->GetWidth(); + int height = objImageDataPointer->GetHeight(); + size_t leftKeyIndex = camName.find("left"); + size_t rightKeyIndex = camName.find("right"); + + uchar * pBuffer = (BYTE*)objImageDataPointer->GetBuffer(); + + // 相机拍摄下的图像1440*1080, 直接用于算法判断 + QImage img = QImage(pBuffer, width, height, QImage::Format_Grayscale8); // 用于展示 +// QImage imgAlgo = img.copy(0, 0, width, height); + + // 用于显示的图像需要缩小到400 * 300的尺寸 + img = img.scaled(SettingConfig::getInstance().IRIS_DISPLAY_HEIGHT, SettingConfig::getInstance().IRIS_DISPLAY_WIDTH); + img = img.transformed(QTransform().rotate(-90)); // 图像逆时针旋转90度 + + // 发送到界面进行显示 + emit sendIrisFrameToDraw(img); +// cv::Mat irisMat = ImageUtil::QImageToMat(imgAlgo); + +// irisInfo.data = imgAlgo; +// irisInfo.matData = irisMat; + +// // 将图像显示在注册页面的label上 +// // 并将虹膜信息对象存入队列中 +// ProMemory::getInstance().pushCasicIris(irisInfo); + +// if (leftKeyIndex >= 0 && leftKeyIndex < 32) +// { +// emit sendIrisFrameToDraw(img, 0); // 左眼画面 +// } else if (rightKeyIndex >= 0 && rightKeyIndex < 32) +// { +// emit sendIrisFrameToDraw(img, 1); // 右眼画面 +// } +/* + if (pBuffer != NULL) + { + // 创建虹膜信息对象 + CasicIrisInfo irisInfo; + irisInfo.hasEye = false; + if (leftKeyIndex >= 0 && leftKeyIndex < 32) + { + // 左眼相机拍摄的图像 + irisInfo.leftOrRight = "left"; + } else if (rightKeyIndex >= 0 && rightKeyIndex < 32) + { + // 右眼相机 + irisInfo.leftOrRight = "right"; + } + + if (ProMemory::getInstance().widgeFrame == CasicBioRecConst::RECOGNIZE_RESULT_FORM) + { + // 相机拍摄下的图像1280*960, 直接用于算法判断 + QImage imgDisp = QImage(pBuffer, width, height, QImage::Format_Grayscale8); + cv::Mat irisMat = ImageUtil::QImageToMat(imgDisp); + + irisInfo.data = imgDisp; + irisInfo.matData = irisMat; + + ProMemory::getInstance().pushCasicIris(irisInfo); + +// cv::imwrite(QString("D:\\irisLogs\\iristest-%1.bmp").arg(irisInfo.leftOrRight).toStdString(), irisMat); + } else if (ProMemory::getInstance().widgeFrame == CasicBioRecConst::ADD_PERSON_CAPTURE_IRIS) + { + // 相机拍摄下的图像1280*960, 直接用于算法判断 + QImage img = QImage(pBuffer, width, height, QImage::Format_Grayscale8); + QImage imgAlgo = img.copy(0, 0, width, height); + + // 用于显示的图像需要缩小到1/4的尺寸 + img = img.scaled(640, 480); + cv::Mat irisMat = ImageUtil::QImageToMat(imgAlgo); + + irisInfo.data = imgAlgo; + irisInfo.matData = irisMat; + + // 将图像显示在注册页面的label上 + // 并将虹膜信息对象存入队列中 + ProMemory::getInstance().pushCasicIris(irisInfo); + + if (leftKeyIndex >= 0 && leftKeyIndex < 32) + { + emit sendIrisFrameToDraw(img, 0); // 左眼画面 + } else if (rightKeyIndex >= 0 && rightKeyIndex < 32) + { + emit sendIrisFrameToDraw(img, 1); // 右眼画面 + } + } + }*/ + } +} diff --git a/device/IrisCameraCapEventHandler.h b/device/IrisCameraCapEventHandler.h new file mode 100644 index 0000000..ad75a97 --- /dev/null +++ b/device/IrisCameraCapEventHandler.h @@ -0,0 +1,30 @@ +#ifndef IRISCAMERACAPEVENTHANDLER_H +#define IRISCAMERACAPEVENTHANDLER_H + +#include +#include +#include "include/opencv2/opencv.hpp" +#include "include/daheng/GalaxyIncludes.h" + +//#include "casic/iris/CasicIrisInterface.h" +#include "ProMemory.h" + +#include "utils/UtilInclude.h" + +class IrisCameraCapEventHandler : public QObject, public ICaptureEventHandler +{ + Q_OBJECT +public: + explicit IrisCameraCapEventHandler(QObject *parent = nullptr); + + void DoOnImageCaptured(CImageDataPointer &objImageDataPointer, void *pUserParam); + +private: + unsigned char* pImageBuffer; + +signals: + void sendIrisFrameToDraw(QImage irisImage); + +}; + +#endif // IRISCAMERACAPEVENTHANDLER_H diff --git a/device/IrisCameraController.cpp b/device/IrisCameraController.cpp new file mode 100644 index 0000000..0928176 --- /dev/null +++ b/device/IrisCameraController.cpp @@ -0,0 +1,110 @@ +#include "IrisCameraController.h" + +IrisCameraController::IrisCameraController(QObject *parent) : QObject(parent) +{ + this->irisCamHandler = new IrisCameraCapEventHandler(this); +} +IrisCameraController::~IrisCameraController() +{ + this->closeIrisCamera(); +} + + +void IrisCameraController::initIrisCamera() +{ + IGXFactory::GetInstance().Init(); + + //枚举设备 + IGXFactory::GetInstance().UpdateDeviceList(1000, irisCamList); + + this->OpenDevice(); +} + +void IrisCameraController::openIrisCamera() +{ + //设置Buffer处理模式 + irisStreamFeaturePtr->GetEnumFeature("StreamBufferHandlingMode")->SetValue("OldestFirst"); + + //注册回调函数 + irisStreamPtr->RegisterCaptureCallback(irisCamHandler, &irisCamPtr); + + //开启流层通道 + irisStreamPtr->StartGrab(); + + //发送开采命令 + irisFeaturePtr->GetCommandFeature("AcquisitionStart")->Execute(); + + // 启动定时器 + TimeCounterUtil::getInstance().irisCapCounter->start(SettingConfig::getInstance().IRIS_FRAME_INTERVAL); // 50ms执行一次定时器 +} + +void IrisCameraController::closeIrisCamera() +{ + +} + +void IrisCameraController::startCapture() +{ + // 获取定时器, 绑定定时函数 + connect(TimeCounterUtil::getInstance().irisCapCounter, &QTimer::timeout, this, &IrisCameraController::getOneFaceFrm); +// LOG(DEBUG) << QString("[IrisCameraController][startCapture]虹膜相机拍图").toStdString(); +// LOG_DEBUG(QString("[IrisCameraController][startCapture]虹膜相机拍图").toStdString()); + +} +void IrisCameraController::stopCapture() +{ + // 获取定时器, 绑定定时函数 + disconnect(TimeCounterUtil::getInstance().irisCapCounter, &QTimer::timeout, this, &IrisCameraController::getOneFaceFrm); +// LOG(DEBUG) << QString("[IrisCameraController][stopCapture]虹膜相机停止拍图").toStdString(); +// LOG_DEBUG(QString("[IrisCameraController][stopCapture]虹膜相机停止拍图").toStdString()); + +} + +void IrisCameraController::getOneFaceFrm() +{ + // 发送软触发命令(在触发模式开启时有效) + irisFeaturePtr->GetCommandFeature("TriggerSoftware")->Execute(); +} + +void IrisCameraController::getLeftAndRightEyeFrame() +{ + irisFeaturePtr->GetCommandFeature("TriggerSoftware")->Execute(); +} + +void IrisCameraController::OpenDevice() +{ + auto device = irisCamList.at(0); + + irisCamPtr = IGXFactory::GetInstance().OpenDeviceByUserID(device.GetUserID(), GX_ACCESS_EXCLUSIVE); + irisFeaturePtr = irisCamPtr->GetRemoteFeatureControl(); + + // 判断设备流是否大于零, 如果大于零则打开流 + int nStreamCount = irisCamPtr->GetStreamCount(); + if (nStreamCount > 0) + { + irisStreamPtr = irisCamPtr->OpenStream(0); + irisStreamFeaturePtr = irisStreamPtr->GetFeatureControl(); + } + + // 建议用户在打开网络相机之后, 根据当前网络环境设置相机的流通道包长值, + // 以提高网络相机的采集性能, 设置方法参考以下代码。 + GX_DEVICE_CLASS_LIST objDeviceClass = irisCamPtr->GetDeviceInfo().GetDeviceClass(); + if(GX_DEVICE_CLASS_GEV == objDeviceClass) + { + // 判断设备是否支持流通道数据包功能 + if(true == irisFeaturePtr->IsImplemented("GevSCPSPacketSize")) + { + // 获取当前网络环境的最优包长值 + int nPacketSize = irisStreamPtr->GetOptimalPacketSize(); + // 将最优包长值设置为当前设备的流通道包长值 + irisFeaturePtr->GetIntFeature("GevSCPSPacketSize")->SetValue(nPacketSize); + } + } + + //设置采集模式为连续采集模式 + irisFeaturePtr->GetEnumFeature("AcquisitionMode")->SetValue("Continuous"); + + //设置触发模式关 + irisFeaturePtr->GetEnumFeature("TriggerMode")->SetValue("On"); + irisFeaturePtr->GetEnumFeature("TriggerSource")->SetValue("Software"); +} diff --git a/device/IrisCameraController.h b/device/IrisCameraController.h new file mode 100644 index 0000000..5d7e269 --- /dev/null +++ b/device/IrisCameraController.h @@ -0,0 +1,49 @@ +#ifndef IRISCAMERACONTROLLER_H +#define IRISCAMERACONTROLLER_H + +#include + +#include "IrisCameraCapEventHandler.h" + +class IrisCameraCapEventHandler; + +class IrisCameraController : public QObject +{ + Q_OBJECT +public: + explicit IrisCameraController(QObject *parent = nullptr); + ~IrisCameraController(); + + // 初始化并打开人脸相机 + void initIrisCamera(); + void openIrisCamera(); + void closeIrisCamera(); + + void startCapture(); + void stopCapture(); + + void getLeftAndRightEyeFrame(); + + IrisCameraCapEventHandler * irisCamHandler; + +private: + GxIAPICPP::gxdeviceinfo_vector irisCamList; + + CGXDevicePointer irisCamPtr; ///< 设备句柄 + + CGXStreamPointer irisStreamPtr; ///< 左眼设备流 + + CGXFeatureControlPointer irisFeaturePtr; ///< 左眼属性控制器 + + CGXFeatureControlPointer irisStreamFeaturePtr; ///< 左眼流层控制器对象 + + void OpenDevice(); + +signals: + +public slots: + void getOneFaceFrm(); + +}; + +#endif // IRISCAMERACONTROLLER_H diff --git a/AppConstants.h b/AppConstants.h new file mode 100644 index 0000000..296c53f --- /dev/null +++ b/AppConstants.h @@ -0,0 +1,28 @@ +#ifndef APPCONSTANTS_H +#define APPCONSTANTS_H + +class AppConstants +{ +public: + enum WidgeFrameName + { + MAIN_PAGE = 0, // 主页面 + PERSON_LIST_FORM = 1, // 人员列表页面 + ADD_PERSON_FORM = 2, // 添加人员页面 + ADD_PERSON_CAPTURE_FACE = 21, // 添加/编辑人员时进行人脸拍图 + ADD_PERSON_CAPTURE_IRIS = 22, // 添加/编辑人员时进行虹膜拍图 + SETTING_FORM = 3, // 设置页面 + RECOGNIZE_RESULT_FORM = 4, // 识别结果界面 + IDENTIFY_FORM = 5, // 识别界面 含识别中 和 识别结果 + LOCKSCREEN_FORM = 6 // 锁屏待机界面 + }; + + enum ApplicationState + { + STATE_WAIT = 0, // 待机 + STATE_WORKING = 1, // 工作状态 + STATE_IDENTIFYING = 2, // 识别中 + }; +}; + +#endif // APPCONSTANTS_H diff --git a/CasicIrisIdentify.pro b/CasicIrisIdentify.pro index 5d7fea6..575ce3d 100644 --- a/CasicIrisIdentify.pro +++ b/CasicIrisIdentify.pro @@ -1,4 +1,4 @@ -QT += core gui +QT += core gui sql network texttospeech greaterThan(QT_MAJOR_VERSION, 4): QT += widgets @@ -15,20 +15,46 @@ # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 -SOURCES += \ - main.cpp \ - IdentifyForm.cpp +include("dao/dao.pri") +include("device/device.pri") +include("utils/utils.pri") -HEADERS += \ - IdentifyForm.h +SOURCES += main.cpp +SOURCES += ProMemory.cpp +SOURCES += MainWindowForm.cpp +SOURCES += IdentifyForm.cpp +SOURCES += LockScreenForm.cpp -FORMS += \ - IdentifyForm.ui +HEADERS += AppConstants.h +HEADERS += ProMemory.h +HEADERS += MainWindowForm.h +HEADERS += IdentifyForm.h +HEADERS += LockScreenForm.h -TRANSLATIONS += \ - CasicIrisIdentify_zh_CN.ts +FORMS += MainWindowForm.ui +FORMS += IdentifyForm.ui +FORMS += LockScreenForm.ui + +RESOURCES += resource.qrc + +DISTFILES += conf/config.ini + +#TRANSLATIONS += CasicIrisIdentify_zh_CN.ts + +#INCLUDEPATH += include/spdlog +#DEPENDPATH += include/spdlog # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target + + +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lopencv_world420 +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lGxIAPICPPEx + +INCLUDEPATH += $$PWD/include/daheng +DEPENDPATH += $$PWD/include/daheng + +INCLUDEPATH += $$PWD/include +DEPENDPATH += $$PWD/include diff --git a/CasicIrisIdentify_zh_CN.ts b/CasicIrisIdentify_zh_CN.ts index 5526fe4..81900df 100644 --- a/CasicIrisIdentify_zh_CN.ts +++ b/CasicIrisIdentify_zh_CN.ts @@ -1,3 +1,12 @@ - + + + IdentifyForm + + + IdentifyForm + + + + diff --git a/IdentifyForm.cpp b/IdentifyForm.cpp index 348a897..ba1f251 100644 --- a/IdentifyForm.cpp +++ b/IdentifyForm.cpp @@ -1,4 +1,4 @@ -#include "IdentifyForm.h" +#include "IdentifyForm.h" #include "ui_IdentifyForm.h" IdentifyForm::IdentifyForm(QWidget *parent) @@ -6,6 +6,12 @@ , ui(new Ui::IdentifyForm) { ui->setupUi(this); + + // 初始化更新界面的定时器 + // 每秒执行一次 + connect(TimeCounterUtil::getInstance().clockCounter, &QTimer::timeout, this, &IdentifyForm::updateDateAndTime); + + TimeCounterUtil::getInstance().clockCounter->start(1000); } IdentifyForm::~IdentifyForm() @@ -13,3 +19,16 @@ delete ui; } +void IdentifyForm::drawIrisImageOnFrame(QImage image) +{ + // 只在识别界面才显示画面 + if (ui->wgtStacked->currentIndex() == 0) { + ui->labelVideo->setPixmap(QPixmap::fromImage(image)); + } +} + + +void IdentifyForm::updateDateAndTime() +{ + ui->labelTime->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd dddd HH:mm:ss")); +} diff --git a/IdentifyForm.h b/IdentifyForm.h index fc857a1..ae1cd22 100644 --- a/IdentifyForm.h +++ b/IdentifyForm.h @@ -1,7 +1,10 @@ -#ifndef IDENTIFYFORM_H +#ifndef IDENTIFYFORM_H #define IDENTIFYFORM_H #include +#include + +#include "utils/UtilInclude.h" QT_BEGIN_NAMESPACE namespace Ui { class IdentifyForm; } @@ -15,7 +18,14 @@ IdentifyForm(QWidget *parent = nullptr); ~IdentifyForm(); +public slots: + void drawIrisImageOnFrame(QImage image); + private: Ui::IdentifyForm *ui; + +private slots: + void updateDateAndTime(); + }; #endif // IDENTIFYFORM_H diff --git a/IdentifyForm.ui b/IdentifyForm.ui index c72a36f..879dc9a 100644 --- a/IdentifyForm.ui +++ b/IdentifyForm.ui @@ -6,13 +6,59 @@ 0 0 - 800 + 600 600 IdentifyForm + + + + 0 + 40 + 600 + 450 + + + + 0 + + + + + + 100 + 10 + 400 + 300 + + + + + + + + + + + + + + 0 + 0 + 600 + 40 + + + + TextLabel + + + Qt::AlignCenter + + diff --git a/LockScreenForm.cpp b/LockScreenForm.cpp new file mode 100644 index 0000000..58dc54b --- /dev/null +++ b/LockScreenForm.cpp @@ -0,0 +1,14 @@ +#include "LockScreenForm.h" +#include "ui_LockScreenForm.h" + +LockScreenForm::LockScreenForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::LockScreenForm) +{ + ui->setupUi(this); +} + +LockScreenForm::~LockScreenForm() +{ + delete ui; +} diff --git a/LockScreenForm.h b/LockScreenForm.h new file mode 100644 index 0000000..b5ded48 --- /dev/null +++ b/LockScreenForm.h @@ -0,0 +1,25 @@ +#ifndef LOCKSCREENFORM_H +#define LOCKSCREENFORM_H + +#include +#include + +#include "utils/UtilInclude.h" + +namespace Ui { +class LockScreenForm; +} + +class LockScreenForm : public QWidget +{ + Q_OBJECT + +public: + explicit LockScreenForm(QWidget *parent = nullptr); + ~LockScreenForm(); + +private: + Ui::LockScreenForm *ui; +}; + +#endif // LOCKSCREENFORM_H diff --git a/LockScreenForm.ui b/LockScreenForm.ui new file mode 100644 index 0000000..7f2a6db --- /dev/null +++ b/LockScreenForm.ui @@ -0,0 +1,45 @@ + + + LockScreenForm + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + 180 + 100 + 54 + 12 + + + + TextLabel + + + + + + 180 + 160 + 54 + 12 + + + + TextLabel + + + + + + diff --git a/MainWindowForm.cpp b/MainWindowForm.cpp new file mode 100644 index 0000000..84f8159 --- /dev/null +++ b/MainWindowForm.cpp @@ -0,0 +1,86 @@ +#include "MainWindowForm.h" +#include "ui_MainWindowForm.h" +#include + +MainWindowForm::MainWindowForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::MainWindowForm) +{ + ui->setupUi(this); + + // 设置窗口透明和大小、位置 + this->setWindowFlags(Qt::FramelessWindowHint); + this->move(1400, 15); + this->resize(SettingConfig::getInstance().WINDOW_WIDTH, SettingConfig::getInstance().WINDOW_HEIGHT); + + // 通过调色板的颜色来设置窗口的统一背景色 + qApp->setPalette(QPalette(QColor(SettingConfig::getInstance().WINDOW_BACKGROUND_COLOR))); + + // 加载css文件设置控件样式 + QFile file(QApplication::applicationDirPath() + "/qss/main.css"); + if (file.open(QFile::ReadOnly)) + { + QString qssStr = QLatin1String(file.readAll()); + this->setStyleSheet(qssStr); + file.close(); + } + + initFormsPtr(); + + // 设置标题文字 + ui->labelTitle->setText(SettingConfig::getInstance().WINDOW_TITLE); + ui->labelCopyright->setText(SettingConfig::getInstance().WINDOW_RIGHTS); + ui->labelVersion->setText(SettingConfig::getInstance().WINDOW_VERSION); + + // 初始化虹膜相机控制 + ProMemory::getInstance().irisCam = new IrisCameraController(this); + ProMemory::getInstance().irisCam->initIrisCamera(); + ProMemory::getInstance().irisCam->openIrisCamera(); + connect(ProMemory::getInstance().irisCam->irisCamHandler, &IrisCameraCapEventHandler::sendIrisFrameToDraw, identifyForm, &IdentifyForm::drawIrisImageOnFrame); + +// LOG_INFO(QString("应用程序启动成功[Application Startup Success]").toStdString()); + qDebug() << "应用程序启动成功[Application Startup Success]"; + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::IDENTIFY_FORM; + ui->wdgtStatced->setCurrentWidget(identifyForm); + + // 开始虹膜相机拍图 + ProMemory::getInstance().irisCam->startCapture(); +} + +MainWindowForm::~MainWindowForm() +{ + delete ui; +} + +void MainWindowForm::lockScreen() +{ + ui->wdgtStatced->setCurrentWidget(lockScreenForm); + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::LOCKSCREEN_FORM; + ProMemory::getInstance().appState = AppConstants::ApplicationState::STATE_WAIT; +} + +void MainWindowForm::keyPressEvent(QKeyEvent *event) +{ + switch (event->key()) { + case Qt::Key_Escape: + QTimer::singleShot(100, qApp, [=](){ + QApplication::quit(); + }); + + default: + QWidget::keyPressEvent(event); + } +} + +void MainWindowForm::initFormsPtr() +{ + // 初始化各个form + lockScreenForm = new LockScreenForm(this); + identifyForm = new IdentifyForm(this); + + // 将form添加到statcked widget中 + ui->wdgtStatced->addWidget(identifyForm); + ui->wdgtStatced->addWidget(lockScreenForm); + + // 绑定按钮函数 +} diff --git a/MainWindowForm.h b/MainWindowForm.h new file mode 100644 index 0000000..7fb2d89 --- /dev/null +++ b/MainWindowForm.h @@ -0,0 +1,38 @@ +#ifndef MAINWINDOWFORM_H +#define MAINWINDOWFORM_H + +#include +#include +#include + +#include "utils/UtilInclude.h" +#include "ProMemory.h" +#include "LockScreenForm.h" +#include "IdentifyForm.h" + +namespace Ui { +class MainWindowForm; +} + +class MainWindowForm : public QWidget +{ + Q_OBJECT + +public: + explicit MainWindowForm(QWidget *parent = nullptr); + ~MainWindowForm(); + +public slots: + void lockScreen(); + +private: + Ui::MainWindowForm *ui; + LockScreenForm * lockScreenForm; + IdentifyForm * identifyForm; + + void keyPressEvent(QKeyEvent *event); + + void initFormsPtr(); +}; + +#endif // MAINWINDOWFORM_H diff --git a/MainWindowForm.ui b/MainWindowForm.ui new file mode 100644 index 0000000..e793ebf --- /dev/null +++ b/MainWindowForm.ui @@ -0,0 +1,85 @@ + + + MainWindowForm + + + + 0 + 0 + 600 + 1024 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + 0 + 0 + 600 + 84 + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + + + + TextLabel + + + Qt::AlignBottom|Qt::AlignHCenter + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + diff --git a/ProMemory.cpp b/ProMemory.cpp new file mode 100644 index 0000000..19e7403 --- /dev/null +++ b/ProMemory.cpp @@ -0,0 +1,84 @@ +#include "ProMemory.h" + +ProMemory::ProMemory() +{ + +} + +ProMemory::~ProMemory() +{ + +} + +/* +void ProMemory::pushCasicIris(CasicIrisInfo irisInfo) +{ + QMutex mutex; + mutex.lock(); + if (this->irisQueue.size() > 30) + { + QStack empty; + std::swap(empty, irisQueue); + } + + irisQueue.push(irisInfo); + mutex.unlock(); +} +CasicIrisInfo ProMemory::popCasicIris() +{ + CasicIrisInfo result; + + QMutex mutex; + mutex.lock(); + if (this->irisQueue.size() > 0) + { + result = irisQueue.pop(); + } + + mutex.unlock(); + + return result; +} +*/ +int ProMemory::getIrisQueueSize() +{ + int size = 0; + + QMutex mutex; + mutex.lock(); + +// size = this->irisQueue.size(); + + mutex.unlock(); + + return size; +} +bool ProMemory::isIrisQueueEmpty() +{ + bool empty = true; + + QMutex mutex; + mutex.lock(); + +// empty = this->irisQueue.isEmpty(); + + mutex.unlock(); + + return empty; +} +void ProMemory::clearIrisQueue() +{ + QMutex mutex; + mutex.lock(); + +// QStack empty; +// std::swap(empty, irisQueue); + + mutex.unlock(); +} + + +void ProMemory::initIrisFeatures(QString personId) +{ +// irisRegistPro->sendDataToExract(QByteArray(QString("[-u]").append(personId).toLocal8Bit())); +} diff --git a/ProMemory.h b/ProMemory.h new file mode 100644 index 0000000..2ecd653 --- /dev/null +++ b/ProMemory.h @@ -0,0 +1,52 @@ +#ifndef PROMEMORY_H +#define PROMEMORY_H + +#include +#include + +#include "AppConstants.h" +//#include "casic/iris/CasicIrisInfo.h" +#include "dao/IrisDataDao.h" + +#include "device/IrisCameraController.h" +//#include "device/iris/IrisRegistProcess.h" +//#include "device/iris/IrisRecogProcess.h" + +class IrisCameraController; +class IrisRegistProcess; +class IrisRecogProcess; + +class ProMemory +{ +public: + ~ProMemory(); + ProMemory(const ProMemory&)=delete; + ProMemory& operator=(const ProMemory&)=delete; + + static ProMemory& getInstance() { + static ProMemory instance; + return instance; + } + +// void pushCasicIris(CasicIrisInfo irisInfo); +// CasicIrisInfo popCasicIris(); + int getIrisQueueSize(); + bool isIrisQueueEmpty(); + void clearIrisQueue(); + + volatile int widgeFrame = 0; // 当前显示的界面 + volatile int appState = 0; // 当前程序所处的状态 + + void initIrisFeatures(QString personId = ""); // 初始化虹膜特征值集合 + + IrisCameraController * irisCam; + IrisRecogProcess * irisRecogPro; + +private: + ProMemory(); + +// QStack irisQueue; // 虹膜信息队列 + QVector irisFeatures; // 虹膜特征值集合 +}; + +#endif // PROMEMORY_H diff --git a/conf/config.ini b/conf/config.ini new file mode 100644 index 0000000..66e46ad --- /dev/null +++ b/conf/config.ini @@ -0,0 +1,67 @@ +[recognize] +#最大允许识别时间(ms) +maxMatchTime=10000 +#识别成功界面停留时间(ms) +successTipsLast=5000 +#识别失败界面停留时间(ms) +failureTipsLast=3000 +#人脸识别最大尝试次数 +maxFaceTryCount=20 +#持续没找到人脸的最大次数 +maxFaceNotFoundCount=500 +#注册时最小人脸 +minFaceRegist=240 +#识别时最小人脸 +minFaceRecog=100 + +#虹膜识别最大尝试次数 +maxIrisTryCount=10 +#虹膜识别持续没有找到眼的最大次数 +maxEyeNotFoundCount=50 + +#识别方式[1=人脸;2=虹膜;3=双认证;4=任意] +recogType=4 + +[window] +#界面窗口宽(px) +width=600 +#界面窗口高(px) +height=1024 +#统一背景色 +backgroundColor="#FFFFFF" +#标题 +title="虹膜识别终端" + +[work] +#工作状态检测时最小人脸范围 +minFaceSize=160 +#人脸范围最小横坐标 +minFacePosX=320 +#人脸范围最大横坐标 +maxFacePosX=960 +#人脸范围最小纵坐标 +minFacePosY=180 +#人脸范围最大纵坐标 +maxFacePosY=540 +#人脸太近阈值 +faceCloseSize=360 +#人脸太远阈值 +faceFarSize=480 + +[camera] +#虹膜相机取一幅画面的时间间隔(ms) +irisFrameInterval=100 +#虹膜相机拍摄宽度 +irisFrameWidth=1440 +#虹膜相机拍摄高度 +irisFrameHeight=1080 +#虹膜图像高度 +irisWidth=640 +#虹膜图像高度 +irisHeight=480 + +[log] +#日志文件位置 +logFile="d://irisLogs//casic_log.txt" +#日志级别 +logLevel="trace" diff --git a/dao/BaseDao.cpp b/dao/BaseDao.cpp new file mode 100644 index 0000000..f51c144 --- /dev/null +++ b/dao/BaseDao.cpp @@ -0,0 +1,12 @@ +#include "BaseDao.h" +#include "dao/util/ConnectionManager.h" + +BaseDao::BaseDao(QObject *parent) : QObject(parent) +{ + +} + +BaseDao::~BaseDao() +{ + +} diff --git a/dao/BaseDao.h b/dao/BaseDao.h new file mode 100644 index 0000000..1693c88 --- /dev/null +++ b/dao/BaseDao.h @@ -0,0 +1,32 @@ +#ifndef BASEDAO_H +#define BASEDAO_H + +#include +#include +#include +#include + +#include "dao/util/ConnectionManager.h" +#include "utils/UtilInclude.h" + +class BaseDao : public QObject +{ + Q_OBJECT +public: + explicit BaseDao(QObject *parent = nullptr); + ~BaseDao(); + + virtual QVector findAllRecord() = 0; + virtual QVariantMap findRecordById(QString id) = 0; + + virtual QString save(QVariantMap object) = 0; + virtual bool edit(QVariantMap newObject, QString id) = 0; + virtual bool dele(QString id) = 0; + +private: + +signals: + +}; + +#endif // BASEDAO_H diff --git a/dao/IrisDataDao.cpp b/dao/IrisDataDao.cpp new file mode 100644 index 0000000..37a0ed6 --- /dev/null +++ b/dao/IrisDataDao.cpp @@ -0,0 +1,204 @@ +#include "IrisDataDao.h" + +IrisDataDao::IrisDataDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector IrisDataDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM IRIS_DATA"; + query.prepare(sql); + + // 执行查询 + query.exec(); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + item.insert("id", query.value("id").toString()); + item.insert("person_id", query.value("person_id").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("left_iris_code1", query.value("left_iris_code1")); + item.insert("left_iris_code2", query.value("left_iris_code2")); + item.insert("left_iris_code3", query.value("left_iris_code3")); + item.insert("right_iris_code1", query.value("right_iris_code1")); + item.insert("right_iris_code2", query.value("right_iris_code2")); + item.insert("right_iris_code3", query.value("right_iris_code3")); + + result.append(item); + } + +// LOG_DEBUG(QString("查询IRIS_DATA表的所有记录[结果数:%1]").arg(result.size()).toStdString()); + return result; +} + +QVariantMap IrisDataDao::findRecordById(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM IRIS_DATA WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + // 获取结果 + if (query.next()) + { + result.insert("id", query.value("id").toString()); + result.insert("person_id", query.value("person_id").toLongLong()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("left_iris_code1", query.value("left_iris_code1")); + result.insert("left_iris_code2", query.value("left_iris_code2")); + result.insert("left_iris_code3", query.value("left_iris_code3")); + result.insert("right_iris_code1", query.value("right_iris_code1")); + result.insert("right_iris_code2", query.value("right_iris_code2")); + result.insert("right_iris_code3", query.value("right_iris_code3")); + } + +// LOG_DEBUG(QString("根据id查询IRIS_DATA表的记录[id=%1]").arg(id).toStdString()); + return result; +} + +QVariantMap IrisDataDao::findRecordByPersonId(QString personId) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM IRIS_DATA WHERE PERSON_ID = :personId"); + query.prepare(sql); + query.bindValue(":personId", personId); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + if (query.next()) + { + result.insert("id", query.value("id").toString()); + result.insert("person_id", query.value("person_id").toLongLong()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("left_iris_code1", query.value("left_iris_code1")); + result.insert("left_iris_code2", query.value("left_iris_code2")); + result.insert("left_iris_code3", query.value("left_iris_code3")); + result.insert("right_iris_code1", query.value("right_iris_code1")); + result.insert("right_iris_code2", query.value("right_iris_code2")); + result.insert("right_iris_code3", query.value("right_iris_code3")); + } + +// LOG_DEBUG(QString("根据personId查询IRIS_DATA表的记录[personId=%1]").arg(personId).toStdString()); + return result; +} + + +QString IrisDataDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + + // INSERT语句 + QString sql = QString("INSERT INTO IRIS_DATA (ID, PERSON_ID, ID_CARD_NO, LEFT_IRIS_CODE1, RIGHT_IRIS_CODE1) VALUES (:id, :personId, :idCardNo, :left1, :right1)"); + + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":personId", object.value("person_id").toString()); + query.bindValue(":idCardNo", object.value("id_card_no").toString()); + query.bindValue(":left1", object.value("left_iris_code1")); + query.bindValue(":right1", object.value("right_iris_code1")); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(); + +// LOG_DEBUG(QString("保存虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool IrisDataDao::edit(QVariantMap newObject, QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // UPDATE语句 + if (!newObject.contains("left_iris_code1") || !newObject.contains("right_iris_code1")){ + return false; + } + QString sql = QString("UPDATE IRIS_DATA SET LEFT_IRIS_CODE1 = :left1, RIGHT_IRIS_CODE1 = :right1 WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":left1", newObject.value("left_iris_code1")); + query.bindValue(":right1", newObject.value("right_iris_code1")); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(); + +// LOG_DEBUG(QString("编辑虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; +} + + +bool IrisDataDao::dele(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + QString sql = QString("DELETE FROM IRIS_DATA WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(); + +// LOG_DEBUG(QString("删除虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; +} diff --git a/dao/IrisDataDao.h b/dao/IrisDataDao.h new file mode 100644 index 0000000..c74dbbd --- /dev/null +++ b/dao/IrisDataDao.h @@ -0,0 +1,25 @@ +#ifndef IRISDATADAO_H +#define IRISDATADAO_H + +#include +#include "BaseDao.h" + +class IrisDataDao : public BaseDao +{ + Q_OBJECT +public: + explicit IrisDataDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + QVariantMap findRecordByPersonId(QString personId); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +signals: + +}; + +#endif // IRISDATADAO_H diff --git a/dao/RecognitionRecordsDao.cpp b/dao/RecognitionRecordsDao.cpp new file mode 100644 index 0000000..40db453 --- /dev/null +++ b/dao/RecognitionRecordsDao.cpp @@ -0,0 +1,100 @@ +#include "RecognitionRecordsDao.h" + +RecognitionRecordsDao::RecognitionRecordsDao(QObject *parent) : BaseDao(parent) +{ + +} + + +QVector RecognitionRecordsDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM RECOGNITION_RECORDS"; + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + item.insert("id", query.value("id").toLongLong()); + result.append(item); + } + +// LOG_DEBUG(QString("查询RECOGNITION_RECORDS表的所有记录[记录数:%1]").arg(result.size()).toStdString()); + return result; +} + +QVariantMap RecognitionRecordsDao::findRecordById(QString id) +{ + QVariantMap item; + return item; +} + +QString RecognitionRecordsDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + + // INSERT语句 + QString sql = QString("INSERT INTO RECOGNITION_RECORDS (ID, PERSON_ID, DATETIME, REC_TYPE, DEV_CODE, DOOR_CODE, INOUT_TYPE) " + "VALUES (:id, :personId, :datetime, :recType, :devCode, :doorCode, :inoutType)"); + + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":personId", object.value("person_id").toString()); + query.bindValue(":datetime", object.value("date_time").toString()); + query.bindValue(":recType", object.value("rec_type").toString()); + query.bindValue(":devCode", object.value("dev_code").toString()); + query.bindValue(":doorCode", object.value("door_code").toString()); + query.bindValue(":inoutType", object.value("inout_type").toString()); + +// LOG_DEBUG(sql.toStdString()); + + // 插入识别的log日志 + QString logStr = QString("INSERT INTO RECOGNITION_LOGS (ID, LOG_INFO) VALUES (:id, :logInfo)"); + + QSqlQuery logQuery(ConnectionManager::getInstance()->getConnection()); + logQuery.prepare(logStr); + logQuery.bindValue(":id", id); + logQuery.bindValue(":logInfo", object.value("debug_info").toString()); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(); + logQuery.exec(); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool RecognitionRecordsDao::edit(QVariantMap newObject, QString id) +{ + return false; +} + +bool RecognitionRecordsDao::dele(QString id) +{ + return false; +} diff --git a/dao/RecognitionRecordsDao.h b/dao/RecognitionRecordsDao.h new file mode 100644 index 0000000..38de7c9 --- /dev/null +++ b/dao/RecognitionRecordsDao.h @@ -0,0 +1,23 @@ +#ifndef RECOGNITIONRECORDSDAO_H +#define RECOGNITIONRECORDSDAO_H + +#include +#include "BaseDao.h" +class RecognitionRecordsDao: public BaseDao +{ + Q_OBJECT +public: + explicit RecognitionRecordsDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +signals: + +}; + +#endif // RECOGNITIONRECORDSDAO_H diff --git a/dao/SysDeptDao.cpp b/dao/SysDeptDao.cpp new file mode 100644 index 0000000..22f9946 --- /dev/null +++ b/dao/SysDeptDao.cpp @@ -0,0 +1,88 @@ +#include "SysDeptDao.h" + +SysDeptDao::SysDeptDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector SysDeptDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_DEPT WHERE PID != '-1' ORDER BY PID, NUM"; + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + item.insert("id", query.value("id").toString()); + item.insert("pid", query.value("pid").toString()); + item.insert("pids", query.value("pids").toString()); + item.insert("simplename", query.value("simplename").toString()); + item.insert("fullname", query.value("fullname").toString()); + } + +// LOG_TRACE(QString("查询表[SYS_DEPT]的所有记录[%1][%2]").arg(result.size()).arg(sql).toStdString()); + + return result; +} + +QVariantMap SysDeptDao::findRecordById(QString id) +{ + QVariantMap item; + return item; + + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM SYS_DEPT WHERE SYS_DEPT.ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + // 获取结果集的大小 + query.last(); + int count = query.at() + 1; + + if (count >=1) + { + query.first(); + + result.insert("id", query.value("id").toString()); + result.insert("pid", query.value("pid").toString()); + result.insert("pids", query.value("pids").toString()); + result.insert("simplename", query.value("simplename").toString()); + result.insert("fullname", query.value("fullname").toString()); + } + +// LOG_TRACE(QString("根据id查询SYS_DEPT表的记录[ID=%1][%2]").arg(id).arg(sql).toStdString()); + + return result; +} + + +QString SysDeptDao::save(QVariantMap object) +{ + return "0"; +} +bool SysDeptDao::edit(QVariantMap newObject, QString id) +{ + return true; +} +bool SysDeptDao::dele(QString id) +{ + return true; +} diff --git a/dao/SysDeptDao.h b/dao/SysDeptDao.h new file mode 100644 index 0000000..e07a09f --- /dev/null +++ b/dao/SysDeptDao.h @@ -0,0 +1,24 @@ +#ifndef SYSDEPTDAO_H +#define SYSDEPTDAO_H + +#include +#include "BaseDao.h" + +class SysDeptDao : public BaseDao +{ + Q_OBJECT +public: + explicit SysDeptDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +private: + +}; + +#endif // SYSDEPTDAO_H diff --git a/dao/SysPersonDao.cpp b/dao/SysPersonDao.cpp new file mode 100644 index 0000000..dd9480f --- /dev/null +++ b/dao/SysPersonDao.cpp @@ -0,0 +1,371 @@ +#include "SysPersonDao.h" + + +SysPersonDao::SysPersonDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector SysPersonDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0'"; + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + count++; + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + result.append(item); + } + +// LOG(TRACE) << QString("查询SYS_PERSON表的所有记录[%1]").arg(count).toStdString(); +// LOG_TRACE(QString("查询SYS_PERSON表的所有记录[%1]").arg(count).toStdString()); + + return result; +} + +QVariantMap SysPersonDao::findRecordById(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0' AND SYS_PERSON.ID = '%1'").arg(id); + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVariantMap result; + + // 获取结果集的大小 + query.last(); + int count = query.at() + 1; + + if (count >=1) + { + query.first(); + + result.insert("id", query.value("id").toString()); + result.insert("delflag", query.value("delflag").toString()); + result.insert("createtime", query.value("createtime").toString()); + result.insert("updatetime", query.value("updatetime").toString()); + result.insert("name", query.value("name").toString()); + result.insert("gender", query.value("gender").toString()); + result.insert("deptid", query.value("deptid").toString()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("remarks", query.value("remarks").toString()); + result.insert("person_code", query.value("person_code").toString()); + result.insert("deptname", query.value("fullname").toString()); + result.insert("sync_id", query.value("sync_id").toString()); + result.insert("hasFace", query.value("face_valid").toString()); + result.insert("hasIris", query.value("iris_valid").toString()); + } + +// LOG(TRACE) << QString("根据id查询SYS_PERSON表的记录[id=%1][%2]").arg(id).arg(sql).toStdString(); +// LOG_TRACE(QString("根据id查询SYS_PERSON表的记录[id=%1][%2]").arg(id).arg(sql).toStdString()); + + return result; +} + +int SysPersonDao::findRecordCountByNameAndDept(QString name, QString dept) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT COUNT(P.ID) AS RECCT FROM SYS_PERSON P LEFT JOIN SYS_DEPT D ON P.DEPTID = D.ID WHERE P.DELFLAG = '0'"; + if (name.isEmpty() == false) + { + sql += " AND P.NAME LIKE '%" + name + "%'"; + } + if (dept.isEmpty() == false && dept.indexOf("-1") < 0) + { + sql += QString(" AND ((P.DEPTID = '%1') OR (D.PIDS LIKE '%,%1,%'))").arg(dept); + } + + // 执行查询 + query.exec(sql); + + // 返回结果 + int result; + + // 遍历查询结果 + if (query.next()) { + result = query.value("RECCT").toInt(); + } + +// LOG(TRACE) << QString("根据姓名和部门查询SYS_PERSON记录总数[%1][%2]").arg(result).arg(sql).toStdString(); +// LOG_TRACE(QString("根据姓名和部门查询SYS_PERSON记录总数[%1][%2]").arg(result).arg(sql).toStdString()); + + return result; +} + +QVector SysPersonDao::findRecordsByNameAndDept(QString name, QString dept, qint8 limit, qint16 offset) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON P LEFT JOIN SYS_DEPT D ON P.DEPTID = D.ID WHERE P.DELFLAG = '0'"; + if (name.isEmpty() == false) + { + sql += " AND P.NAME LIKE '%" + name + "%'"; + } + if (dept.isEmpty() == false && dept.indexOf("-1") < 0) + { + sql += QString(" AND ((P.DEPTID = '%1') OR (D.PIDS LIKE '%,%1,%'))").arg(dept); + } + + sql += QString(" LIMIT %1 OFFSET %2").arg(limit).arg(offset); + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + count++; + + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + + result.append(item); + } + +// LOG(TRACE) << QString("根据姓名和部门分页查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString(); +// LOG_TRACE(QString("根据姓名和部门分页查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString()); + + return result; +} + +QVector SysPersonDao::findRecordsByProperties(QVariantMap conditions) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0'"; + QVariantMap::iterator it; + for (it = conditions.begin(); it != conditions.end(); it++) + { + sql += QString(" AND SYS_PERSON.%1 = %2").arg(it.key()).arg(it.value().toString()); + } + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + count++; + + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + + result.append(item); + } + +// LOG(TRACE) << QString("根据属性值查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString(); +// LOG_TRACE(QString("根据属性值查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString()); + + return result; +} + +QString SysPersonDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + + // INSERT语句 + QString sql = QString("INSERT INTO SYS_PERSON " + "(ID, DELFLAG, CREATETIME, UPDATETIME, " + "NAME, GENDER, DEPTID, ID_CARD_NO, " + "REMARKS, PERSON_CODE, SYNC_ID, FACE_VALID, IRIS_VALID) " + "VALUES ('%1', '0', '%2', '%2', '%3', '%4', '%5', '%6', '%7', '%8', '%9', 0, 0)") + .arg(id).arg(tm) + .arg(object.value("name").toString()) + .arg(object.value("gender").toString()) + .arg(object.value("deptid").toString()) + .arg(object.value("id_card_no").toString()) + .arg(object.value("remarks").toString()) + .arg(object.value("person_code").toString()) + .arg(object.value("sync_id").toString()); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(sql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { +// LOG(DEBUG) << QString("保存SYS_PERSON记录成功[ID = %1][%2]").arg(id).arg(sql).toStdString(); +// LOG_DEBUG(QString("保存SYS_PERSON记录成功[ID = %1][%2]").arg(id).arg(sql).toStdString()); + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool SysPersonDao::edit(QVariantMap newObject, QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + + // UPDATE语句 + QString sql = QString("UPDATE SYS_PERSON SET UPDATETIME = '%1'").arg(tm); + if (newObject.contains("name")) + { + sql.append(QString(", NAME = '%1'").arg(newObject.value("name").toString())); + } + if (newObject.contains("gender")) + { + sql.append(QString(", GENDER = '%1'").arg(newObject.value("gender").toString())); + } + if (newObject.contains("deptid")) + { + sql.append(QString(", DEPTID = '%1'").arg(newObject.value("deptid").toString())); + } + if (newObject.contains("person_code")) + { + sql.append(QString(", PERSON_CODE = '%1'").arg(newObject.value("person_code").toString())); + } + if (newObject.contains("face_valid")) + { + sql.append(QString(", FACE_VALID = '%1'").arg(newObject.value("face_valid").toString())); + } + if (newObject.contains("iris_valid")) + { + sql.append(QString(", IRIS_VALID = '%1'").arg(newObject.value("iris_valid").toString())); + } + + sql.append(QString(" WHERE ID = '%1'").arg(id)); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(sql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + +// LOG(DEBUG) << QString("编辑人员[ID=%1][%2]").arg(id).arg(sql).toStdString(); +// LOG_DEBUG(QString("编辑人员[ID=%1][%2]").arg(id).arg(sql).toStdString()); + + // 返回结果 + return success; +} + +bool SysPersonDao::dele(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + QSqlQuery irisDel(ConnectionManager::getInstance()->getConnection()); + + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + qint64 tmms = QDateTime::currentDateTime().toMSecsSinceEpoch(); + + // UPDATE语句 + QString sql = QString("UPDATE SYS_PERSON SET UPDATETIME = :updateTime, DELFLAG = :flag WHERE ID = :id").arg(tm).arg(tmms).arg(id); + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":updateTime", tm); + query.bindValue(":flag", tmms); + + // 物理删除人员的人脸和虹膜数据 + QString delIrisSql = QString("DELETE FROM IRIS_DATA WHERE PERSON_ID = :personId"); + irisDel.prepare(delIrisSql); + irisDel.bindValue(":personId", id); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(sql); + query.exec(delIrisSql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + +// LOG_DEBUG(QString("删除人员SYS_PERSON[ID=%1][%2]").arg(id).arg(success).toStdString()); + + // 返回结果 + return success; +} diff --git a/dao/SysPersonDao.h b/dao/SysPersonDao.h new file mode 100644 index 0000000..e02e5ba --- /dev/null +++ b/dao/SysPersonDao.h @@ -0,0 +1,27 @@ +#ifndef SYSPERSONDAO_H +#define SYSPERSONDAO_H + +#include +#include "BaseDao.h" + +class SysPersonDao : public BaseDao +{ + Q_OBJECT +public: + explicit SysPersonDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + int findRecordCountByNameAndDept(QString name, QString dept); + QVector findRecordsByNameAndDept(QString name, QString dept, qint8 limit, qint16 offset); + QVector findRecordsByProperties(QVariantMap conditions); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); +signals: + +}; + +#endif // SYSPERSONDAO_H diff --git a/dao/dao.pri b/dao/dao.pri new file mode 100644 index 0000000..1e04ce4 --- /dev/null +++ b/dao/dao.pri @@ -0,0 +1,18 @@ + +HEADERS += $$PWD/BaseDao.h +HEADERS += $$PWD/IrisDataDao.h +HEADERS += $$PWD/RecognitionRecordsDao.h +HEADERS += $$PWD/SysPersonDao.h +HEADERS += $$PWD/SysDeptDao.h + +SOURCES += $$PWD/BaseDao.cpp +SOURCES += $$PWD/IrisDataDao.cpp +SOURCES += $$PWD/RecognitionRecordsDao.cpp +SOURCES += $$PWD/SysPersonDao.cpp +SOURCES += $$PWD/SysDeptDao.cpp + +HEADERS += $$PWD/util/ConnectionManager.h +SOURCES += $$PWD/util/ConnectionManager.cpp +#HEADERS += $$PWD/util/CacheManager.h +#SOURCES += $$PWD/util/CacheManager.cpp + diff --git a/dao/util/ConnectionManager.cpp b/dao/util/ConnectionManager.cpp new file mode 100644 index 0000000..84b17be --- /dev/null +++ b/dao/util/ConnectionManager.cpp @@ -0,0 +1,47 @@ +#include "ConnectionManager.h" +#include + +Q_GLOBAL_STATIC(ConnectionManager, cm) + +ConnectionManager::ConnectionManager(QObject *parent) : QObject(parent) +{ + // 初始化数据库连接 + if (QSqlDatabase::contains("qt_sql_dafault_connection")) + { + conn = QSqlDatabase::database("qt_sql_default_connection"); + } + else + { + conn = QSqlDatabase::addDatabase("QSQLITE"); + conn.setDatabaseName(QApplication::applicationDirPath() + "/data/casic.db"); + + bool succ = conn.open(); + if (succ == true) + { +// LOG_INFO(QString("打开数据库操作正常[Open Database Success]").toStdString()); + } else + { +// LOG_ERROR(QString("打开数据库操作失败[Open Database Failed]").toStdString()); + } + } +} + +ConnectionManager::~ConnectionManager() +{ + conn.close(); +} + +ConnectionManager* ConnectionManager::getInstance() +{ + return cm; +} + +QSqlDatabase ConnectionManager::getConnection() +{ + return this->conn; +} + +qint64 ConnectionManager::generateId() +{ + return this->idWorker.nextId(); +} diff --git a/dao/util/ConnectionManager.h b/dao/util/ConnectionManager.h new file mode 100644 index 0000000..84647e3 --- /dev/null +++ b/dao/util/ConnectionManager.h @@ -0,0 +1,34 @@ +#ifndef CONNECTIONMANAGER_H +#define CONNECTIONMANAGER_H + +#include +#include +#include "utils/id/IdWorker.h" +#include "utils/UtilInclude.h" + +using namespace Jiawa::Core; + +class ConnectionManager : public QObject +{ + Q_OBJECT +public: + explicit ConnectionManager(QObject *parent = nullptr); + ~ConnectionManager(); + + static ConnectionManager * getInstance(); + + QSqlDatabase getConnection(); + qint64 generateId(); + +private: + // 数据库连接 + QSqlDatabase conn; + + // 雪花id生成工具 + IdWorker &idWorker = Singleton::instance(); + +signals: + +}; + +#endif // CONNECTIONMANAGER_H diff --git a/device/IrisCameraCapEventHandler.cpp b/device/IrisCameraCapEventHandler.cpp new file mode 100644 index 0000000..45df089 --- /dev/null +++ b/device/IrisCameraCapEventHandler.cpp @@ -0,0 +1,103 @@ +#include "IrisCameraCapEventHandler.h" + +IrisCameraCapEventHandler::IrisCameraCapEventHandler(QObject *parent) : QObject(parent) +{ + +} + +void IrisCameraCapEventHandler::DoOnImageCaptured(CImageDataPointer &objImageDataPointer, void *pUserParam) +{ + if (objImageDataPointer.IsNull() == false) + { + CGXDevicePointer* cam = (CGXDevicePointer *) pUserParam; + + auto camName = cam->getPtr()->GetDeviceInfo().GetUserID(); + int width = objImageDataPointer->GetWidth(); + int height = objImageDataPointer->GetHeight(); + size_t leftKeyIndex = camName.find("left"); + size_t rightKeyIndex = camName.find("right"); + + uchar * pBuffer = (BYTE*)objImageDataPointer->GetBuffer(); + + // 相机拍摄下的图像1440*1080, 直接用于算法判断 + QImage img = QImage(pBuffer, width, height, QImage::Format_Grayscale8); // 用于展示 +// QImage imgAlgo = img.copy(0, 0, width, height); + + // 用于显示的图像需要缩小到400 * 300的尺寸 + img = img.scaled(SettingConfig::getInstance().IRIS_DISPLAY_HEIGHT, SettingConfig::getInstance().IRIS_DISPLAY_WIDTH); + img = img.transformed(QTransform().rotate(-90)); // 图像逆时针旋转90度 + + // 发送到界面进行显示 + emit sendIrisFrameToDraw(img); +// cv::Mat irisMat = ImageUtil::QImageToMat(imgAlgo); + +// irisInfo.data = imgAlgo; +// irisInfo.matData = irisMat; + +// // 将图像显示在注册页面的label上 +// // 并将虹膜信息对象存入队列中 +// ProMemory::getInstance().pushCasicIris(irisInfo); + +// if (leftKeyIndex >= 0 && leftKeyIndex < 32) +// { +// emit sendIrisFrameToDraw(img, 0); // 左眼画面 +// } else if (rightKeyIndex >= 0 && rightKeyIndex < 32) +// { +// emit sendIrisFrameToDraw(img, 1); // 右眼画面 +// } +/* + if (pBuffer != NULL) + { + // 创建虹膜信息对象 + CasicIrisInfo irisInfo; + irisInfo.hasEye = false; + if (leftKeyIndex >= 0 && leftKeyIndex < 32) + { + // 左眼相机拍摄的图像 + irisInfo.leftOrRight = "left"; + } else if (rightKeyIndex >= 0 && rightKeyIndex < 32) + { + // 右眼相机 + irisInfo.leftOrRight = "right"; + } + + if (ProMemory::getInstance().widgeFrame == CasicBioRecConst::RECOGNIZE_RESULT_FORM) + { + // 相机拍摄下的图像1280*960, 直接用于算法判断 + QImage imgDisp = QImage(pBuffer, width, height, QImage::Format_Grayscale8); + cv::Mat irisMat = ImageUtil::QImageToMat(imgDisp); + + irisInfo.data = imgDisp; + irisInfo.matData = irisMat; + + ProMemory::getInstance().pushCasicIris(irisInfo); + +// cv::imwrite(QString("D:\\irisLogs\\iristest-%1.bmp").arg(irisInfo.leftOrRight).toStdString(), irisMat); + } else if (ProMemory::getInstance().widgeFrame == CasicBioRecConst::ADD_PERSON_CAPTURE_IRIS) + { + // 相机拍摄下的图像1280*960, 直接用于算法判断 + QImage img = QImage(pBuffer, width, height, QImage::Format_Grayscale8); + QImage imgAlgo = img.copy(0, 0, width, height); + + // 用于显示的图像需要缩小到1/4的尺寸 + img = img.scaled(640, 480); + cv::Mat irisMat = ImageUtil::QImageToMat(imgAlgo); + + irisInfo.data = imgAlgo; + irisInfo.matData = irisMat; + + // 将图像显示在注册页面的label上 + // 并将虹膜信息对象存入队列中 + ProMemory::getInstance().pushCasicIris(irisInfo); + + if (leftKeyIndex >= 0 && leftKeyIndex < 32) + { + emit sendIrisFrameToDraw(img, 0); // 左眼画面 + } else if (rightKeyIndex >= 0 && rightKeyIndex < 32) + { + emit sendIrisFrameToDraw(img, 1); // 右眼画面 + } + } + }*/ + } +} diff --git a/device/IrisCameraCapEventHandler.h b/device/IrisCameraCapEventHandler.h new file mode 100644 index 0000000..ad75a97 --- /dev/null +++ b/device/IrisCameraCapEventHandler.h @@ -0,0 +1,30 @@ +#ifndef IRISCAMERACAPEVENTHANDLER_H +#define IRISCAMERACAPEVENTHANDLER_H + +#include +#include +#include "include/opencv2/opencv.hpp" +#include "include/daheng/GalaxyIncludes.h" + +//#include "casic/iris/CasicIrisInterface.h" +#include "ProMemory.h" + +#include "utils/UtilInclude.h" + +class IrisCameraCapEventHandler : public QObject, public ICaptureEventHandler +{ + Q_OBJECT +public: + explicit IrisCameraCapEventHandler(QObject *parent = nullptr); + + void DoOnImageCaptured(CImageDataPointer &objImageDataPointer, void *pUserParam); + +private: + unsigned char* pImageBuffer; + +signals: + void sendIrisFrameToDraw(QImage irisImage); + +}; + +#endif // IRISCAMERACAPEVENTHANDLER_H diff --git a/device/IrisCameraController.cpp b/device/IrisCameraController.cpp new file mode 100644 index 0000000..0928176 --- /dev/null +++ b/device/IrisCameraController.cpp @@ -0,0 +1,110 @@ +#include "IrisCameraController.h" + +IrisCameraController::IrisCameraController(QObject *parent) : QObject(parent) +{ + this->irisCamHandler = new IrisCameraCapEventHandler(this); +} +IrisCameraController::~IrisCameraController() +{ + this->closeIrisCamera(); +} + + +void IrisCameraController::initIrisCamera() +{ + IGXFactory::GetInstance().Init(); + + //枚举设备 + IGXFactory::GetInstance().UpdateDeviceList(1000, irisCamList); + + this->OpenDevice(); +} + +void IrisCameraController::openIrisCamera() +{ + //设置Buffer处理模式 + irisStreamFeaturePtr->GetEnumFeature("StreamBufferHandlingMode")->SetValue("OldestFirst"); + + //注册回调函数 + irisStreamPtr->RegisterCaptureCallback(irisCamHandler, &irisCamPtr); + + //开启流层通道 + irisStreamPtr->StartGrab(); + + //发送开采命令 + irisFeaturePtr->GetCommandFeature("AcquisitionStart")->Execute(); + + // 启动定时器 + TimeCounterUtil::getInstance().irisCapCounter->start(SettingConfig::getInstance().IRIS_FRAME_INTERVAL); // 50ms执行一次定时器 +} + +void IrisCameraController::closeIrisCamera() +{ + +} + +void IrisCameraController::startCapture() +{ + // 获取定时器, 绑定定时函数 + connect(TimeCounterUtil::getInstance().irisCapCounter, &QTimer::timeout, this, &IrisCameraController::getOneFaceFrm); +// LOG(DEBUG) << QString("[IrisCameraController][startCapture]虹膜相机拍图").toStdString(); +// LOG_DEBUG(QString("[IrisCameraController][startCapture]虹膜相机拍图").toStdString()); + +} +void IrisCameraController::stopCapture() +{ + // 获取定时器, 绑定定时函数 + disconnect(TimeCounterUtil::getInstance().irisCapCounter, &QTimer::timeout, this, &IrisCameraController::getOneFaceFrm); +// LOG(DEBUG) << QString("[IrisCameraController][stopCapture]虹膜相机停止拍图").toStdString(); +// LOG_DEBUG(QString("[IrisCameraController][stopCapture]虹膜相机停止拍图").toStdString()); + +} + +void IrisCameraController::getOneFaceFrm() +{ + // 发送软触发命令(在触发模式开启时有效) + irisFeaturePtr->GetCommandFeature("TriggerSoftware")->Execute(); +} + +void IrisCameraController::getLeftAndRightEyeFrame() +{ + irisFeaturePtr->GetCommandFeature("TriggerSoftware")->Execute(); +} + +void IrisCameraController::OpenDevice() +{ + auto device = irisCamList.at(0); + + irisCamPtr = IGXFactory::GetInstance().OpenDeviceByUserID(device.GetUserID(), GX_ACCESS_EXCLUSIVE); + irisFeaturePtr = irisCamPtr->GetRemoteFeatureControl(); + + // 判断设备流是否大于零, 如果大于零则打开流 + int nStreamCount = irisCamPtr->GetStreamCount(); + if (nStreamCount > 0) + { + irisStreamPtr = irisCamPtr->OpenStream(0); + irisStreamFeaturePtr = irisStreamPtr->GetFeatureControl(); + } + + // 建议用户在打开网络相机之后, 根据当前网络环境设置相机的流通道包长值, + // 以提高网络相机的采集性能, 设置方法参考以下代码。 + GX_DEVICE_CLASS_LIST objDeviceClass = irisCamPtr->GetDeviceInfo().GetDeviceClass(); + if(GX_DEVICE_CLASS_GEV == objDeviceClass) + { + // 判断设备是否支持流通道数据包功能 + if(true == irisFeaturePtr->IsImplemented("GevSCPSPacketSize")) + { + // 获取当前网络环境的最优包长值 + int nPacketSize = irisStreamPtr->GetOptimalPacketSize(); + // 将最优包长值设置为当前设备的流通道包长值 + irisFeaturePtr->GetIntFeature("GevSCPSPacketSize")->SetValue(nPacketSize); + } + } + + //设置采集模式为连续采集模式 + irisFeaturePtr->GetEnumFeature("AcquisitionMode")->SetValue("Continuous"); + + //设置触发模式关 + irisFeaturePtr->GetEnumFeature("TriggerMode")->SetValue("On"); + irisFeaturePtr->GetEnumFeature("TriggerSource")->SetValue("Software"); +} diff --git a/device/IrisCameraController.h b/device/IrisCameraController.h new file mode 100644 index 0000000..5d7e269 --- /dev/null +++ b/device/IrisCameraController.h @@ -0,0 +1,49 @@ +#ifndef IRISCAMERACONTROLLER_H +#define IRISCAMERACONTROLLER_H + +#include + +#include "IrisCameraCapEventHandler.h" + +class IrisCameraCapEventHandler; + +class IrisCameraController : public QObject +{ + Q_OBJECT +public: + explicit IrisCameraController(QObject *parent = nullptr); + ~IrisCameraController(); + + // 初始化并打开人脸相机 + void initIrisCamera(); + void openIrisCamera(); + void closeIrisCamera(); + + void startCapture(); + void stopCapture(); + + void getLeftAndRightEyeFrame(); + + IrisCameraCapEventHandler * irisCamHandler; + +private: + GxIAPICPP::gxdeviceinfo_vector irisCamList; + + CGXDevicePointer irisCamPtr; ///< 设备句柄 + + CGXStreamPointer irisStreamPtr; ///< 左眼设备流 + + CGXFeatureControlPointer irisFeaturePtr; ///< 左眼属性控制器 + + CGXFeatureControlPointer irisStreamFeaturePtr; ///< 左眼流层控制器对象 + + void OpenDevice(); + +signals: + +public slots: + void getOneFaceFrm(); + +}; + +#endif // IRISCAMERACONTROLLER_H diff --git a/device/device.pri b/device/device.pri new file mode 100644 index 0000000..a8417f2 --- /dev/null +++ b/device/device.pri @@ -0,0 +1,13 @@ + +HEADERS += $$PWD/IrisCameraController.h +HEADERS += $$PWD/IrisCameraCapEventHandler.h +#HEADERS += $$PWD/iris/IrisRegistProcess.h +#HEADERS += $$PWD/iris/IrisRecogProcess.h +#HEADERS += $$PWD/iris/CasicIrisRecState.h + +SOURCES += $$PWD/IrisCameraController.cpp +SOURCES += $$PWD/IrisCameraCapEventHandler.cpp +#SOURCES += $$PWD/iris/IrisRegistProcess.cpp +#SOURCES += $$PWD/iris/IrisRecogProcess.cpp +#SOURCES += $$PWD/iris/CasicIrisRecState.cpp + diff --git a/AppConstants.h b/AppConstants.h new file mode 100644 index 0000000..296c53f --- /dev/null +++ b/AppConstants.h @@ -0,0 +1,28 @@ +#ifndef APPCONSTANTS_H +#define APPCONSTANTS_H + +class AppConstants +{ +public: + enum WidgeFrameName + { + MAIN_PAGE = 0, // 主页面 + PERSON_LIST_FORM = 1, // 人员列表页面 + ADD_PERSON_FORM = 2, // 添加人员页面 + ADD_PERSON_CAPTURE_FACE = 21, // 添加/编辑人员时进行人脸拍图 + ADD_PERSON_CAPTURE_IRIS = 22, // 添加/编辑人员时进行虹膜拍图 + SETTING_FORM = 3, // 设置页面 + RECOGNIZE_RESULT_FORM = 4, // 识别结果界面 + IDENTIFY_FORM = 5, // 识别界面 含识别中 和 识别结果 + LOCKSCREEN_FORM = 6 // 锁屏待机界面 + }; + + enum ApplicationState + { + STATE_WAIT = 0, // 待机 + STATE_WORKING = 1, // 工作状态 + STATE_IDENTIFYING = 2, // 识别中 + }; +}; + +#endif // APPCONSTANTS_H diff --git a/CasicIrisIdentify.pro b/CasicIrisIdentify.pro index 5d7fea6..575ce3d 100644 --- a/CasicIrisIdentify.pro +++ b/CasicIrisIdentify.pro @@ -1,4 +1,4 @@ -QT += core gui +QT += core gui sql network texttospeech greaterThan(QT_MAJOR_VERSION, 4): QT += widgets @@ -15,20 +15,46 @@ # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 -SOURCES += \ - main.cpp \ - IdentifyForm.cpp +include("dao/dao.pri") +include("device/device.pri") +include("utils/utils.pri") -HEADERS += \ - IdentifyForm.h +SOURCES += main.cpp +SOURCES += ProMemory.cpp +SOURCES += MainWindowForm.cpp +SOURCES += IdentifyForm.cpp +SOURCES += LockScreenForm.cpp -FORMS += \ - IdentifyForm.ui +HEADERS += AppConstants.h +HEADERS += ProMemory.h +HEADERS += MainWindowForm.h +HEADERS += IdentifyForm.h +HEADERS += LockScreenForm.h -TRANSLATIONS += \ - CasicIrisIdentify_zh_CN.ts +FORMS += MainWindowForm.ui +FORMS += IdentifyForm.ui +FORMS += LockScreenForm.ui + +RESOURCES += resource.qrc + +DISTFILES += conf/config.ini + +#TRANSLATIONS += CasicIrisIdentify_zh_CN.ts + +#INCLUDEPATH += include/spdlog +#DEPENDPATH += include/spdlog # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target + + +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lopencv_world420 +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lGxIAPICPPEx + +INCLUDEPATH += $$PWD/include/daheng +DEPENDPATH += $$PWD/include/daheng + +INCLUDEPATH += $$PWD/include +DEPENDPATH += $$PWD/include diff --git a/CasicIrisIdentify_zh_CN.ts b/CasicIrisIdentify_zh_CN.ts index 5526fe4..81900df 100644 --- a/CasicIrisIdentify_zh_CN.ts +++ b/CasicIrisIdentify_zh_CN.ts @@ -1,3 +1,12 @@ - + + + IdentifyForm + + + IdentifyForm + + + + diff --git a/IdentifyForm.cpp b/IdentifyForm.cpp index 348a897..ba1f251 100644 --- a/IdentifyForm.cpp +++ b/IdentifyForm.cpp @@ -1,4 +1,4 @@ -#include "IdentifyForm.h" +#include "IdentifyForm.h" #include "ui_IdentifyForm.h" IdentifyForm::IdentifyForm(QWidget *parent) @@ -6,6 +6,12 @@ , ui(new Ui::IdentifyForm) { ui->setupUi(this); + + // 初始化更新界面的定时器 + // 每秒执行一次 + connect(TimeCounterUtil::getInstance().clockCounter, &QTimer::timeout, this, &IdentifyForm::updateDateAndTime); + + TimeCounterUtil::getInstance().clockCounter->start(1000); } IdentifyForm::~IdentifyForm() @@ -13,3 +19,16 @@ delete ui; } +void IdentifyForm::drawIrisImageOnFrame(QImage image) +{ + // 只在识别界面才显示画面 + if (ui->wgtStacked->currentIndex() == 0) { + ui->labelVideo->setPixmap(QPixmap::fromImage(image)); + } +} + + +void IdentifyForm::updateDateAndTime() +{ + ui->labelTime->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd dddd HH:mm:ss")); +} diff --git a/IdentifyForm.h b/IdentifyForm.h index fc857a1..ae1cd22 100644 --- a/IdentifyForm.h +++ b/IdentifyForm.h @@ -1,7 +1,10 @@ -#ifndef IDENTIFYFORM_H +#ifndef IDENTIFYFORM_H #define IDENTIFYFORM_H #include +#include + +#include "utils/UtilInclude.h" QT_BEGIN_NAMESPACE namespace Ui { class IdentifyForm; } @@ -15,7 +18,14 @@ IdentifyForm(QWidget *parent = nullptr); ~IdentifyForm(); +public slots: + void drawIrisImageOnFrame(QImage image); + private: Ui::IdentifyForm *ui; + +private slots: + void updateDateAndTime(); + }; #endif // IDENTIFYFORM_H diff --git a/IdentifyForm.ui b/IdentifyForm.ui index c72a36f..879dc9a 100644 --- a/IdentifyForm.ui +++ b/IdentifyForm.ui @@ -6,13 +6,59 @@ 0 0 - 800 + 600 600 IdentifyForm + + + + 0 + 40 + 600 + 450 + + + + 0 + + + + + + 100 + 10 + 400 + 300 + + + + + + + + + + + + + + 0 + 0 + 600 + 40 + + + + TextLabel + + + Qt::AlignCenter + + diff --git a/LockScreenForm.cpp b/LockScreenForm.cpp new file mode 100644 index 0000000..58dc54b --- /dev/null +++ b/LockScreenForm.cpp @@ -0,0 +1,14 @@ +#include "LockScreenForm.h" +#include "ui_LockScreenForm.h" + +LockScreenForm::LockScreenForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::LockScreenForm) +{ + ui->setupUi(this); +} + +LockScreenForm::~LockScreenForm() +{ + delete ui; +} diff --git a/LockScreenForm.h b/LockScreenForm.h new file mode 100644 index 0000000..b5ded48 --- /dev/null +++ b/LockScreenForm.h @@ -0,0 +1,25 @@ +#ifndef LOCKSCREENFORM_H +#define LOCKSCREENFORM_H + +#include +#include + +#include "utils/UtilInclude.h" + +namespace Ui { +class LockScreenForm; +} + +class LockScreenForm : public QWidget +{ + Q_OBJECT + +public: + explicit LockScreenForm(QWidget *parent = nullptr); + ~LockScreenForm(); + +private: + Ui::LockScreenForm *ui; +}; + +#endif // LOCKSCREENFORM_H diff --git a/LockScreenForm.ui b/LockScreenForm.ui new file mode 100644 index 0000000..7f2a6db --- /dev/null +++ b/LockScreenForm.ui @@ -0,0 +1,45 @@ + + + LockScreenForm + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + 180 + 100 + 54 + 12 + + + + TextLabel + + + + + + 180 + 160 + 54 + 12 + + + + TextLabel + + + + + + diff --git a/MainWindowForm.cpp b/MainWindowForm.cpp new file mode 100644 index 0000000..84f8159 --- /dev/null +++ b/MainWindowForm.cpp @@ -0,0 +1,86 @@ +#include "MainWindowForm.h" +#include "ui_MainWindowForm.h" +#include + +MainWindowForm::MainWindowForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::MainWindowForm) +{ + ui->setupUi(this); + + // 设置窗口透明和大小、位置 + this->setWindowFlags(Qt::FramelessWindowHint); + this->move(1400, 15); + this->resize(SettingConfig::getInstance().WINDOW_WIDTH, SettingConfig::getInstance().WINDOW_HEIGHT); + + // 通过调色板的颜色来设置窗口的统一背景色 + qApp->setPalette(QPalette(QColor(SettingConfig::getInstance().WINDOW_BACKGROUND_COLOR))); + + // 加载css文件设置控件样式 + QFile file(QApplication::applicationDirPath() + "/qss/main.css"); + if (file.open(QFile::ReadOnly)) + { + QString qssStr = QLatin1String(file.readAll()); + this->setStyleSheet(qssStr); + file.close(); + } + + initFormsPtr(); + + // 设置标题文字 + ui->labelTitle->setText(SettingConfig::getInstance().WINDOW_TITLE); + ui->labelCopyright->setText(SettingConfig::getInstance().WINDOW_RIGHTS); + ui->labelVersion->setText(SettingConfig::getInstance().WINDOW_VERSION); + + // 初始化虹膜相机控制 + ProMemory::getInstance().irisCam = new IrisCameraController(this); + ProMemory::getInstance().irisCam->initIrisCamera(); + ProMemory::getInstance().irisCam->openIrisCamera(); + connect(ProMemory::getInstance().irisCam->irisCamHandler, &IrisCameraCapEventHandler::sendIrisFrameToDraw, identifyForm, &IdentifyForm::drawIrisImageOnFrame); + +// LOG_INFO(QString("应用程序启动成功[Application Startup Success]").toStdString()); + qDebug() << "应用程序启动成功[Application Startup Success]"; + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::IDENTIFY_FORM; + ui->wdgtStatced->setCurrentWidget(identifyForm); + + // 开始虹膜相机拍图 + ProMemory::getInstance().irisCam->startCapture(); +} + +MainWindowForm::~MainWindowForm() +{ + delete ui; +} + +void MainWindowForm::lockScreen() +{ + ui->wdgtStatced->setCurrentWidget(lockScreenForm); + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::LOCKSCREEN_FORM; + ProMemory::getInstance().appState = AppConstants::ApplicationState::STATE_WAIT; +} + +void MainWindowForm::keyPressEvent(QKeyEvent *event) +{ + switch (event->key()) { + case Qt::Key_Escape: + QTimer::singleShot(100, qApp, [=](){ + QApplication::quit(); + }); + + default: + QWidget::keyPressEvent(event); + } +} + +void MainWindowForm::initFormsPtr() +{ + // 初始化各个form + lockScreenForm = new LockScreenForm(this); + identifyForm = new IdentifyForm(this); + + // 将form添加到statcked widget中 + ui->wdgtStatced->addWidget(identifyForm); + ui->wdgtStatced->addWidget(lockScreenForm); + + // 绑定按钮函数 +} diff --git a/MainWindowForm.h b/MainWindowForm.h new file mode 100644 index 0000000..7fb2d89 --- /dev/null +++ b/MainWindowForm.h @@ -0,0 +1,38 @@ +#ifndef MAINWINDOWFORM_H +#define MAINWINDOWFORM_H + +#include +#include +#include + +#include "utils/UtilInclude.h" +#include "ProMemory.h" +#include "LockScreenForm.h" +#include "IdentifyForm.h" + +namespace Ui { +class MainWindowForm; +} + +class MainWindowForm : public QWidget +{ + Q_OBJECT + +public: + explicit MainWindowForm(QWidget *parent = nullptr); + ~MainWindowForm(); + +public slots: + void lockScreen(); + +private: + Ui::MainWindowForm *ui; + LockScreenForm * lockScreenForm; + IdentifyForm * identifyForm; + + void keyPressEvent(QKeyEvent *event); + + void initFormsPtr(); +}; + +#endif // MAINWINDOWFORM_H diff --git a/MainWindowForm.ui b/MainWindowForm.ui new file mode 100644 index 0000000..e793ebf --- /dev/null +++ b/MainWindowForm.ui @@ -0,0 +1,85 @@ + + + MainWindowForm + + + + 0 + 0 + 600 + 1024 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + 0 + 0 + 600 + 84 + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + + + + TextLabel + + + Qt::AlignBottom|Qt::AlignHCenter + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + diff --git a/ProMemory.cpp b/ProMemory.cpp new file mode 100644 index 0000000..19e7403 --- /dev/null +++ b/ProMemory.cpp @@ -0,0 +1,84 @@ +#include "ProMemory.h" + +ProMemory::ProMemory() +{ + +} + +ProMemory::~ProMemory() +{ + +} + +/* +void ProMemory::pushCasicIris(CasicIrisInfo irisInfo) +{ + QMutex mutex; + mutex.lock(); + if (this->irisQueue.size() > 30) + { + QStack empty; + std::swap(empty, irisQueue); + } + + irisQueue.push(irisInfo); + mutex.unlock(); +} +CasicIrisInfo ProMemory::popCasicIris() +{ + CasicIrisInfo result; + + QMutex mutex; + mutex.lock(); + if (this->irisQueue.size() > 0) + { + result = irisQueue.pop(); + } + + mutex.unlock(); + + return result; +} +*/ +int ProMemory::getIrisQueueSize() +{ + int size = 0; + + QMutex mutex; + mutex.lock(); + +// size = this->irisQueue.size(); + + mutex.unlock(); + + return size; +} +bool ProMemory::isIrisQueueEmpty() +{ + bool empty = true; + + QMutex mutex; + mutex.lock(); + +// empty = this->irisQueue.isEmpty(); + + mutex.unlock(); + + return empty; +} +void ProMemory::clearIrisQueue() +{ + QMutex mutex; + mutex.lock(); + +// QStack empty; +// std::swap(empty, irisQueue); + + mutex.unlock(); +} + + +void ProMemory::initIrisFeatures(QString personId) +{ +// irisRegistPro->sendDataToExract(QByteArray(QString("[-u]").append(personId).toLocal8Bit())); +} diff --git a/ProMemory.h b/ProMemory.h new file mode 100644 index 0000000..2ecd653 --- /dev/null +++ b/ProMemory.h @@ -0,0 +1,52 @@ +#ifndef PROMEMORY_H +#define PROMEMORY_H + +#include +#include + +#include "AppConstants.h" +//#include "casic/iris/CasicIrisInfo.h" +#include "dao/IrisDataDao.h" + +#include "device/IrisCameraController.h" +//#include "device/iris/IrisRegistProcess.h" +//#include "device/iris/IrisRecogProcess.h" + +class IrisCameraController; +class IrisRegistProcess; +class IrisRecogProcess; + +class ProMemory +{ +public: + ~ProMemory(); + ProMemory(const ProMemory&)=delete; + ProMemory& operator=(const ProMemory&)=delete; + + static ProMemory& getInstance() { + static ProMemory instance; + return instance; + } + +// void pushCasicIris(CasicIrisInfo irisInfo); +// CasicIrisInfo popCasicIris(); + int getIrisQueueSize(); + bool isIrisQueueEmpty(); + void clearIrisQueue(); + + volatile int widgeFrame = 0; // 当前显示的界面 + volatile int appState = 0; // 当前程序所处的状态 + + void initIrisFeatures(QString personId = ""); // 初始化虹膜特征值集合 + + IrisCameraController * irisCam; + IrisRecogProcess * irisRecogPro; + +private: + ProMemory(); + +// QStack irisQueue; // 虹膜信息队列 + QVector irisFeatures; // 虹膜特征值集合 +}; + +#endif // PROMEMORY_H diff --git a/conf/config.ini b/conf/config.ini new file mode 100644 index 0000000..66e46ad --- /dev/null +++ b/conf/config.ini @@ -0,0 +1,67 @@ +[recognize] +#最大允许识别时间(ms) +maxMatchTime=10000 +#识别成功界面停留时间(ms) +successTipsLast=5000 +#识别失败界面停留时间(ms) +failureTipsLast=3000 +#人脸识别最大尝试次数 +maxFaceTryCount=20 +#持续没找到人脸的最大次数 +maxFaceNotFoundCount=500 +#注册时最小人脸 +minFaceRegist=240 +#识别时最小人脸 +minFaceRecog=100 + +#虹膜识别最大尝试次数 +maxIrisTryCount=10 +#虹膜识别持续没有找到眼的最大次数 +maxEyeNotFoundCount=50 + +#识别方式[1=人脸;2=虹膜;3=双认证;4=任意] +recogType=4 + +[window] +#界面窗口宽(px) +width=600 +#界面窗口高(px) +height=1024 +#统一背景色 +backgroundColor="#FFFFFF" +#标题 +title="虹膜识别终端" + +[work] +#工作状态检测时最小人脸范围 +minFaceSize=160 +#人脸范围最小横坐标 +minFacePosX=320 +#人脸范围最大横坐标 +maxFacePosX=960 +#人脸范围最小纵坐标 +minFacePosY=180 +#人脸范围最大纵坐标 +maxFacePosY=540 +#人脸太近阈值 +faceCloseSize=360 +#人脸太远阈值 +faceFarSize=480 + +[camera] +#虹膜相机取一幅画面的时间间隔(ms) +irisFrameInterval=100 +#虹膜相机拍摄宽度 +irisFrameWidth=1440 +#虹膜相机拍摄高度 +irisFrameHeight=1080 +#虹膜图像高度 +irisWidth=640 +#虹膜图像高度 +irisHeight=480 + +[log] +#日志文件位置 +logFile="d://irisLogs//casic_log.txt" +#日志级别 +logLevel="trace" diff --git a/dao/BaseDao.cpp b/dao/BaseDao.cpp new file mode 100644 index 0000000..f51c144 --- /dev/null +++ b/dao/BaseDao.cpp @@ -0,0 +1,12 @@ +#include "BaseDao.h" +#include "dao/util/ConnectionManager.h" + +BaseDao::BaseDao(QObject *parent) : QObject(parent) +{ + +} + +BaseDao::~BaseDao() +{ + +} diff --git a/dao/BaseDao.h b/dao/BaseDao.h new file mode 100644 index 0000000..1693c88 --- /dev/null +++ b/dao/BaseDao.h @@ -0,0 +1,32 @@ +#ifndef BASEDAO_H +#define BASEDAO_H + +#include +#include +#include +#include + +#include "dao/util/ConnectionManager.h" +#include "utils/UtilInclude.h" + +class BaseDao : public QObject +{ + Q_OBJECT +public: + explicit BaseDao(QObject *parent = nullptr); + ~BaseDao(); + + virtual QVector findAllRecord() = 0; + virtual QVariantMap findRecordById(QString id) = 0; + + virtual QString save(QVariantMap object) = 0; + virtual bool edit(QVariantMap newObject, QString id) = 0; + virtual bool dele(QString id) = 0; + +private: + +signals: + +}; + +#endif // BASEDAO_H diff --git a/dao/IrisDataDao.cpp b/dao/IrisDataDao.cpp new file mode 100644 index 0000000..37a0ed6 --- /dev/null +++ b/dao/IrisDataDao.cpp @@ -0,0 +1,204 @@ +#include "IrisDataDao.h" + +IrisDataDao::IrisDataDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector IrisDataDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM IRIS_DATA"; + query.prepare(sql); + + // 执行查询 + query.exec(); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + item.insert("id", query.value("id").toString()); + item.insert("person_id", query.value("person_id").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("left_iris_code1", query.value("left_iris_code1")); + item.insert("left_iris_code2", query.value("left_iris_code2")); + item.insert("left_iris_code3", query.value("left_iris_code3")); + item.insert("right_iris_code1", query.value("right_iris_code1")); + item.insert("right_iris_code2", query.value("right_iris_code2")); + item.insert("right_iris_code3", query.value("right_iris_code3")); + + result.append(item); + } + +// LOG_DEBUG(QString("查询IRIS_DATA表的所有记录[结果数:%1]").arg(result.size()).toStdString()); + return result; +} + +QVariantMap IrisDataDao::findRecordById(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM IRIS_DATA WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + // 获取结果 + if (query.next()) + { + result.insert("id", query.value("id").toString()); + result.insert("person_id", query.value("person_id").toLongLong()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("left_iris_code1", query.value("left_iris_code1")); + result.insert("left_iris_code2", query.value("left_iris_code2")); + result.insert("left_iris_code3", query.value("left_iris_code3")); + result.insert("right_iris_code1", query.value("right_iris_code1")); + result.insert("right_iris_code2", query.value("right_iris_code2")); + result.insert("right_iris_code3", query.value("right_iris_code3")); + } + +// LOG_DEBUG(QString("根据id查询IRIS_DATA表的记录[id=%1]").arg(id).toStdString()); + return result; +} + +QVariantMap IrisDataDao::findRecordByPersonId(QString personId) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM IRIS_DATA WHERE PERSON_ID = :personId"); + query.prepare(sql); + query.bindValue(":personId", personId); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + if (query.next()) + { + result.insert("id", query.value("id").toString()); + result.insert("person_id", query.value("person_id").toLongLong()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("left_iris_code1", query.value("left_iris_code1")); + result.insert("left_iris_code2", query.value("left_iris_code2")); + result.insert("left_iris_code3", query.value("left_iris_code3")); + result.insert("right_iris_code1", query.value("right_iris_code1")); + result.insert("right_iris_code2", query.value("right_iris_code2")); + result.insert("right_iris_code3", query.value("right_iris_code3")); + } + +// LOG_DEBUG(QString("根据personId查询IRIS_DATA表的记录[personId=%1]").arg(personId).toStdString()); + return result; +} + + +QString IrisDataDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + + // INSERT语句 + QString sql = QString("INSERT INTO IRIS_DATA (ID, PERSON_ID, ID_CARD_NO, LEFT_IRIS_CODE1, RIGHT_IRIS_CODE1) VALUES (:id, :personId, :idCardNo, :left1, :right1)"); + + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":personId", object.value("person_id").toString()); + query.bindValue(":idCardNo", object.value("id_card_no").toString()); + query.bindValue(":left1", object.value("left_iris_code1")); + query.bindValue(":right1", object.value("right_iris_code1")); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(); + +// LOG_DEBUG(QString("保存虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool IrisDataDao::edit(QVariantMap newObject, QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // UPDATE语句 + if (!newObject.contains("left_iris_code1") || !newObject.contains("right_iris_code1")){ + return false; + } + QString sql = QString("UPDATE IRIS_DATA SET LEFT_IRIS_CODE1 = :left1, RIGHT_IRIS_CODE1 = :right1 WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":left1", newObject.value("left_iris_code1")); + query.bindValue(":right1", newObject.value("right_iris_code1")); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(); + +// LOG_DEBUG(QString("编辑虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; +} + + +bool IrisDataDao::dele(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + QString sql = QString("DELETE FROM IRIS_DATA WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(); + +// LOG_DEBUG(QString("删除虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; +} diff --git a/dao/IrisDataDao.h b/dao/IrisDataDao.h new file mode 100644 index 0000000..c74dbbd --- /dev/null +++ b/dao/IrisDataDao.h @@ -0,0 +1,25 @@ +#ifndef IRISDATADAO_H +#define IRISDATADAO_H + +#include +#include "BaseDao.h" + +class IrisDataDao : public BaseDao +{ + Q_OBJECT +public: + explicit IrisDataDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + QVariantMap findRecordByPersonId(QString personId); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +signals: + +}; + +#endif // IRISDATADAO_H diff --git a/dao/RecognitionRecordsDao.cpp b/dao/RecognitionRecordsDao.cpp new file mode 100644 index 0000000..40db453 --- /dev/null +++ b/dao/RecognitionRecordsDao.cpp @@ -0,0 +1,100 @@ +#include "RecognitionRecordsDao.h" + +RecognitionRecordsDao::RecognitionRecordsDao(QObject *parent) : BaseDao(parent) +{ + +} + + +QVector RecognitionRecordsDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM RECOGNITION_RECORDS"; + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + item.insert("id", query.value("id").toLongLong()); + result.append(item); + } + +// LOG_DEBUG(QString("查询RECOGNITION_RECORDS表的所有记录[记录数:%1]").arg(result.size()).toStdString()); + return result; +} + +QVariantMap RecognitionRecordsDao::findRecordById(QString id) +{ + QVariantMap item; + return item; +} + +QString RecognitionRecordsDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + + // INSERT语句 + QString sql = QString("INSERT INTO RECOGNITION_RECORDS (ID, PERSON_ID, DATETIME, REC_TYPE, DEV_CODE, DOOR_CODE, INOUT_TYPE) " + "VALUES (:id, :personId, :datetime, :recType, :devCode, :doorCode, :inoutType)"); + + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":personId", object.value("person_id").toString()); + query.bindValue(":datetime", object.value("date_time").toString()); + query.bindValue(":recType", object.value("rec_type").toString()); + query.bindValue(":devCode", object.value("dev_code").toString()); + query.bindValue(":doorCode", object.value("door_code").toString()); + query.bindValue(":inoutType", object.value("inout_type").toString()); + +// LOG_DEBUG(sql.toStdString()); + + // 插入识别的log日志 + QString logStr = QString("INSERT INTO RECOGNITION_LOGS (ID, LOG_INFO) VALUES (:id, :logInfo)"); + + QSqlQuery logQuery(ConnectionManager::getInstance()->getConnection()); + logQuery.prepare(logStr); + logQuery.bindValue(":id", id); + logQuery.bindValue(":logInfo", object.value("debug_info").toString()); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(); + logQuery.exec(); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool RecognitionRecordsDao::edit(QVariantMap newObject, QString id) +{ + return false; +} + +bool RecognitionRecordsDao::dele(QString id) +{ + return false; +} diff --git a/dao/RecognitionRecordsDao.h b/dao/RecognitionRecordsDao.h new file mode 100644 index 0000000..38de7c9 --- /dev/null +++ b/dao/RecognitionRecordsDao.h @@ -0,0 +1,23 @@ +#ifndef RECOGNITIONRECORDSDAO_H +#define RECOGNITIONRECORDSDAO_H + +#include +#include "BaseDao.h" +class RecognitionRecordsDao: public BaseDao +{ + Q_OBJECT +public: + explicit RecognitionRecordsDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +signals: + +}; + +#endif // RECOGNITIONRECORDSDAO_H diff --git a/dao/SysDeptDao.cpp b/dao/SysDeptDao.cpp new file mode 100644 index 0000000..22f9946 --- /dev/null +++ b/dao/SysDeptDao.cpp @@ -0,0 +1,88 @@ +#include "SysDeptDao.h" + +SysDeptDao::SysDeptDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector SysDeptDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_DEPT WHERE PID != '-1' ORDER BY PID, NUM"; + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + item.insert("id", query.value("id").toString()); + item.insert("pid", query.value("pid").toString()); + item.insert("pids", query.value("pids").toString()); + item.insert("simplename", query.value("simplename").toString()); + item.insert("fullname", query.value("fullname").toString()); + } + +// LOG_TRACE(QString("查询表[SYS_DEPT]的所有记录[%1][%2]").arg(result.size()).arg(sql).toStdString()); + + return result; +} + +QVariantMap SysDeptDao::findRecordById(QString id) +{ + QVariantMap item; + return item; + + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM SYS_DEPT WHERE SYS_DEPT.ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + // 获取结果集的大小 + query.last(); + int count = query.at() + 1; + + if (count >=1) + { + query.first(); + + result.insert("id", query.value("id").toString()); + result.insert("pid", query.value("pid").toString()); + result.insert("pids", query.value("pids").toString()); + result.insert("simplename", query.value("simplename").toString()); + result.insert("fullname", query.value("fullname").toString()); + } + +// LOG_TRACE(QString("根据id查询SYS_DEPT表的记录[ID=%1][%2]").arg(id).arg(sql).toStdString()); + + return result; +} + + +QString SysDeptDao::save(QVariantMap object) +{ + return "0"; +} +bool SysDeptDao::edit(QVariantMap newObject, QString id) +{ + return true; +} +bool SysDeptDao::dele(QString id) +{ + return true; +} diff --git a/dao/SysDeptDao.h b/dao/SysDeptDao.h new file mode 100644 index 0000000..e07a09f --- /dev/null +++ b/dao/SysDeptDao.h @@ -0,0 +1,24 @@ +#ifndef SYSDEPTDAO_H +#define SYSDEPTDAO_H + +#include +#include "BaseDao.h" + +class SysDeptDao : public BaseDao +{ + Q_OBJECT +public: + explicit SysDeptDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +private: + +}; + +#endif // SYSDEPTDAO_H diff --git a/dao/SysPersonDao.cpp b/dao/SysPersonDao.cpp new file mode 100644 index 0000000..dd9480f --- /dev/null +++ b/dao/SysPersonDao.cpp @@ -0,0 +1,371 @@ +#include "SysPersonDao.h" + + +SysPersonDao::SysPersonDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector SysPersonDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0'"; + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + count++; + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + result.append(item); + } + +// LOG(TRACE) << QString("查询SYS_PERSON表的所有记录[%1]").arg(count).toStdString(); +// LOG_TRACE(QString("查询SYS_PERSON表的所有记录[%1]").arg(count).toStdString()); + + return result; +} + +QVariantMap SysPersonDao::findRecordById(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0' AND SYS_PERSON.ID = '%1'").arg(id); + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVariantMap result; + + // 获取结果集的大小 + query.last(); + int count = query.at() + 1; + + if (count >=1) + { + query.first(); + + result.insert("id", query.value("id").toString()); + result.insert("delflag", query.value("delflag").toString()); + result.insert("createtime", query.value("createtime").toString()); + result.insert("updatetime", query.value("updatetime").toString()); + result.insert("name", query.value("name").toString()); + result.insert("gender", query.value("gender").toString()); + result.insert("deptid", query.value("deptid").toString()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("remarks", query.value("remarks").toString()); + result.insert("person_code", query.value("person_code").toString()); + result.insert("deptname", query.value("fullname").toString()); + result.insert("sync_id", query.value("sync_id").toString()); + result.insert("hasFace", query.value("face_valid").toString()); + result.insert("hasIris", query.value("iris_valid").toString()); + } + +// LOG(TRACE) << QString("根据id查询SYS_PERSON表的记录[id=%1][%2]").arg(id).arg(sql).toStdString(); +// LOG_TRACE(QString("根据id查询SYS_PERSON表的记录[id=%1][%2]").arg(id).arg(sql).toStdString()); + + return result; +} + +int SysPersonDao::findRecordCountByNameAndDept(QString name, QString dept) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT COUNT(P.ID) AS RECCT FROM SYS_PERSON P LEFT JOIN SYS_DEPT D ON P.DEPTID = D.ID WHERE P.DELFLAG = '0'"; + if (name.isEmpty() == false) + { + sql += " AND P.NAME LIKE '%" + name + "%'"; + } + if (dept.isEmpty() == false && dept.indexOf("-1") < 0) + { + sql += QString(" AND ((P.DEPTID = '%1') OR (D.PIDS LIKE '%,%1,%'))").arg(dept); + } + + // 执行查询 + query.exec(sql); + + // 返回结果 + int result; + + // 遍历查询结果 + if (query.next()) { + result = query.value("RECCT").toInt(); + } + +// LOG(TRACE) << QString("根据姓名和部门查询SYS_PERSON记录总数[%1][%2]").arg(result).arg(sql).toStdString(); +// LOG_TRACE(QString("根据姓名和部门查询SYS_PERSON记录总数[%1][%2]").arg(result).arg(sql).toStdString()); + + return result; +} + +QVector SysPersonDao::findRecordsByNameAndDept(QString name, QString dept, qint8 limit, qint16 offset) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON P LEFT JOIN SYS_DEPT D ON P.DEPTID = D.ID WHERE P.DELFLAG = '0'"; + if (name.isEmpty() == false) + { + sql += " AND P.NAME LIKE '%" + name + "%'"; + } + if (dept.isEmpty() == false && dept.indexOf("-1") < 0) + { + sql += QString(" AND ((P.DEPTID = '%1') OR (D.PIDS LIKE '%,%1,%'))").arg(dept); + } + + sql += QString(" LIMIT %1 OFFSET %2").arg(limit).arg(offset); + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + count++; + + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + + result.append(item); + } + +// LOG(TRACE) << QString("根据姓名和部门分页查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString(); +// LOG_TRACE(QString("根据姓名和部门分页查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString()); + + return result; +} + +QVector SysPersonDao::findRecordsByProperties(QVariantMap conditions) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0'"; + QVariantMap::iterator it; + for (it = conditions.begin(); it != conditions.end(); it++) + { + sql += QString(" AND SYS_PERSON.%1 = %2").arg(it.key()).arg(it.value().toString()); + } + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + count++; + + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + + result.append(item); + } + +// LOG(TRACE) << QString("根据属性值查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString(); +// LOG_TRACE(QString("根据属性值查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString()); + + return result; +} + +QString SysPersonDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + + // INSERT语句 + QString sql = QString("INSERT INTO SYS_PERSON " + "(ID, DELFLAG, CREATETIME, UPDATETIME, " + "NAME, GENDER, DEPTID, ID_CARD_NO, " + "REMARKS, PERSON_CODE, SYNC_ID, FACE_VALID, IRIS_VALID) " + "VALUES ('%1', '0', '%2', '%2', '%3', '%4', '%5', '%6', '%7', '%8', '%9', 0, 0)") + .arg(id).arg(tm) + .arg(object.value("name").toString()) + .arg(object.value("gender").toString()) + .arg(object.value("deptid").toString()) + .arg(object.value("id_card_no").toString()) + .arg(object.value("remarks").toString()) + .arg(object.value("person_code").toString()) + .arg(object.value("sync_id").toString()); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(sql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { +// LOG(DEBUG) << QString("保存SYS_PERSON记录成功[ID = %1][%2]").arg(id).arg(sql).toStdString(); +// LOG_DEBUG(QString("保存SYS_PERSON记录成功[ID = %1][%2]").arg(id).arg(sql).toStdString()); + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool SysPersonDao::edit(QVariantMap newObject, QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + + // UPDATE语句 + QString sql = QString("UPDATE SYS_PERSON SET UPDATETIME = '%1'").arg(tm); + if (newObject.contains("name")) + { + sql.append(QString(", NAME = '%1'").arg(newObject.value("name").toString())); + } + if (newObject.contains("gender")) + { + sql.append(QString(", GENDER = '%1'").arg(newObject.value("gender").toString())); + } + if (newObject.contains("deptid")) + { + sql.append(QString(", DEPTID = '%1'").arg(newObject.value("deptid").toString())); + } + if (newObject.contains("person_code")) + { + sql.append(QString(", PERSON_CODE = '%1'").arg(newObject.value("person_code").toString())); + } + if (newObject.contains("face_valid")) + { + sql.append(QString(", FACE_VALID = '%1'").arg(newObject.value("face_valid").toString())); + } + if (newObject.contains("iris_valid")) + { + sql.append(QString(", IRIS_VALID = '%1'").arg(newObject.value("iris_valid").toString())); + } + + sql.append(QString(" WHERE ID = '%1'").arg(id)); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(sql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + +// LOG(DEBUG) << QString("编辑人员[ID=%1][%2]").arg(id).arg(sql).toStdString(); +// LOG_DEBUG(QString("编辑人员[ID=%1][%2]").arg(id).arg(sql).toStdString()); + + // 返回结果 + return success; +} + +bool SysPersonDao::dele(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + QSqlQuery irisDel(ConnectionManager::getInstance()->getConnection()); + + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + qint64 tmms = QDateTime::currentDateTime().toMSecsSinceEpoch(); + + // UPDATE语句 + QString sql = QString("UPDATE SYS_PERSON SET UPDATETIME = :updateTime, DELFLAG = :flag WHERE ID = :id").arg(tm).arg(tmms).arg(id); + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":updateTime", tm); + query.bindValue(":flag", tmms); + + // 物理删除人员的人脸和虹膜数据 + QString delIrisSql = QString("DELETE FROM IRIS_DATA WHERE PERSON_ID = :personId"); + irisDel.prepare(delIrisSql); + irisDel.bindValue(":personId", id); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(sql); + query.exec(delIrisSql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + +// LOG_DEBUG(QString("删除人员SYS_PERSON[ID=%1][%2]").arg(id).arg(success).toStdString()); + + // 返回结果 + return success; +} diff --git a/dao/SysPersonDao.h b/dao/SysPersonDao.h new file mode 100644 index 0000000..e02e5ba --- /dev/null +++ b/dao/SysPersonDao.h @@ -0,0 +1,27 @@ +#ifndef SYSPERSONDAO_H +#define SYSPERSONDAO_H + +#include +#include "BaseDao.h" + +class SysPersonDao : public BaseDao +{ + Q_OBJECT +public: + explicit SysPersonDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + int findRecordCountByNameAndDept(QString name, QString dept); + QVector findRecordsByNameAndDept(QString name, QString dept, qint8 limit, qint16 offset); + QVector findRecordsByProperties(QVariantMap conditions); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); +signals: + +}; + +#endif // SYSPERSONDAO_H diff --git a/dao/dao.pri b/dao/dao.pri new file mode 100644 index 0000000..1e04ce4 --- /dev/null +++ b/dao/dao.pri @@ -0,0 +1,18 @@ + +HEADERS += $$PWD/BaseDao.h +HEADERS += $$PWD/IrisDataDao.h +HEADERS += $$PWD/RecognitionRecordsDao.h +HEADERS += $$PWD/SysPersonDao.h +HEADERS += $$PWD/SysDeptDao.h + +SOURCES += $$PWD/BaseDao.cpp +SOURCES += $$PWD/IrisDataDao.cpp +SOURCES += $$PWD/RecognitionRecordsDao.cpp +SOURCES += $$PWD/SysPersonDao.cpp +SOURCES += $$PWD/SysDeptDao.cpp + +HEADERS += $$PWD/util/ConnectionManager.h +SOURCES += $$PWD/util/ConnectionManager.cpp +#HEADERS += $$PWD/util/CacheManager.h +#SOURCES += $$PWD/util/CacheManager.cpp + diff --git a/dao/util/ConnectionManager.cpp b/dao/util/ConnectionManager.cpp new file mode 100644 index 0000000..84b17be --- /dev/null +++ b/dao/util/ConnectionManager.cpp @@ -0,0 +1,47 @@ +#include "ConnectionManager.h" +#include + +Q_GLOBAL_STATIC(ConnectionManager, cm) + +ConnectionManager::ConnectionManager(QObject *parent) : QObject(parent) +{ + // 初始化数据库连接 + if (QSqlDatabase::contains("qt_sql_dafault_connection")) + { + conn = QSqlDatabase::database("qt_sql_default_connection"); + } + else + { + conn = QSqlDatabase::addDatabase("QSQLITE"); + conn.setDatabaseName(QApplication::applicationDirPath() + "/data/casic.db"); + + bool succ = conn.open(); + if (succ == true) + { +// LOG_INFO(QString("打开数据库操作正常[Open Database Success]").toStdString()); + } else + { +// LOG_ERROR(QString("打开数据库操作失败[Open Database Failed]").toStdString()); + } + } +} + +ConnectionManager::~ConnectionManager() +{ + conn.close(); +} + +ConnectionManager* ConnectionManager::getInstance() +{ + return cm; +} + +QSqlDatabase ConnectionManager::getConnection() +{ + return this->conn; +} + +qint64 ConnectionManager::generateId() +{ + return this->idWorker.nextId(); +} diff --git a/dao/util/ConnectionManager.h b/dao/util/ConnectionManager.h new file mode 100644 index 0000000..84647e3 --- /dev/null +++ b/dao/util/ConnectionManager.h @@ -0,0 +1,34 @@ +#ifndef CONNECTIONMANAGER_H +#define CONNECTIONMANAGER_H + +#include +#include +#include "utils/id/IdWorker.h" +#include "utils/UtilInclude.h" + +using namespace Jiawa::Core; + +class ConnectionManager : public QObject +{ + Q_OBJECT +public: + explicit ConnectionManager(QObject *parent = nullptr); + ~ConnectionManager(); + + static ConnectionManager * getInstance(); + + QSqlDatabase getConnection(); + qint64 generateId(); + +private: + // 数据库连接 + QSqlDatabase conn; + + // 雪花id生成工具 + IdWorker &idWorker = Singleton::instance(); + +signals: + +}; + +#endif // CONNECTIONMANAGER_H diff --git a/device/IrisCameraCapEventHandler.cpp b/device/IrisCameraCapEventHandler.cpp new file mode 100644 index 0000000..45df089 --- /dev/null +++ b/device/IrisCameraCapEventHandler.cpp @@ -0,0 +1,103 @@ +#include "IrisCameraCapEventHandler.h" + +IrisCameraCapEventHandler::IrisCameraCapEventHandler(QObject *parent) : QObject(parent) +{ + +} + +void IrisCameraCapEventHandler::DoOnImageCaptured(CImageDataPointer &objImageDataPointer, void *pUserParam) +{ + if (objImageDataPointer.IsNull() == false) + { + CGXDevicePointer* cam = (CGXDevicePointer *) pUserParam; + + auto camName = cam->getPtr()->GetDeviceInfo().GetUserID(); + int width = objImageDataPointer->GetWidth(); + int height = objImageDataPointer->GetHeight(); + size_t leftKeyIndex = camName.find("left"); + size_t rightKeyIndex = camName.find("right"); + + uchar * pBuffer = (BYTE*)objImageDataPointer->GetBuffer(); + + // 相机拍摄下的图像1440*1080, 直接用于算法判断 + QImage img = QImage(pBuffer, width, height, QImage::Format_Grayscale8); // 用于展示 +// QImage imgAlgo = img.copy(0, 0, width, height); + + // 用于显示的图像需要缩小到400 * 300的尺寸 + img = img.scaled(SettingConfig::getInstance().IRIS_DISPLAY_HEIGHT, SettingConfig::getInstance().IRIS_DISPLAY_WIDTH); + img = img.transformed(QTransform().rotate(-90)); // 图像逆时针旋转90度 + + // 发送到界面进行显示 + emit sendIrisFrameToDraw(img); +// cv::Mat irisMat = ImageUtil::QImageToMat(imgAlgo); + +// irisInfo.data = imgAlgo; +// irisInfo.matData = irisMat; + +// // 将图像显示在注册页面的label上 +// // 并将虹膜信息对象存入队列中 +// ProMemory::getInstance().pushCasicIris(irisInfo); + +// if (leftKeyIndex >= 0 && leftKeyIndex < 32) +// { +// emit sendIrisFrameToDraw(img, 0); // 左眼画面 +// } else if (rightKeyIndex >= 0 && rightKeyIndex < 32) +// { +// emit sendIrisFrameToDraw(img, 1); // 右眼画面 +// } +/* + if (pBuffer != NULL) + { + // 创建虹膜信息对象 + CasicIrisInfo irisInfo; + irisInfo.hasEye = false; + if (leftKeyIndex >= 0 && leftKeyIndex < 32) + { + // 左眼相机拍摄的图像 + irisInfo.leftOrRight = "left"; + } else if (rightKeyIndex >= 0 && rightKeyIndex < 32) + { + // 右眼相机 + irisInfo.leftOrRight = "right"; + } + + if (ProMemory::getInstance().widgeFrame == CasicBioRecConst::RECOGNIZE_RESULT_FORM) + { + // 相机拍摄下的图像1280*960, 直接用于算法判断 + QImage imgDisp = QImage(pBuffer, width, height, QImage::Format_Grayscale8); + cv::Mat irisMat = ImageUtil::QImageToMat(imgDisp); + + irisInfo.data = imgDisp; + irisInfo.matData = irisMat; + + ProMemory::getInstance().pushCasicIris(irisInfo); + +// cv::imwrite(QString("D:\\irisLogs\\iristest-%1.bmp").arg(irisInfo.leftOrRight).toStdString(), irisMat); + } else if (ProMemory::getInstance().widgeFrame == CasicBioRecConst::ADD_PERSON_CAPTURE_IRIS) + { + // 相机拍摄下的图像1280*960, 直接用于算法判断 + QImage img = QImage(pBuffer, width, height, QImage::Format_Grayscale8); + QImage imgAlgo = img.copy(0, 0, width, height); + + // 用于显示的图像需要缩小到1/4的尺寸 + img = img.scaled(640, 480); + cv::Mat irisMat = ImageUtil::QImageToMat(imgAlgo); + + irisInfo.data = imgAlgo; + irisInfo.matData = irisMat; + + // 将图像显示在注册页面的label上 + // 并将虹膜信息对象存入队列中 + ProMemory::getInstance().pushCasicIris(irisInfo); + + if (leftKeyIndex >= 0 && leftKeyIndex < 32) + { + emit sendIrisFrameToDraw(img, 0); // 左眼画面 + } else if (rightKeyIndex >= 0 && rightKeyIndex < 32) + { + emit sendIrisFrameToDraw(img, 1); // 右眼画面 + } + } + }*/ + } +} diff --git a/device/IrisCameraCapEventHandler.h b/device/IrisCameraCapEventHandler.h new file mode 100644 index 0000000..ad75a97 --- /dev/null +++ b/device/IrisCameraCapEventHandler.h @@ -0,0 +1,30 @@ +#ifndef IRISCAMERACAPEVENTHANDLER_H +#define IRISCAMERACAPEVENTHANDLER_H + +#include +#include +#include "include/opencv2/opencv.hpp" +#include "include/daheng/GalaxyIncludes.h" + +//#include "casic/iris/CasicIrisInterface.h" +#include "ProMemory.h" + +#include "utils/UtilInclude.h" + +class IrisCameraCapEventHandler : public QObject, public ICaptureEventHandler +{ + Q_OBJECT +public: + explicit IrisCameraCapEventHandler(QObject *parent = nullptr); + + void DoOnImageCaptured(CImageDataPointer &objImageDataPointer, void *pUserParam); + +private: + unsigned char* pImageBuffer; + +signals: + void sendIrisFrameToDraw(QImage irisImage); + +}; + +#endif // IRISCAMERACAPEVENTHANDLER_H diff --git a/device/IrisCameraController.cpp b/device/IrisCameraController.cpp new file mode 100644 index 0000000..0928176 --- /dev/null +++ b/device/IrisCameraController.cpp @@ -0,0 +1,110 @@ +#include "IrisCameraController.h" + +IrisCameraController::IrisCameraController(QObject *parent) : QObject(parent) +{ + this->irisCamHandler = new IrisCameraCapEventHandler(this); +} +IrisCameraController::~IrisCameraController() +{ + this->closeIrisCamera(); +} + + +void IrisCameraController::initIrisCamera() +{ + IGXFactory::GetInstance().Init(); + + //枚举设备 + IGXFactory::GetInstance().UpdateDeviceList(1000, irisCamList); + + this->OpenDevice(); +} + +void IrisCameraController::openIrisCamera() +{ + //设置Buffer处理模式 + irisStreamFeaturePtr->GetEnumFeature("StreamBufferHandlingMode")->SetValue("OldestFirst"); + + //注册回调函数 + irisStreamPtr->RegisterCaptureCallback(irisCamHandler, &irisCamPtr); + + //开启流层通道 + irisStreamPtr->StartGrab(); + + //发送开采命令 + irisFeaturePtr->GetCommandFeature("AcquisitionStart")->Execute(); + + // 启动定时器 + TimeCounterUtil::getInstance().irisCapCounter->start(SettingConfig::getInstance().IRIS_FRAME_INTERVAL); // 50ms执行一次定时器 +} + +void IrisCameraController::closeIrisCamera() +{ + +} + +void IrisCameraController::startCapture() +{ + // 获取定时器, 绑定定时函数 + connect(TimeCounterUtil::getInstance().irisCapCounter, &QTimer::timeout, this, &IrisCameraController::getOneFaceFrm); +// LOG(DEBUG) << QString("[IrisCameraController][startCapture]虹膜相机拍图").toStdString(); +// LOG_DEBUG(QString("[IrisCameraController][startCapture]虹膜相机拍图").toStdString()); + +} +void IrisCameraController::stopCapture() +{ + // 获取定时器, 绑定定时函数 + disconnect(TimeCounterUtil::getInstance().irisCapCounter, &QTimer::timeout, this, &IrisCameraController::getOneFaceFrm); +// LOG(DEBUG) << QString("[IrisCameraController][stopCapture]虹膜相机停止拍图").toStdString(); +// LOG_DEBUG(QString("[IrisCameraController][stopCapture]虹膜相机停止拍图").toStdString()); + +} + +void IrisCameraController::getOneFaceFrm() +{ + // 发送软触发命令(在触发模式开启时有效) + irisFeaturePtr->GetCommandFeature("TriggerSoftware")->Execute(); +} + +void IrisCameraController::getLeftAndRightEyeFrame() +{ + irisFeaturePtr->GetCommandFeature("TriggerSoftware")->Execute(); +} + +void IrisCameraController::OpenDevice() +{ + auto device = irisCamList.at(0); + + irisCamPtr = IGXFactory::GetInstance().OpenDeviceByUserID(device.GetUserID(), GX_ACCESS_EXCLUSIVE); + irisFeaturePtr = irisCamPtr->GetRemoteFeatureControl(); + + // 判断设备流是否大于零, 如果大于零则打开流 + int nStreamCount = irisCamPtr->GetStreamCount(); + if (nStreamCount > 0) + { + irisStreamPtr = irisCamPtr->OpenStream(0); + irisStreamFeaturePtr = irisStreamPtr->GetFeatureControl(); + } + + // 建议用户在打开网络相机之后, 根据当前网络环境设置相机的流通道包长值, + // 以提高网络相机的采集性能, 设置方法参考以下代码。 + GX_DEVICE_CLASS_LIST objDeviceClass = irisCamPtr->GetDeviceInfo().GetDeviceClass(); + if(GX_DEVICE_CLASS_GEV == objDeviceClass) + { + // 判断设备是否支持流通道数据包功能 + if(true == irisFeaturePtr->IsImplemented("GevSCPSPacketSize")) + { + // 获取当前网络环境的最优包长值 + int nPacketSize = irisStreamPtr->GetOptimalPacketSize(); + // 将最优包长值设置为当前设备的流通道包长值 + irisFeaturePtr->GetIntFeature("GevSCPSPacketSize")->SetValue(nPacketSize); + } + } + + //设置采集模式为连续采集模式 + irisFeaturePtr->GetEnumFeature("AcquisitionMode")->SetValue("Continuous"); + + //设置触发模式关 + irisFeaturePtr->GetEnumFeature("TriggerMode")->SetValue("On"); + irisFeaturePtr->GetEnumFeature("TriggerSource")->SetValue("Software"); +} diff --git a/device/IrisCameraController.h b/device/IrisCameraController.h new file mode 100644 index 0000000..5d7e269 --- /dev/null +++ b/device/IrisCameraController.h @@ -0,0 +1,49 @@ +#ifndef IRISCAMERACONTROLLER_H +#define IRISCAMERACONTROLLER_H + +#include + +#include "IrisCameraCapEventHandler.h" + +class IrisCameraCapEventHandler; + +class IrisCameraController : public QObject +{ + Q_OBJECT +public: + explicit IrisCameraController(QObject *parent = nullptr); + ~IrisCameraController(); + + // 初始化并打开人脸相机 + void initIrisCamera(); + void openIrisCamera(); + void closeIrisCamera(); + + void startCapture(); + void stopCapture(); + + void getLeftAndRightEyeFrame(); + + IrisCameraCapEventHandler * irisCamHandler; + +private: + GxIAPICPP::gxdeviceinfo_vector irisCamList; + + CGXDevicePointer irisCamPtr; ///< 设备句柄 + + CGXStreamPointer irisStreamPtr; ///< 左眼设备流 + + CGXFeatureControlPointer irisFeaturePtr; ///< 左眼属性控制器 + + CGXFeatureControlPointer irisStreamFeaturePtr; ///< 左眼流层控制器对象 + + void OpenDevice(); + +signals: + +public slots: + void getOneFaceFrm(); + +}; + +#endif // IRISCAMERACONTROLLER_H diff --git a/device/device.pri b/device/device.pri new file mode 100644 index 0000000..a8417f2 --- /dev/null +++ b/device/device.pri @@ -0,0 +1,13 @@ + +HEADERS += $$PWD/IrisCameraController.h +HEADERS += $$PWD/IrisCameraCapEventHandler.h +#HEADERS += $$PWD/iris/IrisRegistProcess.h +#HEADERS += $$PWD/iris/IrisRecogProcess.h +#HEADERS += $$PWD/iris/CasicIrisRecState.h + +SOURCES += $$PWD/IrisCameraController.cpp +SOURCES += $$PWD/IrisCameraCapEventHandler.cpp +#SOURCES += $$PWD/iris/IrisRegistProcess.cpp +#SOURCES += $$PWD/iris/IrisRecogProcess.cpp +#SOURCES += $$PWD/iris/CasicIrisRecState.cpp + diff --git a/images/bg_footer.png b/images/bg_footer.png new file mode 100644 index 0000000..a3a99ab --- /dev/null +++ b/images/bg_footer.png Binary files differ diff --git a/AppConstants.h b/AppConstants.h new file mode 100644 index 0000000..296c53f --- /dev/null +++ b/AppConstants.h @@ -0,0 +1,28 @@ +#ifndef APPCONSTANTS_H +#define APPCONSTANTS_H + +class AppConstants +{ +public: + enum WidgeFrameName + { + MAIN_PAGE = 0, // 主页面 + PERSON_LIST_FORM = 1, // 人员列表页面 + ADD_PERSON_FORM = 2, // 添加人员页面 + ADD_PERSON_CAPTURE_FACE = 21, // 添加/编辑人员时进行人脸拍图 + ADD_PERSON_CAPTURE_IRIS = 22, // 添加/编辑人员时进行虹膜拍图 + SETTING_FORM = 3, // 设置页面 + RECOGNIZE_RESULT_FORM = 4, // 识别结果界面 + IDENTIFY_FORM = 5, // 识别界面 含识别中 和 识别结果 + LOCKSCREEN_FORM = 6 // 锁屏待机界面 + }; + + enum ApplicationState + { + STATE_WAIT = 0, // 待机 + STATE_WORKING = 1, // 工作状态 + STATE_IDENTIFYING = 2, // 识别中 + }; +}; + +#endif // APPCONSTANTS_H diff --git a/CasicIrisIdentify.pro b/CasicIrisIdentify.pro index 5d7fea6..575ce3d 100644 --- a/CasicIrisIdentify.pro +++ b/CasicIrisIdentify.pro @@ -1,4 +1,4 @@ -QT += core gui +QT += core gui sql network texttospeech greaterThan(QT_MAJOR_VERSION, 4): QT += widgets @@ -15,20 +15,46 @@ # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 -SOURCES += \ - main.cpp \ - IdentifyForm.cpp +include("dao/dao.pri") +include("device/device.pri") +include("utils/utils.pri") -HEADERS += \ - IdentifyForm.h +SOURCES += main.cpp +SOURCES += ProMemory.cpp +SOURCES += MainWindowForm.cpp +SOURCES += IdentifyForm.cpp +SOURCES += LockScreenForm.cpp -FORMS += \ - IdentifyForm.ui +HEADERS += AppConstants.h +HEADERS += ProMemory.h +HEADERS += MainWindowForm.h +HEADERS += IdentifyForm.h +HEADERS += LockScreenForm.h -TRANSLATIONS += \ - CasicIrisIdentify_zh_CN.ts +FORMS += MainWindowForm.ui +FORMS += IdentifyForm.ui +FORMS += LockScreenForm.ui + +RESOURCES += resource.qrc + +DISTFILES += conf/config.ini + +#TRANSLATIONS += CasicIrisIdentify_zh_CN.ts + +#INCLUDEPATH += include/spdlog +#DEPENDPATH += include/spdlog # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target + + +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lopencv_world420 +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lGxIAPICPPEx + +INCLUDEPATH += $$PWD/include/daheng +DEPENDPATH += $$PWD/include/daheng + +INCLUDEPATH += $$PWD/include +DEPENDPATH += $$PWD/include diff --git a/CasicIrisIdentify_zh_CN.ts b/CasicIrisIdentify_zh_CN.ts index 5526fe4..81900df 100644 --- a/CasicIrisIdentify_zh_CN.ts +++ b/CasicIrisIdentify_zh_CN.ts @@ -1,3 +1,12 @@ - + + + IdentifyForm + + + IdentifyForm + + + + diff --git a/IdentifyForm.cpp b/IdentifyForm.cpp index 348a897..ba1f251 100644 --- a/IdentifyForm.cpp +++ b/IdentifyForm.cpp @@ -1,4 +1,4 @@ -#include "IdentifyForm.h" +#include "IdentifyForm.h" #include "ui_IdentifyForm.h" IdentifyForm::IdentifyForm(QWidget *parent) @@ -6,6 +6,12 @@ , ui(new Ui::IdentifyForm) { ui->setupUi(this); + + // 初始化更新界面的定时器 + // 每秒执行一次 + connect(TimeCounterUtil::getInstance().clockCounter, &QTimer::timeout, this, &IdentifyForm::updateDateAndTime); + + TimeCounterUtil::getInstance().clockCounter->start(1000); } IdentifyForm::~IdentifyForm() @@ -13,3 +19,16 @@ delete ui; } +void IdentifyForm::drawIrisImageOnFrame(QImage image) +{ + // 只在识别界面才显示画面 + if (ui->wgtStacked->currentIndex() == 0) { + ui->labelVideo->setPixmap(QPixmap::fromImage(image)); + } +} + + +void IdentifyForm::updateDateAndTime() +{ + ui->labelTime->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd dddd HH:mm:ss")); +} diff --git a/IdentifyForm.h b/IdentifyForm.h index fc857a1..ae1cd22 100644 --- a/IdentifyForm.h +++ b/IdentifyForm.h @@ -1,7 +1,10 @@ -#ifndef IDENTIFYFORM_H +#ifndef IDENTIFYFORM_H #define IDENTIFYFORM_H #include +#include + +#include "utils/UtilInclude.h" QT_BEGIN_NAMESPACE namespace Ui { class IdentifyForm; } @@ -15,7 +18,14 @@ IdentifyForm(QWidget *parent = nullptr); ~IdentifyForm(); +public slots: + void drawIrisImageOnFrame(QImage image); + private: Ui::IdentifyForm *ui; + +private slots: + void updateDateAndTime(); + }; #endif // IDENTIFYFORM_H diff --git a/IdentifyForm.ui b/IdentifyForm.ui index c72a36f..879dc9a 100644 --- a/IdentifyForm.ui +++ b/IdentifyForm.ui @@ -6,13 +6,59 @@ 0 0 - 800 + 600 600 IdentifyForm + + + + 0 + 40 + 600 + 450 + + + + 0 + + + + + + 100 + 10 + 400 + 300 + + + + + + + + + + + + + + 0 + 0 + 600 + 40 + + + + TextLabel + + + Qt::AlignCenter + + diff --git a/LockScreenForm.cpp b/LockScreenForm.cpp new file mode 100644 index 0000000..58dc54b --- /dev/null +++ b/LockScreenForm.cpp @@ -0,0 +1,14 @@ +#include "LockScreenForm.h" +#include "ui_LockScreenForm.h" + +LockScreenForm::LockScreenForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::LockScreenForm) +{ + ui->setupUi(this); +} + +LockScreenForm::~LockScreenForm() +{ + delete ui; +} diff --git a/LockScreenForm.h b/LockScreenForm.h new file mode 100644 index 0000000..b5ded48 --- /dev/null +++ b/LockScreenForm.h @@ -0,0 +1,25 @@ +#ifndef LOCKSCREENFORM_H +#define LOCKSCREENFORM_H + +#include +#include + +#include "utils/UtilInclude.h" + +namespace Ui { +class LockScreenForm; +} + +class LockScreenForm : public QWidget +{ + Q_OBJECT + +public: + explicit LockScreenForm(QWidget *parent = nullptr); + ~LockScreenForm(); + +private: + Ui::LockScreenForm *ui; +}; + +#endif // LOCKSCREENFORM_H diff --git a/LockScreenForm.ui b/LockScreenForm.ui new file mode 100644 index 0000000..7f2a6db --- /dev/null +++ b/LockScreenForm.ui @@ -0,0 +1,45 @@ + + + LockScreenForm + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + 180 + 100 + 54 + 12 + + + + TextLabel + + + + + + 180 + 160 + 54 + 12 + + + + TextLabel + + + + + + diff --git a/MainWindowForm.cpp b/MainWindowForm.cpp new file mode 100644 index 0000000..84f8159 --- /dev/null +++ b/MainWindowForm.cpp @@ -0,0 +1,86 @@ +#include "MainWindowForm.h" +#include "ui_MainWindowForm.h" +#include + +MainWindowForm::MainWindowForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::MainWindowForm) +{ + ui->setupUi(this); + + // 设置窗口透明和大小、位置 + this->setWindowFlags(Qt::FramelessWindowHint); + this->move(1400, 15); + this->resize(SettingConfig::getInstance().WINDOW_WIDTH, SettingConfig::getInstance().WINDOW_HEIGHT); + + // 通过调色板的颜色来设置窗口的统一背景色 + qApp->setPalette(QPalette(QColor(SettingConfig::getInstance().WINDOW_BACKGROUND_COLOR))); + + // 加载css文件设置控件样式 + QFile file(QApplication::applicationDirPath() + "/qss/main.css"); + if (file.open(QFile::ReadOnly)) + { + QString qssStr = QLatin1String(file.readAll()); + this->setStyleSheet(qssStr); + file.close(); + } + + initFormsPtr(); + + // 设置标题文字 + ui->labelTitle->setText(SettingConfig::getInstance().WINDOW_TITLE); + ui->labelCopyright->setText(SettingConfig::getInstance().WINDOW_RIGHTS); + ui->labelVersion->setText(SettingConfig::getInstance().WINDOW_VERSION); + + // 初始化虹膜相机控制 + ProMemory::getInstance().irisCam = new IrisCameraController(this); + ProMemory::getInstance().irisCam->initIrisCamera(); + ProMemory::getInstance().irisCam->openIrisCamera(); + connect(ProMemory::getInstance().irisCam->irisCamHandler, &IrisCameraCapEventHandler::sendIrisFrameToDraw, identifyForm, &IdentifyForm::drawIrisImageOnFrame); + +// LOG_INFO(QString("应用程序启动成功[Application Startup Success]").toStdString()); + qDebug() << "应用程序启动成功[Application Startup Success]"; + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::IDENTIFY_FORM; + ui->wdgtStatced->setCurrentWidget(identifyForm); + + // 开始虹膜相机拍图 + ProMemory::getInstance().irisCam->startCapture(); +} + +MainWindowForm::~MainWindowForm() +{ + delete ui; +} + +void MainWindowForm::lockScreen() +{ + ui->wdgtStatced->setCurrentWidget(lockScreenForm); + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::LOCKSCREEN_FORM; + ProMemory::getInstance().appState = AppConstants::ApplicationState::STATE_WAIT; +} + +void MainWindowForm::keyPressEvent(QKeyEvent *event) +{ + switch (event->key()) { + case Qt::Key_Escape: + QTimer::singleShot(100, qApp, [=](){ + QApplication::quit(); + }); + + default: + QWidget::keyPressEvent(event); + } +} + +void MainWindowForm::initFormsPtr() +{ + // 初始化各个form + lockScreenForm = new LockScreenForm(this); + identifyForm = new IdentifyForm(this); + + // 将form添加到statcked widget中 + ui->wdgtStatced->addWidget(identifyForm); + ui->wdgtStatced->addWidget(lockScreenForm); + + // 绑定按钮函数 +} diff --git a/MainWindowForm.h b/MainWindowForm.h new file mode 100644 index 0000000..7fb2d89 --- /dev/null +++ b/MainWindowForm.h @@ -0,0 +1,38 @@ +#ifndef MAINWINDOWFORM_H +#define MAINWINDOWFORM_H + +#include +#include +#include + +#include "utils/UtilInclude.h" +#include "ProMemory.h" +#include "LockScreenForm.h" +#include "IdentifyForm.h" + +namespace Ui { +class MainWindowForm; +} + +class MainWindowForm : public QWidget +{ + Q_OBJECT + +public: + explicit MainWindowForm(QWidget *parent = nullptr); + ~MainWindowForm(); + +public slots: + void lockScreen(); + +private: + Ui::MainWindowForm *ui; + LockScreenForm * lockScreenForm; + IdentifyForm * identifyForm; + + void keyPressEvent(QKeyEvent *event); + + void initFormsPtr(); +}; + +#endif // MAINWINDOWFORM_H diff --git a/MainWindowForm.ui b/MainWindowForm.ui new file mode 100644 index 0000000..e793ebf --- /dev/null +++ b/MainWindowForm.ui @@ -0,0 +1,85 @@ + + + MainWindowForm + + + + 0 + 0 + 600 + 1024 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + 0 + 0 + 600 + 84 + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + + + + TextLabel + + + Qt::AlignBottom|Qt::AlignHCenter + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + diff --git a/ProMemory.cpp b/ProMemory.cpp new file mode 100644 index 0000000..19e7403 --- /dev/null +++ b/ProMemory.cpp @@ -0,0 +1,84 @@ +#include "ProMemory.h" + +ProMemory::ProMemory() +{ + +} + +ProMemory::~ProMemory() +{ + +} + +/* +void ProMemory::pushCasicIris(CasicIrisInfo irisInfo) +{ + QMutex mutex; + mutex.lock(); + if (this->irisQueue.size() > 30) + { + QStack empty; + std::swap(empty, irisQueue); + } + + irisQueue.push(irisInfo); + mutex.unlock(); +} +CasicIrisInfo ProMemory::popCasicIris() +{ + CasicIrisInfo result; + + QMutex mutex; + mutex.lock(); + if (this->irisQueue.size() > 0) + { + result = irisQueue.pop(); + } + + mutex.unlock(); + + return result; +} +*/ +int ProMemory::getIrisQueueSize() +{ + int size = 0; + + QMutex mutex; + mutex.lock(); + +// size = this->irisQueue.size(); + + mutex.unlock(); + + return size; +} +bool ProMemory::isIrisQueueEmpty() +{ + bool empty = true; + + QMutex mutex; + mutex.lock(); + +// empty = this->irisQueue.isEmpty(); + + mutex.unlock(); + + return empty; +} +void ProMemory::clearIrisQueue() +{ + QMutex mutex; + mutex.lock(); + +// QStack empty; +// std::swap(empty, irisQueue); + + mutex.unlock(); +} + + +void ProMemory::initIrisFeatures(QString personId) +{ +// irisRegistPro->sendDataToExract(QByteArray(QString("[-u]").append(personId).toLocal8Bit())); +} diff --git a/ProMemory.h b/ProMemory.h new file mode 100644 index 0000000..2ecd653 --- /dev/null +++ b/ProMemory.h @@ -0,0 +1,52 @@ +#ifndef PROMEMORY_H +#define PROMEMORY_H + +#include +#include + +#include "AppConstants.h" +//#include "casic/iris/CasicIrisInfo.h" +#include "dao/IrisDataDao.h" + +#include "device/IrisCameraController.h" +//#include "device/iris/IrisRegistProcess.h" +//#include "device/iris/IrisRecogProcess.h" + +class IrisCameraController; +class IrisRegistProcess; +class IrisRecogProcess; + +class ProMemory +{ +public: + ~ProMemory(); + ProMemory(const ProMemory&)=delete; + ProMemory& operator=(const ProMemory&)=delete; + + static ProMemory& getInstance() { + static ProMemory instance; + return instance; + } + +// void pushCasicIris(CasicIrisInfo irisInfo); +// CasicIrisInfo popCasicIris(); + int getIrisQueueSize(); + bool isIrisQueueEmpty(); + void clearIrisQueue(); + + volatile int widgeFrame = 0; // 当前显示的界面 + volatile int appState = 0; // 当前程序所处的状态 + + void initIrisFeatures(QString personId = ""); // 初始化虹膜特征值集合 + + IrisCameraController * irisCam; + IrisRecogProcess * irisRecogPro; + +private: + ProMemory(); + +// QStack irisQueue; // 虹膜信息队列 + QVector irisFeatures; // 虹膜特征值集合 +}; + +#endif // PROMEMORY_H diff --git a/conf/config.ini b/conf/config.ini new file mode 100644 index 0000000..66e46ad --- /dev/null +++ b/conf/config.ini @@ -0,0 +1,67 @@ +[recognize] +#最大允许识别时间(ms) +maxMatchTime=10000 +#识别成功界面停留时间(ms) +successTipsLast=5000 +#识别失败界面停留时间(ms) +failureTipsLast=3000 +#人脸识别最大尝试次数 +maxFaceTryCount=20 +#持续没找到人脸的最大次数 +maxFaceNotFoundCount=500 +#注册时最小人脸 +minFaceRegist=240 +#识别时最小人脸 +minFaceRecog=100 + +#虹膜识别最大尝试次数 +maxIrisTryCount=10 +#虹膜识别持续没有找到眼的最大次数 +maxEyeNotFoundCount=50 + +#识别方式[1=人脸;2=虹膜;3=双认证;4=任意] +recogType=4 + +[window] +#界面窗口宽(px) +width=600 +#界面窗口高(px) +height=1024 +#统一背景色 +backgroundColor="#FFFFFF" +#标题 +title="虹膜识别终端" + +[work] +#工作状态检测时最小人脸范围 +minFaceSize=160 +#人脸范围最小横坐标 +minFacePosX=320 +#人脸范围最大横坐标 +maxFacePosX=960 +#人脸范围最小纵坐标 +minFacePosY=180 +#人脸范围最大纵坐标 +maxFacePosY=540 +#人脸太近阈值 +faceCloseSize=360 +#人脸太远阈值 +faceFarSize=480 + +[camera] +#虹膜相机取一幅画面的时间间隔(ms) +irisFrameInterval=100 +#虹膜相机拍摄宽度 +irisFrameWidth=1440 +#虹膜相机拍摄高度 +irisFrameHeight=1080 +#虹膜图像高度 +irisWidth=640 +#虹膜图像高度 +irisHeight=480 + +[log] +#日志文件位置 +logFile="d://irisLogs//casic_log.txt" +#日志级别 +logLevel="trace" diff --git a/dao/BaseDao.cpp b/dao/BaseDao.cpp new file mode 100644 index 0000000..f51c144 --- /dev/null +++ b/dao/BaseDao.cpp @@ -0,0 +1,12 @@ +#include "BaseDao.h" +#include "dao/util/ConnectionManager.h" + +BaseDao::BaseDao(QObject *parent) : QObject(parent) +{ + +} + +BaseDao::~BaseDao() +{ + +} diff --git a/dao/BaseDao.h b/dao/BaseDao.h new file mode 100644 index 0000000..1693c88 --- /dev/null +++ b/dao/BaseDao.h @@ -0,0 +1,32 @@ +#ifndef BASEDAO_H +#define BASEDAO_H + +#include +#include +#include +#include + +#include "dao/util/ConnectionManager.h" +#include "utils/UtilInclude.h" + +class BaseDao : public QObject +{ + Q_OBJECT +public: + explicit BaseDao(QObject *parent = nullptr); + ~BaseDao(); + + virtual QVector findAllRecord() = 0; + virtual QVariantMap findRecordById(QString id) = 0; + + virtual QString save(QVariantMap object) = 0; + virtual bool edit(QVariantMap newObject, QString id) = 0; + virtual bool dele(QString id) = 0; + +private: + +signals: + +}; + +#endif // BASEDAO_H diff --git a/dao/IrisDataDao.cpp b/dao/IrisDataDao.cpp new file mode 100644 index 0000000..37a0ed6 --- /dev/null +++ b/dao/IrisDataDao.cpp @@ -0,0 +1,204 @@ +#include "IrisDataDao.h" + +IrisDataDao::IrisDataDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector IrisDataDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM IRIS_DATA"; + query.prepare(sql); + + // 执行查询 + query.exec(); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + item.insert("id", query.value("id").toString()); + item.insert("person_id", query.value("person_id").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("left_iris_code1", query.value("left_iris_code1")); + item.insert("left_iris_code2", query.value("left_iris_code2")); + item.insert("left_iris_code3", query.value("left_iris_code3")); + item.insert("right_iris_code1", query.value("right_iris_code1")); + item.insert("right_iris_code2", query.value("right_iris_code2")); + item.insert("right_iris_code3", query.value("right_iris_code3")); + + result.append(item); + } + +// LOG_DEBUG(QString("查询IRIS_DATA表的所有记录[结果数:%1]").arg(result.size()).toStdString()); + return result; +} + +QVariantMap IrisDataDao::findRecordById(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM IRIS_DATA WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + // 获取结果 + if (query.next()) + { + result.insert("id", query.value("id").toString()); + result.insert("person_id", query.value("person_id").toLongLong()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("left_iris_code1", query.value("left_iris_code1")); + result.insert("left_iris_code2", query.value("left_iris_code2")); + result.insert("left_iris_code3", query.value("left_iris_code3")); + result.insert("right_iris_code1", query.value("right_iris_code1")); + result.insert("right_iris_code2", query.value("right_iris_code2")); + result.insert("right_iris_code3", query.value("right_iris_code3")); + } + +// LOG_DEBUG(QString("根据id查询IRIS_DATA表的记录[id=%1]").arg(id).toStdString()); + return result; +} + +QVariantMap IrisDataDao::findRecordByPersonId(QString personId) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM IRIS_DATA WHERE PERSON_ID = :personId"); + query.prepare(sql); + query.bindValue(":personId", personId); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + if (query.next()) + { + result.insert("id", query.value("id").toString()); + result.insert("person_id", query.value("person_id").toLongLong()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("left_iris_code1", query.value("left_iris_code1")); + result.insert("left_iris_code2", query.value("left_iris_code2")); + result.insert("left_iris_code3", query.value("left_iris_code3")); + result.insert("right_iris_code1", query.value("right_iris_code1")); + result.insert("right_iris_code2", query.value("right_iris_code2")); + result.insert("right_iris_code3", query.value("right_iris_code3")); + } + +// LOG_DEBUG(QString("根据personId查询IRIS_DATA表的记录[personId=%1]").arg(personId).toStdString()); + return result; +} + + +QString IrisDataDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + + // INSERT语句 + QString sql = QString("INSERT INTO IRIS_DATA (ID, PERSON_ID, ID_CARD_NO, LEFT_IRIS_CODE1, RIGHT_IRIS_CODE1) VALUES (:id, :personId, :idCardNo, :left1, :right1)"); + + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":personId", object.value("person_id").toString()); + query.bindValue(":idCardNo", object.value("id_card_no").toString()); + query.bindValue(":left1", object.value("left_iris_code1")); + query.bindValue(":right1", object.value("right_iris_code1")); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(); + +// LOG_DEBUG(QString("保存虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool IrisDataDao::edit(QVariantMap newObject, QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // UPDATE语句 + if (!newObject.contains("left_iris_code1") || !newObject.contains("right_iris_code1")){ + return false; + } + QString sql = QString("UPDATE IRIS_DATA SET LEFT_IRIS_CODE1 = :left1, RIGHT_IRIS_CODE1 = :right1 WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":left1", newObject.value("left_iris_code1")); + query.bindValue(":right1", newObject.value("right_iris_code1")); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(); + +// LOG_DEBUG(QString("编辑虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; +} + + +bool IrisDataDao::dele(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + QString sql = QString("DELETE FROM IRIS_DATA WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(); + +// LOG_DEBUG(QString("删除虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; +} diff --git a/dao/IrisDataDao.h b/dao/IrisDataDao.h new file mode 100644 index 0000000..c74dbbd --- /dev/null +++ b/dao/IrisDataDao.h @@ -0,0 +1,25 @@ +#ifndef IRISDATADAO_H +#define IRISDATADAO_H + +#include +#include "BaseDao.h" + +class IrisDataDao : public BaseDao +{ + Q_OBJECT +public: + explicit IrisDataDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + QVariantMap findRecordByPersonId(QString personId); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +signals: + +}; + +#endif // IRISDATADAO_H diff --git a/dao/RecognitionRecordsDao.cpp b/dao/RecognitionRecordsDao.cpp new file mode 100644 index 0000000..40db453 --- /dev/null +++ b/dao/RecognitionRecordsDao.cpp @@ -0,0 +1,100 @@ +#include "RecognitionRecordsDao.h" + +RecognitionRecordsDao::RecognitionRecordsDao(QObject *parent) : BaseDao(parent) +{ + +} + + +QVector RecognitionRecordsDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM RECOGNITION_RECORDS"; + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + item.insert("id", query.value("id").toLongLong()); + result.append(item); + } + +// LOG_DEBUG(QString("查询RECOGNITION_RECORDS表的所有记录[记录数:%1]").arg(result.size()).toStdString()); + return result; +} + +QVariantMap RecognitionRecordsDao::findRecordById(QString id) +{ + QVariantMap item; + return item; +} + +QString RecognitionRecordsDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + + // INSERT语句 + QString sql = QString("INSERT INTO RECOGNITION_RECORDS (ID, PERSON_ID, DATETIME, REC_TYPE, DEV_CODE, DOOR_CODE, INOUT_TYPE) " + "VALUES (:id, :personId, :datetime, :recType, :devCode, :doorCode, :inoutType)"); + + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":personId", object.value("person_id").toString()); + query.bindValue(":datetime", object.value("date_time").toString()); + query.bindValue(":recType", object.value("rec_type").toString()); + query.bindValue(":devCode", object.value("dev_code").toString()); + query.bindValue(":doorCode", object.value("door_code").toString()); + query.bindValue(":inoutType", object.value("inout_type").toString()); + +// LOG_DEBUG(sql.toStdString()); + + // 插入识别的log日志 + QString logStr = QString("INSERT INTO RECOGNITION_LOGS (ID, LOG_INFO) VALUES (:id, :logInfo)"); + + QSqlQuery logQuery(ConnectionManager::getInstance()->getConnection()); + logQuery.prepare(logStr); + logQuery.bindValue(":id", id); + logQuery.bindValue(":logInfo", object.value("debug_info").toString()); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(); + logQuery.exec(); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool RecognitionRecordsDao::edit(QVariantMap newObject, QString id) +{ + return false; +} + +bool RecognitionRecordsDao::dele(QString id) +{ + return false; +} diff --git a/dao/RecognitionRecordsDao.h b/dao/RecognitionRecordsDao.h new file mode 100644 index 0000000..38de7c9 --- /dev/null +++ b/dao/RecognitionRecordsDao.h @@ -0,0 +1,23 @@ +#ifndef RECOGNITIONRECORDSDAO_H +#define RECOGNITIONRECORDSDAO_H + +#include +#include "BaseDao.h" +class RecognitionRecordsDao: public BaseDao +{ + Q_OBJECT +public: + explicit RecognitionRecordsDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +signals: + +}; + +#endif // RECOGNITIONRECORDSDAO_H diff --git a/dao/SysDeptDao.cpp b/dao/SysDeptDao.cpp new file mode 100644 index 0000000..22f9946 --- /dev/null +++ b/dao/SysDeptDao.cpp @@ -0,0 +1,88 @@ +#include "SysDeptDao.h" + +SysDeptDao::SysDeptDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector SysDeptDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_DEPT WHERE PID != '-1' ORDER BY PID, NUM"; + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + item.insert("id", query.value("id").toString()); + item.insert("pid", query.value("pid").toString()); + item.insert("pids", query.value("pids").toString()); + item.insert("simplename", query.value("simplename").toString()); + item.insert("fullname", query.value("fullname").toString()); + } + +// LOG_TRACE(QString("查询表[SYS_DEPT]的所有记录[%1][%2]").arg(result.size()).arg(sql).toStdString()); + + return result; +} + +QVariantMap SysDeptDao::findRecordById(QString id) +{ + QVariantMap item; + return item; + + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM SYS_DEPT WHERE SYS_DEPT.ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + // 获取结果集的大小 + query.last(); + int count = query.at() + 1; + + if (count >=1) + { + query.first(); + + result.insert("id", query.value("id").toString()); + result.insert("pid", query.value("pid").toString()); + result.insert("pids", query.value("pids").toString()); + result.insert("simplename", query.value("simplename").toString()); + result.insert("fullname", query.value("fullname").toString()); + } + +// LOG_TRACE(QString("根据id查询SYS_DEPT表的记录[ID=%1][%2]").arg(id).arg(sql).toStdString()); + + return result; +} + + +QString SysDeptDao::save(QVariantMap object) +{ + return "0"; +} +bool SysDeptDao::edit(QVariantMap newObject, QString id) +{ + return true; +} +bool SysDeptDao::dele(QString id) +{ + return true; +} diff --git a/dao/SysDeptDao.h b/dao/SysDeptDao.h new file mode 100644 index 0000000..e07a09f --- /dev/null +++ b/dao/SysDeptDao.h @@ -0,0 +1,24 @@ +#ifndef SYSDEPTDAO_H +#define SYSDEPTDAO_H + +#include +#include "BaseDao.h" + +class SysDeptDao : public BaseDao +{ + Q_OBJECT +public: + explicit SysDeptDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +private: + +}; + +#endif // SYSDEPTDAO_H diff --git a/dao/SysPersonDao.cpp b/dao/SysPersonDao.cpp new file mode 100644 index 0000000..dd9480f --- /dev/null +++ b/dao/SysPersonDao.cpp @@ -0,0 +1,371 @@ +#include "SysPersonDao.h" + + +SysPersonDao::SysPersonDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector SysPersonDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0'"; + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + count++; + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + result.append(item); + } + +// LOG(TRACE) << QString("查询SYS_PERSON表的所有记录[%1]").arg(count).toStdString(); +// LOG_TRACE(QString("查询SYS_PERSON表的所有记录[%1]").arg(count).toStdString()); + + return result; +} + +QVariantMap SysPersonDao::findRecordById(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0' AND SYS_PERSON.ID = '%1'").arg(id); + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVariantMap result; + + // 获取结果集的大小 + query.last(); + int count = query.at() + 1; + + if (count >=1) + { + query.first(); + + result.insert("id", query.value("id").toString()); + result.insert("delflag", query.value("delflag").toString()); + result.insert("createtime", query.value("createtime").toString()); + result.insert("updatetime", query.value("updatetime").toString()); + result.insert("name", query.value("name").toString()); + result.insert("gender", query.value("gender").toString()); + result.insert("deptid", query.value("deptid").toString()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("remarks", query.value("remarks").toString()); + result.insert("person_code", query.value("person_code").toString()); + result.insert("deptname", query.value("fullname").toString()); + result.insert("sync_id", query.value("sync_id").toString()); + result.insert("hasFace", query.value("face_valid").toString()); + result.insert("hasIris", query.value("iris_valid").toString()); + } + +// LOG(TRACE) << QString("根据id查询SYS_PERSON表的记录[id=%1][%2]").arg(id).arg(sql).toStdString(); +// LOG_TRACE(QString("根据id查询SYS_PERSON表的记录[id=%1][%2]").arg(id).arg(sql).toStdString()); + + return result; +} + +int SysPersonDao::findRecordCountByNameAndDept(QString name, QString dept) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT COUNT(P.ID) AS RECCT FROM SYS_PERSON P LEFT JOIN SYS_DEPT D ON P.DEPTID = D.ID WHERE P.DELFLAG = '0'"; + if (name.isEmpty() == false) + { + sql += " AND P.NAME LIKE '%" + name + "%'"; + } + if (dept.isEmpty() == false && dept.indexOf("-1") < 0) + { + sql += QString(" AND ((P.DEPTID = '%1') OR (D.PIDS LIKE '%,%1,%'))").arg(dept); + } + + // 执行查询 + query.exec(sql); + + // 返回结果 + int result; + + // 遍历查询结果 + if (query.next()) { + result = query.value("RECCT").toInt(); + } + +// LOG(TRACE) << QString("根据姓名和部门查询SYS_PERSON记录总数[%1][%2]").arg(result).arg(sql).toStdString(); +// LOG_TRACE(QString("根据姓名和部门查询SYS_PERSON记录总数[%1][%2]").arg(result).arg(sql).toStdString()); + + return result; +} + +QVector SysPersonDao::findRecordsByNameAndDept(QString name, QString dept, qint8 limit, qint16 offset) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON P LEFT JOIN SYS_DEPT D ON P.DEPTID = D.ID WHERE P.DELFLAG = '0'"; + if (name.isEmpty() == false) + { + sql += " AND P.NAME LIKE '%" + name + "%'"; + } + if (dept.isEmpty() == false && dept.indexOf("-1") < 0) + { + sql += QString(" AND ((P.DEPTID = '%1') OR (D.PIDS LIKE '%,%1,%'))").arg(dept); + } + + sql += QString(" LIMIT %1 OFFSET %2").arg(limit).arg(offset); + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + count++; + + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + + result.append(item); + } + +// LOG(TRACE) << QString("根据姓名和部门分页查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString(); +// LOG_TRACE(QString("根据姓名和部门分页查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString()); + + return result; +} + +QVector SysPersonDao::findRecordsByProperties(QVariantMap conditions) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0'"; + QVariantMap::iterator it; + for (it = conditions.begin(); it != conditions.end(); it++) + { + sql += QString(" AND SYS_PERSON.%1 = %2").arg(it.key()).arg(it.value().toString()); + } + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + count++; + + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + + result.append(item); + } + +// LOG(TRACE) << QString("根据属性值查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString(); +// LOG_TRACE(QString("根据属性值查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString()); + + return result; +} + +QString SysPersonDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + + // INSERT语句 + QString sql = QString("INSERT INTO SYS_PERSON " + "(ID, DELFLAG, CREATETIME, UPDATETIME, " + "NAME, GENDER, DEPTID, ID_CARD_NO, " + "REMARKS, PERSON_CODE, SYNC_ID, FACE_VALID, IRIS_VALID) " + "VALUES ('%1', '0', '%2', '%2', '%3', '%4', '%5', '%6', '%7', '%8', '%9', 0, 0)") + .arg(id).arg(tm) + .arg(object.value("name").toString()) + .arg(object.value("gender").toString()) + .arg(object.value("deptid").toString()) + .arg(object.value("id_card_no").toString()) + .arg(object.value("remarks").toString()) + .arg(object.value("person_code").toString()) + .arg(object.value("sync_id").toString()); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(sql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { +// LOG(DEBUG) << QString("保存SYS_PERSON记录成功[ID = %1][%2]").arg(id).arg(sql).toStdString(); +// LOG_DEBUG(QString("保存SYS_PERSON记录成功[ID = %1][%2]").arg(id).arg(sql).toStdString()); + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool SysPersonDao::edit(QVariantMap newObject, QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + + // UPDATE语句 + QString sql = QString("UPDATE SYS_PERSON SET UPDATETIME = '%1'").arg(tm); + if (newObject.contains("name")) + { + sql.append(QString(", NAME = '%1'").arg(newObject.value("name").toString())); + } + if (newObject.contains("gender")) + { + sql.append(QString(", GENDER = '%1'").arg(newObject.value("gender").toString())); + } + if (newObject.contains("deptid")) + { + sql.append(QString(", DEPTID = '%1'").arg(newObject.value("deptid").toString())); + } + if (newObject.contains("person_code")) + { + sql.append(QString(", PERSON_CODE = '%1'").arg(newObject.value("person_code").toString())); + } + if (newObject.contains("face_valid")) + { + sql.append(QString(", FACE_VALID = '%1'").arg(newObject.value("face_valid").toString())); + } + if (newObject.contains("iris_valid")) + { + sql.append(QString(", IRIS_VALID = '%1'").arg(newObject.value("iris_valid").toString())); + } + + sql.append(QString(" WHERE ID = '%1'").arg(id)); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(sql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + +// LOG(DEBUG) << QString("编辑人员[ID=%1][%2]").arg(id).arg(sql).toStdString(); +// LOG_DEBUG(QString("编辑人员[ID=%1][%2]").arg(id).arg(sql).toStdString()); + + // 返回结果 + return success; +} + +bool SysPersonDao::dele(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + QSqlQuery irisDel(ConnectionManager::getInstance()->getConnection()); + + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + qint64 tmms = QDateTime::currentDateTime().toMSecsSinceEpoch(); + + // UPDATE语句 + QString sql = QString("UPDATE SYS_PERSON SET UPDATETIME = :updateTime, DELFLAG = :flag WHERE ID = :id").arg(tm).arg(tmms).arg(id); + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":updateTime", tm); + query.bindValue(":flag", tmms); + + // 物理删除人员的人脸和虹膜数据 + QString delIrisSql = QString("DELETE FROM IRIS_DATA WHERE PERSON_ID = :personId"); + irisDel.prepare(delIrisSql); + irisDel.bindValue(":personId", id); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(sql); + query.exec(delIrisSql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + +// LOG_DEBUG(QString("删除人员SYS_PERSON[ID=%1][%2]").arg(id).arg(success).toStdString()); + + // 返回结果 + return success; +} diff --git a/dao/SysPersonDao.h b/dao/SysPersonDao.h new file mode 100644 index 0000000..e02e5ba --- /dev/null +++ b/dao/SysPersonDao.h @@ -0,0 +1,27 @@ +#ifndef SYSPERSONDAO_H +#define SYSPERSONDAO_H + +#include +#include "BaseDao.h" + +class SysPersonDao : public BaseDao +{ + Q_OBJECT +public: + explicit SysPersonDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + int findRecordCountByNameAndDept(QString name, QString dept); + QVector findRecordsByNameAndDept(QString name, QString dept, qint8 limit, qint16 offset); + QVector findRecordsByProperties(QVariantMap conditions); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); +signals: + +}; + +#endif // SYSPERSONDAO_H diff --git a/dao/dao.pri b/dao/dao.pri new file mode 100644 index 0000000..1e04ce4 --- /dev/null +++ b/dao/dao.pri @@ -0,0 +1,18 @@ + +HEADERS += $$PWD/BaseDao.h +HEADERS += $$PWD/IrisDataDao.h +HEADERS += $$PWD/RecognitionRecordsDao.h +HEADERS += $$PWD/SysPersonDao.h +HEADERS += $$PWD/SysDeptDao.h + +SOURCES += $$PWD/BaseDao.cpp +SOURCES += $$PWD/IrisDataDao.cpp +SOURCES += $$PWD/RecognitionRecordsDao.cpp +SOURCES += $$PWD/SysPersonDao.cpp +SOURCES += $$PWD/SysDeptDao.cpp + +HEADERS += $$PWD/util/ConnectionManager.h +SOURCES += $$PWD/util/ConnectionManager.cpp +#HEADERS += $$PWD/util/CacheManager.h +#SOURCES += $$PWD/util/CacheManager.cpp + diff --git a/dao/util/ConnectionManager.cpp b/dao/util/ConnectionManager.cpp new file mode 100644 index 0000000..84b17be --- /dev/null +++ b/dao/util/ConnectionManager.cpp @@ -0,0 +1,47 @@ +#include "ConnectionManager.h" +#include + +Q_GLOBAL_STATIC(ConnectionManager, cm) + +ConnectionManager::ConnectionManager(QObject *parent) : QObject(parent) +{ + // 初始化数据库连接 + if (QSqlDatabase::contains("qt_sql_dafault_connection")) + { + conn = QSqlDatabase::database("qt_sql_default_connection"); + } + else + { + conn = QSqlDatabase::addDatabase("QSQLITE"); + conn.setDatabaseName(QApplication::applicationDirPath() + "/data/casic.db"); + + bool succ = conn.open(); + if (succ == true) + { +// LOG_INFO(QString("打开数据库操作正常[Open Database Success]").toStdString()); + } else + { +// LOG_ERROR(QString("打开数据库操作失败[Open Database Failed]").toStdString()); + } + } +} + +ConnectionManager::~ConnectionManager() +{ + conn.close(); +} + +ConnectionManager* ConnectionManager::getInstance() +{ + return cm; +} + +QSqlDatabase ConnectionManager::getConnection() +{ + return this->conn; +} + +qint64 ConnectionManager::generateId() +{ + return this->idWorker.nextId(); +} diff --git a/dao/util/ConnectionManager.h b/dao/util/ConnectionManager.h new file mode 100644 index 0000000..84647e3 --- /dev/null +++ b/dao/util/ConnectionManager.h @@ -0,0 +1,34 @@ +#ifndef CONNECTIONMANAGER_H +#define CONNECTIONMANAGER_H + +#include +#include +#include "utils/id/IdWorker.h" +#include "utils/UtilInclude.h" + +using namespace Jiawa::Core; + +class ConnectionManager : public QObject +{ + Q_OBJECT +public: + explicit ConnectionManager(QObject *parent = nullptr); + ~ConnectionManager(); + + static ConnectionManager * getInstance(); + + QSqlDatabase getConnection(); + qint64 generateId(); + +private: + // 数据库连接 + QSqlDatabase conn; + + // 雪花id生成工具 + IdWorker &idWorker = Singleton::instance(); + +signals: + +}; + +#endif // CONNECTIONMANAGER_H diff --git a/device/IrisCameraCapEventHandler.cpp b/device/IrisCameraCapEventHandler.cpp new file mode 100644 index 0000000..45df089 --- /dev/null +++ b/device/IrisCameraCapEventHandler.cpp @@ -0,0 +1,103 @@ +#include "IrisCameraCapEventHandler.h" + +IrisCameraCapEventHandler::IrisCameraCapEventHandler(QObject *parent) : QObject(parent) +{ + +} + +void IrisCameraCapEventHandler::DoOnImageCaptured(CImageDataPointer &objImageDataPointer, void *pUserParam) +{ + if (objImageDataPointer.IsNull() == false) + { + CGXDevicePointer* cam = (CGXDevicePointer *) pUserParam; + + auto camName = cam->getPtr()->GetDeviceInfo().GetUserID(); + int width = objImageDataPointer->GetWidth(); + int height = objImageDataPointer->GetHeight(); + size_t leftKeyIndex = camName.find("left"); + size_t rightKeyIndex = camName.find("right"); + + uchar * pBuffer = (BYTE*)objImageDataPointer->GetBuffer(); + + // 相机拍摄下的图像1440*1080, 直接用于算法判断 + QImage img = QImage(pBuffer, width, height, QImage::Format_Grayscale8); // 用于展示 +// QImage imgAlgo = img.copy(0, 0, width, height); + + // 用于显示的图像需要缩小到400 * 300的尺寸 + img = img.scaled(SettingConfig::getInstance().IRIS_DISPLAY_HEIGHT, SettingConfig::getInstance().IRIS_DISPLAY_WIDTH); + img = img.transformed(QTransform().rotate(-90)); // 图像逆时针旋转90度 + + // 发送到界面进行显示 + emit sendIrisFrameToDraw(img); +// cv::Mat irisMat = ImageUtil::QImageToMat(imgAlgo); + +// irisInfo.data = imgAlgo; +// irisInfo.matData = irisMat; + +// // 将图像显示在注册页面的label上 +// // 并将虹膜信息对象存入队列中 +// ProMemory::getInstance().pushCasicIris(irisInfo); + +// if (leftKeyIndex >= 0 && leftKeyIndex < 32) +// { +// emit sendIrisFrameToDraw(img, 0); // 左眼画面 +// } else if (rightKeyIndex >= 0 && rightKeyIndex < 32) +// { +// emit sendIrisFrameToDraw(img, 1); // 右眼画面 +// } +/* + if (pBuffer != NULL) + { + // 创建虹膜信息对象 + CasicIrisInfo irisInfo; + irisInfo.hasEye = false; + if (leftKeyIndex >= 0 && leftKeyIndex < 32) + { + // 左眼相机拍摄的图像 + irisInfo.leftOrRight = "left"; + } else if (rightKeyIndex >= 0 && rightKeyIndex < 32) + { + // 右眼相机 + irisInfo.leftOrRight = "right"; + } + + if (ProMemory::getInstance().widgeFrame == CasicBioRecConst::RECOGNIZE_RESULT_FORM) + { + // 相机拍摄下的图像1280*960, 直接用于算法判断 + QImage imgDisp = QImage(pBuffer, width, height, QImage::Format_Grayscale8); + cv::Mat irisMat = ImageUtil::QImageToMat(imgDisp); + + irisInfo.data = imgDisp; + irisInfo.matData = irisMat; + + ProMemory::getInstance().pushCasicIris(irisInfo); + +// cv::imwrite(QString("D:\\irisLogs\\iristest-%1.bmp").arg(irisInfo.leftOrRight).toStdString(), irisMat); + } else if (ProMemory::getInstance().widgeFrame == CasicBioRecConst::ADD_PERSON_CAPTURE_IRIS) + { + // 相机拍摄下的图像1280*960, 直接用于算法判断 + QImage img = QImage(pBuffer, width, height, QImage::Format_Grayscale8); + QImage imgAlgo = img.copy(0, 0, width, height); + + // 用于显示的图像需要缩小到1/4的尺寸 + img = img.scaled(640, 480); + cv::Mat irisMat = ImageUtil::QImageToMat(imgAlgo); + + irisInfo.data = imgAlgo; + irisInfo.matData = irisMat; + + // 将图像显示在注册页面的label上 + // 并将虹膜信息对象存入队列中 + ProMemory::getInstance().pushCasicIris(irisInfo); + + if (leftKeyIndex >= 0 && leftKeyIndex < 32) + { + emit sendIrisFrameToDraw(img, 0); // 左眼画面 + } else if (rightKeyIndex >= 0 && rightKeyIndex < 32) + { + emit sendIrisFrameToDraw(img, 1); // 右眼画面 + } + } + }*/ + } +} diff --git a/device/IrisCameraCapEventHandler.h b/device/IrisCameraCapEventHandler.h new file mode 100644 index 0000000..ad75a97 --- /dev/null +++ b/device/IrisCameraCapEventHandler.h @@ -0,0 +1,30 @@ +#ifndef IRISCAMERACAPEVENTHANDLER_H +#define IRISCAMERACAPEVENTHANDLER_H + +#include +#include +#include "include/opencv2/opencv.hpp" +#include "include/daheng/GalaxyIncludes.h" + +//#include "casic/iris/CasicIrisInterface.h" +#include "ProMemory.h" + +#include "utils/UtilInclude.h" + +class IrisCameraCapEventHandler : public QObject, public ICaptureEventHandler +{ + Q_OBJECT +public: + explicit IrisCameraCapEventHandler(QObject *parent = nullptr); + + void DoOnImageCaptured(CImageDataPointer &objImageDataPointer, void *pUserParam); + +private: + unsigned char* pImageBuffer; + +signals: + void sendIrisFrameToDraw(QImage irisImage); + +}; + +#endif // IRISCAMERACAPEVENTHANDLER_H diff --git a/device/IrisCameraController.cpp b/device/IrisCameraController.cpp new file mode 100644 index 0000000..0928176 --- /dev/null +++ b/device/IrisCameraController.cpp @@ -0,0 +1,110 @@ +#include "IrisCameraController.h" + +IrisCameraController::IrisCameraController(QObject *parent) : QObject(parent) +{ + this->irisCamHandler = new IrisCameraCapEventHandler(this); +} +IrisCameraController::~IrisCameraController() +{ + this->closeIrisCamera(); +} + + +void IrisCameraController::initIrisCamera() +{ + IGXFactory::GetInstance().Init(); + + //枚举设备 + IGXFactory::GetInstance().UpdateDeviceList(1000, irisCamList); + + this->OpenDevice(); +} + +void IrisCameraController::openIrisCamera() +{ + //设置Buffer处理模式 + irisStreamFeaturePtr->GetEnumFeature("StreamBufferHandlingMode")->SetValue("OldestFirst"); + + //注册回调函数 + irisStreamPtr->RegisterCaptureCallback(irisCamHandler, &irisCamPtr); + + //开启流层通道 + irisStreamPtr->StartGrab(); + + //发送开采命令 + irisFeaturePtr->GetCommandFeature("AcquisitionStart")->Execute(); + + // 启动定时器 + TimeCounterUtil::getInstance().irisCapCounter->start(SettingConfig::getInstance().IRIS_FRAME_INTERVAL); // 50ms执行一次定时器 +} + +void IrisCameraController::closeIrisCamera() +{ + +} + +void IrisCameraController::startCapture() +{ + // 获取定时器, 绑定定时函数 + connect(TimeCounterUtil::getInstance().irisCapCounter, &QTimer::timeout, this, &IrisCameraController::getOneFaceFrm); +// LOG(DEBUG) << QString("[IrisCameraController][startCapture]虹膜相机拍图").toStdString(); +// LOG_DEBUG(QString("[IrisCameraController][startCapture]虹膜相机拍图").toStdString()); + +} +void IrisCameraController::stopCapture() +{ + // 获取定时器, 绑定定时函数 + disconnect(TimeCounterUtil::getInstance().irisCapCounter, &QTimer::timeout, this, &IrisCameraController::getOneFaceFrm); +// LOG(DEBUG) << QString("[IrisCameraController][stopCapture]虹膜相机停止拍图").toStdString(); +// LOG_DEBUG(QString("[IrisCameraController][stopCapture]虹膜相机停止拍图").toStdString()); + +} + +void IrisCameraController::getOneFaceFrm() +{ + // 发送软触发命令(在触发模式开启时有效) + irisFeaturePtr->GetCommandFeature("TriggerSoftware")->Execute(); +} + +void IrisCameraController::getLeftAndRightEyeFrame() +{ + irisFeaturePtr->GetCommandFeature("TriggerSoftware")->Execute(); +} + +void IrisCameraController::OpenDevice() +{ + auto device = irisCamList.at(0); + + irisCamPtr = IGXFactory::GetInstance().OpenDeviceByUserID(device.GetUserID(), GX_ACCESS_EXCLUSIVE); + irisFeaturePtr = irisCamPtr->GetRemoteFeatureControl(); + + // 判断设备流是否大于零, 如果大于零则打开流 + int nStreamCount = irisCamPtr->GetStreamCount(); + if (nStreamCount > 0) + { + irisStreamPtr = irisCamPtr->OpenStream(0); + irisStreamFeaturePtr = irisStreamPtr->GetFeatureControl(); + } + + // 建议用户在打开网络相机之后, 根据当前网络环境设置相机的流通道包长值, + // 以提高网络相机的采集性能, 设置方法参考以下代码。 + GX_DEVICE_CLASS_LIST objDeviceClass = irisCamPtr->GetDeviceInfo().GetDeviceClass(); + if(GX_DEVICE_CLASS_GEV == objDeviceClass) + { + // 判断设备是否支持流通道数据包功能 + if(true == irisFeaturePtr->IsImplemented("GevSCPSPacketSize")) + { + // 获取当前网络环境的最优包长值 + int nPacketSize = irisStreamPtr->GetOptimalPacketSize(); + // 将最优包长值设置为当前设备的流通道包长值 + irisFeaturePtr->GetIntFeature("GevSCPSPacketSize")->SetValue(nPacketSize); + } + } + + //设置采集模式为连续采集模式 + irisFeaturePtr->GetEnumFeature("AcquisitionMode")->SetValue("Continuous"); + + //设置触发模式关 + irisFeaturePtr->GetEnumFeature("TriggerMode")->SetValue("On"); + irisFeaturePtr->GetEnumFeature("TriggerSource")->SetValue("Software"); +} diff --git a/device/IrisCameraController.h b/device/IrisCameraController.h new file mode 100644 index 0000000..5d7e269 --- /dev/null +++ b/device/IrisCameraController.h @@ -0,0 +1,49 @@ +#ifndef IRISCAMERACONTROLLER_H +#define IRISCAMERACONTROLLER_H + +#include + +#include "IrisCameraCapEventHandler.h" + +class IrisCameraCapEventHandler; + +class IrisCameraController : public QObject +{ + Q_OBJECT +public: + explicit IrisCameraController(QObject *parent = nullptr); + ~IrisCameraController(); + + // 初始化并打开人脸相机 + void initIrisCamera(); + void openIrisCamera(); + void closeIrisCamera(); + + void startCapture(); + void stopCapture(); + + void getLeftAndRightEyeFrame(); + + IrisCameraCapEventHandler * irisCamHandler; + +private: + GxIAPICPP::gxdeviceinfo_vector irisCamList; + + CGXDevicePointer irisCamPtr; ///< 设备句柄 + + CGXStreamPointer irisStreamPtr; ///< 左眼设备流 + + CGXFeatureControlPointer irisFeaturePtr; ///< 左眼属性控制器 + + CGXFeatureControlPointer irisStreamFeaturePtr; ///< 左眼流层控制器对象 + + void OpenDevice(); + +signals: + +public slots: + void getOneFaceFrm(); + +}; + +#endif // IRISCAMERACONTROLLER_H diff --git a/device/device.pri b/device/device.pri new file mode 100644 index 0000000..a8417f2 --- /dev/null +++ b/device/device.pri @@ -0,0 +1,13 @@ + +HEADERS += $$PWD/IrisCameraController.h +HEADERS += $$PWD/IrisCameraCapEventHandler.h +#HEADERS += $$PWD/iris/IrisRegistProcess.h +#HEADERS += $$PWD/iris/IrisRecogProcess.h +#HEADERS += $$PWD/iris/CasicIrisRecState.h + +SOURCES += $$PWD/IrisCameraController.cpp +SOURCES += $$PWD/IrisCameraCapEventHandler.cpp +#SOURCES += $$PWD/iris/IrisRegistProcess.cpp +#SOURCES += $$PWD/iris/IrisRecogProcess.cpp +#SOURCES += $$PWD/iris/CasicIrisRecState.cpp + diff --git a/images/bg_footer.png b/images/bg_footer.png new file mode 100644 index 0000000..a3a99ab --- /dev/null +++ b/images/bg_footer.png Binary files differ diff --git a/images/bg_statcked.png b/images/bg_statcked.png new file mode 100644 index 0000000..18b63e1 --- /dev/null +++ b/images/bg_statcked.png Binary files differ diff --git a/AppConstants.h b/AppConstants.h new file mode 100644 index 0000000..296c53f --- /dev/null +++ b/AppConstants.h @@ -0,0 +1,28 @@ +#ifndef APPCONSTANTS_H +#define APPCONSTANTS_H + +class AppConstants +{ +public: + enum WidgeFrameName + { + MAIN_PAGE = 0, // 主页面 + PERSON_LIST_FORM = 1, // 人员列表页面 + ADD_PERSON_FORM = 2, // 添加人员页面 + ADD_PERSON_CAPTURE_FACE = 21, // 添加/编辑人员时进行人脸拍图 + ADD_PERSON_CAPTURE_IRIS = 22, // 添加/编辑人员时进行虹膜拍图 + SETTING_FORM = 3, // 设置页面 + RECOGNIZE_RESULT_FORM = 4, // 识别结果界面 + IDENTIFY_FORM = 5, // 识别界面 含识别中 和 识别结果 + LOCKSCREEN_FORM = 6 // 锁屏待机界面 + }; + + enum ApplicationState + { + STATE_WAIT = 0, // 待机 + STATE_WORKING = 1, // 工作状态 + STATE_IDENTIFYING = 2, // 识别中 + }; +}; + +#endif // APPCONSTANTS_H diff --git a/CasicIrisIdentify.pro b/CasicIrisIdentify.pro index 5d7fea6..575ce3d 100644 --- a/CasicIrisIdentify.pro +++ b/CasicIrisIdentify.pro @@ -1,4 +1,4 @@ -QT += core gui +QT += core gui sql network texttospeech greaterThan(QT_MAJOR_VERSION, 4): QT += widgets @@ -15,20 +15,46 @@ # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 -SOURCES += \ - main.cpp \ - IdentifyForm.cpp +include("dao/dao.pri") +include("device/device.pri") +include("utils/utils.pri") -HEADERS += \ - IdentifyForm.h +SOURCES += main.cpp +SOURCES += ProMemory.cpp +SOURCES += MainWindowForm.cpp +SOURCES += IdentifyForm.cpp +SOURCES += LockScreenForm.cpp -FORMS += \ - IdentifyForm.ui +HEADERS += AppConstants.h +HEADERS += ProMemory.h +HEADERS += MainWindowForm.h +HEADERS += IdentifyForm.h +HEADERS += LockScreenForm.h -TRANSLATIONS += \ - CasicIrisIdentify_zh_CN.ts +FORMS += MainWindowForm.ui +FORMS += IdentifyForm.ui +FORMS += LockScreenForm.ui + +RESOURCES += resource.qrc + +DISTFILES += conf/config.ini + +#TRANSLATIONS += CasicIrisIdentify_zh_CN.ts + +#INCLUDEPATH += include/spdlog +#DEPENDPATH += include/spdlog # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target + + +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lopencv_world420 +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lGxIAPICPPEx + +INCLUDEPATH += $$PWD/include/daheng +DEPENDPATH += $$PWD/include/daheng + +INCLUDEPATH += $$PWD/include +DEPENDPATH += $$PWD/include diff --git a/CasicIrisIdentify_zh_CN.ts b/CasicIrisIdentify_zh_CN.ts index 5526fe4..81900df 100644 --- a/CasicIrisIdentify_zh_CN.ts +++ b/CasicIrisIdentify_zh_CN.ts @@ -1,3 +1,12 @@ - + + + IdentifyForm + + + IdentifyForm + + + + diff --git a/IdentifyForm.cpp b/IdentifyForm.cpp index 348a897..ba1f251 100644 --- a/IdentifyForm.cpp +++ b/IdentifyForm.cpp @@ -1,4 +1,4 @@ -#include "IdentifyForm.h" +#include "IdentifyForm.h" #include "ui_IdentifyForm.h" IdentifyForm::IdentifyForm(QWidget *parent) @@ -6,6 +6,12 @@ , ui(new Ui::IdentifyForm) { ui->setupUi(this); + + // 初始化更新界面的定时器 + // 每秒执行一次 + connect(TimeCounterUtil::getInstance().clockCounter, &QTimer::timeout, this, &IdentifyForm::updateDateAndTime); + + TimeCounterUtil::getInstance().clockCounter->start(1000); } IdentifyForm::~IdentifyForm() @@ -13,3 +19,16 @@ delete ui; } +void IdentifyForm::drawIrisImageOnFrame(QImage image) +{ + // 只在识别界面才显示画面 + if (ui->wgtStacked->currentIndex() == 0) { + ui->labelVideo->setPixmap(QPixmap::fromImage(image)); + } +} + + +void IdentifyForm::updateDateAndTime() +{ + ui->labelTime->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd dddd HH:mm:ss")); +} diff --git a/IdentifyForm.h b/IdentifyForm.h index fc857a1..ae1cd22 100644 --- a/IdentifyForm.h +++ b/IdentifyForm.h @@ -1,7 +1,10 @@ -#ifndef IDENTIFYFORM_H +#ifndef IDENTIFYFORM_H #define IDENTIFYFORM_H #include +#include + +#include "utils/UtilInclude.h" QT_BEGIN_NAMESPACE namespace Ui { class IdentifyForm; } @@ -15,7 +18,14 @@ IdentifyForm(QWidget *parent = nullptr); ~IdentifyForm(); +public slots: + void drawIrisImageOnFrame(QImage image); + private: Ui::IdentifyForm *ui; + +private slots: + void updateDateAndTime(); + }; #endif // IDENTIFYFORM_H diff --git a/IdentifyForm.ui b/IdentifyForm.ui index c72a36f..879dc9a 100644 --- a/IdentifyForm.ui +++ b/IdentifyForm.ui @@ -6,13 +6,59 @@ 0 0 - 800 + 600 600 IdentifyForm + + + + 0 + 40 + 600 + 450 + + + + 0 + + + + + + 100 + 10 + 400 + 300 + + + + + + + + + + + + + + 0 + 0 + 600 + 40 + + + + TextLabel + + + Qt::AlignCenter + + diff --git a/LockScreenForm.cpp b/LockScreenForm.cpp new file mode 100644 index 0000000..58dc54b --- /dev/null +++ b/LockScreenForm.cpp @@ -0,0 +1,14 @@ +#include "LockScreenForm.h" +#include "ui_LockScreenForm.h" + +LockScreenForm::LockScreenForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::LockScreenForm) +{ + ui->setupUi(this); +} + +LockScreenForm::~LockScreenForm() +{ + delete ui; +} diff --git a/LockScreenForm.h b/LockScreenForm.h new file mode 100644 index 0000000..b5ded48 --- /dev/null +++ b/LockScreenForm.h @@ -0,0 +1,25 @@ +#ifndef LOCKSCREENFORM_H +#define LOCKSCREENFORM_H + +#include +#include + +#include "utils/UtilInclude.h" + +namespace Ui { +class LockScreenForm; +} + +class LockScreenForm : public QWidget +{ + Q_OBJECT + +public: + explicit LockScreenForm(QWidget *parent = nullptr); + ~LockScreenForm(); + +private: + Ui::LockScreenForm *ui; +}; + +#endif // LOCKSCREENFORM_H diff --git a/LockScreenForm.ui b/LockScreenForm.ui new file mode 100644 index 0000000..7f2a6db --- /dev/null +++ b/LockScreenForm.ui @@ -0,0 +1,45 @@ + + + LockScreenForm + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + 180 + 100 + 54 + 12 + + + + TextLabel + + + + + + 180 + 160 + 54 + 12 + + + + TextLabel + + + + + + diff --git a/MainWindowForm.cpp b/MainWindowForm.cpp new file mode 100644 index 0000000..84f8159 --- /dev/null +++ b/MainWindowForm.cpp @@ -0,0 +1,86 @@ +#include "MainWindowForm.h" +#include "ui_MainWindowForm.h" +#include + +MainWindowForm::MainWindowForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::MainWindowForm) +{ + ui->setupUi(this); + + // 设置窗口透明和大小、位置 + this->setWindowFlags(Qt::FramelessWindowHint); + this->move(1400, 15); + this->resize(SettingConfig::getInstance().WINDOW_WIDTH, SettingConfig::getInstance().WINDOW_HEIGHT); + + // 通过调色板的颜色来设置窗口的统一背景色 + qApp->setPalette(QPalette(QColor(SettingConfig::getInstance().WINDOW_BACKGROUND_COLOR))); + + // 加载css文件设置控件样式 + QFile file(QApplication::applicationDirPath() + "/qss/main.css"); + if (file.open(QFile::ReadOnly)) + { + QString qssStr = QLatin1String(file.readAll()); + this->setStyleSheet(qssStr); + file.close(); + } + + initFormsPtr(); + + // 设置标题文字 + ui->labelTitle->setText(SettingConfig::getInstance().WINDOW_TITLE); + ui->labelCopyright->setText(SettingConfig::getInstance().WINDOW_RIGHTS); + ui->labelVersion->setText(SettingConfig::getInstance().WINDOW_VERSION); + + // 初始化虹膜相机控制 + ProMemory::getInstance().irisCam = new IrisCameraController(this); + ProMemory::getInstance().irisCam->initIrisCamera(); + ProMemory::getInstance().irisCam->openIrisCamera(); + connect(ProMemory::getInstance().irisCam->irisCamHandler, &IrisCameraCapEventHandler::sendIrisFrameToDraw, identifyForm, &IdentifyForm::drawIrisImageOnFrame); + +// LOG_INFO(QString("应用程序启动成功[Application Startup Success]").toStdString()); + qDebug() << "应用程序启动成功[Application Startup Success]"; + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::IDENTIFY_FORM; + ui->wdgtStatced->setCurrentWidget(identifyForm); + + // 开始虹膜相机拍图 + ProMemory::getInstance().irisCam->startCapture(); +} + +MainWindowForm::~MainWindowForm() +{ + delete ui; +} + +void MainWindowForm::lockScreen() +{ + ui->wdgtStatced->setCurrentWidget(lockScreenForm); + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::LOCKSCREEN_FORM; + ProMemory::getInstance().appState = AppConstants::ApplicationState::STATE_WAIT; +} + +void MainWindowForm::keyPressEvent(QKeyEvent *event) +{ + switch (event->key()) { + case Qt::Key_Escape: + QTimer::singleShot(100, qApp, [=](){ + QApplication::quit(); + }); + + default: + QWidget::keyPressEvent(event); + } +} + +void MainWindowForm::initFormsPtr() +{ + // 初始化各个form + lockScreenForm = new LockScreenForm(this); + identifyForm = new IdentifyForm(this); + + // 将form添加到statcked widget中 + ui->wdgtStatced->addWidget(identifyForm); + ui->wdgtStatced->addWidget(lockScreenForm); + + // 绑定按钮函数 +} diff --git a/MainWindowForm.h b/MainWindowForm.h new file mode 100644 index 0000000..7fb2d89 --- /dev/null +++ b/MainWindowForm.h @@ -0,0 +1,38 @@ +#ifndef MAINWINDOWFORM_H +#define MAINWINDOWFORM_H + +#include +#include +#include + +#include "utils/UtilInclude.h" +#include "ProMemory.h" +#include "LockScreenForm.h" +#include "IdentifyForm.h" + +namespace Ui { +class MainWindowForm; +} + +class MainWindowForm : public QWidget +{ + Q_OBJECT + +public: + explicit MainWindowForm(QWidget *parent = nullptr); + ~MainWindowForm(); + +public slots: + void lockScreen(); + +private: + Ui::MainWindowForm *ui; + LockScreenForm * lockScreenForm; + IdentifyForm * identifyForm; + + void keyPressEvent(QKeyEvent *event); + + void initFormsPtr(); +}; + +#endif // MAINWINDOWFORM_H diff --git a/MainWindowForm.ui b/MainWindowForm.ui new file mode 100644 index 0000000..e793ebf --- /dev/null +++ b/MainWindowForm.ui @@ -0,0 +1,85 @@ + + + MainWindowForm + + + + 0 + 0 + 600 + 1024 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + 0 + 0 + 600 + 84 + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + + + + TextLabel + + + Qt::AlignBottom|Qt::AlignHCenter + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + diff --git a/ProMemory.cpp b/ProMemory.cpp new file mode 100644 index 0000000..19e7403 --- /dev/null +++ b/ProMemory.cpp @@ -0,0 +1,84 @@ +#include "ProMemory.h" + +ProMemory::ProMemory() +{ + +} + +ProMemory::~ProMemory() +{ + +} + +/* +void ProMemory::pushCasicIris(CasicIrisInfo irisInfo) +{ + QMutex mutex; + mutex.lock(); + if (this->irisQueue.size() > 30) + { + QStack empty; + std::swap(empty, irisQueue); + } + + irisQueue.push(irisInfo); + mutex.unlock(); +} +CasicIrisInfo ProMemory::popCasicIris() +{ + CasicIrisInfo result; + + QMutex mutex; + mutex.lock(); + if (this->irisQueue.size() > 0) + { + result = irisQueue.pop(); + } + + mutex.unlock(); + + return result; +} +*/ +int ProMemory::getIrisQueueSize() +{ + int size = 0; + + QMutex mutex; + mutex.lock(); + +// size = this->irisQueue.size(); + + mutex.unlock(); + + return size; +} +bool ProMemory::isIrisQueueEmpty() +{ + bool empty = true; + + QMutex mutex; + mutex.lock(); + +// empty = this->irisQueue.isEmpty(); + + mutex.unlock(); + + return empty; +} +void ProMemory::clearIrisQueue() +{ + QMutex mutex; + mutex.lock(); + +// QStack empty; +// std::swap(empty, irisQueue); + + mutex.unlock(); +} + + +void ProMemory::initIrisFeatures(QString personId) +{ +// irisRegistPro->sendDataToExract(QByteArray(QString("[-u]").append(personId).toLocal8Bit())); +} diff --git a/ProMemory.h b/ProMemory.h new file mode 100644 index 0000000..2ecd653 --- /dev/null +++ b/ProMemory.h @@ -0,0 +1,52 @@ +#ifndef PROMEMORY_H +#define PROMEMORY_H + +#include +#include + +#include "AppConstants.h" +//#include "casic/iris/CasicIrisInfo.h" +#include "dao/IrisDataDao.h" + +#include "device/IrisCameraController.h" +//#include "device/iris/IrisRegistProcess.h" +//#include "device/iris/IrisRecogProcess.h" + +class IrisCameraController; +class IrisRegistProcess; +class IrisRecogProcess; + +class ProMemory +{ +public: + ~ProMemory(); + ProMemory(const ProMemory&)=delete; + ProMemory& operator=(const ProMemory&)=delete; + + static ProMemory& getInstance() { + static ProMemory instance; + return instance; + } + +// void pushCasicIris(CasicIrisInfo irisInfo); +// CasicIrisInfo popCasicIris(); + int getIrisQueueSize(); + bool isIrisQueueEmpty(); + void clearIrisQueue(); + + volatile int widgeFrame = 0; // 当前显示的界面 + volatile int appState = 0; // 当前程序所处的状态 + + void initIrisFeatures(QString personId = ""); // 初始化虹膜特征值集合 + + IrisCameraController * irisCam; + IrisRecogProcess * irisRecogPro; + +private: + ProMemory(); + +// QStack irisQueue; // 虹膜信息队列 + QVector irisFeatures; // 虹膜特征值集合 +}; + +#endif // PROMEMORY_H diff --git a/conf/config.ini b/conf/config.ini new file mode 100644 index 0000000..66e46ad --- /dev/null +++ b/conf/config.ini @@ -0,0 +1,67 @@ +[recognize] +#最大允许识别时间(ms) +maxMatchTime=10000 +#识别成功界面停留时间(ms) +successTipsLast=5000 +#识别失败界面停留时间(ms) +failureTipsLast=3000 +#人脸识别最大尝试次数 +maxFaceTryCount=20 +#持续没找到人脸的最大次数 +maxFaceNotFoundCount=500 +#注册时最小人脸 +minFaceRegist=240 +#识别时最小人脸 +minFaceRecog=100 + +#虹膜识别最大尝试次数 +maxIrisTryCount=10 +#虹膜识别持续没有找到眼的最大次数 +maxEyeNotFoundCount=50 + +#识别方式[1=人脸;2=虹膜;3=双认证;4=任意] +recogType=4 + +[window] +#界面窗口宽(px) +width=600 +#界面窗口高(px) +height=1024 +#统一背景色 +backgroundColor="#FFFFFF" +#标题 +title="虹膜识别终端" + +[work] +#工作状态检测时最小人脸范围 +minFaceSize=160 +#人脸范围最小横坐标 +minFacePosX=320 +#人脸范围最大横坐标 +maxFacePosX=960 +#人脸范围最小纵坐标 +minFacePosY=180 +#人脸范围最大纵坐标 +maxFacePosY=540 +#人脸太近阈值 +faceCloseSize=360 +#人脸太远阈值 +faceFarSize=480 + +[camera] +#虹膜相机取一幅画面的时间间隔(ms) +irisFrameInterval=100 +#虹膜相机拍摄宽度 +irisFrameWidth=1440 +#虹膜相机拍摄高度 +irisFrameHeight=1080 +#虹膜图像高度 +irisWidth=640 +#虹膜图像高度 +irisHeight=480 + +[log] +#日志文件位置 +logFile="d://irisLogs//casic_log.txt" +#日志级别 +logLevel="trace" diff --git a/dao/BaseDao.cpp b/dao/BaseDao.cpp new file mode 100644 index 0000000..f51c144 --- /dev/null +++ b/dao/BaseDao.cpp @@ -0,0 +1,12 @@ +#include "BaseDao.h" +#include "dao/util/ConnectionManager.h" + +BaseDao::BaseDao(QObject *parent) : QObject(parent) +{ + +} + +BaseDao::~BaseDao() +{ + +} diff --git a/dao/BaseDao.h b/dao/BaseDao.h new file mode 100644 index 0000000..1693c88 --- /dev/null +++ b/dao/BaseDao.h @@ -0,0 +1,32 @@ +#ifndef BASEDAO_H +#define BASEDAO_H + +#include +#include +#include +#include + +#include "dao/util/ConnectionManager.h" +#include "utils/UtilInclude.h" + +class BaseDao : public QObject +{ + Q_OBJECT +public: + explicit BaseDao(QObject *parent = nullptr); + ~BaseDao(); + + virtual QVector findAllRecord() = 0; + virtual QVariantMap findRecordById(QString id) = 0; + + virtual QString save(QVariantMap object) = 0; + virtual bool edit(QVariantMap newObject, QString id) = 0; + virtual bool dele(QString id) = 0; + +private: + +signals: + +}; + +#endif // BASEDAO_H diff --git a/dao/IrisDataDao.cpp b/dao/IrisDataDao.cpp new file mode 100644 index 0000000..37a0ed6 --- /dev/null +++ b/dao/IrisDataDao.cpp @@ -0,0 +1,204 @@ +#include "IrisDataDao.h" + +IrisDataDao::IrisDataDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector IrisDataDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM IRIS_DATA"; + query.prepare(sql); + + // 执行查询 + query.exec(); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + item.insert("id", query.value("id").toString()); + item.insert("person_id", query.value("person_id").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("left_iris_code1", query.value("left_iris_code1")); + item.insert("left_iris_code2", query.value("left_iris_code2")); + item.insert("left_iris_code3", query.value("left_iris_code3")); + item.insert("right_iris_code1", query.value("right_iris_code1")); + item.insert("right_iris_code2", query.value("right_iris_code2")); + item.insert("right_iris_code3", query.value("right_iris_code3")); + + result.append(item); + } + +// LOG_DEBUG(QString("查询IRIS_DATA表的所有记录[结果数:%1]").arg(result.size()).toStdString()); + return result; +} + +QVariantMap IrisDataDao::findRecordById(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM IRIS_DATA WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + // 获取结果 + if (query.next()) + { + result.insert("id", query.value("id").toString()); + result.insert("person_id", query.value("person_id").toLongLong()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("left_iris_code1", query.value("left_iris_code1")); + result.insert("left_iris_code2", query.value("left_iris_code2")); + result.insert("left_iris_code3", query.value("left_iris_code3")); + result.insert("right_iris_code1", query.value("right_iris_code1")); + result.insert("right_iris_code2", query.value("right_iris_code2")); + result.insert("right_iris_code3", query.value("right_iris_code3")); + } + +// LOG_DEBUG(QString("根据id查询IRIS_DATA表的记录[id=%1]").arg(id).toStdString()); + return result; +} + +QVariantMap IrisDataDao::findRecordByPersonId(QString personId) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM IRIS_DATA WHERE PERSON_ID = :personId"); + query.prepare(sql); + query.bindValue(":personId", personId); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + if (query.next()) + { + result.insert("id", query.value("id").toString()); + result.insert("person_id", query.value("person_id").toLongLong()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("left_iris_code1", query.value("left_iris_code1")); + result.insert("left_iris_code2", query.value("left_iris_code2")); + result.insert("left_iris_code3", query.value("left_iris_code3")); + result.insert("right_iris_code1", query.value("right_iris_code1")); + result.insert("right_iris_code2", query.value("right_iris_code2")); + result.insert("right_iris_code3", query.value("right_iris_code3")); + } + +// LOG_DEBUG(QString("根据personId查询IRIS_DATA表的记录[personId=%1]").arg(personId).toStdString()); + return result; +} + + +QString IrisDataDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + + // INSERT语句 + QString sql = QString("INSERT INTO IRIS_DATA (ID, PERSON_ID, ID_CARD_NO, LEFT_IRIS_CODE1, RIGHT_IRIS_CODE1) VALUES (:id, :personId, :idCardNo, :left1, :right1)"); + + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":personId", object.value("person_id").toString()); + query.bindValue(":idCardNo", object.value("id_card_no").toString()); + query.bindValue(":left1", object.value("left_iris_code1")); + query.bindValue(":right1", object.value("right_iris_code1")); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(); + +// LOG_DEBUG(QString("保存虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool IrisDataDao::edit(QVariantMap newObject, QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // UPDATE语句 + if (!newObject.contains("left_iris_code1") || !newObject.contains("right_iris_code1")){ + return false; + } + QString sql = QString("UPDATE IRIS_DATA SET LEFT_IRIS_CODE1 = :left1, RIGHT_IRIS_CODE1 = :right1 WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":left1", newObject.value("left_iris_code1")); + query.bindValue(":right1", newObject.value("right_iris_code1")); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(); + +// LOG_DEBUG(QString("编辑虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; +} + + +bool IrisDataDao::dele(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + QString sql = QString("DELETE FROM IRIS_DATA WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(); + +// LOG_DEBUG(QString("删除虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; +} diff --git a/dao/IrisDataDao.h b/dao/IrisDataDao.h new file mode 100644 index 0000000..c74dbbd --- /dev/null +++ b/dao/IrisDataDao.h @@ -0,0 +1,25 @@ +#ifndef IRISDATADAO_H +#define IRISDATADAO_H + +#include +#include "BaseDao.h" + +class IrisDataDao : public BaseDao +{ + Q_OBJECT +public: + explicit IrisDataDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + QVariantMap findRecordByPersonId(QString personId); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +signals: + +}; + +#endif // IRISDATADAO_H diff --git a/dao/RecognitionRecordsDao.cpp b/dao/RecognitionRecordsDao.cpp new file mode 100644 index 0000000..40db453 --- /dev/null +++ b/dao/RecognitionRecordsDao.cpp @@ -0,0 +1,100 @@ +#include "RecognitionRecordsDao.h" + +RecognitionRecordsDao::RecognitionRecordsDao(QObject *parent) : BaseDao(parent) +{ + +} + + +QVector RecognitionRecordsDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM RECOGNITION_RECORDS"; + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + item.insert("id", query.value("id").toLongLong()); + result.append(item); + } + +// LOG_DEBUG(QString("查询RECOGNITION_RECORDS表的所有记录[记录数:%1]").arg(result.size()).toStdString()); + return result; +} + +QVariantMap RecognitionRecordsDao::findRecordById(QString id) +{ + QVariantMap item; + return item; +} + +QString RecognitionRecordsDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + + // INSERT语句 + QString sql = QString("INSERT INTO RECOGNITION_RECORDS (ID, PERSON_ID, DATETIME, REC_TYPE, DEV_CODE, DOOR_CODE, INOUT_TYPE) " + "VALUES (:id, :personId, :datetime, :recType, :devCode, :doorCode, :inoutType)"); + + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":personId", object.value("person_id").toString()); + query.bindValue(":datetime", object.value("date_time").toString()); + query.bindValue(":recType", object.value("rec_type").toString()); + query.bindValue(":devCode", object.value("dev_code").toString()); + query.bindValue(":doorCode", object.value("door_code").toString()); + query.bindValue(":inoutType", object.value("inout_type").toString()); + +// LOG_DEBUG(sql.toStdString()); + + // 插入识别的log日志 + QString logStr = QString("INSERT INTO RECOGNITION_LOGS (ID, LOG_INFO) VALUES (:id, :logInfo)"); + + QSqlQuery logQuery(ConnectionManager::getInstance()->getConnection()); + logQuery.prepare(logStr); + logQuery.bindValue(":id", id); + logQuery.bindValue(":logInfo", object.value("debug_info").toString()); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(); + logQuery.exec(); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool RecognitionRecordsDao::edit(QVariantMap newObject, QString id) +{ + return false; +} + +bool RecognitionRecordsDao::dele(QString id) +{ + return false; +} diff --git a/dao/RecognitionRecordsDao.h b/dao/RecognitionRecordsDao.h new file mode 100644 index 0000000..38de7c9 --- /dev/null +++ b/dao/RecognitionRecordsDao.h @@ -0,0 +1,23 @@ +#ifndef RECOGNITIONRECORDSDAO_H +#define RECOGNITIONRECORDSDAO_H + +#include +#include "BaseDao.h" +class RecognitionRecordsDao: public BaseDao +{ + Q_OBJECT +public: + explicit RecognitionRecordsDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +signals: + +}; + +#endif // RECOGNITIONRECORDSDAO_H diff --git a/dao/SysDeptDao.cpp b/dao/SysDeptDao.cpp new file mode 100644 index 0000000..22f9946 --- /dev/null +++ b/dao/SysDeptDao.cpp @@ -0,0 +1,88 @@ +#include "SysDeptDao.h" + +SysDeptDao::SysDeptDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector SysDeptDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_DEPT WHERE PID != '-1' ORDER BY PID, NUM"; + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + item.insert("id", query.value("id").toString()); + item.insert("pid", query.value("pid").toString()); + item.insert("pids", query.value("pids").toString()); + item.insert("simplename", query.value("simplename").toString()); + item.insert("fullname", query.value("fullname").toString()); + } + +// LOG_TRACE(QString("查询表[SYS_DEPT]的所有记录[%1][%2]").arg(result.size()).arg(sql).toStdString()); + + return result; +} + +QVariantMap SysDeptDao::findRecordById(QString id) +{ + QVariantMap item; + return item; + + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM SYS_DEPT WHERE SYS_DEPT.ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + // 获取结果集的大小 + query.last(); + int count = query.at() + 1; + + if (count >=1) + { + query.first(); + + result.insert("id", query.value("id").toString()); + result.insert("pid", query.value("pid").toString()); + result.insert("pids", query.value("pids").toString()); + result.insert("simplename", query.value("simplename").toString()); + result.insert("fullname", query.value("fullname").toString()); + } + +// LOG_TRACE(QString("根据id查询SYS_DEPT表的记录[ID=%1][%2]").arg(id).arg(sql).toStdString()); + + return result; +} + + +QString SysDeptDao::save(QVariantMap object) +{ + return "0"; +} +bool SysDeptDao::edit(QVariantMap newObject, QString id) +{ + return true; +} +bool SysDeptDao::dele(QString id) +{ + return true; +} diff --git a/dao/SysDeptDao.h b/dao/SysDeptDao.h new file mode 100644 index 0000000..e07a09f --- /dev/null +++ b/dao/SysDeptDao.h @@ -0,0 +1,24 @@ +#ifndef SYSDEPTDAO_H +#define SYSDEPTDAO_H + +#include +#include "BaseDao.h" + +class SysDeptDao : public BaseDao +{ + Q_OBJECT +public: + explicit SysDeptDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +private: + +}; + +#endif // SYSDEPTDAO_H diff --git a/dao/SysPersonDao.cpp b/dao/SysPersonDao.cpp new file mode 100644 index 0000000..dd9480f --- /dev/null +++ b/dao/SysPersonDao.cpp @@ -0,0 +1,371 @@ +#include "SysPersonDao.h" + + +SysPersonDao::SysPersonDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector SysPersonDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0'"; + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + count++; + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + result.append(item); + } + +// LOG(TRACE) << QString("查询SYS_PERSON表的所有记录[%1]").arg(count).toStdString(); +// LOG_TRACE(QString("查询SYS_PERSON表的所有记录[%1]").arg(count).toStdString()); + + return result; +} + +QVariantMap SysPersonDao::findRecordById(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0' AND SYS_PERSON.ID = '%1'").arg(id); + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVariantMap result; + + // 获取结果集的大小 + query.last(); + int count = query.at() + 1; + + if (count >=1) + { + query.first(); + + result.insert("id", query.value("id").toString()); + result.insert("delflag", query.value("delflag").toString()); + result.insert("createtime", query.value("createtime").toString()); + result.insert("updatetime", query.value("updatetime").toString()); + result.insert("name", query.value("name").toString()); + result.insert("gender", query.value("gender").toString()); + result.insert("deptid", query.value("deptid").toString()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("remarks", query.value("remarks").toString()); + result.insert("person_code", query.value("person_code").toString()); + result.insert("deptname", query.value("fullname").toString()); + result.insert("sync_id", query.value("sync_id").toString()); + result.insert("hasFace", query.value("face_valid").toString()); + result.insert("hasIris", query.value("iris_valid").toString()); + } + +// LOG(TRACE) << QString("根据id查询SYS_PERSON表的记录[id=%1][%2]").arg(id).arg(sql).toStdString(); +// LOG_TRACE(QString("根据id查询SYS_PERSON表的记录[id=%1][%2]").arg(id).arg(sql).toStdString()); + + return result; +} + +int SysPersonDao::findRecordCountByNameAndDept(QString name, QString dept) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT COUNT(P.ID) AS RECCT FROM SYS_PERSON P LEFT JOIN SYS_DEPT D ON P.DEPTID = D.ID WHERE P.DELFLAG = '0'"; + if (name.isEmpty() == false) + { + sql += " AND P.NAME LIKE '%" + name + "%'"; + } + if (dept.isEmpty() == false && dept.indexOf("-1") < 0) + { + sql += QString(" AND ((P.DEPTID = '%1') OR (D.PIDS LIKE '%,%1,%'))").arg(dept); + } + + // 执行查询 + query.exec(sql); + + // 返回结果 + int result; + + // 遍历查询结果 + if (query.next()) { + result = query.value("RECCT").toInt(); + } + +// LOG(TRACE) << QString("根据姓名和部门查询SYS_PERSON记录总数[%1][%2]").arg(result).arg(sql).toStdString(); +// LOG_TRACE(QString("根据姓名和部门查询SYS_PERSON记录总数[%1][%2]").arg(result).arg(sql).toStdString()); + + return result; +} + +QVector SysPersonDao::findRecordsByNameAndDept(QString name, QString dept, qint8 limit, qint16 offset) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON P LEFT JOIN SYS_DEPT D ON P.DEPTID = D.ID WHERE P.DELFLAG = '0'"; + if (name.isEmpty() == false) + { + sql += " AND P.NAME LIKE '%" + name + "%'"; + } + if (dept.isEmpty() == false && dept.indexOf("-1") < 0) + { + sql += QString(" AND ((P.DEPTID = '%1') OR (D.PIDS LIKE '%,%1,%'))").arg(dept); + } + + sql += QString(" LIMIT %1 OFFSET %2").arg(limit).arg(offset); + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + count++; + + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + + result.append(item); + } + +// LOG(TRACE) << QString("根据姓名和部门分页查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString(); +// LOG_TRACE(QString("根据姓名和部门分页查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString()); + + return result; +} + +QVector SysPersonDao::findRecordsByProperties(QVariantMap conditions) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0'"; + QVariantMap::iterator it; + for (it = conditions.begin(); it != conditions.end(); it++) + { + sql += QString(" AND SYS_PERSON.%1 = %2").arg(it.key()).arg(it.value().toString()); + } + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + count++; + + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + + result.append(item); + } + +// LOG(TRACE) << QString("根据属性值查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString(); +// LOG_TRACE(QString("根据属性值查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString()); + + return result; +} + +QString SysPersonDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + + // INSERT语句 + QString sql = QString("INSERT INTO SYS_PERSON " + "(ID, DELFLAG, CREATETIME, UPDATETIME, " + "NAME, GENDER, DEPTID, ID_CARD_NO, " + "REMARKS, PERSON_CODE, SYNC_ID, FACE_VALID, IRIS_VALID) " + "VALUES ('%1', '0', '%2', '%2', '%3', '%4', '%5', '%6', '%7', '%8', '%9', 0, 0)") + .arg(id).arg(tm) + .arg(object.value("name").toString()) + .arg(object.value("gender").toString()) + .arg(object.value("deptid").toString()) + .arg(object.value("id_card_no").toString()) + .arg(object.value("remarks").toString()) + .arg(object.value("person_code").toString()) + .arg(object.value("sync_id").toString()); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(sql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { +// LOG(DEBUG) << QString("保存SYS_PERSON记录成功[ID = %1][%2]").arg(id).arg(sql).toStdString(); +// LOG_DEBUG(QString("保存SYS_PERSON记录成功[ID = %1][%2]").arg(id).arg(sql).toStdString()); + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool SysPersonDao::edit(QVariantMap newObject, QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + + // UPDATE语句 + QString sql = QString("UPDATE SYS_PERSON SET UPDATETIME = '%1'").arg(tm); + if (newObject.contains("name")) + { + sql.append(QString(", NAME = '%1'").arg(newObject.value("name").toString())); + } + if (newObject.contains("gender")) + { + sql.append(QString(", GENDER = '%1'").arg(newObject.value("gender").toString())); + } + if (newObject.contains("deptid")) + { + sql.append(QString(", DEPTID = '%1'").arg(newObject.value("deptid").toString())); + } + if (newObject.contains("person_code")) + { + sql.append(QString(", PERSON_CODE = '%1'").arg(newObject.value("person_code").toString())); + } + if (newObject.contains("face_valid")) + { + sql.append(QString(", FACE_VALID = '%1'").arg(newObject.value("face_valid").toString())); + } + if (newObject.contains("iris_valid")) + { + sql.append(QString(", IRIS_VALID = '%1'").arg(newObject.value("iris_valid").toString())); + } + + sql.append(QString(" WHERE ID = '%1'").arg(id)); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(sql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + +// LOG(DEBUG) << QString("编辑人员[ID=%1][%2]").arg(id).arg(sql).toStdString(); +// LOG_DEBUG(QString("编辑人员[ID=%1][%2]").arg(id).arg(sql).toStdString()); + + // 返回结果 + return success; +} + +bool SysPersonDao::dele(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + QSqlQuery irisDel(ConnectionManager::getInstance()->getConnection()); + + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + qint64 tmms = QDateTime::currentDateTime().toMSecsSinceEpoch(); + + // UPDATE语句 + QString sql = QString("UPDATE SYS_PERSON SET UPDATETIME = :updateTime, DELFLAG = :flag WHERE ID = :id").arg(tm).arg(tmms).arg(id); + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":updateTime", tm); + query.bindValue(":flag", tmms); + + // 物理删除人员的人脸和虹膜数据 + QString delIrisSql = QString("DELETE FROM IRIS_DATA WHERE PERSON_ID = :personId"); + irisDel.prepare(delIrisSql); + irisDel.bindValue(":personId", id); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(sql); + query.exec(delIrisSql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + +// LOG_DEBUG(QString("删除人员SYS_PERSON[ID=%1][%2]").arg(id).arg(success).toStdString()); + + // 返回结果 + return success; +} diff --git a/dao/SysPersonDao.h b/dao/SysPersonDao.h new file mode 100644 index 0000000..e02e5ba --- /dev/null +++ b/dao/SysPersonDao.h @@ -0,0 +1,27 @@ +#ifndef SYSPERSONDAO_H +#define SYSPERSONDAO_H + +#include +#include "BaseDao.h" + +class SysPersonDao : public BaseDao +{ + Q_OBJECT +public: + explicit SysPersonDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + int findRecordCountByNameAndDept(QString name, QString dept); + QVector findRecordsByNameAndDept(QString name, QString dept, qint8 limit, qint16 offset); + QVector findRecordsByProperties(QVariantMap conditions); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); +signals: + +}; + +#endif // SYSPERSONDAO_H diff --git a/dao/dao.pri b/dao/dao.pri new file mode 100644 index 0000000..1e04ce4 --- /dev/null +++ b/dao/dao.pri @@ -0,0 +1,18 @@ + +HEADERS += $$PWD/BaseDao.h +HEADERS += $$PWD/IrisDataDao.h +HEADERS += $$PWD/RecognitionRecordsDao.h +HEADERS += $$PWD/SysPersonDao.h +HEADERS += $$PWD/SysDeptDao.h + +SOURCES += $$PWD/BaseDao.cpp +SOURCES += $$PWD/IrisDataDao.cpp +SOURCES += $$PWD/RecognitionRecordsDao.cpp +SOURCES += $$PWD/SysPersonDao.cpp +SOURCES += $$PWD/SysDeptDao.cpp + +HEADERS += $$PWD/util/ConnectionManager.h +SOURCES += $$PWD/util/ConnectionManager.cpp +#HEADERS += $$PWD/util/CacheManager.h +#SOURCES += $$PWD/util/CacheManager.cpp + diff --git a/dao/util/ConnectionManager.cpp b/dao/util/ConnectionManager.cpp new file mode 100644 index 0000000..84b17be --- /dev/null +++ b/dao/util/ConnectionManager.cpp @@ -0,0 +1,47 @@ +#include "ConnectionManager.h" +#include + +Q_GLOBAL_STATIC(ConnectionManager, cm) + +ConnectionManager::ConnectionManager(QObject *parent) : QObject(parent) +{ + // 初始化数据库连接 + if (QSqlDatabase::contains("qt_sql_dafault_connection")) + { + conn = QSqlDatabase::database("qt_sql_default_connection"); + } + else + { + conn = QSqlDatabase::addDatabase("QSQLITE"); + conn.setDatabaseName(QApplication::applicationDirPath() + "/data/casic.db"); + + bool succ = conn.open(); + if (succ == true) + { +// LOG_INFO(QString("打开数据库操作正常[Open Database Success]").toStdString()); + } else + { +// LOG_ERROR(QString("打开数据库操作失败[Open Database Failed]").toStdString()); + } + } +} + +ConnectionManager::~ConnectionManager() +{ + conn.close(); +} + +ConnectionManager* ConnectionManager::getInstance() +{ + return cm; +} + +QSqlDatabase ConnectionManager::getConnection() +{ + return this->conn; +} + +qint64 ConnectionManager::generateId() +{ + return this->idWorker.nextId(); +} diff --git a/dao/util/ConnectionManager.h b/dao/util/ConnectionManager.h new file mode 100644 index 0000000..84647e3 --- /dev/null +++ b/dao/util/ConnectionManager.h @@ -0,0 +1,34 @@ +#ifndef CONNECTIONMANAGER_H +#define CONNECTIONMANAGER_H + +#include +#include +#include "utils/id/IdWorker.h" +#include "utils/UtilInclude.h" + +using namespace Jiawa::Core; + +class ConnectionManager : public QObject +{ + Q_OBJECT +public: + explicit ConnectionManager(QObject *parent = nullptr); + ~ConnectionManager(); + + static ConnectionManager * getInstance(); + + QSqlDatabase getConnection(); + qint64 generateId(); + +private: + // 数据库连接 + QSqlDatabase conn; + + // 雪花id生成工具 + IdWorker &idWorker = Singleton::instance(); + +signals: + +}; + +#endif // CONNECTIONMANAGER_H diff --git a/device/IrisCameraCapEventHandler.cpp b/device/IrisCameraCapEventHandler.cpp new file mode 100644 index 0000000..45df089 --- /dev/null +++ b/device/IrisCameraCapEventHandler.cpp @@ -0,0 +1,103 @@ +#include "IrisCameraCapEventHandler.h" + +IrisCameraCapEventHandler::IrisCameraCapEventHandler(QObject *parent) : QObject(parent) +{ + +} + +void IrisCameraCapEventHandler::DoOnImageCaptured(CImageDataPointer &objImageDataPointer, void *pUserParam) +{ + if (objImageDataPointer.IsNull() == false) + { + CGXDevicePointer* cam = (CGXDevicePointer *) pUserParam; + + auto camName = cam->getPtr()->GetDeviceInfo().GetUserID(); + int width = objImageDataPointer->GetWidth(); + int height = objImageDataPointer->GetHeight(); + size_t leftKeyIndex = camName.find("left"); + size_t rightKeyIndex = camName.find("right"); + + uchar * pBuffer = (BYTE*)objImageDataPointer->GetBuffer(); + + // 相机拍摄下的图像1440*1080, 直接用于算法判断 + QImage img = QImage(pBuffer, width, height, QImage::Format_Grayscale8); // 用于展示 +// QImage imgAlgo = img.copy(0, 0, width, height); + + // 用于显示的图像需要缩小到400 * 300的尺寸 + img = img.scaled(SettingConfig::getInstance().IRIS_DISPLAY_HEIGHT, SettingConfig::getInstance().IRIS_DISPLAY_WIDTH); + img = img.transformed(QTransform().rotate(-90)); // 图像逆时针旋转90度 + + // 发送到界面进行显示 + emit sendIrisFrameToDraw(img); +// cv::Mat irisMat = ImageUtil::QImageToMat(imgAlgo); + +// irisInfo.data = imgAlgo; +// irisInfo.matData = irisMat; + +// // 将图像显示在注册页面的label上 +// // 并将虹膜信息对象存入队列中 +// ProMemory::getInstance().pushCasicIris(irisInfo); + +// if (leftKeyIndex >= 0 && leftKeyIndex < 32) +// { +// emit sendIrisFrameToDraw(img, 0); // 左眼画面 +// } else if (rightKeyIndex >= 0 && rightKeyIndex < 32) +// { +// emit sendIrisFrameToDraw(img, 1); // 右眼画面 +// } +/* + if (pBuffer != NULL) + { + // 创建虹膜信息对象 + CasicIrisInfo irisInfo; + irisInfo.hasEye = false; + if (leftKeyIndex >= 0 && leftKeyIndex < 32) + { + // 左眼相机拍摄的图像 + irisInfo.leftOrRight = "left"; + } else if (rightKeyIndex >= 0 && rightKeyIndex < 32) + { + // 右眼相机 + irisInfo.leftOrRight = "right"; + } + + if (ProMemory::getInstance().widgeFrame == CasicBioRecConst::RECOGNIZE_RESULT_FORM) + { + // 相机拍摄下的图像1280*960, 直接用于算法判断 + QImage imgDisp = QImage(pBuffer, width, height, QImage::Format_Grayscale8); + cv::Mat irisMat = ImageUtil::QImageToMat(imgDisp); + + irisInfo.data = imgDisp; + irisInfo.matData = irisMat; + + ProMemory::getInstance().pushCasicIris(irisInfo); + +// cv::imwrite(QString("D:\\irisLogs\\iristest-%1.bmp").arg(irisInfo.leftOrRight).toStdString(), irisMat); + } else if (ProMemory::getInstance().widgeFrame == CasicBioRecConst::ADD_PERSON_CAPTURE_IRIS) + { + // 相机拍摄下的图像1280*960, 直接用于算法判断 + QImage img = QImage(pBuffer, width, height, QImage::Format_Grayscale8); + QImage imgAlgo = img.copy(0, 0, width, height); + + // 用于显示的图像需要缩小到1/4的尺寸 + img = img.scaled(640, 480); + cv::Mat irisMat = ImageUtil::QImageToMat(imgAlgo); + + irisInfo.data = imgAlgo; + irisInfo.matData = irisMat; + + // 将图像显示在注册页面的label上 + // 并将虹膜信息对象存入队列中 + ProMemory::getInstance().pushCasicIris(irisInfo); + + if (leftKeyIndex >= 0 && leftKeyIndex < 32) + { + emit sendIrisFrameToDraw(img, 0); // 左眼画面 + } else if (rightKeyIndex >= 0 && rightKeyIndex < 32) + { + emit sendIrisFrameToDraw(img, 1); // 右眼画面 + } + } + }*/ + } +} diff --git a/device/IrisCameraCapEventHandler.h b/device/IrisCameraCapEventHandler.h new file mode 100644 index 0000000..ad75a97 --- /dev/null +++ b/device/IrisCameraCapEventHandler.h @@ -0,0 +1,30 @@ +#ifndef IRISCAMERACAPEVENTHANDLER_H +#define IRISCAMERACAPEVENTHANDLER_H + +#include +#include +#include "include/opencv2/opencv.hpp" +#include "include/daheng/GalaxyIncludes.h" + +//#include "casic/iris/CasicIrisInterface.h" +#include "ProMemory.h" + +#include "utils/UtilInclude.h" + +class IrisCameraCapEventHandler : public QObject, public ICaptureEventHandler +{ + Q_OBJECT +public: + explicit IrisCameraCapEventHandler(QObject *parent = nullptr); + + void DoOnImageCaptured(CImageDataPointer &objImageDataPointer, void *pUserParam); + +private: + unsigned char* pImageBuffer; + +signals: + void sendIrisFrameToDraw(QImage irisImage); + +}; + +#endif // IRISCAMERACAPEVENTHANDLER_H diff --git a/device/IrisCameraController.cpp b/device/IrisCameraController.cpp new file mode 100644 index 0000000..0928176 --- /dev/null +++ b/device/IrisCameraController.cpp @@ -0,0 +1,110 @@ +#include "IrisCameraController.h" + +IrisCameraController::IrisCameraController(QObject *parent) : QObject(parent) +{ + this->irisCamHandler = new IrisCameraCapEventHandler(this); +} +IrisCameraController::~IrisCameraController() +{ + this->closeIrisCamera(); +} + + +void IrisCameraController::initIrisCamera() +{ + IGXFactory::GetInstance().Init(); + + //枚举设备 + IGXFactory::GetInstance().UpdateDeviceList(1000, irisCamList); + + this->OpenDevice(); +} + +void IrisCameraController::openIrisCamera() +{ + //设置Buffer处理模式 + irisStreamFeaturePtr->GetEnumFeature("StreamBufferHandlingMode")->SetValue("OldestFirst"); + + //注册回调函数 + irisStreamPtr->RegisterCaptureCallback(irisCamHandler, &irisCamPtr); + + //开启流层通道 + irisStreamPtr->StartGrab(); + + //发送开采命令 + irisFeaturePtr->GetCommandFeature("AcquisitionStart")->Execute(); + + // 启动定时器 + TimeCounterUtil::getInstance().irisCapCounter->start(SettingConfig::getInstance().IRIS_FRAME_INTERVAL); // 50ms执行一次定时器 +} + +void IrisCameraController::closeIrisCamera() +{ + +} + +void IrisCameraController::startCapture() +{ + // 获取定时器, 绑定定时函数 + connect(TimeCounterUtil::getInstance().irisCapCounter, &QTimer::timeout, this, &IrisCameraController::getOneFaceFrm); +// LOG(DEBUG) << QString("[IrisCameraController][startCapture]虹膜相机拍图").toStdString(); +// LOG_DEBUG(QString("[IrisCameraController][startCapture]虹膜相机拍图").toStdString()); + +} +void IrisCameraController::stopCapture() +{ + // 获取定时器, 绑定定时函数 + disconnect(TimeCounterUtil::getInstance().irisCapCounter, &QTimer::timeout, this, &IrisCameraController::getOneFaceFrm); +// LOG(DEBUG) << QString("[IrisCameraController][stopCapture]虹膜相机停止拍图").toStdString(); +// LOG_DEBUG(QString("[IrisCameraController][stopCapture]虹膜相机停止拍图").toStdString()); + +} + +void IrisCameraController::getOneFaceFrm() +{ + // 发送软触发命令(在触发模式开启时有效) + irisFeaturePtr->GetCommandFeature("TriggerSoftware")->Execute(); +} + +void IrisCameraController::getLeftAndRightEyeFrame() +{ + irisFeaturePtr->GetCommandFeature("TriggerSoftware")->Execute(); +} + +void IrisCameraController::OpenDevice() +{ + auto device = irisCamList.at(0); + + irisCamPtr = IGXFactory::GetInstance().OpenDeviceByUserID(device.GetUserID(), GX_ACCESS_EXCLUSIVE); + irisFeaturePtr = irisCamPtr->GetRemoteFeatureControl(); + + // 判断设备流是否大于零, 如果大于零则打开流 + int nStreamCount = irisCamPtr->GetStreamCount(); + if (nStreamCount > 0) + { + irisStreamPtr = irisCamPtr->OpenStream(0); + irisStreamFeaturePtr = irisStreamPtr->GetFeatureControl(); + } + + // 建议用户在打开网络相机之后, 根据当前网络环境设置相机的流通道包长值, + // 以提高网络相机的采集性能, 设置方法参考以下代码。 + GX_DEVICE_CLASS_LIST objDeviceClass = irisCamPtr->GetDeviceInfo().GetDeviceClass(); + if(GX_DEVICE_CLASS_GEV == objDeviceClass) + { + // 判断设备是否支持流通道数据包功能 + if(true == irisFeaturePtr->IsImplemented("GevSCPSPacketSize")) + { + // 获取当前网络环境的最优包长值 + int nPacketSize = irisStreamPtr->GetOptimalPacketSize(); + // 将最优包长值设置为当前设备的流通道包长值 + irisFeaturePtr->GetIntFeature("GevSCPSPacketSize")->SetValue(nPacketSize); + } + } + + //设置采集模式为连续采集模式 + irisFeaturePtr->GetEnumFeature("AcquisitionMode")->SetValue("Continuous"); + + //设置触发模式关 + irisFeaturePtr->GetEnumFeature("TriggerMode")->SetValue("On"); + irisFeaturePtr->GetEnumFeature("TriggerSource")->SetValue("Software"); +} diff --git a/device/IrisCameraController.h b/device/IrisCameraController.h new file mode 100644 index 0000000..5d7e269 --- /dev/null +++ b/device/IrisCameraController.h @@ -0,0 +1,49 @@ +#ifndef IRISCAMERACONTROLLER_H +#define IRISCAMERACONTROLLER_H + +#include + +#include "IrisCameraCapEventHandler.h" + +class IrisCameraCapEventHandler; + +class IrisCameraController : public QObject +{ + Q_OBJECT +public: + explicit IrisCameraController(QObject *parent = nullptr); + ~IrisCameraController(); + + // 初始化并打开人脸相机 + void initIrisCamera(); + void openIrisCamera(); + void closeIrisCamera(); + + void startCapture(); + void stopCapture(); + + void getLeftAndRightEyeFrame(); + + IrisCameraCapEventHandler * irisCamHandler; + +private: + GxIAPICPP::gxdeviceinfo_vector irisCamList; + + CGXDevicePointer irisCamPtr; ///< 设备句柄 + + CGXStreamPointer irisStreamPtr; ///< 左眼设备流 + + CGXFeatureControlPointer irisFeaturePtr; ///< 左眼属性控制器 + + CGXFeatureControlPointer irisStreamFeaturePtr; ///< 左眼流层控制器对象 + + void OpenDevice(); + +signals: + +public slots: + void getOneFaceFrm(); + +}; + +#endif // IRISCAMERACONTROLLER_H diff --git a/device/device.pri b/device/device.pri new file mode 100644 index 0000000..a8417f2 --- /dev/null +++ b/device/device.pri @@ -0,0 +1,13 @@ + +HEADERS += $$PWD/IrisCameraController.h +HEADERS += $$PWD/IrisCameraCapEventHandler.h +#HEADERS += $$PWD/iris/IrisRegistProcess.h +#HEADERS += $$PWD/iris/IrisRecogProcess.h +#HEADERS += $$PWD/iris/CasicIrisRecState.h + +SOURCES += $$PWD/IrisCameraController.cpp +SOURCES += $$PWD/IrisCameraCapEventHandler.cpp +#SOURCES += $$PWD/iris/IrisRegistProcess.cpp +#SOURCES += $$PWD/iris/IrisRecogProcess.cpp +#SOURCES += $$PWD/iris/CasicIrisRecState.cpp + diff --git a/images/bg_footer.png b/images/bg_footer.png new file mode 100644 index 0000000..a3a99ab --- /dev/null +++ b/images/bg_footer.png Binary files differ diff --git a/images/bg_statcked.png b/images/bg_statcked.png new file mode 100644 index 0000000..18b63e1 --- /dev/null +++ b/images/bg_statcked.png Binary files differ diff --git a/images/bg_title.png b/images/bg_title.png new file mode 100644 index 0000000..0316e2d --- /dev/null +++ b/images/bg_title.png Binary files differ diff --git a/AppConstants.h b/AppConstants.h new file mode 100644 index 0000000..296c53f --- /dev/null +++ b/AppConstants.h @@ -0,0 +1,28 @@ +#ifndef APPCONSTANTS_H +#define APPCONSTANTS_H + +class AppConstants +{ +public: + enum WidgeFrameName + { + MAIN_PAGE = 0, // 主页面 + PERSON_LIST_FORM = 1, // 人员列表页面 + ADD_PERSON_FORM = 2, // 添加人员页面 + ADD_PERSON_CAPTURE_FACE = 21, // 添加/编辑人员时进行人脸拍图 + ADD_PERSON_CAPTURE_IRIS = 22, // 添加/编辑人员时进行虹膜拍图 + SETTING_FORM = 3, // 设置页面 + RECOGNIZE_RESULT_FORM = 4, // 识别结果界面 + IDENTIFY_FORM = 5, // 识别界面 含识别中 和 识别结果 + LOCKSCREEN_FORM = 6 // 锁屏待机界面 + }; + + enum ApplicationState + { + STATE_WAIT = 0, // 待机 + STATE_WORKING = 1, // 工作状态 + STATE_IDENTIFYING = 2, // 识别中 + }; +}; + +#endif // APPCONSTANTS_H diff --git a/CasicIrisIdentify.pro b/CasicIrisIdentify.pro index 5d7fea6..575ce3d 100644 --- a/CasicIrisIdentify.pro +++ b/CasicIrisIdentify.pro @@ -1,4 +1,4 @@ -QT += core gui +QT += core gui sql network texttospeech greaterThan(QT_MAJOR_VERSION, 4): QT += widgets @@ -15,20 +15,46 @@ # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 -SOURCES += \ - main.cpp \ - IdentifyForm.cpp +include("dao/dao.pri") +include("device/device.pri") +include("utils/utils.pri") -HEADERS += \ - IdentifyForm.h +SOURCES += main.cpp +SOURCES += ProMemory.cpp +SOURCES += MainWindowForm.cpp +SOURCES += IdentifyForm.cpp +SOURCES += LockScreenForm.cpp -FORMS += \ - IdentifyForm.ui +HEADERS += AppConstants.h +HEADERS += ProMemory.h +HEADERS += MainWindowForm.h +HEADERS += IdentifyForm.h +HEADERS += LockScreenForm.h -TRANSLATIONS += \ - CasicIrisIdentify_zh_CN.ts +FORMS += MainWindowForm.ui +FORMS += IdentifyForm.ui +FORMS += LockScreenForm.ui + +RESOURCES += resource.qrc + +DISTFILES += conf/config.ini + +#TRANSLATIONS += CasicIrisIdentify_zh_CN.ts + +#INCLUDEPATH += include/spdlog +#DEPENDPATH += include/spdlog # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target + + +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lopencv_world420 +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lGxIAPICPPEx + +INCLUDEPATH += $$PWD/include/daheng +DEPENDPATH += $$PWD/include/daheng + +INCLUDEPATH += $$PWD/include +DEPENDPATH += $$PWD/include diff --git a/CasicIrisIdentify_zh_CN.ts b/CasicIrisIdentify_zh_CN.ts index 5526fe4..81900df 100644 --- a/CasicIrisIdentify_zh_CN.ts +++ b/CasicIrisIdentify_zh_CN.ts @@ -1,3 +1,12 @@ - + + + IdentifyForm + + + IdentifyForm + + + + diff --git a/IdentifyForm.cpp b/IdentifyForm.cpp index 348a897..ba1f251 100644 --- a/IdentifyForm.cpp +++ b/IdentifyForm.cpp @@ -1,4 +1,4 @@ -#include "IdentifyForm.h" +#include "IdentifyForm.h" #include "ui_IdentifyForm.h" IdentifyForm::IdentifyForm(QWidget *parent) @@ -6,6 +6,12 @@ , ui(new Ui::IdentifyForm) { ui->setupUi(this); + + // 初始化更新界面的定时器 + // 每秒执行一次 + connect(TimeCounterUtil::getInstance().clockCounter, &QTimer::timeout, this, &IdentifyForm::updateDateAndTime); + + TimeCounterUtil::getInstance().clockCounter->start(1000); } IdentifyForm::~IdentifyForm() @@ -13,3 +19,16 @@ delete ui; } +void IdentifyForm::drawIrisImageOnFrame(QImage image) +{ + // 只在识别界面才显示画面 + if (ui->wgtStacked->currentIndex() == 0) { + ui->labelVideo->setPixmap(QPixmap::fromImage(image)); + } +} + + +void IdentifyForm::updateDateAndTime() +{ + ui->labelTime->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd dddd HH:mm:ss")); +} diff --git a/IdentifyForm.h b/IdentifyForm.h index fc857a1..ae1cd22 100644 --- a/IdentifyForm.h +++ b/IdentifyForm.h @@ -1,7 +1,10 @@ -#ifndef IDENTIFYFORM_H +#ifndef IDENTIFYFORM_H #define IDENTIFYFORM_H #include +#include + +#include "utils/UtilInclude.h" QT_BEGIN_NAMESPACE namespace Ui { class IdentifyForm; } @@ -15,7 +18,14 @@ IdentifyForm(QWidget *parent = nullptr); ~IdentifyForm(); +public slots: + void drawIrisImageOnFrame(QImage image); + private: Ui::IdentifyForm *ui; + +private slots: + void updateDateAndTime(); + }; #endif // IDENTIFYFORM_H diff --git a/IdentifyForm.ui b/IdentifyForm.ui index c72a36f..879dc9a 100644 --- a/IdentifyForm.ui +++ b/IdentifyForm.ui @@ -6,13 +6,59 @@ 0 0 - 800 + 600 600 IdentifyForm + + + + 0 + 40 + 600 + 450 + + + + 0 + + + + + + 100 + 10 + 400 + 300 + + + + + + + + + + + + + + 0 + 0 + 600 + 40 + + + + TextLabel + + + Qt::AlignCenter + + diff --git a/LockScreenForm.cpp b/LockScreenForm.cpp new file mode 100644 index 0000000..58dc54b --- /dev/null +++ b/LockScreenForm.cpp @@ -0,0 +1,14 @@ +#include "LockScreenForm.h" +#include "ui_LockScreenForm.h" + +LockScreenForm::LockScreenForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::LockScreenForm) +{ + ui->setupUi(this); +} + +LockScreenForm::~LockScreenForm() +{ + delete ui; +} diff --git a/LockScreenForm.h b/LockScreenForm.h new file mode 100644 index 0000000..b5ded48 --- /dev/null +++ b/LockScreenForm.h @@ -0,0 +1,25 @@ +#ifndef LOCKSCREENFORM_H +#define LOCKSCREENFORM_H + +#include +#include + +#include "utils/UtilInclude.h" + +namespace Ui { +class LockScreenForm; +} + +class LockScreenForm : public QWidget +{ + Q_OBJECT + +public: + explicit LockScreenForm(QWidget *parent = nullptr); + ~LockScreenForm(); + +private: + Ui::LockScreenForm *ui; +}; + +#endif // LOCKSCREENFORM_H diff --git a/LockScreenForm.ui b/LockScreenForm.ui new file mode 100644 index 0000000..7f2a6db --- /dev/null +++ b/LockScreenForm.ui @@ -0,0 +1,45 @@ + + + LockScreenForm + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + 180 + 100 + 54 + 12 + + + + TextLabel + + + + + + 180 + 160 + 54 + 12 + + + + TextLabel + + + + + + diff --git a/MainWindowForm.cpp b/MainWindowForm.cpp new file mode 100644 index 0000000..84f8159 --- /dev/null +++ b/MainWindowForm.cpp @@ -0,0 +1,86 @@ +#include "MainWindowForm.h" +#include "ui_MainWindowForm.h" +#include + +MainWindowForm::MainWindowForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::MainWindowForm) +{ + ui->setupUi(this); + + // 设置窗口透明和大小、位置 + this->setWindowFlags(Qt::FramelessWindowHint); + this->move(1400, 15); + this->resize(SettingConfig::getInstance().WINDOW_WIDTH, SettingConfig::getInstance().WINDOW_HEIGHT); + + // 通过调色板的颜色来设置窗口的统一背景色 + qApp->setPalette(QPalette(QColor(SettingConfig::getInstance().WINDOW_BACKGROUND_COLOR))); + + // 加载css文件设置控件样式 + QFile file(QApplication::applicationDirPath() + "/qss/main.css"); + if (file.open(QFile::ReadOnly)) + { + QString qssStr = QLatin1String(file.readAll()); + this->setStyleSheet(qssStr); + file.close(); + } + + initFormsPtr(); + + // 设置标题文字 + ui->labelTitle->setText(SettingConfig::getInstance().WINDOW_TITLE); + ui->labelCopyright->setText(SettingConfig::getInstance().WINDOW_RIGHTS); + ui->labelVersion->setText(SettingConfig::getInstance().WINDOW_VERSION); + + // 初始化虹膜相机控制 + ProMemory::getInstance().irisCam = new IrisCameraController(this); + ProMemory::getInstance().irisCam->initIrisCamera(); + ProMemory::getInstance().irisCam->openIrisCamera(); + connect(ProMemory::getInstance().irisCam->irisCamHandler, &IrisCameraCapEventHandler::sendIrisFrameToDraw, identifyForm, &IdentifyForm::drawIrisImageOnFrame); + +// LOG_INFO(QString("应用程序启动成功[Application Startup Success]").toStdString()); + qDebug() << "应用程序启动成功[Application Startup Success]"; + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::IDENTIFY_FORM; + ui->wdgtStatced->setCurrentWidget(identifyForm); + + // 开始虹膜相机拍图 + ProMemory::getInstance().irisCam->startCapture(); +} + +MainWindowForm::~MainWindowForm() +{ + delete ui; +} + +void MainWindowForm::lockScreen() +{ + ui->wdgtStatced->setCurrentWidget(lockScreenForm); + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::LOCKSCREEN_FORM; + ProMemory::getInstance().appState = AppConstants::ApplicationState::STATE_WAIT; +} + +void MainWindowForm::keyPressEvent(QKeyEvent *event) +{ + switch (event->key()) { + case Qt::Key_Escape: + QTimer::singleShot(100, qApp, [=](){ + QApplication::quit(); + }); + + default: + QWidget::keyPressEvent(event); + } +} + +void MainWindowForm::initFormsPtr() +{ + // 初始化各个form + lockScreenForm = new LockScreenForm(this); + identifyForm = new IdentifyForm(this); + + // 将form添加到statcked widget中 + ui->wdgtStatced->addWidget(identifyForm); + ui->wdgtStatced->addWidget(lockScreenForm); + + // 绑定按钮函数 +} diff --git a/MainWindowForm.h b/MainWindowForm.h new file mode 100644 index 0000000..7fb2d89 --- /dev/null +++ b/MainWindowForm.h @@ -0,0 +1,38 @@ +#ifndef MAINWINDOWFORM_H +#define MAINWINDOWFORM_H + +#include +#include +#include + +#include "utils/UtilInclude.h" +#include "ProMemory.h" +#include "LockScreenForm.h" +#include "IdentifyForm.h" + +namespace Ui { +class MainWindowForm; +} + +class MainWindowForm : public QWidget +{ + Q_OBJECT + +public: + explicit MainWindowForm(QWidget *parent = nullptr); + ~MainWindowForm(); + +public slots: + void lockScreen(); + +private: + Ui::MainWindowForm *ui; + LockScreenForm * lockScreenForm; + IdentifyForm * identifyForm; + + void keyPressEvent(QKeyEvent *event); + + void initFormsPtr(); +}; + +#endif // MAINWINDOWFORM_H diff --git a/MainWindowForm.ui b/MainWindowForm.ui new file mode 100644 index 0000000..e793ebf --- /dev/null +++ b/MainWindowForm.ui @@ -0,0 +1,85 @@ + + + MainWindowForm + + + + 0 + 0 + 600 + 1024 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + 0 + 0 + 600 + 84 + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + + + + TextLabel + + + Qt::AlignBottom|Qt::AlignHCenter + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + diff --git a/ProMemory.cpp b/ProMemory.cpp new file mode 100644 index 0000000..19e7403 --- /dev/null +++ b/ProMemory.cpp @@ -0,0 +1,84 @@ +#include "ProMemory.h" + +ProMemory::ProMemory() +{ + +} + +ProMemory::~ProMemory() +{ + +} + +/* +void ProMemory::pushCasicIris(CasicIrisInfo irisInfo) +{ + QMutex mutex; + mutex.lock(); + if (this->irisQueue.size() > 30) + { + QStack empty; + std::swap(empty, irisQueue); + } + + irisQueue.push(irisInfo); + mutex.unlock(); +} +CasicIrisInfo ProMemory::popCasicIris() +{ + CasicIrisInfo result; + + QMutex mutex; + mutex.lock(); + if (this->irisQueue.size() > 0) + { + result = irisQueue.pop(); + } + + mutex.unlock(); + + return result; +} +*/ +int ProMemory::getIrisQueueSize() +{ + int size = 0; + + QMutex mutex; + mutex.lock(); + +// size = this->irisQueue.size(); + + mutex.unlock(); + + return size; +} +bool ProMemory::isIrisQueueEmpty() +{ + bool empty = true; + + QMutex mutex; + mutex.lock(); + +// empty = this->irisQueue.isEmpty(); + + mutex.unlock(); + + return empty; +} +void ProMemory::clearIrisQueue() +{ + QMutex mutex; + mutex.lock(); + +// QStack empty; +// std::swap(empty, irisQueue); + + mutex.unlock(); +} + + +void ProMemory::initIrisFeatures(QString personId) +{ +// irisRegistPro->sendDataToExract(QByteArray(QString("[-u]").append(personId).toLocal8Bit())); +} diff --git a/ProMemory.h b/ProMemory.h new file mode 100644 index 0000000..2ecd653 --- /dev/null +++ b/ProMemory.h @@ -0,0 +1,52 @@ +#ifndef PROMEMORY_H +#define PROMEMORY_H + +#include +#include + +#include "AppConstants.h" +//#include "casic/iris/CasicIrisInfo.h" +#include "dao/IrisDataDao.h" + +#include "device/IrisCameraController.h" +//#include "device/iris/IrisRegistProcess.h" +//#include "device/iris/IrisRecogProcess.h" + +class IrisCameraController; +class IrisRegistProcess; +class IrisRecogProcess; + +class ProMemory +{ +public: + ~ProMemory(); + ProMemory(const ProMemory&)=delete; + ProMemory& operator=(const ProMemory&)=delete; + + static ProMemory& getInstance() { + static ProMemory instance; + return instance; + } + +// void pushCasicIris(CasicIrisInfo irisInfo); +// CasicIrisInfo popCasicIris(); + int getIrisQueueSize(); + bool isIrisQueueEmpty(); + void clearIrisQueue(); + + volatile int widgeFrame = 0; // 当前显示的界面 + volatile int appState = 0; // 当前程序所处的状态 + + void initIrisFeatures(QString personId = ""); // 初始化虹膜特征值集合 + + IrisCameraController * irisCam; + IrisRecogProcess * irisRecogPro; + +private: + ProMemory(); + +// QStack irisQueue; // 虹膜信息队列 + QVector irisFeatures; // 虹膜特征值集合 +}; + +#endif // PROMEMORY_H diff --git a/conf/config.ini b/conf/config.ini new file mode 100644 index 0000000..66e46ad --- /dev/null +++ b/conf/config.ini @@ -0,0 +1,67 @@ +[recognize] +#最大允许识别时间(ms) +maxMatchTime=10000 +#识别成功界面停留时间(ms) +successTipsLast=5000 +#识别失败界面停留时间(ms) +failureTipsLast=3000 +#人脸识别最大尝试次数 +maxFaceTryCount=20 +#持续没找到人脸的最大次数 +maxFaceNotFoundCount=500 +#注册时最小人脸 +minFaceRegist=240 +#识别时最小人脸 +minFaceRecog=100 + +#虹膜识别最大尝试次数 +maxIrisTryCount=10 +#虹膜识别持续没有找到眼的最大次数 +maxEyeNotFoundCount=50 + +#识别方式[1=人脸;2=虹膜;3=双认证;4=任意] +recogType=4 + +[window] +#界面窗口宽(px) +width=600 +#界面窗口高(px) +height=1024 +#统一背景色 +backgroundColor="#FFFFFF" +#标题 +title="虹膜识别终端" + +[work] +#工作状态检测时最小人脸范围 +minFaceSize=160 +#人脸范围最小横坐标 +minFacePosX=320 +#人脸范围最大横坐标 +maxFacePosX=960 +#人脸范围最小纵坐标 +minFacePosY=180 +#人脸范围最大纵坐标 +maxFacePosY=540 +#人脸太近阈值 +faceCloseSize=360 +#人脸太远阈值 +faceFarSize=480 + +[camera] +#虹膜相机取一幅画面的时间间隔(ms) +irisFrameInterval=100 +#虹膜相机拍摄宽度 +irisFrameWidth=1440 +#虹膜相机拍摄高度 +irisFrameHeight=1080 +#虹膜图像高度 +irisWidth=640 +#虹膜图像高度 +irisHeight=480 + +[log] +#日志文件位置 +logFile="d://irisLogs//casic_log.txt" +#日志级别 +logLevel="trace" diff --git a/dao/BaseDao.cpp b/dao/BaseDao.cpp new file mode 100644 index 0000000..f51c144 --- /dev/null +++ b/dao/BaseDao.cpp @@ -0,0 +1,12 @@ +#include "BaseDao.h" +#include "dao/util/ConnectionManager.h" + +BaseDao::BaseDao(QObject *parent) : QObject(parent) +{ + +} + +BaseDao::~BaseDao() +{ + +} diff --git a/dao/BaseDao.h b/dao/BaseDao.h new file mode 100644 index 0000000..1693c88 --- /dev/null +++ b/dao/BaseDao.h @@ -0,0 +1,32 @@ +#ifndef BASEDAO_H +#define BASEDAO_H + +#include +#include +#include +#include + +#include "dao/util/ConnectionManager.h" +#include "utils/UtilInclude.h" + +class BaseDao : public QObject +{ + Q_OBJECT +public: + explicit BaseDao(QObject *parent = nullptr); + ~BaseDao(); + + virtual QVector findAllRecord() = 0; + virtual QVariantMap findRecordById(QString id) = 0; + + virtual QString save(QVariantMap object) = 0; + virtual bool edit(QVariantMap newObject, QString id) = 0; + virtual bool dele(QString id) = 0; + +private: + +signals: + +}; + +#endif // BASEDAO_H diff --git a/dao/IrisDataDao.cpp b/dao/IrisDataDao.cpp new file mode 100644 index 0000000..37a0ed6 --- /dev/null +++ b/dao/IrisDataDao.cpp @@ -0,0 +1,204 @@ +#include "IrisDataDao.h" + +IrisDataDao::IrisDataDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector IrisDataDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM IRIS_DATA"; + query.prepare(sql); + + // 执行查询 + query.exec(); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + item.insert("id", query.value("id").toString()); + item.insert("person_id", query.value("person_id").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("left_iris_code1", query.value("left_iris_code1")); + item.insert("left_iris_code2", query.value("left_iris_code2")); + item.insert("left_iris_code3", query.value("left_iris_code3")); + item.insert("right_iris_code1", query.value("right_iris_code1")); + item.insert("right_iris_code2", query.value("right_iris_code2")); + item.insert("right_iris_code3", query.value("right_iris_code3")); + + result.append(item); + } + +// LOG_DEBUG(QString("查询IRIS_DATA表的所有记录[结果数:%1]").arg(result.size()).toStdString()); + return result; +} + +QVariantMap IrisDataDao::findRecordById(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM IRIS_DATA WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + // 获取结果 + if (query.next()) + { + result.insert("id", query.value("id").toString()); + result.insert("person_id", query.value("person_id").toLongLong()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("left_iris_code1", query.value("left_iris_code1")); + result.insert("left_iris_code2", query.value("left_iris_code2")); + result.insert("left_iris_code3", query.value("left_iris_code3")); + result.insert("right_iris_code1", query.value("right_iris_code1")); + result.insert("right_iris_code2", query.value("right_iris_code2")); + result.insert("right_iris_code3", query.value("right_iris_code3")); + } + +// LOG_DEBUG(QString("根据id查询IRIS_DATA表的记录[id=%1]").arg(id).toStdString()); + return result; +} + +QVariantMap IrisDataDao::findRecordByPersonId(QString personId) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM IRIS_DATA WHERE PERSON_ID = :personId"); + query.prepare(sql); + query.bindValue(":personId", personId); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + if (query.next()) + { + result.insert("id", query.value("id").toString()); + result.insert("person_id", query.value("person_id").toLongLong()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("left_iris_code1", query.value("left_iris_code1")); + result.insert("left_iris_code2", query.value("left_iris_code2")); + result.insert("left_iris_code3", query.value("left_iris_code3")); + result.insert("right_iris_code1", query.value("right_iris_code1")); + result.insert("right_iris_code2", query.value("right_iris_code2")); + result.insert("right_iris_code3", query.value("right_iris_code3")); + } + +// LOG_DEBUG(QString("根据personId查询IRIS_DATA表的记录[personId=%1]").arg(personId).toStdString()); + return result; +} + + +QString IrisDataDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + + // INSERT语句 + QString sql = QString("INSERT INTO IRIS_DATA (ID, PERSON_ID, ID_CARD_NO, LEFT_IRIS_CODE1, RIGHT_IRIS_CODE1) VALUES (:id, :personId, :idCardNo, :left1, :right1)"); + + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":personId", object.value("person_id").toString()); + query.bindValue(":idCardNo", object.value("id_card_no").toString()); + query.bindValue(":left1", object.value("left_iris_code1")); + query.bindValue(":right1", object.value("right_iris_code1")); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(); + +// LOG_DEBUG(QString("保存虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool IrisDataDao::edit(QVariantMap newObject, QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // UPDATE语句 + if (!newObject.contains("left_iris_code1") || !newObject.contains("right_iris_code1")){ + return false; + } + QString sql = QString("UPDATE IRIS_DATA SET LEFT_IRIS_CODE1 = :left1, RIGHT_IRIS_CODE1 = :right1 WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":left1", newObject.value("left_iris_code1")); + query.bindValue(":right1", newObject.value("right_iris_code1")); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(); + +// LOG_DEBUG(QString("编辑虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; +} + + +bool IrisDataDao::dele(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + QString sql = QString("DELETE FROM IRIS_DATA WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(); + +// LOG_DEBUG(QString("删除虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; +} diff --git a/dao/IrisDataDao.h b/dao/IrisDataDao.h new file mode 100644 index 0000000..c74dbbd --- /dev/null +++ b/dao/IrisDataDao.h @@ -0,0 +1,25 @@ +#ifndef IRISDATADAO_H +#define IRISDATADAO_H + +#include +#include "BaseDao.h" + +class IrisDataDao : public BaseDao +{ + Q_OBJECT +public: + explicit IrisDataDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + QVariantMap findRecordByPersonId(QString personId); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +signals: + +}; + +#endif // IRISDATADAO_H diff --git a/dao/RecognitionRecordsDao.cpp b/dao/RecognitionRecordsDao.cpp new file mode 100644 index 0000000..40db453 --- /dev/null +++ b/dao/RecognitionRecordsDao.cpp @@ -0,0 +1,100 @@ +#include "RecognitionRecordsDao.h" + +RecognitionRecordsDao::RecognitionRecordsDao(QObject *parent) : BaseDao(parent) +{ + +} + + +QVector RecognitionRecordsDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM RECOGNITION_RECORDS"; + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + item.insert("id", query.value("id").toLongLong()); + result.append(item); + } + +// LOG_DEBUG(QString("查询RECOGNITION_RECORDS表的所有记录[记录数:%1]").arg(result.size()).toStdString()); + return result; +} + +QVariantMap RecognitionRecordsDao::findRecordById(QString id) +{ + QVariantMap item; + return item; +} + +QString RecognitionRecordsDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + + // INSERT语句 + QString sql = QString("INSERT INTO RECOGNITION_RECORDS (ID, PERSON_ID, DATETIME, REC_TYPE, DEV_CODE, DOOR_CODE, INOUT_TYPE) " + "VALUES (:id, :personId, :datetime, :recType, :devCode, :doorCode, :inoutType)"); + + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":personId", object.value("person_id").toString()); + query.bindValue(":datetime", object.value("date_time").toString()); + query.bindValue(":recType", object.value("rec_type").toString()); + query.bindValue(":devCode", object.value("dev_code").toString()); + query.bindValue(":doorCode", object.value("door_code").toString()); + query.bindValue(":inoutType", object.value("inout_type").toString()); + +// LOG_DEBUG(sql.toStdString()); + + // 插入识别的log日志 + QString logStr = QString("INSERT INTO RECOGNITION_LOGS (ID, LOG_INFO) VALUES (:id, :logInfo)"); + + QSqlQuery logQuery(ConnectionManager::getInstance()->getConnection()); + logQuery.prepare(logStr); + logQuery.bindValue(":id", id); + logQuery.bindValue(":logInfo", object.value("debug_info").toString()); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(); + logQuery.exec(); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool RecognitionRecordsDao::edit(QVariantMap newObject, QString id) +{ + return false; +} + +bool RecognitionRecordsDao::dele(QString id) +{ + return false; +} diff --git a/dao/RecognitionRecordsDao.h b/dao/RecognitionRecordsDao.h new file mode 100644 index 0000000..38de7c9 --- /dev/null +++ b/dao/RecognitionRecordsDao.h @@ -0,0 +1,23 @@ +#ifndef RECOGNITIONRECORDSDAO_H +#define RECOGNITIONRECORDSDAO_H + +#include +#include "BaseDao.h" +class RecognitionRecordsDao: public BaseDao +{ + Q_OBJECT +public: + explicit RecognitionRecordsDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +signals: + +}; + +#endif // RECOGNITIONRECORDSDAO_H diff --git a/dao/SysDeptDao.cpp b/dao/SysDeptDao.cpp new file mode 100644 index 0000000..22f9946 --- /dev/null +++ b/dao/SysDeptDao.cpp @@ -0,0 +1,88 @@ +#include "SysDeptDao.h" + +SysDeptDao::SysDeptDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector SysDeptDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_DEPT WHERE PID != '-1' ORDER BY PID, NUM"; + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + item.insert("id", query.value("id").toString()); + item.insert("pid", query.value("pid").toString()); + item.insert("pids", query.value("pids").toString()); + item.insert("simplename", query.value("simplename").toString()); + item.insert("fullname", query.value("fullname").toString()); + } + +// LOG_TRACE(QString("查询表[SYS_DEPT]的所有记录[%1][%2]").arg(result.size()).arg(sql).toStdString()); + + return result; +} + +QVariantMap SysDeptDao::findRecordById(QString id) +{ + QVariantMap item; + return item; + + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM SYS_DEPT WHERE SYS_DEPT.ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + // 获取结果集的大小 + query.last(); + int count = query.at() + 1; + + if (count >=1) + { + query.first(); + + result.insert("id", query.value("id").toString()); + result.insert("pid", query.value("pid").toString()); + result.insert("pids", query.value("pids").toString()); + result.insert("simplename", query.value("simplename").toString()); + result.insert("fullname", query.value("fullname").toString()); + } + +// LOG_TRACE(QString("根据id查询SYS_DEPT表的记录[ID=%1][%2]").arg(id).arg(sql).toStdString()); + + return result; +} + + +QString SysDeptDao::save(QVariantMap object) +{ + return "0"; +} +bool SysDeptDao::edit(QVariantMap newObject, QString id) +{ + return true; +} +bool SysDeptDao::dele(QString id) +{ + return true; +} diff --git a/dao/SysDeptDao.h b/dao/SysDeptDao.h new file mode 100644 index 0000000..e07a09f --- /dev/null +++ b/dao/SysDeptDao.h @@ -0,0 +1,24 @@ +#ifndef SYSDEPTDAO_H +#define SYSDEPTDAO_H + +#include +#include "BaseDao.h" + +class SysDeptDao : public BaseDao +{ + Q_OBJECT +public: + explicit SysDeptDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +private: + +}; + +#endif // SYSDEPTDAO_H diff --git a/dao/SysPersonDao.cpp b/dao/SysPersonDao.cpp new file mode 100644 index 0000000..dd9480f --- /dev/null +++ b/dao/SysPersonDao.cpp @@ -0,0 +1,371 @@ +#include "SysPersonDao.h" + + +SysPersonDao::SysPersonDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector SysPersonDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0'"; + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + count++; + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + result.append(item); + } + +// LOG(TRACE) << QString("查询SYS_PERSON表的所有记录[%1]").arg(count).toStdString(); +// LOG_TRACE(QString("查询SYS_PERSON表的所有记录[%1]").arg(count).toStdString()); + + return result; +} + +QVariantMap SysPersonDao::findRecordById(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0' AND SYS_PERSON.ID = '%1'").arg(id); + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVariantMap result; + + // 获取结果集的大小 + query.last(); + int count = query.at() + 1; + + if (count >=1) + { + query.first(); + + result.insert("id", query.value("id").toString()); + result.insert("delflag", query.value("delflag").toString()); + result.insert("createtime", query.value("createtime").toString()); + result.insert("updatetime", query.value("updatetime").toString()); + result.insert("name", query.value("name").toString()); + result.insert("gender", query.value("gender").toString()); + result.insert("deptid", query.value("deptid").toString()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("remarks", query.value("remarks").toString()); + result.insert("person_code", query.value("person_code").toString()); + result.insert("deptname", query.value("fullname").toString()); + result.insert("sync_id", query.value("sync_id").toString()); + result.insert("hasFace", query.value("face_valid").toString()); + result.insert("hasIris", query.value("iris_valid").toString()); + } + +// LOG(TRACE) << QString("根据id查询SYS_PERSON表的记录[id=%1][%2]").arg(id).arg(sql).toStdString(); +// LOG_TRACE(QString("根据id查询SYS_PERSON表的记录[id=%1][%2]").arg(id).arg(sql).toStdString()); + + return result; +} + +int SysPersonDao::findRecordCountByNameAndDept(QString name, QString dept) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT COUNT(P.ID) AS RECCT FROM SYS_PERSON P LEFT JOIN SYS_DEPT D ON P.DEPTID = D.ID WHERE P.DELFLAG = '0'"; + if (name.isEmpty() == false) + { + sql += " AND P.NAME LIKE '%" + name + "%'"; + } + if (dept.isEmpty() == false && dept.indexOf("-1") < 0) + { + sql += QString(" AND ((P.DEPTID = '%1') OR (D.PIDS LIKE '%,%1,%'))").arg(dept); + } + + // 执行查询 + query.exec(sql); + + // 返回结果 + int result; + + // 遍历查询结果 + if (query.next()) { + result = query.value("RECCT").toInt(); + } + +// LOG(TRACE) << QString("根据姓名和部门查询SYS_PERSON记录总数[%1][%2]").arg(result).arg(sql).toStdString(); +// LOG_TRACE(QString("根据姓名和部门查询SYS_PERSON记录总数[%1][%2]").arg(result).arg(sql).toStdString()); + + return result; +} + +QVector SysPersonDao::findRecordsByNameAndDept(QString name, QString dept, qint8 limit, qint16 offset) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON P LEFT JOIN SYS_DEPT D ON P.DEPTID = D.ID WHERE P.DELFLAG = '0'"; + if (name.isEmpty() == false) + { + sql += " AND P.NAME LIKE '%" + name + "%'"; + } + if (dept.isEmpty() == false && dept.indexOf("-1") < 0) + { + sql += QString(" AND ((P.DEPTID = '%1') OR (D.PIDS LIKE '%,%1,%'))").arg(dept); + } + + sql += QString(" LIMIT %1 OFFSET %2").arg(limit).arg(offset); + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + count++; + + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + + result.append(item); + } + +// LOG(TRACE) << QString("根据姓名和部门分页查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString(); +// LOG_TRACE(QString("根据姓名和部门分页查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString()); + + return result; +} + +QVector SysPersonDao::findRecordsByProperties(QVariantMap conditions) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0'"; + QVariantMap::iterator it; + for (it = conditions.begin(); it != conditions.end(); it++) + { + sql += QString(" AND SYS_PERSON.%1 = %2").arg(it.key()).arg(it.value().toString()); + } + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + count++; + + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + + result.append(item); + } + +// LOG(TRACE) << QString("根据属性值查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString(); +// LOG_TRACE(QString("根据属性值查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString()); + + return result; +} + +QString SysPersonDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + + // INSERT语句 + QString sql = QString("INSERT INTO SYS_PERSON " + "(ID, DELFLAG, CREATETIME, UPDATETIME, " + "NAME, GENDER, DEPTID, ID_CARD_NO, " + "REMARKS, PERSON_CODE, SYNC_ID, FACE_VALID, IRIS_VALID) " + "VALUES ('%1', '0', '%2', '%2', '%3', '%4', '%5', '%6', '%7', '%8', '%9', 0, 0)") + .arg(id).arg(tm) + .arg(object.value("name").toString()) + .arg(object.value("gender").toString()) + .arg(object.value("deptid").toString()) + .arg(object.value("id_card_no").toString()) + .arg(object.value("remarks").toString()) + .arg(object.value("person_code").toString()) + .arg(object.value("sync_id").toString()); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(sql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { +// LOG(DEBUG) << QString("保存SYS_PERSON记录成功[ID = %1][%2]").arg(id).arg(sql).toStdString(); +// LOG_DEBUG(QString("保存SYS_PERSON记录成功[ID = %1][%2]").arg(id).arg(sql).toStdString()); + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool SysPersonDao::edit(QVariantMap newObject, QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + + // UPDATE语句 + QString sql = QString("UPDATE SYS_PERSON SET UPDATETIME = '%1'").arg(tm); + if (newObject.contains("name")) + { + sql.append(QString(", NAME = '%1'").arg(newObject.value("name").toString())); + } + if (newObject.contains("gender")) + { + sql.append(QString(", GENDER = '%1'").arg(newObject.value("gender").toString())); + } + if (newObject.contains("deptid")) + { + sql.append(QString(", DEPTID = '%1'").arg(newObject.value("deptid").toString())); + } + if (newObject.contains("person_code")) + { + sql.append(QString(", PERSON_CODE = '%1'").arg(newObject.value("person_code").toString())); + } + if (newObject.contains("face_valid")) + { + sql.append(QString(", FACE_VALID = '%1'").arg(newObject.value("face_valid").toString())); + } + if (newObject.contains("iris_valid")) + { + sql.append(QString(", IRIS_VALID = '%1'").arg(newObject.value("iris_valid").toString())); + } + + sql.append(QString(" WHERE ID = '%1'").arg(id)); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(sql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + +// LOG(DEBUG) << QString("编辑人员[ID=%1][%2]").arg(id).arg(sql).toStdString(); +// LOG_DEBUG(QString("编辑人员[ID=%1][%2]").arg(id).arg(sql).toStdString()); + + // 返回结果 + return success; +} + +bool SysPersonDao::dele(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + QSqlQuery irisDel(ConnectionManager::getInstance()->getConnection()); + + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + qint64 tmms = QDateTime::currentDateTime().toMSecsSinceEpoch(); + + // UPDATE语句 + QString sql = QString("UPDATE SYS_PERSON SET UPDATETIME = :updateTime, DELFLAG = :flag WHERE ID = :id").arg(tm).arg(tmms).arg(id); + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":updateTime", tm); + query.bindValue(":flag", tmms); + + // 物理删除人员的人脸和虹膜数据 + QString delIrisSql = QString("DELETE FROM IRIS_DATA WHERE PERSON_ID = :personId"); + irisDel.prepare(delIrisSql); + irisDel.bindValue(":personId", id); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(sql); + query.exec(delIrisSql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + +// LOG_DEBUG(QString("删除人员SYS_PERSON[ID=%1][%2]").arg(id).arg(success).toStdString()); + + // 返回结果 + return success; +} diff --git a/dao/SysPersonDao.h b/dao/SysPersonDao.h new file mode 100644 index 0000000..e02e5ba --- /dev/null +++ b/dao/SysPersonDao.h @@ -0,0 +1,27 @@ +#ifndef SYSPERSONDAO_H +#define SYSPERSONDAO_H + +#include +#include "BaseDao.h" + +class SysPersonDao : public BaseDao +{ + Q_OBJECT +public: + explicit SysPersonDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + int findRecordCountByNameAndDept(QString name, QString dept); + QVector findRecordsByNameAndDept(QString name, QString dept, qint8 limit, qint16 offset); + QVector findRecordsByProperties(QVariantMap conditions); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); +signals: + +}; + +#endif // SYSPERSONDAO_H diff --git a/dao/dao.pri b/dao/dao.pri new file mode 100644 index 0000000..1e04ce4 --- /dev/null +++ b/dao/dao.pri @@ -0,0 +1,18 @@ + +HEADERS += $$PWD/BaseDao.h +HEADERS += $$PWD/IrisDataDao.h +HEADERS += $$PWD/RecognitionRecordsDao.h +HEADERS += $$PWD/SysPersonDao.h +HEADERS += $$PWD/SysDeptDao.h + +SOURCES += $$PWD/BaseDao.cpp +SOURCES += $$PWD/IrisDataDao.cpp +SOURCES += $$PWD/RecognitionRecordsDao.cpp +SOURCES += $$PWD/SysPersonDao.cpp +SOURCES += $$PWD/SysDeptDao.cpp + +HEADERS += $$PWD/util/ConnectionManager.h +SOURCES += $$PWD/util/ConnectionManager.cpp +#HEADERS += $$PWD/util/CacheManager.h +#SOURCES += $$PWD/util/CacheManager.cpp + diff --git a/dao/util/ConnectionManager.cpp b/dao/util/ConnectionManager.cpp new file mode 100644 index 0000000..84b17be --- /dev/null +++ b/dao/util/ConnectionManager.cpp @@ -0,0 +1,47 @@ +#include "ConnectionManager.h" +#include + +Q_GLOBAL_STATIC(ConnectionManager, cm) + +ConnectionManager::ConnectionManager(QObject *parent) : QObject(parent) +{ + // 初始化数据库连接 + if (QSqlDatabase::contains("qt_sql_dafault_connection")) + { + conn = QSqlDatabase::database("qt_sql_default_connection"); + } + else + { + conn = QSqlDatabase::addDatabase("QSQLITE"); + conn.setDatabaseName(QApplication::applicationDirPath() + "/data/casic.db"); + + bool succ = conn.open(); + if (succ == true) + { +// LOG_INFO(QString("打开数据库操作正常[Open Database Success]").toStdString()); + } else + { +// LOG_ERROR(QString("打开数据库操作失败[Open Database Failed]").toStdString()); + } + } +} + +ConnectionManager::~ConnectionManager() +{ + conn.close(); +} + +ConnectionManager* ConnectionManager::getInstance() +{ + return cm; +} + +QSqlDatabase ConnectionManager::getConnection() +{ + return this->conn; +} + +qint64 ConnectionManager::generateId() +{ + return this->idWorker.nextId(); +} diff --git a/dao/util/ConnectionManager.h b/dao/util/ConnectionManager.h new file mode 100644 index 0000000..84647e3 --- /dev/null +++ b/dao/util/ConnectionManager.h @@ -0,0 +1,34 @@ +#ifndef CONNECTIONMANAGER_H +#define CONNECTIONMANAGER_H + +#include +#include +#include "utils/id/IdWorker.h" +#include "utils/UtilInclude.h" + +using namespace Jiawa::Core; + +class ConnectionManager : public QObject +{ + Q_OBJECT +public: + explicit ConnectionManager(QObject *parent = nullptr); + ~ConnectionManager(); + + static ConnectionManager * getInstance(); + + QSqlDatabase getConnection(); + qint64 generateId(); + +private: + // 数据库连接 + QSqlDatabase conn; + + // 雪花id生成工具 + IdWorker &idWorker = Singleton::instance(); + +signals: + +}; + +#endif // CONNECTIONMANAGER_H diff --git a/device/IrisCameraCapEventHandler.cpp b/device/IrisCameraCapEventHandler.cpp new file mode 100644 index 0000000..45df089 --- /dev/null +++ b/device/IrisCameraCapEventHandler.cpp @@ -0,0 +1,103 @@ +#include "IrisCameraCapEventHandler.h" + +IrisCameraCapEventHandler::IrisCameraCapEventHandler(QObject *parent) : QObject(parent) +{ + +} + +void IrisCameraCapEventHandler::DoOnImageCaptured(CImageDataPointer &objImageDataPointer, void *pUserParam) +{ + if (objImageDataPointer.IsNull() == false) + { + CGXDevicePointer* cam = (CGXDevicePointer *) pUserParam; + + auto camName = cam->getPtr()->GetDeviceInfo().GetUserID(); + int width = objImageDataPointer->GetWidth(); + int height = objImageDataPointer->GetHeight(); + size_t leftKeyIndex = camName.find("left"); + size_t rightKeyIndex = camName.find("right"); + + uchar * pBuffer = (BYTE*)objImageDataPointer->GetBuffer(); + + // 相机拍摄下的图像1440*1080, 直接用于算法判断 + QImage img = QImage(pBuffer, width, height, QImage::Format_Grayscale8); // 用于展示 +// QImage imgAlgo = img.copy(0, 0, width, height); + + // 用于显示的图像需要缩小到400 * 300的尺寸 + img = img.scaled(SettingConfig::getInstance().IRIS_DISPLAY_HEIGHT, SettingConfig::getInstance().IRIS_DISPLAY_WIDTH); + img = img.transformed(QTransform().rotate(-90)); // 图像逆时针旋转90度 + + // 发送到界面进行显示 + emit sendIrisFrameToDraw(img); +// cv::Mat irisMat = ImageUtil::QImageToMat(imgAlgo); + +// irisInfo.data = imgAlgo; +// irisInfo.matData = irisMat; + +// // 将图像显示在注册页面的label上 +// // 并将虹膜信息对象存入队列中 +// ProMemory::getInstance().pushCasicIris(irisInfo); + +// if (leftKeyIndex >= 0 && leftKeyIndex < 32) +// { +// emit sendIrisFrameToDraw(img, 0); // 左眼画面 +// } else if (rightKeyIndex >= 0 && rightKeyIndex < 32) +// { +// emit sendIrisFrameToDraw(img, 1); // 右眼画面 +// } +/* + if (pBuffer != NULL) + { + // 创建虹膜信息对象 + CasicIrisInfo irisInfo; + irisInfo.hasEye = false; + if (leftKeyIndex >= 0 && leftKeyIndex < 32) + { + // 左眼相机拍摄的图像 + irisInfo.leftOrRight = "left"; + } else if (rightKeyIndex >= 0 && rightKeyIndex < 32) + { + // 右眼相机 + irisInfo.leftOrRight = "right"; + } + + if (ProMemory::getInstance().widgeFrame == CasicBioRecConst::RECOGNIZE_RESULT_FORM) + { + // 相机拍摄下的图像1280*960, 直接用于算法判断 + QImage imgDisp = QImage(pBuffer, width, height, QImage::Format_Grayscale8); + cv::Mat irisMat = ImageUtil::QImageToMat(imgDisp); + + irisInfo.data = imgDisp; + irisInfo.matData = irisMat; + + ProMemory::getInstance().pushCasicIris(irisInfo); + +// cv::imwrite(QString("D:\\irisLogs\\iristest-%1.bmp").arg(irisInfo.leftOrRight).toStdString(), irisMat); + } else if (ProMemory::getInstance().widgeFrame == CasicBioRecConst::ADD_PERSON_CAPTURE_IRIS) + { + // 相机拍摄下的图像1280*960, 直接用于算法判断 + QImage img = QImage(pBuffer, width, height, QImage::Format_Grayscale8); + QImage imgAlgo = img.copy(0, 0, width, height); + + // 用于显示的图像需要缩小到1/4的尺寸 + img = img.scaled(640, 480); + cv::Mat irisMat = ImageUtil::QImageToMat(imgAlgo); + + irisInfo.data = imgAlgo; + irisInfo.matData = irisMat; + + // 将图像显示在注册页面的label上 + // 并将虹膜信息对象存入队列中 + ProMemory::getInstance().pushCasicIris(irisInfo); + + if (leftKeyIndex >= 0 && leftKeyIndex < 32) + { + emit sendIrisFrameToDraw(img, 0); // 左眼画面 + } else if (rightKeyIndex >= 0 && rightKeyIndex < 32) + { + emit sendIrisFrameToDraw(img, 1); // 右眼画面 + } + } + }*/ + } +} diff --git a/device/IrisCameraCapEventHandler.h b/device/IrisCameraCapEventHandler.h new file mode 100644 index 0000000..ad75a97 --- /dev/null +++ b/device/IrisCameraCapEventHandler.h @@ -0,0 +1,30 @@ +#ifndef IRISCAMERACAPEVENTHANDLER_H +#define IRISCAMERACAPEVENTHANDLER_H + +#include +#include +#include "include/opencv2/opencv.hpp" +#include "include/daheng/GalaxyIncludes.h" + +//#include "casic/iris/CasicIrisInterface.h" +#include "ProMemory.h" + +#include "utils/UtilInclude.h" + +class IrisCameraCapEventHandler : public QObject, public ICaptureEventHandler +{ + Q_OBJECT +public: + explicit IrisCameraCapEventHandler(QObject *parent = nullptr); + + void DoOnImageCaptured(CImageDataPointer &objImageDataPointer, void *pUserParam); + +private: + unsigned char* pImageBuffer; + +signals: + void sendIrisFrameToDraw(QImage irisImage); + +}; + +#endif // IRISCAMERACAPEVENTHANDLER_H diff --git a/device/IrisCameraController.cpp b/device/IrisCameraController.cpp new file mode 100644 index 0000000..0928176 --- /dev/null +++ b/device/IrisCameraController.cpp @@ -0,0 +1,110 @@ +#include "IrisCameraController.h" + +IrisCameraController::IrisCameraController(QObject *parent) : QObject(parent) +{ + this->irisCamHandler = new IrisCameraCapEventHandler(this); +} +IrisCameraController::~IrisCameraController() +{ + this->closeIrisCamera(); +} + + +void IrisCameraController::initIrisCamera() +{ + IGXFactory::GetInstance().Init(); + + //枚举设备 + IGXFactory::GetInstance().UpdateDeviceList(1000, irisCamList); + + this->OpenDevice(); +} + +void IrisCameraController::openIrisCamera() +{ + //设置Buffer处理模式 + irisStreamFeaturePtr->GetEnumFeature("StreamBufferHandlingMode")->SetValue("OldestFirst"); + + //注册回调函数 + irisStreamPtr->RegisterCaptureCallback(irisCamHandler, &irisCamPtr); + + //开启流层通道 + irisStreamPtr->StartGrab(); + + //发送开采命令 + irisFeaturePtr->GetCommandFeature("AcquisitionStart")->Execute(); + + // 启动定时器 + TimeCounterUtil::getInstance().irisCapCounter->start(SettingConfig::getInstance().IRIS_FRAME_INTERVAL); // 50ms执行一次定时器 +} + +void IrisCameraController::closeIrisCamera() +{ + +} + +void IrisCameraController::startCapture() +{ + // 获取定时器, 绑定定时函数 + connect(TimeCounterUtil::getInstance().irisCapCounter, &QTimer::timeout, this, &IrisCameraController::getOneFaceFrm); +// LOG(DEBUG) << QString("[IrisCameraController][startCapture]虹膜相机拍图").toStdString(); +// LOG_DEBUG(QString("[IrisCameraController][startCapture]虹膜相机拍图").toStdString()); + +} +void IrisCameraController::stopCapture() +{ + // 获取定时器, 绑定定时函数 + disconnect(TimeCounterUtil::getInstance().irisCapCounter, &QTimer::timeout, this, &IrisCameraController::getOneFaceFrm); +// LOG(DEBUG) << QString("[IrisCameraController][stopCapture]虹膜相机停止拍图").toStdString(); +// LOG_DEBUG(QString("[IrisCameraController][stopCapture]虹膜相机停止拍图").toStdString()); + +} + +void IrisCameraController::getOneFaceFrm() +{ + // 发送软触发命令(在触发模式开启时有效) + irisFeaturePtr->GetCommandFeature("TriggerSoftware")->Execute(); +} + +void IrisCameraController::getLeftAndRightEyeFrame() +{ + irisFeaturePtr->GetCommandFeature("TriggerSoftware")->Execute(); +} + +void IrisCameraController::OpenDevice() +{ + auto device = irisCamList.at(0); + + irisCamPtr = IGXFactory::GetInstance().OpenDeviceByUserID(device.GetUserID(), GX_ACCESS_EXCLUSIVE); + irisFeaturePtr = irisCamPtr->GetRemoteFeatureControl(); + + // 判断设备流是否大于零, 如果大于零则打开流 + int nStreamCount = irisCamPtr->GetStreamCount(); + if (nStreamCount > 0) + { + irisStreamPtr = irisCamPtr->OpenStream(0); + irisStreamFeaturePtr = irisStreamPtr->GetFeatureControl(); + } + + // 建议用户在打开网络相机之后, 根据当前网络环境设置相机的流通道包长值, + // 以提高网络相机的采集性能, 设置方法参考以下代码。 + GX_DEVICE_CLASS_LIST objDeviceClass = irisCamPtr->GetDeviceInfo().GetDeviceClass(); + if(GX_DEVICE_CLASS_GEV == objDeviceClass) + { + // 判断设备是否支持流通道数据包功能 + if(true == irisFeaturePtr->IsImplemented("GevSCPSPacketSize")) + { + // 获取当前网络环境的最优包长值 + int nPacketSize = irisStreamPtr->GetOptimalPacketSize(); + // 将最优包长值设置为当前设备的流通道包长值 + irisFeaturePtr->GetIntFeature("GevSCPSPacketSize")->SetValue(nPacketSize); + } + } + + //设置采集模式为连续采集模式 + irisFeaturePtr->GetEnumFeature("AcquisitionMode")->SetValue("Continuous"); + + //设置触发模式关 + irisFeaturePtr->GetEnumFeature("TriggerMode")->SetValue("On"); + irisFeaturePtr->GetEnumFeature("TriggerSource")->SetValue("Software"); +} diff --git a/device/IrisCameraController.h b/device/IrisCameraController.h new file mode 100644 index 0000000..5d7e269 --- /dev/null +++ b/device/IrisCameraController.h @@ -0,0 +1,49 @@ +#ifndef IRISCAMERACONTROLLER_H +#define IRISCAMERACONTROLLER_H + +#include + +#include "IrisCameraCapEventHandler.h" + +class IrisCameraCapEventHandler; + +class IrisCameraController : public QObject +{ + Q_OBJECT +public: + explicit IrisCameraController(QObject *parent = nullptr); + ~IrisCameraController(); + + // 初始化并打开人脸相机 + void initIrisCamera(); + void openIrisCamera(); + void closeIrisCamera(); + + void startCapture(); + void stopCapture(); + + void getLeftAndRightEyeFrame(); + + IrisCameraCapEventHandler * irisCamHandler; + +private: + GxIAPICPP::gxdeviceinfo_vector irisCamList; + + CGXDevicePointer irisCamPtr; ///< 设备句柄 + + CGXStreamPointer irisStreamPtr; ///< 左眼设备流 + + CGXFeatureControlPointer irisFeaturePtr; ///< 左眼属性控制器 + + CGXFeatureControlPointer irisStreamFeaturePtr; ///< 左眼流层控制器对象 + + void OpenDevice(); + +signals: + +public slots: + void getOneFaceFrm(); + +}; + +#endif // IRISCAMERACONTROLLER_H diff --git a/device/device.pri b/device/device.pri new file mode 100644 index 0000000..a8417f2 --- /dev/null +++ b/device/device.pri @@ -0,0 +1,13 @@ + +HEADERS += $$PWD/IrisCameraController.h +HEADERS += $$PWD/IrisCameraCapEventHandler.h +#HEADERS += $$PWD/iris/IrisRegistProcess.h +#HEADERS += $$PWD/iris/IrisRecogProcess.h +#HEADERS += $$PWD/iris/CasicIrisRecState.h + +SOURCES += $$PWD/IrisCameraController.cpp +SOURCES += $$PWD/IrisCameraCapEventHandler.cpp +#SOURCES += $$PWD/iris/IrisRegistProcess.cpp +#SOURCES += $$PWD/iris/IrisRecogProcess.cpp +#SOURCES += $$PWD/iris/CasicIrisRecState.cpp + diff --git a/images/bg_footer.png b/images/bg_footer.png new file mode 100644 index 0000000..a3a99ab --- /dev/null +++ b/images/bg_footer.png Binary files differ diff --git a/images/bg_statcked.png b/images/bg_statcked.png new file mode 100644 index 0000000..18b63e1 --- /dev/null +++ b/images/bg_statcked.png Binary files differ diff --git a/images/bg_title.png b/images/bg_title.png new file mode 100644 index 0000000..0316e2d --- /dev/null +++ b/images/bg_title.png Binary files differ diff --git a/main.cpp b/main.cpp index 16bc45b..9052ddb 100644 --- a/main.cpp +++ b/main.cpp @@ -1,11 +1,11 @@ -#include "IdentifyForm.h" +#include "MainWindowForm.h" #include int main(int argc, char *argv[]) { QApplication a(argc, argv); - IdentifyForm w; + MainWindowForm w; w.show(); return a.exec(); } diff --git a/AppConstants.h b/AppConstants.h new file mode 100644 index 0000000..296c53f --- /dev/null +++ b/AppConstants.h @@ -0,0 +1,28 @@ +#ifndef APPCONSTANTS_H +#define APPCONSTANTS_H + +class AppConstants +{ +public: + enum WidgeFrameName + { + MAIN_PAGE = 0, // 主页面 + PERSON_LIST_FORM = 1, // 人员列表页面 + ADD_PERSON_FORM = 2, // 添加人员页面 + ADD_PERSON_CAPTURE_FACE = 21, // 添加/编辑人员时进行人脸拍图 + ADD_PERSON_CAPTURE_IRIS = 22, // 添加/编辑人员时进行虹膜拍图 + SETTING_FORM = 3, // 设置页面 + RECOGNIZE_RESULT_FORM = 4, // 识别结果界面 + IDENTIFY_FORM = 5, // 识别界面 含识别中 和 识别结果 + LOCKSCREEN_FORM = 6 // 锁屏待机界面 + }; + + enum ApplicationState + { + STATE_WAIT = 0, // 待机 + STATE_WORKING = 1, // 工作状态 + STATE_IDENTIFYING = 2, // 识别中 + }; +}; + +#endif // APPCONSTANTS_H diff --git a/CasicIrisIdentify.pro b/CasicIrisIdentify.pro index 5d7fea6..575ce3d 100644 --- a/CasicIrisIdentify.pro +++ b/CasicIrisIdentify.pro @@ -1,4 +1,4 @@ -QT += core gui +QT += core gui sql network texttospeech greaterThan(QT_MAJOR_VERSION, 4): QT += widgets @@ -15,20 +15,46 @@ # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 -SOURCES += \ - main.cpp \ - IdentifyForm.cpp +include("dao/dao.pri") +include("device/device.pri") +include("utils/utils.pri") -HEADERS += \ - IdentifyForm.h +SOURCES += main.cpp +SOURCES += ProMemory.cpp +SOURCES += MainWindowForm.cpp +SOURCES += IdentifyForm.cpp +SOURCES += LockScreenForm.cpp -FORMS += \ - IdentifyForm.ui +HEADERS += AppConstants.h +HEADERS += ProMemory.h +HEADERS += MainWindowForm.h +HEADERS += IdentifyForm.h +HEADERS += LockScreenForm.h -TRANSLATIONS += \ - CasicIrisIdentify_zh_CN.ts +FORMS += MainWindowForm.ui +FORMS += IdentifyForm.ui +FORMS += LockScreenForm.ui + +RESOURCES += resource.qrc + +DISTFILES += conf/config.ini + +#TRANSLATIONS += CasicIrisIdentify_zh_CN.ts + +#INCLUDEPATH += include/spdlog +#DEPENDPATH += include/spdlog # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target + + +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lopencv_world420 +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lGxIAPICPPEx + +INCLUDEPATH += $$PWD/include/daheng +DEPENDPATH += $$PWD/include/daheng + +INCLUDEPATH += $$PWD/include +DEPENDPATH += $$PWD/include diff --git a/CasicIrisIdentify_zh_CN.ts b/CasicIrisIdentify_zh_CN.ts index 5526fe4..81900df 100644 --- a/CasicIrisIdentify_zh_CN.ts +++ b/CasicIrisIdentify_zh_CN.ts @@ -1,3 +1,12 @@ - + + + IdentifyForm + + + IdentifyForm + + + + diff --git a/IdentifyForm.cpp b/IdentifyForm.cpp index 348a897..ba1f251 100644 --- a/IdentifyForm.cpp +++ b/IdentifyForm.cpp @@ -1,4 +1,4 @@ -#include "IdentifyForm.h" +#include "IdentifyForm.h" #include "ui_IdentifyForm.h" IdentifyForm::IdentifyForm(QWidget *parent) @@ -6,6 +6,12 @@ , ui(new Ui::IdentifyForm) { ui->setupUi(this); + + // 初始化更新界面的定时器 + // 每秒执行一次 + connect(TimeCounterUtil::getInstance().clockCounter, &QTimer::timeout, this, &IdentifyForm::updateDateAndTime); + + TimeCounterUtil::getInstance().clockCounter->start(1000); } IdentifyForm::~IdentifyForm() @@ -13,3 +19,16 @@ delete ui; } +void IdentifyForm::drawIrisImageOnFrame(QImage image) +{ + // 只在识别界面才显示画面 + if (ui->wgtStacked->currentIndex() == 0) { + ui->labelVideo->setPixmap(QPixmap::fromImage(image)); + } +} + + +void IdentifyForm::updateDateAndTime() +{ + ui->labelTime->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd dddd HH:mm:ss")); +} diff --git a/IdentifyForm.h b/IdentifyForm.h index fc857a1..ae1cd22 100644 --- a/IdentifyForm.h +++ b/IdentifyForm.h @@ -1,7 +1,10 @@ -#ifndef IDENTIFYFORM_H +#ifndef IDENTIFYFORM_H #define IDENTIFYFORM_H #include +#include + +#include "utils/UtilInclude.h" QT_BEGIN_NAMESPACE namespace Ui { class IdentifyForm; } @@ -15,7 +18,14 @@ IdentifyForm(QWidget *parent = nullptr); ~IdentifyForm(); +public slots: + void drawIrisImageOnFrame(QImage image); + private: Ui::IdentifyForm *ui; + +private slots: + void updateDateAndTime(); + }; #endif // IDENTIFYFORM_H diff --git a/IdentifyForm.ui b/IdentifyForm.ui index c72a36f..879dc9a 100644 --- a/IdentifyForm.ui +++ b/IdentifyForm.ui @@ -6,13 +6,59 @@ 0 0 - 800 + 600 600 IdentifyForm + + + + 0 + 40 + 600 + 450 + + + + 0 + + + + + + 100 + 10 + 400 + 300 + + + + + + + + + + + + + + 0 + 0 + 600 + 40 + + + + TextLabel + + + Qt::AlignCenter + + diff --git a/LockScreenForm.cpp b/LockScreenForm.cpp new file mode 100644 index 0000000..58dc54b --- /dev/null +++ b/LockScreenForm.cpp @@ -0,0 +1,14 @@ +#include "LockScreenForm.h" +#include "ui_LockScreenForm.h" + +LockScreenForm::LockScreenForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::LockScreenForm) +{ + ui->setupUi(this); +} + +LockScreenForm::~LockScreenForm() +{ + delete ui; +} diff --git a/LockScreenForm.h b/LockScreenForm.h new file mode 100644 index 0000000..b5ded48 --- /dev/null +++ b/LockScreenForm.h @@ -0,0 +1,25 @@ +#ifndef LOCKSCREENFORM_H +#define LOCKSCREENFORM_H + +#include +#include + +#include "utils/UtilInclude.h" + +namespace Ui { +class LockScreenForm; +} + +class LockScreenForm : public QWidget +{ + Q_OBJECT + +public: + explicit LockScreenForm(QWidget *parent = nullptr); + ~LockScreenForm(); + +private: + Ui::LockScreenForm *ui; +}; + +#endif // LOCKSCREENFORM_H diff --git a/LockScreenForm.ui b/LockScreenForm.ui new file mode 100644 index 0000000..7f2a6db --- /dev/null +++ b/LockScreenForm.ui @@ -0,0 +1,45 @@ + + + LockScreenForm + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + 180 + 100 + 54 + 12 + + + + TextLabel + + + + + + 180 + 160 + 54 + 12 + + + + TextLabel + + + + + + diff --git a/MainWindowForm.cpp b/MainWindowForm.cpp new file mode 100644 index 0000000..84f8159 --- /dev/null +++ b/MainWindowForm.cpp @@ -0,0 +1,86 @@ +#include "MainWindowForm.h" +#include "ui_MainWindowForm.h" +#include + +MainWindowForm::MainWindowForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::MainWindowForm) +{ + ui->setupUi(this); + + // 设置窗口透明和大小、位置 + this->setWindowFlags(Qt::FramelessWindowHint); + this->move(1400, 15); + this->resize(SettingConfig::getInstance().WINDOW_WIDTH, SettingConfig::getInstance().WINDOW_HEIGHT); + + // 通过调色板的颜色来设置窗口的统一背景色 + qApp->setPalette(QPalette(QColor(SettingConfig::getInstance().WINDOW_BACKGROUND_COLOR))); + + // 加载css文件设置控件样式 + QFile file(QApplication::applicationDirPath() + "/qss/main.css"); + if (file.open(QFile::ReadOnly)) + { + QString qssStr = QLatin1String(file.readAll()); + this->setStyleSheet(qssStr); + file.close(); + } + + initFormsPtr(); + + // 设置标题文字 + ui->labelTitle->setText(SettingConfig::getInstance().WINDOW_TITLE); + ui->labelCopyright->setText(SettingConfig::getInstance().WINDOW_RIGHTS); + ui->labelVersion->setText(SettingConfig::getInstance().WINDOW_VERSION); + + // 初始化虹膜相机控制 + ProMemory::getInstance().irisCam = new IrisCameraController(this); + ProMemory::getInstance().irisCam->initIrisCamera(); + ProMemory::getInstance().irisCam->openIrisCamera(); + connect(ProMemory::getInstance().irisCam->irisCamHandler, &IrisCameraCapEventHandler::sendIrisFrameToDraw, identifyForm, &IdentifyForm::drawIrisImageOnFrame); + +// LOG_INFO(QString("应用程序启动成功[Application Startup Success]").toStdString()); + qDebug() << "应用程序启动成功[Application Startup Success]"; + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::IDENTIFY_FORM; + ui->wdgtStatced->setCurrentWidget(identifyForm); + + // 开始虹膜相机拍图 + ProMemory::getInstance().irisCam->startCapture(); +} + +MainWindowForm::~MainWindowForm() +{ + delete ui; +} + +void MainWindowForm::lockScreen() +{ + ui->wdgtStatced->setCurrentWidget(lockScreenForm); + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::LOCKSCREEN_FORM; + ProMemory::getInstance().appState = AppConstants::ApplicationState::STATE_WAIT; +} + +void MainWindowForm::keyPressEvent(QKeyEvent *event) +{ + switch (event->key()) { + case Qt::Key_Escape: + QTimer::singleShot(100, qApp, [=](){ + QApplication::quit(); + }); + + default: + QWidget::keyPressEvent(event); + } +} + +void MainWindowForm::initFormsPtr() +{ + // 初始化各个form + lockScreenForm = new LockScreenForm(this); + identifyForm = new IdentifyForm(this); + + // 将form添加到statcked widget中 + ui->wdgtStatced->addWidget(identifyForm); + ui->wdgtStatced->addWidget(lockScreenForm); + + // 绑定按钮函数 +} diff --git a/MainWindowForm.h b/MainWindowForm.h new file mode 100644 index 0000000..7fb2d89 --- /dev/null +++ b/MainWindowForm.h @@ -0,0 +1,38 @@ +#ifndef MAINWINDOWFORM_H +#define MAINWINDOWFORM_H + +#include +#include +#include + +#include "utils/UtilInclude.h" +#include "ProMemory.h" +#include "LockScreenForm.h" +#include "IdentifyForm.h" + +namespace Ui { +class MainWindowForm; +} + +class MainWindowForm : public QWidget +{ + Q_OBJECT + +public: + explicit MainWindowForm(QWidget *parent = nullptr); + ~MainWindowForm(); + +public slots: + void lockScreen(); + +private: + Ui::MainWindowForm *ui; + LockScreenForm * lockScreenForm; + IdentifyForm * identifyForm; + + void keyPressEvent(QKeyEvent *event); + + void initFormsPtr(); +}; + +#endif // MAINWINDOWFORM_H diff --git a/MainWindowForm.ui b/MainWindowForm.ui new file mode 100644 index 0000000..e793ebf --- /dev/null +++ b/MainWindowForm.ui @@ -0,0 +1,85 @@ + + + MainWindowForm + + + + 0 + 0 + 600 + 1024 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + 0 + 0 + 600 + 84 + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + + + + TextLabel + + + Qt::AlignBottom|Qt::AlignHCenter + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + diff --git a/ProMemory.cpp b/ProMemory.cpp new file mode 100644 index 0000000..19e7403 --- /dev/null +++ b/ProMemory.cpp @@ -0,0 +1,84 @@ +#include "ProMemory.h" + +ProMemory::ProMemory() +{ + +} + +ProMemory::~ProMemory() +{ + +} + +/* +void ProMemory::pushCasicIris(CasicIrisInfo irisInfo) +{ + QMutex mutex; + mutex.lock(); + if (this->irisQueue.size() > 30) + { + QStack empty; + std::swap(empty, irisQueue); + } + + irisQueue.push(irisInfo); + mutex.unlock(); +} +CasicIrisInfo ProMemory::popCasicIris() +{ + CasicIrisInfo result; + + QMutex mutex; + mutex.lock(); + if (this->irisQueue.size() > 0) + { + result = irisQueue.pop(); + } + + mutex.unlock(); + + return result; +} +*/ +int ProMemory::getIrisQueueSize() +{ + int size = 0; + + QMutex mutex; + mutex.lock(); + +// size = this->irisQueue.size(); + + mutex.unlock(); + + return size; +} +bool ProMemory::isIrisQueueEmpty() +{ + bool empty = true; + + QMutex mutex; + mutex.lock(); + +// empty = this->irisQueue.isEmpty(); + + mutex.unlock(); + + return empty; +} +void ProMemory::clearIrisQueue() +{ + QMutex mutex; + mutex.lock(); + +// QStack empty; +// std::swap(empty, irisQueue); + + mutex.unlock(); +} + + +void ProMemory::initIrisFeatures(QString personId) +{ +// irisRegistPro->sendDataToExract(QByteArray(QString("[-u]").append(personId).toLocal8Bit())); +} diff --git a/ProMemory.h b/ProMemory.h new file mode 100644 index 0000000..2ecd653 --- /dev/null +++ b/ProMemory.h @@ -0,0 +1,52 @@ +#ifndef PROMEMORY_H +#define PROMEMORY_H + +#include +#include + +#include "AppConstants.h" +//#include "casic/iris/CasicIrisInfo.h" +#include "dao/IrisDataDao.h" + +#include "device/IrisCameraController.h" +//#include "device/iris/IrisRegistProcess.h" +//#include "device/iris/IrisRecogProcess.h" + +class IrisCameraController; +class IrisRegistProcess; +class IrisRecogProcess; + +class ProMemory +{ +public: + ~ProMemory(); + ProMemory(const ProMemory&)=delete; + ProMemory& operator=(const ProMemory&)=delete; + + static ProMemory& getInstance() { + static ProMemory instance; + return instance; + } + +// void pushCasicIris(CasicIrisInfo irisInfo); +// CasicIrisInfo popCasicIris(); + int getIrisQueueSize(); + bool isIrisQueueEmpty(); + void clearIrisQueue(); + + volatile int widgeFrame = 0; // 当前显示的界面 + volatile int appState = 0; // 当前程序所处的状态 + + void initIrisFeatures(QString personId = ""); // 初始化虹膜特征值集合 + + IrisCameraController * irisCam; + IrisRecogProcess * irisRecogPro; + +private: + ProMemory(); + +// QStack irisQueue; // 虹膜信息队列 + QVector irisFeatures; // 虹膜特征值集合 +}; + +#endif // PROMEMORY_H diff --git a/conf/config.ini b/conf/config.ini new file mode 100644 index 0000000..66e46ad --- /dev/null +++ b/conf/config.ini @@ -0,0 +1,67 @@ +[recognize] +#最大允许识别时间(ms) +maxMatchTime=10000 +#识别成功界面停留时间(ms) +successTipsLast=5000 +#识别失败界面停留时间(ms) +failureTipsLast=3000 +#人脸识别最大尝试次数 +maxFaceTryCount=20 +#持续没找到人脸的最大次数 +maxFaceNotFoundCount=500 +#注册时最小人脸 +minFaceRegist=240 +#识别时最小人脸 +minFaceRecog=100 + +#虹膜识别最大尝试次数 +maxIrisTryCount=10 +#虹膜识别持续没有找到眼的最大次数 +maxEyeNotFoundCount=50 + +#识别方式[1=人脸;2=虹膜;3=双认证;4=任意] +recogType=4 + +[window] +#界面窗口宽(px) +width=600 +#界面窗口高(px) +height=1024 +#统一背景色 +backgroundColor="#FFFFFF" +#标题 +title="虹膜识别终端" + +[work] +#工作状态检测时最小人脸范围 +minFaceSize=160 +#人脸范围最小横坐标 +minFacePosX=320 +#人脸范围最大横坐标 +maxFacePosX=960 +#人脸范围最小纵坐标 +minFacePosY=180 +#人脸范围最大纵坐标 +maxFacePosY=540 +#人脸太近阈值 +faceCloseSize=360 +#人脸太远阈值 +faceFarSize=480 + +[camera] +#虹膜相机取一幅画面的时间间隔(ms) +irisFrameInterval=100 +#虹膜相机拍摄宽度 +irisFrameWidth=1440 +#虹膜相机拍摄高度 +irisFrameHeight=1080 +#虹膜图像高度 +irisWidth=640 +#虹膜图像高度 +irisHeight=480 + +[log] +#日志文件位置 +logFile="d://irisLogs//casic_log.txt" +#日志级别 +logLevel="trace" diff --git a/dao/BaseDao.cpp b/dao/BaseDao.cpp new file mode 100644 index 0000000..f51c144 --- /dev/null +++ b/dao/BaseDao.cpp @@ -0,0 +1,12 @@ +#include "BaseDao.h" +#include "dao/util/ConnectionManager.h" + +BaseDao::BaseDao(QObject *parent) : QObject(parent) +{ + +} + +BaseDao::~BaseDao() +{ + +} diff --git a/dao/BaseDao.h b/dao/BaseDao.h new file mode 100644 index 0000000..1693c88 --- /dev/null +++ b/dao/BaseDao.h @@ -0,0 +1,32 @@ +#ifndef BASEDAO_H +#define BASEDAO_H + +#include +#include +#include +#include + +#include "dao/util/ConnectionManager.h" +#include "utils/UtilInclude.h" + +class BaseDao : public QObject +{ + Q_OBJECT +public: + explicit BaseDao(QObject *parent = nullptr); + ~BaseDao(); + + virtual QVector findAllRecord() = 0; + virtual QVariantMap findRecordById(QString id) = 0; + + virtual QString save(QVariantMap object) = 0; + virtual bool edit(QVariantMap newObject, QString id) = 0; + virtual bool dele(QString id) = 0; + +private: + +signals: + +}; + +#endif // BASEDAO_H diff --git a/dao/IrisDataDao.cpp b/dao/IrisDataDao.cpp new file mode 100644 index 0000000..37a0ed6 --- /dev/null +++ b/dao/IrisDataDao.cpp @@ -0,0 +1,204 @@ +#include "IrisDataDao.h" + +IrisDataDao::IrisDataDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector IrisDataDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM IRIS_DATA"; + query.prepare(sql); + + // 执行查询 + query.exec(); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + item.insert("id", query.value("id").toString()); + item.insert("person_id", query.value("person_id").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("left_iris_code1", query.value("left_iris_code1")); + item.insert("left_iris_code2", query.value("left_iris_code2")); + item.insert("left_iris_code3", query.value("left_iris_code3")); + item.insert("right_iris_code1", query.value("right_iris_code1")); + item.insert("right_iris_code2", query.value("right_iris_code2")); + item.insert("right_iris_code3", query.value("right_iris_code3")); + + result.append(item); + } + +// LOG_DEBUG(QString("查询IRIS_DATA表的所有记录[结果数:%1]").arg(result.size()).toStdString()); + return result; +} + +QVariantMap IrisDataDao::findRecordById(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM IRIS_DATA WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + // 获取结果 + if (query.next()) + { + result.insert("id", query.value("id").toString()); + result.insert("person_id", query.value("person_id").toLongLong()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("left_iris_code1", query.value("left_iris_code1")); + result.insert("left_iris_code2", query.value("left_iris_code2")); + result.insert("left_iris_code3", query.value("left_iris_code3")); + result.insert("right_iris_code1", query.value("right_iris_code1")); + result.insert("right_iris_code2", query.value("right_iris_code2")); + result.insert("right_iris_code3", query.value("right_iris_code3")); + } + +// LOG_DEBUG(QString("根据id查询IRIS_DATA表的记录[id=%1]").arg(id).toStdString()); + return result; +} + +QVariantMap IrisDataDao::findRecordByPersonId(QString personId) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM IRIS_DATA WHERE PERSON_ID = :personId"); + query.prepare(sql); + query.bindValue(":personId", personId); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + if (query.next()) + { + result.insert("id", query.value("id").toString()); + result.insert("person_id", query.value("person_id").toLongLong()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("left_iris_code1", query.value("left_iris_code1")); + result.insert("left_iris_code2", query.value("left_iris_code2")); + result.insert("left_iris_code3", query.value("left_iris_code3")); + result.insert("right_iris_code1", query.value("right_iris_code1")); + result.insert("right_iris_code2", query.value("right_iris_code2")); + result.insert("right_iris_code3", query.value("right_iris_code3")); + } + +// LOG_DEBUG(QString("根据personId查询IRIS_DATA表的记录[personId=%1]").arg(personId).toStdString()); + return result; +} + + +QString IrisDataDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + + // INSERT语句 + QString sql = QString("INSERT INTO IRIS_DATA (ID, PERSON_ID, ID_CARD_NO, LEFT_IRIS_CODE1, RIGHT_IRIS_CODE1) VALUES (:id, :personId, :idCardNo, :left1, :right1)"); + + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":personId", object.value("person_id").toString()); + query.bindValue(":idCardNo", object.value("id_card_no").toString()); + query.bindValue(":left1", object.value("left_iris_code1")); + query.bindValue(":right1", object.value("right_iris_code1")); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(); + +// LOG_DEBUG(QString("保存虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool IrisDataDao::edit(QVariantMap newObject, QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // UPDATE语句 + if (!newObject.contains("left_iris_code1") || !newObject.contains("right_iris_code1")){ + return false; + } + QString sql = QString("UPDATE IRIS_DATA SET LEFT_IRIS_CODE1 = :left1, RIGHT_IRIS_CODE1 = :right1 WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":left1", newObject.value("left_iris_code1")); + query.bindValue(":right1", newObject.value("right_iris_code1")); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(); + +// LOG_DEBUG(QString("编辑虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; +} + + +bool IrisDataDao::dele(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + QString sql = QString("DELETE FROM IRIS_DATA WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(); + +// LOG_DEBUG(QString("删除虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; +} diff --git a/dao/IrisDataDao.h b/dao/IrisDataDao.h new file mode 100644 index 0000000..c74dbbd --- /dev/null +++ b/dao/IrisDataDao.h @@ -0,0 +1,25 @@ +#ifndef IRISDATADAO_H +#define IRISDATADAO_H + +#include +#include "BaseDao.h" + +class IrisDataDao : public BaseDao +{ + Q_OBJECT +public: + explicit IrisDataDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + QVariantMap findRecordByPersonId(QString personId); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +signals: + +}; + +#endif // IRISDATADAO_H diff --git a/dao/RecognitionRecordsDao.cpp b/dao/RecognitionRecordsDao.cpp new file mode 100644 index 0000000..40db453 --- /dev/null +++ b/dao/RecognitionRecordsDao.cpp @@ -0,0 +1,100 @@ +#include "RecognitionRecordsDao.h" + +RecognitionRecordsDao::RecognitionRecordsDao(QObject *parent) : BaseDao(parent) +{ + +} + + +QVector RecognitionRecordsDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM RECOGNITION_RECORDS"; + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + item.insert("id", query.value("id").toLongLong()); + result.append(item); + } + +// LOG_DEBUG(QString("查询RECOGNITION_RECORDS表的所有记录[记录数:%1]").arg(result.size()).toStdString()); + return result; +} + +QVariantMap RecognitionRecordsDao::findRecordById(QString id) +{ + QVariantMap item; + return item; +} + +QString RecognitionRecordsDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + + // INSERT语句 + QString sql = QString("INSERT INTO RECOGNITION_RECORDS (ID, PERSON_ID, DATETIME, REC_TYPE, DEV_CODE, DOOR_CODE, INOUT_TYPE) " + "VALUES (:id, :personId, :datetime, :recType, :devCode, :doorCode, :inoutType)"); + + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":personId", object.value("person_id").toString()); + query.bindValue(":datetime", object.value("date_time").toString()); + query.bindValue(":recType", object.value("rec_type").toString()); + query.bindValue(":devCode", object.value("dev_code").toString()); + query.bindValue(":doorCode", object.value("door_code").toString()); + query.bindValue(":inoutType", object.value("inout_type").toString()); + +// LOG_DEBUG(sql.toStdString()); + + // 插入识别的log日志 + QString logStr = QString("INSERT INTO RECOGNITION_LOGS (ID, LOG_INFO) VALUES (:id, :logInfo)"); + + QSqlQuery logQuery(ConnectionManager::getInstance()->getConnection()); + logQuery.prepare(logStr); + logQuery.bindValue(":id", id); + logQuery.bindValue(":logInfo", object.value("debug_info").toString()); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(); + logQuery.exec(); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool RecognitionRecordsDao::edit(QVariantMap newObject, QString id) +{ + return false; +} + +bool RecognitionRecordsDao::dele(QString id) +{ + return false; +} diff --git a/dao/RecognitionRecordsDao.h b/dao/RecognitionRecordsDao.h new file mode 100644 index 0000000..38de7c9 --- /dev/null +++ b/dao/RecognitionRecordsDao.h @@ -0,0 +1,23 @@ +#ifndef RECOGNITIONRECORDSDAO_H +#define RECOGNITIONRECORDSDAO_H + +#include +#include "BaseDao.h" +class RecognitionRecordsDao: public BaseDao +{ + Q_OBJECT +public: + explicit RecognitionRecordsDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +signals: + +}; + +#endif // RECOGNITIONRECORDSDAO_H diff --git a/dao/SysDeptDao.cpp b/dao/SysDeptDao.cpp new file mode 100644 index 0000000..22f9946 --- /dev/null +++ b/dao/SysDeptDao.cpp @@ -0,0 +1,88 @@ +#include "SysDeptDao.h" + +SysDeptDao::SysDeptDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector SysDeptDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_DEPT WHERE PID != '-1' ORDER BY PID, NUM"; + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + item.insert("id", query.value("id").toString()); + item.insert("pid", query.value("pid").toString()); + item.insert("pids", query.value("pids").toString()); + item.insert("simplename", query.value("simplename").toString()); + item.insert("fullname", query.value("fullname").toString()); + } + +// LOG_TRACE(QString("查询表[SYS_DEPT]的所有记录[%1][%2]").arg(result.size()).arg(sql).toStdString()); + + return result; +} + +QVariantMap SysDeptDao::findRecordById(QString id) +{ + QVariantMap item; + return item; + + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM SYS_DEPT WHERE SYS_DEPT.ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + // 获取结果集的大小 + query.last(); + int count = query.at() + 1; + + if (count >=1) + { + query.first(); + + result.insert("id", query.value("id").toString()); + result.insert("pid", query.value("pid").toString()); + result.insert("pids", query.value("pids").toString()); + result.insert("simplename", query.value("simplename").toString()); + result.insert("fullname", query.value("fullname").toString()); + } + +// LOG_TRACE(QString("根据id查询SYS_DEPT表的记录[ID=%1][%2]").arg(id).arg(sql).toStdString()); + + return result; +} + + +QString SysDeptDao::save(QVariantMap object) +{ + return "0"; +} +bool SysDeptDao::edit(QVariantMap newObject, QString id) +{ + return true; +} +bool SysDeptDao::dele(QString id) +{ + return true; +} diff --git a/dao/SysDeptDao.h b/dao/SysDeptDao.h new file mode 100644 index 0000000..e07a09f --- /dev/null +++ b/dao/SysDeptDao.h @@ -0,0 +1,24 @@ +#ifndef SYSDEPTDAO_H +#define SYSDEPTDAO_H + +#include +#include "BaseDao.h" + +class SysDeptDao : public BaseDao +{ + Q_OBJECT +public: + explicit SysDeptDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +private: + +}; + +#endif // SYSDEPTDAO_H diff --git a/dao/SysPersonDao.cpp b/dao/SysPersonDao.cpp new file mode 100644 index 0000000..dd9480f --- /dev/null +++ b/dao/SysPersonDao.cpp @@ -0,0 +1,371 @@ +#include "SysPersonDao.h" + + +SysPersonDao::SysPersonDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector SysPersonDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0'"; + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + count++; + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + result.append(item); + } + +// LOG(TRACE) << QString("查询SYS_PERSON表的所有记录[%1]").arg(count).toStdString(); +// LOG_TRACE(QString("查询SYS_PERSON表的所有记录[%1]").arg(count).toStdString()); + + return result; +} + +QVariantMap SysPersonDao::findRecordById(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0' AND SYS_PERSON.ID = '%1'").arg(id); + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVariantMap result; + + // 获取结果集的大小 + query.last(); + int count = query.at() + 1; + + if (count >=1) + { + query.first(); + + result.insert("id", query.value("id").toString()); + result.insert("delflag", query.value("delflag").toString()); + result.insert("createtime", query.value("createtime").toString()); + result.insert("updatetime", query.value("updatetime").toString()); + result.insert("name", query.value("name").toString()); + result.insert("gender", query.value("gender").toString()); + result.insert("deptid", query.value("deptid").toString()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("remarks", query.value("remarks").toString()); + result.insert("person_code", query.value("person_code").toString()); + result.insert("deptname", query.value("fullname").toString()); + result.insert("sync_id", query.value("sync_id").toString()); + result.insert("hasFace", query.value("face_valid").toString()); + result.insert("hasIris", query.value("iris_valid").toString()); + } + +// LOG(TRACE) << QString("根据id查询SYS_PERSON表的记录[id=%1][%2]").arg(id).arg(sql).toStdString(); +// LOG_TRACE(QString("根据id查询SYS_PERSON表的记录[id=%1][%2]").arg(id).arg(sql).toStdString()); + + return result; +} + +int SysPersonDao::findRecordCountByNameAndDept(QString name, QString dept) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT COUNT(P.ID) AS RECCT FROM SYS_PERSON P LEFT JOIN SYS_DEPT D ON P.DEPTID = D.ID WHERE P.DELFLAG = '0'"; + if (name.isEmpty() == false) + { + sql += " AND P.NAME LIKE '%" + name + "%'"; + } + if (dept.isEmpty() == false && dept.indexOf("-1") < 0) + { + sql += QString(" AND ((P.DEPTID = '%1') OR (D.PIDS LIKE '%,%1,%'))").arg(dept); + } + + // 执行查询 + query.exec(sql); + + // 返回结果 + int result; + + // 遍历查询结果 + if (query.next()) { + result = query.value("RECCT").toInt(); + } + +// LOG(TRACE) << QString("根据姓名和部门查询SYS_PERSON记录总数[%1][%2]").arg(result).arg(sql).toStdString(); +// LOG_TRACE(QString("根据姓名和部门查询SYS_PERSON记录总数[%1][%2]").arg(result).arg(sql).toStdString()); + + return result; +} + +QVector SysPersonDao::findRecordsByNameAndDept(QString name, QString dept, qint8 limit, qint16 offset) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON P LEFT JOIN SYS_DEPT D ON P.DEPTID = D.ID WHERE P.DELFLAG = '0'"; + if (name.isEmpty() == false) + { + sql += " AND P.NAME LIKE '%" + name + "%'"; + } + if (dept.isEmpty() == false && dept.indexOf("-1") < 0) + { + sql += QString(" AND ((P.DEPTID = '%1') OR (D.PIDS LIKE '%,%1,%'))").arg(dept); + } + + sql += QString(" LIMIT %1 OFFSET %2").arg(limit).arg(offset); + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + count++; + + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + + result.append(item); + } + +// LOG(TRACE) << QString("根据姓名和部门分页查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString(); +// LOG_TRACE(QString("根据姓名和部门分页查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString()); + + return result; +} + +QVector SysPersonDao::findRecordsByProperties(QVariantMap conditions) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0'"; + QVariantMap::iterator it; + for (it = conditions.begin(); it != conditions.end(); it++) + { + sql += QString(" AND SYS_PERSON.%1 = %2").arg(it.key()).arg(it.value().toString()); + } + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + count++; + + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + + result.append(item); + } + +// LOG(TRACE) << QString("根据属性值查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString(); +// LOG_TRACE(QString("根据属性值查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString()); + + return result; +} + +QString SysPersonDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + + // INSERT语句 + QString sql = QString("INSERT INTO SYS_PERSON " + "(ID, DELFLAG, CREATETIME, UPDATETIME, " + "NAME, GENDER, DEPTID, ID_CARD_NO, " + "REMARKS, PERSON_CODE, SYNC_ID, FACE_VALID, IRIS_VALID) " + "VALUES ('%1', '0', '%2', '%2', '%3', '%4', '%5', '%6', '%7', '%8', '%9', 0, 0)") + .arg(id).arg(tm) + .arg(object.value("name").toString()) + .arg(object.value("gender").toString()) + .arg(object.value("deptid").toString()) + .arg(object.value("id_card_no").toString()) + .arg(object.value("remarks").toString()) + .arg(object.value("person_code").toString()) + .arg(object.value("sync_id").toString()); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(sql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { +// LOG(DEBUG) << QString("保存SYS_PERSON记录成功[ID = %1][%2]").arg(id).arg(sql).toStdString(); +// LOG_DEBUG(QString("保存SYS_PERSON记录成功[ID = %1][%2]").arg(id).arg(sql).toStdString()); + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool SysPersonDao::edit(QVariantMap newObject, QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + + // UPDATE语句 + QString sql = QString("UPDATE SYS_PERSON SET UPDATETIME = '%1'").arg(tm); + if (newObject.contains("name")) + { + sql.append(QString(", NAME = '%1'").arg(newObject.value("name").toString())); + } + if (newObject.contains("gender")) + { + sql.append(QString(", GENDER = '%1'").arg(newObject.value("gender").toString())); + } + if (newObject.contains("deptid")) + { + sql.append(QString(", DEPTID = '%1'").arg(newObject.value("deptid").toString())); + } + if (newObject.contains("person_code")) + { + sql.append(QString(", PERSON_CODE = '%1'").arg(newObject.value("person_code").toString())); + } + if (newObject.contains("face_valid")) + { + sql.append(QString(", FACE_VALID = '%1'").arg(newObject.value("face_valid").toString())); + } + if (newObject.contains("iris_valid")) + { + sql.append(QString(", IRIS_VALID = '%1'").arg(newObject.value("iris_valid").toString())); + } + + sql.append(QString(" WHERE ID = '%1'").arg(id)); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(sql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + +// LOG(DEBUG) << QString("编辑人员[ID=%1][%2]").arg(id).arg(sql).toStdString(); +// LOG_DEBUG(QString("编辑人员[ID=%1][%2]").arg(id).arg(sql).toStdString()); + + // 返回结果 + return success; +} + +bool SysPersonDao::dele(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + QSqlQuery irisDel(ConnectionManager::getInstance()->getConnection()); + + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + qint64 tmms = QDateTime::currentDateTime().toMSecsSinceEpoch(); + + // UPDATE语句 + QString sql = QString("UPDATE SYS_PERSON SET UPDATETIME = :updateTime, DELFLAG = :flag WHERE ID = :id").arg(tm).arg(tmms).arg(id); + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":updateTime", tm); + query.bindValue(":flag", tmms); + + // 物理删除人员的人脸和虹膜数据 + QString delIrisSql = QString("DELETE FROM IRIS_DATA WHERE PERSON_ID = :personId"); + irisDel.prepare(delIrisSql); + irisDel.bindValue(":personId", id); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(sql); + query.exec(delIrisSql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + +// LOG_DEBUG(QString("删除人员SYS_PERSON[ID=%1][%2]").arg(id).arg(success).toStdString()); + + // 返回结果 + return success; +} diff --git a/dao/SysPersonDao.h b/dao/SysPersonDao.h new file mode 100644 index 0000000..e02e5ba --- /dev/null +++ b/dao/SysPersonDao.h @@ -0,0 +1,27 @@ +#ifndef SYSPERSONDAO_H +#define SYSPERSONDAO_H + +#include +#include "BaseDao.h" + +class SysPersonDao : public BaseDao +{ + Q_OBJECT +public: + explicit SysPersonDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + int findRecordCountByNameAndDept(QString name, QString dept); + QVector findRecordsByNameAndDept(QString name, QString dept, qint8 limit, qint16 offset); + QVector findRecordsByProperties(QVariantMap conditions); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); +signals: + +}; + +#endif // SYSPERSONDAO_H diff --git a/dao/dao.pri b/dao/dao.pri new file mode 100644 index 0000000..1e04ce4 --- /dev/null +++ b/dao/dao.pri @@ -0,0 +1,18 @@ + +HEADERS += $$PWD/BaseDao.h +HEADERS += $$PWD/IrisDataDao.h +HEADERS += $$PWD/RecognitionRecordsDao.h +HEADERS += $$PWD/SysPersonDao.h +HEADERS += $$PWD/SysDeptDao.h + +SOURCES += $$PWD/BaseDao.cpp +SOURCES += $$PWD/IrisDataDao.cpp +SOURCES += $$PWD/RecognitionRecordsDao.cpp +SOURCES += $$PWD/SysPersonDao.cpp +SOURCES += $$PWD/SysDeptDao.cpp + +HEADERS += $$PWD/util/ConnectionManager.h +SOURCES += $$PWD/util/ConnectionManager.cpp +#HEADERS += $$PWD/util/CacheManager.h +#SOURCES += $$PWD/util/CacheManager.cpp + diff --git a/dao/util/ConnectionManager.cpp b/dao/util/ConnectionManager.cpp new file mode 100644 index 0000000..84b17be --- /dev/null +++ b/dao/util/ConnectionManager.cpp @@ -0,0 +1,47 @@ +#include "ConnectionManager.h" +#include + +Q_GLOBAL_STATIC(ConnectionManager, cm) + +ConnectionManager::ConnectionManager(QObject *parent) : QObject(parent) +{ + // 初始化数据库连接 + if (QSqlDatabase::contains("qt_sql_dafault_connection")) + { + conn = QSqlDatabase::database("qt_sql_default_connection"); + } + else + { + conn = QSqlDatabase::addDatabase("QSQLITE"); + conn.setDatabaseName(QApplication::applicationDirPath() + "/data/casic.db"); + + bool succ = conn.open(); + if (succ == true) + { +// LOG_INFO(QString("打开数据库操作正常[Open Database Success]").toStdString()); + } else + { +// LOG_ERROR(QString("打开数据库操作失败[Open Database Failed]").toStdString()); + } + } +} + +ConnectionManager::~ConnectionManager() +{ + conn.close(); +} + +ConnectionManager* ConnectionManager::getInstance() +{ + return cm; +} + +QSqlDatabase ConnectionManager::getConnection() +{ + return this->conn; +} + +qint64 ConnectionManager::generateId() +{ + return this->idWorker.nextId(); +} diff --git a/dao/util/ConnectionManager.h b/dao/util/ConnectionManager.h new file mode 100644 index 0000000..84647e3 --- /dev/null +++ b/dao/util/ConnectionManager.h @@ -0,0 +1,34 @@ +#ifndef CONNECTIONMANAGER_H +#define CONNECTIONMANAGER_H + +#include +#include +#include "utils/id/IdWorker.h" +#include "utils/UtilInclude.h" + +using namespace Jiawa::Core; + +class ConnectionManager : public QObject +{ + Q_OBJECT +public: + explicit ConnectionManager(QObject *parent = nullptr); + ~ConnectionManager(); + + static ConnectionManager * getInstance(); + + QSqlDatabase getConnection(); + qint64 generateId(); + +private: + // 数据库连接 + QSqlDatabase conn; + + // 雪花id生成工具 + IdWorker &idWorker = Singleton::instance(); + +signals: + +}; + +#endif // CONNECTIONMANAGER_H diff --git a/device/IrisCameraCapEventHandler.cpp b/device/IrisCameraCapEventHandler.cpp new file mode 100644 index 0000000..45df089 --- /dev/null +++ b/device/IrisCameraCapEventHandler.cpp @@ -0,0 +1,103 @@ +#include "IrisCameraCapEventHandler.h" + +IrisCameraCapEventHandler::IrisCameraCapEventHandler(QObject *parent) : QObject(parent) +{ + +} + +void IrisCameraCapEventHandler::DoOnImageCaptured(CImageDataPointer &objImageDataPointer, void *pUserParam) +{ + if (objImageDataPointer.IsNull() == false) + { + CGXDevicePointer* cam = (CGXDevicePointer *) pUserParam; + + auto camName = cam->getPtr()->GetDeviceInfo().GetUserID(); + int width = objImageDataPointer->GetWidth(); + int height = objImageDataPointer->GetHeight(); + size_t leftKeyIndex = camName.find("left"); + size_t rightKeyIndex = camName.find("right"); + + uchar * pBuffer = (BYTE*)objImageDataPointer->GetBuffer(); + + // 相机拍摄下的图像1440*1080, 直接用于算法判断 + QImage img = QImage(pBuffer, width, height, QImage::Format_Grayscale8); // 用于展示 +// QImage imgAlgo = img.copy(0, 0, width, height); + + // 用于显示的图像需要缩小到400 * 300的尺寸 + img = img.scaled(SettingConfig::getInstance().IRIS_DISPLAY_HEIGHT, SettingConfig::getInstance().IRIS_DISPLAY_WIDTH); + img = img.transformed(QTransform().rotate(-90)); // 图像逆时针旋转90度 + + // 发送到界面进行显示 + emit sendIrisFrameToDraw(img); +// cv::Mat irisMat = ImageUtil::QImageToMat(imgAlgo); + +// irisInfo.data = imgAlgo; +// irisInfo.matData = irisMat; + +// // 将图像显示在注册页面的label上 +// // 并将虹膜信息对象存入队列中 +// ProMemory::getInstance().pushCasicIris(irisInfo); + +// if (leftKeyIndex >= 0 && leftKeyIndex < 32) +// { +// emit sendIrisFrameToDraw(img, 0); // 左眼画面 +// } else if (rightKeyIndex >= 0 && rightKeyIndex < 32) +// { +// emit sendIrisFrameToDraw(img, 1); // 右眼画面 +// } +/* + if (pBuffer != NULL) + { + // 创建虹膜信息对象 + CasicIrisInfo irisInfo; + irisInfo.hasEye = false; + if (leftKeyIndex >= 0 && leftKeyIndex < 32) + { + // 左眼相机拍摄的图像 + irisInfo.leftOrRight = "left"; + } else if (rightKeyIndex >= 0 && rightKeyIndex < 32) + { + // 右眼相机 + irisInfo.leftOrRight = "right"; + } + + if (ProMemory::getInstance().widgeFrame == CasicBioRecConst::RECOGNIZE_RESULT_FORM) + { + // 相机拍摄下的图像1280*960, 直接用于算法判断 + QImage imgDisp = QImage(pBuffer, width, height, QImage::Format_Grayscale8); + cv::Mat irisMat = ImageUtil::QImageToMat(imgDisp); + + irisInfo.data = imgDisp; + irisInfo.matData = irisMat; + + ProMemory::getInstance().pushCasicIris(irisInfo); + +// cv::imwrite(QString("D:\\irisLogs\\iristest-%1.bmp").arg(irisInfo.leftOrRight).toStdString(), irisMat); + } else if (ProMemory::getInstance().widgeFrame == CasicBioRecConst::ADD_PERSON_CAPTURE_IRIS) + { + // 相机拍摄下的图像1280*960, 直接用于算法判断 + QImage img = QImage(pBuffer, width, height, QImage::Format_Grayscale8); + QImage imgAlgo = img.copy(0, 0, width, height); + + // 用于显示的图像需要缩小到1/4的尺寸 + img = img.scaled(640, 480); + cv::Mat irisMat = ImageUtil::QImageToMat(imgAlgo); + + irisInfo.data = imgAlgo; + irisInfo.matData = irisMat; + + // 将图像显示在注册页面的label上 + // 并将虹膜信息对象存入队列中 + ProMemory::getInstance().pushCasicIris(irisInfo); + + if (leftKeyIndex >= 0 && leftKeyIndex < 32) + { + emit sendIrisFrameToDraw(img, 0); // 左眼画面 + } else if (rightKeyIndex >= 0 && rightKeyIndex < 32) + { + emit sendIrisFrameToDraw(img, 1); // 右眼画面 + } + } + }*/ + } +} diff --git a/device/IrisCameraCapEventHandler.h b/device/IrisCameraCapEventHandler.h new file mode 100644 index 0000000..ad75a97 --- /dev/null +++ b/device/IrisCameraCapEventHandler.h @@ -0,0 +1,30 @@ +#ifndef IRISCAMERACAPEVENTHANDLER_H +#define IRISCAMERACAPEVENTHANDLER_H + +#include +#include +#include "include/opencv2/opencv.hpp" +#include "include/daheng/GalaxyIncludes.h" + +//#include "casic/iris/CasicIrisInterface.h" +#include "ProMemory.h" + +#include "utils/UtilInclude.h" + +class IrisCameraCapEventHandler : public QObject, public ICaptureEventHandler +{ + Q_OBJECT +public: + explicit IrisCameraCapEventHandler(QObject *parent = nullptr); + + void DoOnImageCaptured(CImageDataPointer &objImageDataPointer, void *pUserParam); + +private: + unsigned char* pImageBuffer; + +signals: + void sendIrisFrameToDraw(QImage irisImage); + +}; + +#endif // IRISCAMERACAPEVENTHANDLER_H diff --git a/device/IrisCameraController.cpp b/device/IrisCameraController.cpp new file mode 100644 index 0000000..0928176 --- /dev/null +++ b/device/IrisCameraController.cpp @@ -0,0 +1,110 @@ +#include "IrisCameraController.h" + +IrisCameraController::IrisCameraController(QObject *parent) : QObject(parent) +{ + this->irisCamHandler = new IrisCameraCapEventHandler(this); +} +IrisCameraController::~IrisCameraController() +{ + this->closeIrisCamera(); +} + + +void IrisCameraController::initIrisCamera() +{ + IGXFactory::GetInstance().Init(); + + //枚举设备 + IGXFactory::GetInstance().UpdateDeviceList(1000, irisCamList); + + this->OpenDevice(); +} + +void IrisCameraController::openIrisCamera() +{ + //设置Buffer处理模式 + irisStreamFeaturePtr->GetEnumFeature("StreamBufferHandlingMode")->SetValue("OldestFirst"); + + //注册回调函数 + irisStreamPtr->RegisterCaptureCallback(irisCamHandler, &irisCamPtr); + + //开启流层通道 + irisStreamPtr->StartGrab(); + + //发送开采命令 + irisFeaturePtr->GetCommandFeature("AcquisitionStart")->Execute(); + + // 启动定时器 + TimeCounterUtil::getInstance().irisCapCounter->start(SettingConfig::getInstance().IRIS_FRAME_INTERVAL); // 50ms执行一次定时器 +} + +void IrisCameraController::closeIrisCamera() +{ + +} + +void IrisCameraController::startCapture() +{ + // 获取定时器, 绑定定时函数 + connect(TimeCounterUtil::getInstance().irisCapCounter, &QTimer::timeout, this, &IrisCameraController::getOneFaceFrm); +// LOG(DEBUG) << QString("[IrisCameraController][startCapture]虹膜相机拍图").toStdString(); +// LOG_DEBUG(QString("[IrisCameraController][startCapture]虹膜相机拍图").toStdString()); + +} +void IrisCameraController::stopCapture() +{ + // 获取定时器, 绑定定时函数 + disconnect(TimeCounterUtil::getInstance().irisCapCounter, &QTimer::timeout, this, &IrisCameraController::getOneFaceFrm); +// LOG(DEBUG) << QString("[IrisCameraController][stopCapture]虹膜相机停止拍图").toStdString(); +// LOG_DEBUG(QString("[IrisCameraController][stopCapture]虹膜相机停止拍图").toStdString()); + +} + +void IrisCameraController::getOneFaceFrm() +{ + // 发送软触发命令(在触发模式开启时有效) + irisFeaturePtr->GetCommandFeature("TriggerSoftware")->Execute(); +} + +void IrisCameraController::getLeftAndRightEyeFrame() +{ + irisFeaturePtr->GetCommandFeature("TriggerSoftware")->Execute(); +} + +void IrisCameraController::OpenDevice() +{ + auto device = irisCamList.at(0); + + irisCamPtr = IGXFactory::GetInstance().OpenDeviceByUserID(device.GetUserID(), GX_ACCESS_EXCLUSIVE); + irisFeaturePtr = irisCamPtr->GetRemoteFeatureControl(); + + // 判断设备流是否大于零, 如果大于零则打开流 + int nStreamCount = irisCamPtr->GetStreamCount(); + if (nStreamCount > 0) + { + irisStreamPtr = irisCamPtr->OpenStream(0); + irisStreamFeaturePtr = irisStreamPtr->GetFeatureControl(); + } + + // 建议用户在打开网络相机之后, 根据当前网络环境设置相机的流通道包长值, + // 以提高网络相机的采集性能, 设置方法参考以下代码。 + GX_DEVICE_CLASS_LIST objDeviceClass = irisCamPtr->GetDeviceInfo().GetDeviceClass(); + if(GX_DEVICE_CLASS_GEV == objDeviceClass) + { + // 判断设备是否支持流通道数据包功能 + if(true == irisFeaturePtr->IsImplemented("GevSCPSPacketSize")) + { + // 获取当前网络环境的最优包长值 + int nPacketSize = irisStreamPtr->GetOptimalPacketSize(); + // 将最优包长值设置为当前设备的流通道包长值 + irisFeaturePtr->GetIntFeature("GevSCPSPacketSize")->SetValue(nPacketSize); + } + } + + //设置采集模式为连续采集模式 + irisFeaturePtr->GetEnumFeature("AcquisitionMode")->SetValue("Continuous"); + + //设置触发模式关 + irisFeaturePtr->GetEnumFeature("TriggerMode")->SetValue("On"); + irisFeaturePtr->GetEnumFeature("TriggerSource")->SetValue("Software"); +} diff --git a/device/IrisCameraController.h b/device/IrisCameraController.h new file mode 100644 index 0000000..5d7e269 --- /dev/null +++ b/device/IrisCameraController.h @@ -0,0 +1,49 @@ +#ifndef IRISCAMERACONTROLLER_H +#define IRISCAMERACONTROLLER_H + +#include + +#include "IrisCameraCapEventHandler.h" + +class IrisCameraCapEventHandler; + +class IrisCameraController : public QObject +{ + Q_OBJECT +public: + explicit IrisCameraController(QObject *parent = nullptr); + ~IrisCameraController(); + + // 初始化并打开人脸相机 + void initIrisCamera(); + void openIrisCamera(); + void closeIrisCamera(); + + void startCapture(); + void stopCapture(); + + void getLeftAndRightEyeFrame(); + + IrisCameraCapEventHandler * irisCamHandler; + +private: + GxIAPICPP::gxdeviceinfo_vector irisCamList; + + CGXDevicePointer irisCamPtr; ///< 设备句柄 + + CGXStreamPointer irisStreamPtr; ///< 左眼设备流 + + CGXFeatureControlPointer irisFeaturePtr; ///< 左眼属性控制器 + + CGXFeatureControlPointer irisStreamFeaturePtr; ///< 左眼流层控制器对象 + + void OpenDevice(); + +signals: + +public slots: + void getOneFaceFrm(); + +}; + +#endif // IRISCAMERACONTROLLER_H diff --git a/device/device.pri b/device/device.pri new file mode 100644 index 0000000..a8417f2 --- /dev/null +++ b/device/device.pri @@ -0,0 +1,13 @@ + +HEADERS += $$PWD/IrisCameraController.h +HEADERS += $$PWD/IrisCameraCapEventHandler.h +#HEADERS += $$PWD/iris/IrisRegistProcess.h +#HEADERS += $$PWD/iris/IrisRecogProcess.h +#HEADERS += $$PWD/iris/CasicIrisRecState.h + +SOURCES += $$PWD/IrisCameraController.cpp +SOURCES += $$PWD/IrisCameraCapEventHandler.cpp +#SOURCES += $$PWD/iris/IrisRegistProcess.cpp +#SOURCES += $$PWD/iris/IrisRecogProcess.cpp +#SOURCES += $$PWD/iris/CasicIrisRecState.cpp + diff --git a/images/bg_footer.png b/images/bg_footer.png new file mode 100644 index 0000000..a3a99ab --- /dev/null +++ b/images/bg_footer.png Binary files differ diff --git a/images/bg_statcked.png b/images/bg_statcked.png new file mode 100644 index 0000000..18b63e1 --- /dev/null +++ b/images/bg_statcked.png Binary files differ diff --git a/images/bg_title.png b/images/bg_title.png new file mode 100644 index 0000000..0316e2d --- /dev/null +++ b/images/bg_title.png Binary files differ diff --git a/main.cpp b/main.cpp index 16bc45b..9052ddb 100644 --- a/main.cpp +++ b/main.cpp @@ -1,11 +1,11 @@ -#include "IdentifyForm.h" +#include "MainWindowForm.h" #include int main(int argc, char *argv[]) { QApplication a(argc, argv); - IdentifyForm w; + MainWindowForm w; w.show(); return a.exec(); } diff --git a/resource.qrc b/resource.qrc new file mode 100644 index 0000000..474586a --- /dev/null +++ b/resource.qrc @@ -0,0 +1,35 @@ + + + images/setting.png + images/user.png + images/back.png + images/home.png + images/btnPageFirst.png + images/btnPageLast.png + images/btnPageNext.png + images/btnPagePre.png + images/regist.png + images/photoEyeLeft.png + images/photoEyeRight.png + images/photoFace.png + images/save.png + images/upArrow.png + images/downArrow.png + images/faceCaped.png + images/faceNotCap.png + images/irisCaped.png + images/irisNotCap.png + images/tipsFailure.png + images/tipsSuccess.png + images/tipsConfirm.png + images/bg_recognize_result.png + images/iconRetry.png + images/bg_title.png + images/bg_footer.png + images/bg_statcked.png + + + images/add_bottom.png + images/add_top.png + + diff --git a/AppConstants.h b/AppConstants.h new file mode 100644 index 0000000..296c53f --- /dev/null +++ b/AppConstants.h @@ -0,0 +1,28 @@ +#ifndef APPCONSTANTS_H +#define APPCONSTANTS_H + +class AppConstants +{ +public: + enum WidgeFrameName + { + MAIN_PAGE = 0, // 主页面 + PERSON_LIST_FORM = 1, // 人员列表页面 + ADD_PERSON_FORM = 2, // 添加人员页面 + ADD_PERSON_CAPTURE_FACE = 21, // 添加/编辑人员时进行人脸拍图 + ADD_PERSON_CAPTURE_IRIS = 22, // 添加/编辑人员时进行虹膜拍图 + SETTING_FORM = 3, // 设置页面 + RECOGNIZE_RESULT_FORM = 4, // 识别结果界面 + IDENTIFY_FORM = 5, // 识别界面 含识别中 和 识别结果 + LOCKSCREEN_FORM = 6 // 锁屏待机界面 + }; + + enum ApplicationState + { + STATE_WAIT = 0, // 待机 + STATE_WORKING = 1, // 工作状态 + STATE_IDENTIFYING = 2, // 识别中 + }; +}; + +#endif // APPCONSTANTS_H diff --git a/CasicIrisIdentify.pro b/CasicIrisIdentify.pro index 5d7fea6..575ce3d 100644 --- a/CasicIrisIdentify.pro +++ b/CasicIrisIdentify.pro @@ -1,4 +1,4 @@ -QT += core gui +QT += core gui sql network texttospeech greaterThan(QT_MAJOR_VERSION, 4): QT += widgets @@ -15,20 +15,46 @@ # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 -SOURCES += \ - main.cpp \ - IdentifyForm.cpp +include("dao/dao.pri") +include("device/device.pri") +include("utils/utils.pri") -HEADERS += \ - IdentifyForm.h +SOURCES += main.cpp +SOURCES += ProMemory.cpp +SOURCES += MainWindowForm.cpp +SOURCES += IdentifyForm.cpp +SOURCES += LockScreenForm.cpp -FORMS += \ - IdentifyForm.ui +HEADERS += AppConstants.h +HEADERS += ProMemory.h +HEADERS += MainWindowForm.h +HEADERS += IdentifyForm.h +HEADERS += LockScreenForm.h -TRANSLATIONS += \ - CasicIrisIdentify_zh_CN.ts +FORMS += MainWindowForm.ui +FORMS += IdentifyForm.ui +FORMS += LockScreenForm.ui + +RESOURCES += resource.qrc + +DISTFILES += conf/config.ini + +#TRANSLATIONS += CasicIrisIdentify_zh_CN.ts + +#INCLUDEPATH += include/spdlog +#DEPENDPATH += include/spdlog # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target + + +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lopencv_world420 +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lGxIAPICPPEx + +INCLUDEPATH += $$PWD/include/daheng +DEPENDPATH += $$PWD/include/daheng + +INCLUDEPATH += $$PWD/include +DEPENDPATH += $$PWD/include diff --git a/CasicIrisIdentify_zh_CN.ts b/CasicIrisIdentify_zh_CN.ts index 5526fe4..81900df 100644 --- a/CasicIrisIdentify_zh_CN.ts +++ b/CasicIrisIdentify_zh_CN.ts @@ -1,3 +1,12 @@ - + + + IdentifyForm + + + IdentifyForm + + + + diff --git a/IdentifyForm.cpp b/IdentifyForm.cpp index 348a897..ba1f251 100644 --- a/IdentifyForm.cpp +++ b/IdentifyForm.cpp @@ -1,4 +1,4 @@ -#include "IdentifyForm.h" +#include "IdentifyForm.h" #include "ui_IdentifyForm.h" IdentifyForm::IdentifyForm(QWidget *parent) @@ -6,6 +6,12 @@ , ui(new Ui::IdentifyForm) { ui->setupUi(this); + + // 初始化更新界面的定时器 + // 每秒执行一次 + connect(TimeCounterUtil::getInstance().clockCounter, &QTimer::timeout, this, &IdentifyForm::updateDateAndTime); + + TimeCounterUtil::getInstance().clockCounter->start(1000); } IdentifyForm::~IdentifyForm() @@ -13,3 +19,16 @@ delete ui; } +void IdentifyForm::drawIrisImageOnFrame(QImage image) +{ + // 只在识别界面才显示画面 + if (ui->wgtStacked->currentIndex() == 0) { + ui->labelVideo->setPixmap(QPixmap::fromImage(image)); + } +} + + +void IdentifyForm::updateDateAndTime() +{ + ui->labelTime->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd dddd HH:mm:ss")); +} diff --git a/IdentifyForm.h b/IdentifyForm.h index fc857a1..ae1cd22 100644 --- a/IdentifyForm.h +++ b/IdentifyForm.h @@ -1,7 +1,10 @@ -#ifndef IDENTIFYFORM_H +#ifndef IDENTIFYFORM_H #define IDENTIFYFORM_H #include +#include + +#include "utils/UtilInclude.h" QT_BEGIN_NAMESPACE namespace Ui { class IdentifyForm; } @@ -15,7 +18,14 @@ IdentifyForm(QWidget *parent = nullptr); ~IdentifyForm(); +public slots: + void drawIrisImageOnFrame(QImage image); + private: Ui::IdentifyForm *ui; + +private slots: + void updateDateAndTime(); + }; #endif // IDENTIFYFORM_H diff --git a/IdentifyForm.ui b/IdentifyForm.ui index c72a36f..879dc9a 100644 --- a/IdentifyForm.ui +++ b/IdentifyForm.ui @@ -6,13 +6,59 @@ 0 0 - 800 + 600 600 IdentifyForm + + + + 0 + 40 + 600 + 450 + + + + 0 + + + + + + 100 + 10 + 400 + 300 + + + + + + + + + + + + + + 0 + 0 + 600 + 40 + + + + TextLabel + + + Qt::AlignCenter + + diff --git a/LockScreenForm.cpp b/LockScreenForm.cpp new file mode 100644 index 0000000..58dc54b --- /dev/null +++ b/LockScreenForm.cpp @@ -0,0 +1,14 @@ +#include "LockScreenForm.h" +#include "ui_LockScreenForm.h" + +LockScreenForm::LockScreenForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::LockScreenForm) +{ + ui->setupUi(this); +} + +LockScreenForm::~LockScreenForm() +{ + delete ui; +} diff --git a/LockScreenForm.h b/LockScreenForm.h new file mode 100644 index 0000000..b5ded48 --- /dev/null +++ b/LockScreenForm.h @@ -0,0 +1,25 @@ +#ifndef LOCKSCREENFORM_H +#define LOCKSCREENFORM_H + +#include +#include + +#include "utils/UtilInclude.h" + +namespace Ui { +class LockScreenForm; +} + +class LockScreenForm : public QWidget +{ + Q_OBJECT + +public: + explicit LockScreenForm(QWidget *parent = nullptr); + ~LockScreenForm(); + +private: + Ui::LockScreenForm *ui; +}; + +#endif // LOCKSCREENFORM_H diff --git a/LockScreenForm.ui b/LockScreenForm.ui new file mode 100644 index 0000000..7f2a6db --- /dev/null +++ b/LockScreenForm.ui @@ -0,0 +1,45 @@ + + + LockScreenForm + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + 180 + 100 + 54 + 12 + + + + TextLabel + + + + + + 180 + 160 + 54 + 12 + + + + TextLabel + + + + + + diff --git a/MainWindowForm.cpp b/MainWindowForm.cpp new file mode 100644 index 0000000..84f8159 --- /dev/null +++ b/MainWindowForm.cpp @@ -0,0 +1,86 @@ +#include "MainWindowForm.h" +#include "ui_MainWindowForm.h" +#include + +MainWindowForm::MainWindowForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::MainWindowForm) +{ + ui->setupUi(this); + + // 设置窗口透明和大小、位置 + this->setWindowFlags(Qt::FramelessWindowHint); + this->move(1400, 15); + this->resize(SettingConfig::getInstance().WINDOW_WIDTH, SettingConfig::getInstance().WINDOW_HEIGHT); + + // 通过调色板的颜色来设置窗口的统一背景色 + qApp->setPalette(QPalette(QColor(SettingConfig::getInstance().WINDOW_BACKGROUND_COLOR))); + + // 加载css文件设置控件样式 + QFile file(QApplication::applicationDirPath() + "/qss/main.css"); + if (file.open(QFile::ReadOnly)) + { + QString qssStr = QLatin1String(file.readAll()); + this->setStyleSheet(qssStr); + file.close(); + } + + initFormsPtr(); + + // 设置标题文字 + ui->labelTitle->setText(SettingConfig::getInstance().WINDOW_TITLE); + ui->labelCopyright->setText(SettingConfig::getInstance().WINDOW_RIGHTS); + ui->labelVersion->setText(SettingConfig::getInstance().WINDOW_VERSION); + + // 初始化虹膜相机控制 + ProMemory::getInstance().irisCam = new IrisCameraController(this); + ProMemory::getInstance().irisCam->initIrisCamera(); + ProMemory::getInstance().irisCam->openIrisCamera(); + connect(ProMemory::getInstance().irisCam->irisCamHandler, &IrisCameraCapEventHandler::sendIrisFrameToDraw, identifyForm, &IdentifyForm::drawIrisImageOnFrame); + +// LOG_INFO(QString("应用程序启动成功[Application Startup Success]").toStdString()); + qDebug() << "应用程序启动成功[Application Startup Success]"; + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::IDENTIFY_FORM; + ui->wdgtStatced->setCurrentWidget(identifyForm); + + // 开始虹膜相机拍图 + ProMemory::getInstance().irisCam->startCapture(); +} + +MainWindowForm::~MainWindowForm() +{ + delete ui; +} + +void MainWindowForm::lockScreen() +{ + ui->wdgtStatced->setCurrentWidget(lockScreenForm); + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::LOCKSCREEN_FORM; + ProMemory::getInstance().appState = AppConstants::ApplicationState::STATE_WAIT; +} + +void MainWindowForm::keyPressEvent(QKeyEvent *event) +{ + switch (event->key()) { + case Qt::Key_Escape: + QTimer::singleShot(100, qApp, [=](){ + QApplication::quit(); + }); + + default: + QWidget::keyPressEvent(event); + } +} + +void MainWindowForm::initFormsPtr() +{ + // 初始化各个form + lockScreenForm = new LockScreenForm(this); + identifyForm = new IdentifyForm(this); + + // 将form添加到statcked widget中 + ui->wdgtStatced->addWidget(identifyForm); + ui->wdgtStatced->addWidget(lockScreenForm); + + // 绑定按钮函数 +} diff --git a/MainWindowForm.h b/MainWindowForm.h new file mode 100644 index 0000000..7fb2d89 --- /dev/null +++ b/MainWindowForm.h @@ -0,0 +1,38 @@ +#ifndef MAINWINDOWFORM_H +#define MAINWINDOWFORM_H + +#include +#include +#include + +#include "utils/UtilInclude.h" +#include "ProMemory.h" +#include "LockScreenForm.h" +#include "IdentifyForm.h" + +namespace Ui { +class MainWindowForm; +} + +class MainWindowForm : public QWidget +{ + Q_OBJECT + +public: + explicit MainWindowForm(QWidget *parent = nullptr); + ~MainWindowForm(); + +public slots: + void lockScreen(); + +private: + Ui::MainWindowForm *ui; + LockScreenForm * lockScreenForm; + IdentifyForm * identifyForm; + + void keyPressEvent(QKeyEvent *event); + + void initFormsPtr(); +}; + +#endif // MAINWINDOWFORM_H diff --git a/MainWindowForm.ui b/MainWindowForm.ui new file mode 100644 index 0000000..e793ebf --- /dev/null +++ b/MainWindowForm.ui @@ -0,0 +1,85 @@ + + + MainWindowForm + + + + 0 + 0 + 600 + 1024 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + 0 + 0 + 600 + 84 + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + + + + TextLabel + + + Qt::AlignBottom|Qt::AlignHCenter + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + diff --git a/ProMemory.cpp b/ProMemory.cpp new file mode 100644 index 0000000..19e7403 --- /dev/null +++ b/ProMemory.cpp @@ -0,0 +1,84 @@ +#include "ProMemory.h" + +ProMemory::ProMemory() +{ + +} + +ProMemory::~ProMemory() +{ + +} + +/* +void ProMemory::pushCasicIris(CasicIrisInfo irisInfo) +{ + QMutex mutex; + mutex.lock(); + if (this->irisQueue.size() > 30) + { + QStack empty; + std::swap(empty, irisQueue); + } + + irisQueue.push(irisInfo); + mutex.unlock(); +} +CasicIrisInfo ProMemory::popCasicIris() +{ + CasicIrisInfo result; + + QMutex mutex; + mutex.lock(); + if (this->irisQueue.size() > 0) + { + result = irisQueue.pop(); + } + + mutex.unlock(); + + return result; +} +*/ +int ProMemory::getIrisQueueSize() +{ + int size = 0; + + QMutex mutex; + mutex.lock(); + +// size = this->irisQueue.size(); + + mutex.unlock(); + + return size; +} +bool ProMemory::isIrisQueueEmpty() +{ + bool empty = true; + + QMutex mutex; + mutex.lock(); + +// empty = this->irisQueue.isEmpty(); + + mutex.unlock(); + + return empty; +} +void ProMemory::clearIrisQueue() +{ + QMutex mutex; + mutex.lock(); + +// QStack empty; +// std::swap(empty, irisQueue); + + mutex.unlock(); +} + + +void ProMemory::initIrisFeatures(QString personId) +{ +// irisRegistPro->sendDataToExract(QByteArray(QString("[-u]").append(personId).toLocal8Bit())); +} diff --git a/ProMemory.h b/ProMemory.h new file mode 100644 index 0000000..2ecd653 --- /dev/null +++ b/ProMemory.h @@ -0,0 +1,52 @@ +#ifndef PROMEMORY_H +#define PROMEMORY_H + +#include +#include + +#include "AppConstants.h" +//#include "casic/iris/CasicIrisInfo.h" +#include "dao/IrisDataDao.h" + +#include "device/IrisCameraController.h" +//#include "device/iris/IrisRegistProcess.h" +//#include "device/iris/IrisRecogProcess.h" + +class IrisCameraController; +class IrisRegistProcess; +class IrisRecogProcess; + +class ProMemory +{ +public: + ~ProMemory(); + ProMemory(const ProMemory&)=delete; + ProMemory& operator=(const ProMemory&)=delete; + + static ProMemory& getInstance() { + static ProMemory instance; + return instance; + } + +// void pushCasicIris(CasicIrisInfo irisInfo); +// CasicIrisInfo popCasicIris(); + int getIrisQueueSize(); + bool isIrisQueueEmpty(); + void clearIrisQueue(); + + volatile int widgeFrame = 0; // 当前显示的界面 + volatile int appState = 0; // 当前程序所处的状态 + + void initIrisFeatures(QString personId = ""); // 初始化虹膜特征值集合 + + IrisCameraController * irisCam; + IrisRecogProcess * irisRecogPro; + +private: + ProMemory(); + +// QStack irisQueue; // 虹膜信息队列 + QVector irisFeatures; // 虹膜特征值集合 +}; + +#endif // PROMEMORY_H diff --git a/conf/config.ini b/conf/config.ini new file mode 100644 index 0000000..66e46ad --- /dev/null +++ b/conf/config.ini @@ -0,0 +1,67 @@ +[recognize] +#最大允许识别时间(ms) +maxMatchTime=10000 +#识别成功界面停留时间(ms) +successTipsLast=5000 +#识别失败界面停留时间(ms) +failureTipsLast=3000 +#人脸识别最大尝试次数 +maxFaceTryCount=20 +#持续没找到人脸的最大次数 +maxFaceNotFoundCount=500 +#注册时最小人脸 +minFaceRegist=240 +#识别时最小人脸 +minFaceRecog=100 + +#虹膜识别最大尝试次数 +maxIrisTryCount=10 +#虹膜识别持续没有找到眼的最大次数 +maxEyeNotFoundCount=50 + +#识别方式[1=人脸;2=虹膜;3=双认证;4=任意] +recogType=4 + +[window] +#界面窗口宽(px) +width=600 +#界面窗口高(px) +height=1024 +#统一背景色 +backgroundColor="#FFFFFF" +#标题 +title="虹膜识别终端" + +[work] +#工作状态检测时最小人脸范围 +minFaceSize=160 +#人脸范围最小横坐标 +minFacePosX=320 +#人脸范围最大横坐标 +maxFacePosX=960 +#人脸范围最小纵坐标 +minFacePosY=180 +#人脸范围最大纵坐标 +maxFacePosY=540 +#人脸太近阈值 +faceCloseSize=360 +#人脸太远阈值 +faceFarSize=480 + +[camera] +#虹膜相机取一幅画面的时间间隔(ms) +irisFrameInterval=100 +#虹膜相机拍摄宽度 +irisFrameWidth=1440 +#虹膜相机拍摄高度 +irisFrameHeight=1080 +#虹膜图像高度 +irisWidth=640 +#虹膜图像高度 +irisHeight=480 + +[log] +#日志文件位置 +logFile="d://irisLogs//casic_log.txt" +#日志级别 +logLevel="trace" diff --git a/dao/BaseDao.cpp b/dao/BaseDao.cpp new file mode 100644 index 0000000..f51c144 --- /dev/null +++ b/dao/BaseDao.cpp @@ -0,0 +1,12 @@ +#include "BaseDao.h" +#include "dao/util/ConnectionManager.h" + +BaseDao::BaseDao(QObject *parent) : QObject(parent) +{ + +} + +BaseDao::~BaseDao() +{ + +} diff --git a/dao/BaseDao.h b/dao/BaseDao.h new file mode 100644 index 0000000..1693c88 --- /dev/null +++ b/dao/BaseDao.h @@ -0,0 +1,32 @@ +#ifndef BASEDAO_H +#define BASEDAO_H + +#include +#include +#include +#include + +#include "dao/util/ConnectionManager.h" +#include "utils/UtilInclude.h" + +class BaseDao : public QObject +{ + Q_OBJECT +public: + explicit BaseDao(QObject *parent = nullptr); + ~BaseDao(); + + virtual QVector findAllRecord() = 0; + virtual QVariantMap findRecordById(QString id) = 0; + + virtual QString save(QVariantMap object) = 0; + virtual bool edit(QVariantMap newObject, QString id) = 0; + virtual bool dele(QString id) = 0; + +private: + +signals: + +}; + +#endif // BASEDAO_H diff --git a/dao/IrisDataDao.cpp b/dao/IrisDataDao.cpp new file mode 100644 index 0000000..37a0ed6 --- /dev/null +++ b/dao/IrisDataDao.cpp @@ -0,0 +1,204 @@ +#include "IrisDataDao.h" + +IrisDataDao::IrisDataDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector IrisDataDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM IRIS_DATA"; + query.prepare(sql); + + // 执行查询 + query.exec(); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + item.insert("id", query.value("id").toString()); + item.insert("person_id", query.value("person_id").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("left_iris_code1", query.value("left_iris_code1")); + item.insert("left_iris_code2", query.value("left_iris_code2")); + item.insert("left_iris_code3", query.value("left_iris_code3")); + item.insert("right_iris_code1", query.value("right_iris_code1")); + item.insert("right_iris_code2", query.value("right_iris_code2")); + item.insert("right_iris_code3", query.value("right_iris_code3")); + + result.append(item); + } + +// LOG_DEBUG(QString("查询IRIS_DATA表的所有记录[结果数:%1]").arg(result.size()).toStdString()); + return result; +} + +QVariantMap IrisDataDao::findRecordById(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM IRIS_DATA WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + // 获取结果 + if (query.next()) + { + result.insert("id", query.value("id").toString()); + result.insert("person_id", query.value("person_id").toLongLong()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("left_iris_code1", query.value("left_iris_code1")); + result.insert("left_iris_code2", query.value("left_iris_code2")); + result.insert("left_iris_code3", query.value("left_iris_code3")); + result.insert("right_iris_code1", query.value("right_iris_code1")); + result.insert("right_iris_code2", query.value("right_iris_code2")); + result.insert("right_iris_code3", query.value("right_iris_code3")); + } + +// LOG_DEBUG(QString("根据id查询IRIS_DATA表的记录[id=%1]").arg(id).toStdString()); + return result; +} + +QVariantMap IrisDataDao::findRecordByPersonId(QString personId) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM IRIS_DATA WHERE PERSON_ID = :personId"); + query.prepare(sql); + query.bindValue(":personId", personId); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + if (query.next()) + { + result.insert("id", query.value("id").toString()); + result.insert("person_id", query.value("person_id").toLongLong()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("left_iris_code1", query.value("left_iris_code1")); + result.insert("left_iris_code2", query.value("left_iris_code2")); + result.insert("left_iris_code3", query.value("left_iris_code3")); + result.insert("right_iris_code1", query.value("right_iris_code1")); + result.insert("right_iris_code2", query.value("right_iris_code2")); + result.insert("right_iris_code3", query.value("right_iris_code3")); + } + +// LOG_DEBUG(QString("根据personId查询IRIS_DATA表的记录[personId=%1]").arg(personId).toStdString()); + return result; +} + + +QString IrisDataDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + + // INSERT语句 + QString sql = QString("INSERT INTO IRIS_DATA (ID, PERSON_ID, ID_CARD_NO, LEFT_IRIS_CODE1, RIGHT_IRIS_CODE1) VALUES (:id, :personId, :idCardNo, :left1, :right1)"); + + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":personId", object.value("person_id").toString()); + query.bindValue(":idCardNo", object.value("id_card_no").toString()); + query.bindValue(":left1", object.value("left_iris_code1")); + query.bindValue(":right1", object.value("right_iris_code1")); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(); + +// LOG_DEBUG(QString("保存虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool IrisDataDao::edit(QVariantMap newObject, QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // UPDATE语句 + if (!newObject.contains("left_iris_code1") || !newObject.contains("right_iris_code1")){ + return false; + } + QString sql = QString("UPDATE IRIS_DATA SET LEFT_IRIS_CODE1 = :left1, RIGHT_IRIS_CODE1 = :right1 WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":left1", newObject.value("left_iris_code1")); + query.bindValue(":right1", newObject.value("right_iris_code1")); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(); + +// LOG_DEBUG(QString("编辑虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; +} + + +bool IrisDataDao::dele(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + QString sql = QString("DELETE FROM IRIS_DATA WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(); + +// LOG_DEBUG(QString("删除虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; +} diff --git a/dao/IrisDataDao.h b/dao/IrisDataDao.h new file mode 100644 index 0000000..c74dbbd --- /dev/null +++ b/dao/IrisDataDao.h @@ -0,0 +1,25 @@ +#ifndef IRISDATADAO_H +#define IRISDATADAO_H + +#include +#include "BaseDao.h" + +class IrisDataDao : public BaseDao +{ + Q_OBJECT +public: + explicit IrisDataDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + QVariantMap findRecordByPersonId(QString personId); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +signals: + +}; + +#endif // IRISDATADAO_H diff --git a/dao/RecognitionRecordsDao.cpp b/dao/RecognitionRecordsDao.cpp new file mode 100644 index 0000000..40db453 --- /dev/null +++ b/dao/RecognitionRecordsDao.cpp @@ -0,0 +1,100 @@ +#include "RecognitionRecordsDao.h" + +RecognitionRecordsDao::RecognitionRecordsDao(QObject *parent) : BaseDao(parent) +{ + +} + + +QVector RecognitionRecordsDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM RECOGNITION_RECORDS"; + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + item.insert("id", query.value("id").toLongLong()); + result.append(item); + } + +// LOG_DEBUG(QString("查询RECOGNITION_RECORDS表的所有记录[记录数:%1]").arg(result.size()).toStdString()); + return result; +} + +QVariantMap RecognitionRecordsDao::findRecordById(QString id) +{ + QVariantMap item; + return item; +} + +QString RecognitionRecordsDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + + // INSERT语句 + QString sql = QString("INSERT INTO RECOGNITION_RECORDS (ID, PERSON_ID, DATETIME, REC_TYPE, DEV_CODE, DOOR_CODE, INOUT_TYPE) " + "VALUES (:id, :personId, :datetime, :recType, :devCode, :doorCode, :inoutType)"); + + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":personId", object.value("person_id").toString()); + query.bindValue(":datetime", object.value("date_time").toString()); + query.bindValue(":recType", object.value("rec_type").toString()); + query.bindValue(":devCode", object.value("dev_code").toString()); + query.bindValue(":doorCode", object.value("door_code").toString()); + query.bindValue(":inoutType", object.value("inout_type").toString()); + +// LOG_DEBUG(sql.toStdString()); + + // 插入识别的log日志 + QString logStr = QString("INSERT INTO RECOGNITION_LOGS (ID, LOG_INFO) VALUES (:id, :logInfo)"); + + QSqlQuery logQuery(ConnectionManager::getInstance()->getConnection()); + logQuery.prepare(logStr); + logQuery.bindValue(":id", id); + logQuery.bindValue(":logInfo", object.value("debug_info").toString()); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(); + logQuery.exec(); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool RecognitionRecordsDao::edit(QVariantMap newObject, QString id) +{ + return false; +} + +bool RecognitionRecordsDao::dele(QString id) +{ + return false; +} diff --git a/dao/RecognitionRecordsDao.h b/dao/RecognitionRecordsDao.h new file mode 100644 index 0000000..38de7c9 --- /dev/null +++ b/dao/RecognitionRecordsDao.h @@ -0,0 +1,23 @@ +#ifndef RECOGNITIONRECORDSDAO_H +#define RECOGNITIONRECORDSDAO_H + +#include +#include "BaseDao.h" +class RecognitionRecordsDao: public BaseDao +{ + Q_OBJECT +public: + explicit RecognitionRecordsDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +signals: + +}; + +#endif // RECOGNITIONRECORDSDAO_H diff --git a/dao/SysDeptDao.cpp b/dao/SysDeptDao.cpp new file mode 100644 index 0000000..22f9946 --- /dev/null +++ b/dao/SysDeptDao.cpp @@ -0,0 +1,88 @@ +#include "SysDeptDao.h" + +SysDeptDao::SysDeptDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector SysDeptDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_DEPT WHERE PID != '-1' ORDER BY PID, NUM"; + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + item.insert("id", query.value("id").toString()); + item.insert("pid", query.value("pid").toString()); + item.insert("pids", query.value("pids").toString()); + item.insert("simplename", query.value("simplename").toString()); + item.insert("fullname", query.value("fullname").toString()); + } + +// LOG_TRACE(QString("查询表[SYS_DEPT]的所有记录[%1][%2]").arg(result.size()).arg(sql).toStdString()); + + return result; +} + +QVariantMap SysDeptDao::findRecordById(QString id) +{ + QVariantMap item; + return item; + + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM SYS_DEPT WHERE SYS_DEPT.ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + // 获取结果集的大小 + query.last(); + int count = query.at() + 1; + + if (count >=1) + { + query.first(); + + result.insert("id", query.value("id").toString()); + result.insert("pid", query.value("pid").toString()); + result.insert("pids", query.value("pids").toString()); + result.insert("simplename", query.value("simplename").toString()); + result.insert("fullname", query.value("fullname").toString()); + } + +// LOG_TRACE(QString("根据id查询SYS_DEPT表的记录[ID=%1][%2]").arg(id).arg(sql).toStdString()); + + return result; +} + + +QString SysDeptDao::save(QVariantMap object) +{ + return "0"; +} +bool SysDeptDao::edit(QVariantMap newObject, QString id) +{ + return true; +} +bool SysDeptDao::dele(QString id) +{ + return true; +} diff --git a/dao/SysDeptDao.h b/dao/SysDeptDao.h new file mode 100644 index 0000000..e07a09f --- /dev/null +++ b/dao/SysDeptDao.h @@ -0,0 +1,24 @@ +#ifndef SYSDEPTDAO_H +#define SYSDEPTDAO_H + +#include +#include "BaseDao.h" + +class SysDeptDao : public BaseDao +{ + Q_OBJECT +public: + explicit SysDeptDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +private: + +}; + +#endif // SYSDEPTDAO_H diff --git a/dao/SysPersonDao.cpp b/dao/SysPersonDao.cpp new file mode 100644 index 0000000..dd9480f --- /dev/null +++ b/dao/SysPersonDao.cpp @@ -0,0 +1,371 @@ +#include "SysPersonDao.h" + + +SysPersonDao::SysPersonDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector SysPersonDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0'"; + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + count++; + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + result.append(item); + } + +// LOG(TRACE) << QString("查询SYS_PERSON表的所有记录[%1]").arg(count).toStdString(); +// LOG_TRACE(QString("查询SYS_PERSON表的所有记录[%1]").arg(count).toStdString()); + + return result; +} + +QVariantMap SysPersonDao::findRecordById(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0' AND SYS_PERSON.ID = '%1'").arg(id); + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVariantMap result; + + // 获取结果集的大小 + query.last(); + int count = query.at() + 1; + + if (count >=1) + { + query.first(); + + result.insert("id", query.value("id").toString()); + result.insert("delflag", query.value("delflag").toString()); + result.insert("createtime", query.value("createtime").toString()); + result.insert("updatetime", query.value("updatetime").toString()); + result.insert("name", query.value("name").toString()); + result.insert("gender", query.value("gender").toString()); + result.insert("deptid", query.value("deptid").toString()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("remarks", query.value("remarks").toString()); + result.insert("person_code", query.value("person_code").toString()); + result.insert("deptname", query.value("fullname").toString()); + result.insert("sync_id", query.value("sync_id").toString()); + result.insert("hasFace", query.value("face_valid").toString()); + result.insert("hasIris", query.value("iris_valid").toString()); + } + +// LOG(TRACE) << QString("根据id查询SYS_PERSON表的记录[id=%1][%2]").arg(id).arg(sql).toStdString(); +// LOG_TRACE(QString("根据id查询SYS_PERSON表的记录[id=%1][%2]").arg(id).arg(sql).toStdString()); + + return result; +} + +int SysPersonDao::findRecordCountByNameAndDept(QString name, QString dept) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT COUNT(P.ID) AS RECCT FROM SYS_PERSON P LEFT JOIN SYS_DEPT D ON P.DEPTID = D.ID WHERE P.DELFLAG = '0'"; + if (name.isEmpty() == false) + { + sql += " AND P.NAME LIKE '%" + name + "%'"; + } + if (dept.isEmpty() == false && dept.indexOf("-1") < 0) + { + sql += QString(" AND ((P.DEPTID = '%1') OR (D.PIDS LIKE '%,%1,%'))").arg(dept); + } + + // 执行查询 + query.exec(sql); + + // 返回结果 + int result; + + // 遍历查询结果 + if (query.next()) { + result = query.value("RECCT").toInt(); + } + +// LOG(TRACE) << QString("根据姓名和部门查询SYS_PERSON记录总数[%1][%2]").arg(result).arg(sql).toStdString(); +// LOG_TRACE(QString("根据姓名和部门查询SYS_PERSON记录总数[%1][%2]").arg(result).arg(sql).toStdString()); + + return result; +} + +QVector SysPersonDao::findRecordsByNameAndDept(QString name, QString dept, qint8 limit, qint16 offset) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON P LEFT JOIN SYS_DEPT D ON P.DEPTID = D.ID WHERE P.DELFLAG = '0'"; + if (name.isEmpty() == false) + { + sql += " AND P.NAME LIKE '%" + name + "%'"; + } + if (dept.isEmpty() == false && dept.indexOf("-1") < 0) + { + sql += QString(" AND ((P.DEPTID = '%1') OR (D.PIDS LIKE '%,%1,%'))").arg(dept); + } + + sql += QString(" LIMIT %1 OFFSET %2").arg(limit).arg(offset); + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + count++; + + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + + result.append(item); + } + +// LOG(TRACE) << QString("根据姓名和部门分页查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString(); +// LOG_TRACE(QString("根据姓名和部门分页查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString()); + + return result; +} + +QVector SysPersonDao::findRecordsByProperties(QVariantMap conditions) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0'"; + QVariantMap::iterator it; + for (it = conditions.begin(); it != conditions.end(); it++) + { + sql += QString(" AND SYS_PERSON.%1 = %2").arg(it.key()).arg(it.value().toString()); + } + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + count++; + + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + + result.append(item); + } + +// LOG(TRACE) << QString("根据属性值查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString(); +// LOG_TRACE(QString("根据属性值查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString()); + + return result; +} + +QString SysPersonDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + + // INSERT语句 + QString sql = QString("INSERT INTO SYS_PERSON " + "(ID, DELFLAG, CREATETIME, UPDATETIME, " + "NAME, GENDER, DEPTID, ID_CARD_NO, " + "REMARKS, PERSON_CODE, SYNC_ID, FACE_VALID, IRIS_VALID) " + "VALUES ('%1', '0', '%2', '%2', '%3', '%4', '%5', '%6', '%7', '%8', '%9', 0, 0)") + .arg(id).arg(tm) + .arg(object.value("name").toString()) + .arg(object.value("gender").toString()) + .arg(object.value("deptid").toString()) + .arg(object.value("id_card_no").toString()) + .arg(object.value("remarks").toString()) + .arg(object.value("person_code").toString()) + .arg(object.value("sync_id").toString()); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(sql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { +// LOG(DEBUG) << QString("保存SYS_PERSON记录成功[ID = %1][%2]").arg(id).arg(sql).toStdString(); +// LOG_DEBUG(QString("保存SYS_PERSON记录成功[ID = %1][%2]").arg(id).arg(sql).toStdString()); + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool SysPersonDao::edit(QVariantMap newObject, QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + + // UPDATE语句 + QString sql = QString("UPDATE SYS_PERSON SET UPDATETIME = '%1'").arg(tm); + if (newObject.contains("name")) + { + sql.append(QString(", NAME = '%1'").arg(newObject.value("name").toString())); + } + if (newObject.contains("gender")) + { + sql.append(QString(", GENDER = '%1'").arg(newObject.value("gender").toString())); + } + if (newObject.contains("deptid")) + { + sql.append(QString(", DEPTID = '%1'").arg(newObject.value("deptid").toString())); + } + if (newObject.contains("person_code")) + { + sql.append(QString(", PERSON_CODE = '%1'").arg(newObject.value("person_code").toString())); + } + if (newObject.contains("face_valid")) + { + sql.append(QString(", FACE_VALID = '%1'").arg(newObject.value("face_valid").toString())); + } + if (newObject.contains("iris_valid")) + { + sql.append(QString(", IRIS_VALID = '%1'").arg(newObject.value("iris_valid").toString())); + } + + sql.append(QString(" WHERE ID = '%1'").arg(id)); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(sql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + +// LOG(DEBUG) << QString("编辑人员[ID=%1][%2]").arg(id).arg(sql).toStdString(); +// LOG_DEBUG(QString("编辑人员[ID=%1][%2]").arg(id).arg(sql).toStdString()); + + // 返回结果 + return success; +} + +bool SysPersonDao::dele(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + QSqlQuery irisDel(ConnectionManager::getInstance()->getConnection()); + + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + qint64 tmms = QDateTime::currentDateTime().toMSecsSinceEpoch(); + + // UPDATE语句 + QString sql = QString("UPDATE SYS_PERSON SET UPDATETIME = :updateTime, DELFLAG = :flag WHERE ID = :id").arg(tm).arg(tmms).arg(id); + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":updateTime", tm); + query.bindValue(":flag", tmms); + + // 物理删除人员的人脸和虹膜数据 + QString delIrisSql = QString("DELETE FROM IRIS_DATA WHERE PERSON_ID = :personId"); + irisDel.prepare(delIrisSql); + irisDel.bindValue(":personId", id); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(sql); + query.exec(delIrisSql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + +// LOG_DEBUG(QString("删除人员SYS_PERSON[ID=%1][%2]").arg(id).arg(success).toStdString()); + + // 返回结果 + return success; +} diff --git a/dao/SysPersonDao.h b/dao/SysPersonDao.h new file mode 100644 index 0000000..e02e5ba --- /dev/null +++ b/dao/SysPersonDao.h @@ -0,0 +1,27 @@ +#ifndef SYSPERSONDAO_H +#define SYSPERSONDAO_H + +#include +#include "BaseDao.h" + +class SysPersonDao : public BaseDao +{ + Q_OBJECT +public: + explicit SysPersonDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + int findRecordCountByNameAndDept(QString name, QString dept); + QVector findRecordsByNameAndDept(QString name, QString dept, qint8 limit, qint16 offset); + QVector findRecordsByProperties(QVariantMap conditions); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); +signals: + +}; + +#endif // SYSPERSONDAO_H diff --git a/dao/dao.pri b/dao/dao.pri new file mode 100644 index 0000000..1e04ce4 --- /dev/null +++ b/dao/dao.pri @@ -0,0 +1,18 @@ + +HEADERS += $$PWD/BaseDao.h +HEADERS += $$PWD/IrisDataDao.h +HEADERS += $$PWD/RecognitionRecordsDao.h +HEADERS += $$PWD/SysPersonDao.h +HEADERS += $$PWD/SysDeptDao.h + +SOURCES += $$PWD/BaseDao.cpp +SOURCES += $$PWD/IrisDataDao.cpp +SOURCES += $$PWD/RecognitionRecordsDao.cpp +SOURCES += $$PWD/SysPersonDao.cpp +SOURCES += $$PWD/SysDeptDao.cpp + +HEADERS += $$PWD/util/ConnectionManager.h +SOURCES += $$PWD/util/ConnectionManager.cpp +#HEADERS += $$PWD/util/CacheManager.h +#SOURCES += $$PWD/util/CacheManager.cpp + diff --git a/dao/util/ConnectionManager.cpp b/dao/util/ConnectionManager.cpp new file mode 100644 index 0000000..84b17be --- /dev/null +++ b/dao/util/ConnectionManager.cpp @@ -0,0 +1,47 @@ +#include "ConnectionManager.h" +#include + +Q_GLOBAL_STATIC(ConnectionManager, cm) + +ConnectionManager::ConnectionManager(QObject *parent) : QObject(parent) +{ + // 初始化数据库连接 + if (QSqlDatabase::contains("qt_sql_dafault_connection")) + { + conn = QSqlDatabase::database("qt_sql_default_connection"); + } + else + { + conn = QSqlDatabase::addDatabase("QSQLITE"); + conn.setDatabaseName(QApplication::applicationDirPath() + "/data/casic.db"); + + bool succ = conn.open(); + if (succ == true) + { +// LOG_INFO(QString("打开数据库操作正常[Open Database Success]").toStdString()); + } else + { +// LOG_ERROR(QString("打开数据库操作失败[Open Database Failed]").toStdString()); + } + } +} + +ConnectionManager::~ConnectionManager() +{ + conn.close(); +} + +ConnectionManager* ConnectionManager::getInstance() +{ + return cm; +} + +QSqlDatabase ConnectionManager::getConnection() +{ + return this->conn; +} + +qint64 ConnectionManager::generateId() +{ + return this->idWorker.nextId(); +} diff --git a/dao/util/ConnectionManager.h b/dao/util/ConnectionManager.h new file mode 100644 index 0000000..84647e3 --- /dev/null +++ b/dao/util/ConnectionManager.h @@ -0,0 +1,34 @@ +#ifndef CONNECTIONMANAGER_H +#define CONNECTIONMANAGER_H + +#include +#include +#include "utils/id/IdWorker.h" +#include "utils/UtilInclude.h" + +using namespace Jiawa::Core; + +class ConnectionManager : public QObject +{ + Q_OBJECT +public: + explicit ConnectionManager(QObject *parent = nullptr); + ~ConnectionManager(); + + static ConnectionManager * getInstance(); + + QSqlDatabase getConnection(); + qint64 generateId(); + +private: + // 数据库连接 + QSqlDatabase conn; + + // 雪花id生成工具 + IdWorker &idWorker = Singleton::instance(); + +signals: + +}; + +#endif // CONNECTIONMANAGER_H diff --git a/device/IrisCameraCapEventHandler.cpp b/device/IrisCameraCapEventHandler.cpp new file mode 100644 index 0000000..45df089 --- /dev/null +++ b/device/IrisCameraCapEventHandler.cpp @@ -0,0 +1,103 @@ +#include "IrisCameraCapEventHandler.h" + +IrisCameraCapEventHandler::IrisCameraCapEventHandler(QObject *parent) : QObject(parent) +{ + +} + +void IrisCameraCapEventHandler::DoOnImageCaptured(CImageDataPointer &objImageDataPointer, void *pUserParam) +{ + if (objImageDataPointer.IsNull() == false) + { + CGXDevicePointer* cam = (CGXDevicePointer *) pUserParam; + + auto camName = cam->getPtr()->GetDeviceInfo().GetUserID(); + int width = objImageDataPointer->GetWidth(); + int height = objImageDataPointer->GetHeight(); + size_t leftKeyIndex = camName.find("left"); + size_t rightKeyIndex = camName.find("right"); + + uchar * pBuffer = (BYTE*)objImageDataPointer->GetBuffer(); + + // 相机拍摄下的图像1440*1080, 直接用于算法判断 + QImage img = QImage(pBuffer, width, height, QImage::Format_Grayscale8); // 用于展示 +// QImage imgAlgo = img.copy(0, 0, width, height); + + // 用于显示的图像需要缩小到400 * 300的尺寸 + img = img.scaled(SettingConfig::getInstance().IRIS_DISPLAY_HEIGHT, SettingConfig::getInstance().IRIS_DISPLAY_WIDTH); + img = img.transformed(QTransform().rotate(-90)); // 图像逆时针旋转90度 + + // 发送到界面进行显示 + emit sendIrisFrameToDraw(img); +// cv::Mat irisMat = ImageUtil::QImageToMat(imgAlgo); + +// irisInfo.data = imgAlgo; +// irisInfo.matData = irisMat; + +// // 将图像显示在注册页面的label上 +// // 并将虹膜信息对象存入队列中 +// ProMemory::getInstance().pushCasicIris(irisInfo); + +// if (leftKeyIndex >= 0 && leftKeyIndex < 32) +// { +// emit sendIrisFrameToDraw(img, 0); // 左眼画面 +// } else if (rightKeyIndex >= 0 && rightKeyIndex < 32) +// { +// emit sendIrisFrameToDraw(img, 1); // 右眼画面 +// } +/* + if (pBuffer != NULL) + { + // 创建虹膜信息对象 + CasicIrisInfo irisInfo; + irisInfo.hasEye = false; + if (leftKeyIndex >= 0 && leftKeyIndex < 32) + { + // 左眼相机拍摄的图像 + irisInfo.leftOrRight = "left"; + } else if (rightKeyIndex >= 0 && rightKeyIndex < 32) + { + // 右眼相机 + irisInfo.leftOrRight = "right"; + } + + if (ProMemory::getInstance().widgeFrame == CasicBioRecConst::RECOGNIZE_RESULT_FORM) + { + // 相机拍摄下的图像1280*960, 直接用于算法判断 + QImage imgDisp = QImage(pBuffer, width, height, QImage::Format_Grayscale8); + cv::Mat irisMat = ImageUtil::QImageToMat(imgDisp); + + irisInfo.data = imgDisp; + irisInfo.matData = irisMat; + + ProMemory::getInstance().pushCasicIris(irisInfo); + +// cv::imwrite(QString("D:\\irisLogs\\iristest-%1.bmp").arg(irisInfo.leftOrRight).toStdString(), irisMat); + } else if (ProMemory::getInstance().widgeFrame == CasicBioRecConst::ADD_PERSON_CAPTURE_IRIS) + { + // 相机拍摄下的图像1280*960, 直接用于算法判断 + QImage img = QImage(pBuffer, width, height, QImage::Format_Grayscale8); + QImage imgAlgo = img.copy(0, 0, width, height); + + // 用于显示的图像需要缩小到1/4的尺寸 + img = img.scaled(640, 480); + cv::Mat irisMat = ImageUtil::QImageToMat(imgAlgo); + + irisInfo.data = imgAlgo; + irisInfo.matData = irisMat; + + // 将图像显示在注册页面的label上 + // 并将虹膜信息对象存入队列中 + ProMemory::getInstance().pushCasicIris(irisInfo); + + if (leftKeyIndex >= 0 && leftKeyIndex < 32) + { + emit sendIrisFrameToDraw(img, 0); // 左眼画面 + } else if (rightKeyIndex >= 0 && rightKeyIndex < 32) + { + emit sendIrisFrameToDraw(img, 1); // 右眼画面 + } + } + }*/ + } +} diff --git a/device/IrisCameraCapEventHandler.h b/device/IrisCameraCapEventHandler.h new file mode 100644 index 0000000..ad75a97 --- /dev/null +++ b/device/IrisCameraCapEventHandler.h @@ -0,0 +1,30 @@ +#ifndef IRISCAMERACAPEVENTHANDLER_H +#define IRISCAMERACAPEVENTHANDLER_H + +#include +#include +#include "include/opencv2/opencv.hpp" +#include "include/daheng/GalaxyIncludes.h" + +//#include "casic/iris/CasicIrisInterface.h" +#include "ProMemory.h" + +#include "utils/UtilInclude.h" + +class IrisCameraCapEventHandler : public QObject, public ICaptureEventHandler +{ + Q_OBJECT +public: + explicit IrisCameraCapEventHandler(QObject *parent = nullptr); + + void DoOnImageCaptured(CImageDataPointer &objImageDataPointer, void *pUserParam); + +private: + unsigned char* pImageBuffer; + +signals: + void sendIrisFrameToDraw(QImage irisImage); + +}; + +#endif // IRISCAMERACAPEVENTHANDLER_H diff --git a/device/IrisCameraController.cpp b/device/IrisCameraController.cpp new file mode 100644 index 0000000..0928176 --- /dev/null +++ b/device/IrisCameraController.cpp @@ -0,0 +1,110 @@ +#include "IrisCameraController.h" + +IrisCameraController::IrisCameraController(QObject *parent) : QObject(parent) +{ + this->irisCamHandler = new IrisCameraCapEventHandler(this); +} +IrisCameraController::~IrisCameraController() +{ + this->closeIrisCamera(); +} + + +void IrisCameraController::initIrisCamera() +{ + IGXFactory::GetInstance().Init(); + + //枚举设备 + IGXFactory::GetInstance().UpdateDeviceList(1000, irisCamList); + + this->OpenDevice(); +} + +void IrisCameraController::openIrisCamera() +{ + //设置Buffer处理模式 + irisStreamFeaturePtr->GetEnumFeature("StreamBufferHandlingMode")->SetValue("OldestFirst"); + + //注册回调函数 + irisStreamPtr->RegisterCaptureCallback(irisCamHandler, &irisCamPtr); + + //开启流层通道 + irisStreamPtr->StartGrab(); + + //发送开采命令 + irisFeaturePtr->GetCommandFeature("AcquisitionStart")->Execute(); + + // 启动定时器 + TimeCounterUtil::getInstance().irisCapCounter->start(SettingConfig::getInstance().IRIS_FRAME_INTERVAL); // 50ms执行一次定时器 +} + +void IrisCameraController::closeIrisCamera() +{ + +} + +void IrisCameraController::startCapture() +{ + // 获取定时器, 绑定定时函数 + connect(TimeCounterUtil::getInstance().irisCapCounter, &QTimer::timeout, this, &IrisCameraController::getOneFaceFrm); +// LOG(DEBUG) << QString("[IrisCameraController][startCapture]虹膜相机拍图").toStdString(); +// LOG_DEBUG(QString("[IrisCameraController][startCapture]虹膜相机拍图").toStdString()); + +} +void IrisCameraController::stopCapture() +{ + // 获取定时器, 绑定定时函数 + disconnect(TimeCounterUtil::getInstance().irisCapCounter, &QTimer::timeout, this, &IrisCameraController::getOneFaceFrm); +// LOG(DEBUG) << QString("[IrisCameraController][stopCapture]虹膜相机停止拍图").toStdString(); +// LOG_DEBUG(QString("[IrisCameraController][stopCapture]虹膜相机停止拍图").toStdString()); + +} + +void IrisCameraController::getOneFaceFrm() +{ + // 发送软触发命令(在触发模式开启时有效) + irisFeaturePtr->GetCommandFeature("TriggerSoftware")->Execute(); +} + +void IrisCameraController::getLeftAndRightEyeFrame() +{ + irisFeaturePtr->GetCommandFeature("TriggerSoftware")->Execute(); +} + +void IrisCameraController::OpenDevice() +{ + auto device = irisCamList.at(0); + + irisCamPtr = IGXFactory::GetInstance().OpenDeviceByUserID(device.GetUserID(), GX_ACCESS_EXCLUSIVE); + irisFeaturePtr = irisCamPtr->GetRemoteFeatureControl(); + + // 判断设备流是否大于零, 如果大于零则打开流 + int nStreamCount = irisCamPtr->GetStreamCount(); + if (nStreamCount > 0) + { + irisStreamPtr = irisCamPtr->OpenStream(0); + irisStreamFeaturePtr = irisStreamPtr->GetFeatureControl(); + } + + // 建议用户在打开网络相机之后, 根据当前网络环境设置相机的流通道包长值, + // 以提高网络相机的采集性能, 设置方法参考以下代码。 + GX_DEVICE_CLASS_LIST objDeviceClass = irisCamPtr->GetDeviceInfo().GetDeviceClass(); + if(GX_DEVICE_CLASS_GEV == objDeviceClass) + { + // 判断设备是否支持流通道数据包功能 + if(true == irisFeaturePtr->IsImplemented("GevSCPSPacketSize")) + { + // 获取当前网络环境的最优包长值 + int nPacketSize = irisStreamPtr->GetOptimalPacketSize(); + // 将最优包长值设置为当前设备的流通道包长值 + irisFeaturePtr->GetIntFeature("GevSCPSPacketSize")->SetValue(nPacketSize); + } + } + + //设置采集模式为连续采集模式 + irisFeaturePtr->GetEnumFeature("AcquisitionMode")->SetValue("Continuous"); + + //设置触发模式关 + irisFeaturePtr->GetEnumFeature("TriggerMode")->SetValue("On"); + irisFeaturePtr->GetEnumFeature("TriggerSource")->SetValue("Software"); +} diff --git a/device/IrisCameraController.h b/device/IrisCameraController.h new file mode 100644 index 0000000..5d7e269 --- /dev/null +++ b/device/IrisCameraController.h @@ -0,0 +1,49 @@ +#ifndef IRISCAMERACONTROLLER_H +#define IRISCAMERACONTROLLER_H + +#include + +#include "IrisCameraCapEventHandler.h" + +class IrisCameraCapEventHandler; + +class IrisCameraController : public QObject +{ + Q_OBJECT +public: + explicit IrisCameraController(QObject *parent = nullptr); + ~IrisCameraController(); + + // 初始化并打开人脸相机 + void initIrisCamera(); + void openIrisCamera(); + void closeIrisCamera(); + + void startCapture(); + void stopCapture(); + + void getLeftAndRightEyeFrame(); + + IrisCameraCapEventHandler * irisCamHandler; + +private: + GxIAPICPP::gxdeviceinfo_vector irisCamList; + + CGXDevicePointer irisCamPtr; ///< 设备句柄 + + CGXStreamPointer irisStreamPtr; ///< 左眼设备流 + + CGXFeatureControlPointer irisFeaturePtr; ///< 左眼属性控制器 + + CGXFeatureControlPointer irisStreamFeaturePtr; ///< 左眼流层控制器对象 + + void OpenDevice(); + +signals: + +public slots: + void getOneFaceFrm(); + +}; + +#endif // IRISCAMERACONTROLLER_H diff --git a/device/device.pri b/device/device.pri new file mode 100644 index 0000000..a8417f2 --- /dev/null +++ b/device/device.pri @@ -0,0 +1,13 @@ + +HEADERS += $$PWD/IrisCameraController.h +HEADERS += $$PWD/IrisCameraCapEventHandler.h +#HEADERS += $$PWD/iris/IrisRegistProcess.h +#HEADERS += $$PWD/iris/IrisRecogProcess.h +#HEADERS += $$PWD/iris/CasicIrisRecState.h + +SOURCES += $$PWD/IrisCameraController.cpp +SOURCES += $$PWD/IrisCameraCapEventHandler.cpp +#SOURCES += $$PWD/iris/IrisRegistProcess.cpp +#SOURCES += $$PWD/iris/IrisRecogProcess.cpp +#SOURCES += $$PWD/iris/CasicIrisRecState.cpp + diff --git a/images/bg_footer.png b/images/bg_footer.png new file mode 100644 index 0000000..a3a99ab --- /dev/null +++ b/images/bg_footer.png Binary files differ diff --git a/images/bg_statcked.png b/images/bg_statcked.png new file mode 100644 index 0000000..18b63e1 --- /dev/null +++ b/images/bg_statcked.png Binary files differ diff --git a/images/bg_title.png b/images/bg_title.png new file mode 100644 index 0000000..0316e2d --- /dev/null +++ b/images/bg_title.png Binary files differ diff --git a/main.cpp b/main.cpp index 16bc45b..9052ddb 100644 --- a/main.cpp +++ b/main.cpp @@ -1,11 +1,11 @@ -#include "IdentifyForm.h" +#include "MainWindowForm.h" #include int main(int argc, char *argv[]) { QApplication a(argc, argv); - IdentifyForm w; + MainWindowForm w; w.show(); return a.exec(); } diff --git a/resource.qrc b/resource.qrc new file mode 100644 index 0000000..474586a --- /dev/null +++ b/resource.qrc @@ -0,0 +1,35 @@ + + + images/setting.png + images/user.png + images/back.png + images/home.png + images/btnPageFirst.png + images/btnPageLast.png + images/btnPageNext.png + images/btnPagePre.png + images/regist.png + images/photoEyeLeft.png + images/photoEyeRight.png + images/photoFace.png + images/save.png + images/upArrow.png + images/downArrow.png + images/faceCaped.png + images/faceNotCap.png + images/irisCaped.png + images/irisNotCap.png + images/tipsFailure.png + images/tipsSuccess.png + images/tipsConfirm.png + images/bg_recognize_result.png + images/iconRetry.png + images/bg_title.png + images/bg_footer.png + images/bg_statcked.png + + + images/add_bottom.png + images/add_top.png + + diff --git a/utils/ImageUtil.cpp b/utils/ImageUtil.cpp new file mode 100644 index 0000000..7604572 --- /dev/null +++ b/utils/ImageUtil.cpp @@ -0,0 +1,97 @@ +#include "ImageUtil.h" + +ImageUtil::ImageUtil() +{ + +} + +QImage ImageUtil::MatImageToQImage(const cv::Mat &src) +{ + //CV_8UC1 8位无符号的单通道---灰度图片 + if(src.type() == CV_8UC1) + { + QImage qImage((const unsigned char *)(src.data), src.cols, src.rows, src.cols, QImage::Format_Grayscale8); + return qImage; + } + //为3通道的彩色图片 + else if(src.type() == CV_8UC3) + { + //得到图像的的首地址 + const uchar *pSrc = (const uchar*)src.data; + //以src构造图片 + QImage qImage(pSrc, src.cols, src.rows, src.step, QImage::Format_RGB888); + //在不改变实际图像数据的条件下, 交换红蓝通道 + return qImage.rgbSwapped(); + } + //四通道图片, 带Alpha通道的RGB彩色图像 + else if(src.type() == CV_8UC4) + { + const uchar *pSrc = (const uchar*)src.data; + QImage qImage(pSrc, src.cols, src.rows, src.step, QImage::Format_ARGB32); + //返回图像的子区域作为一个新图像 + return qImage.copy(); + } + else + { + return QImage(); + } +} +/* +QImage ImageUtil::UcharToQImage(unsigned char* data, int width, int height, QImage::Format format) +{ + QImage qImage(data, width, height, format); + //在不改变实际图像数据的条件下, 交换红蓝通道 + return qImage.rgbSwapped(); +} + +cv::Mat ImageUtil::QImageToMat(QImage image) +{ + cv::Mat mat; + switch(image.format()) + { + case QImage::Format_ARGB32: + case QImage::Format_RGB32: + case QImage::Format_ARGB32_Premultiplied: + mat = cv::Mat(image.height(), image.width(), CV_8UC4, (void*)image.constBits(), image.bytesPerLine()); + break; + case QImage::Format_RGB888: + mat = cv::Mat(image.height(), image.width(), CV_8UC3, (void*)image.constBits(), image.bytesPerLine()); + cv::cvtColor(mat, mat, cv::COLOR_BGR2RGB); + break; + case QImage::Format_Indexed8: + mat = cv::Mat(image.height(), image.width(), CV_8UC1, (void*)image.constBits(), image.bytesPerLine()); + break; + case QImage::Format_Grayscale8: + mat = cv::Mat(image.height(), image.width(), CV_8UC1, (void *)image.bits(), image.bytesPerLine()); + break; + } + + mat = mat.clone(); + + return mat; +} + +QString ImageUtil::QImageToBase64(QImage image) +{ + QByteArray ba; + QBuffer buf(&ba); + image.save(&buf, "bmp"); + QString base64String = ba.toBase64(); + return base64String; +} + +cv::Mat ImageUtil::MatImageRect(const cv::Mat &src, cv::Rect rect, int delta) +{ + cv::Mat matClone = src.clone(); + cv::Rect bigRect; + + bigRect.x = rect.x - delta < 0 ? 0 : rect.x - delta; + bigRect.y = rect.y - delta < 0 ? 0 : rect.y - delta; + bigRect.width = rect.x + rect.width + 2 * delta > src.cols ? src.cols - rect.x : rect.width + 2 * delta; + bigRect.height = rect.y + rect.height + 2 * delta > src.rows ? src.rows - rect.y : rect.height + 2 * delta; + + cv::Mat roi = matClone(bigRect); + + return roi; +} +*/ diff --git a/AppConstants.h b/AppConstants.h new file mode 100644 index 0000000..296c53f --- /dev/null +++ b/AppConstants.h @@ -0,0 +1,28 @@ +#ifndef APPCONSTANTS_H +#define APPCONSTANTS_H + +class AppConstants +{ +public: + enum WidgeFrameName + { + MAIN_PAGE = 0, // 主页面 + PERSON_LIST_FORM = 1, // 人员列表页面 + ADD_PERSON_FORM = 2, // 添加人员页面 + ADD_PERSON_CAPTURE_FACE = 21, // 添加/编辑人员时进行人脸拍图 + ADD_PERSON_CAPTURE_IRIS = 22, // 添加/编辑人员时进行虹膜拍图 + SETTING_FORM = 3, // 设置页面 + RECOGNIZE_RESULT_FORM = 4, // 识别结果界面 + IDENTIFY_FORM = 5, // 识别界面 含识别中 和 识别结果 + LOCKSCREEN_FORM = 6 // 锁屏待机界面 + }; + + enum ApplicationState + { + STATE_WAIT = 0, // 待机 + STATE_WORKING = 1, // 工作状态 + STATE_IDENTIFYING = 2, // 识别中 + }; +}; + +#endif // APPCONSTANTS_H diff --git a/CasicIrisIdentify.pro b/CasicIrisIdentify.pro index 5d7fea6..575ce3d 100644 --- a/CasicIrisIdentify.pro +++ b/CasicIrisIdentify.pro @@ -1,4 +1,4 @@ -QT += core gui +QT += core gui sql network texttospeech greaterThan(QT_MAJOR_VERSION, 4): QT += widgets @@ -15,20 +15,46 @@ # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 -SOURCES += \ - main.cpp \ - IdentifyForm.cpp +include("dao/dao.pri") +include("device/device.pri") +include("utils/utils.pri") -HEADERS += \ - IdentifyForm.h +SOURCES += main.cpp +SOURCES += ProMemory.cpp +SOURCES += MainWindowForm.cpp +SOURCES += IdentifyForm.cpp +SOURCES += LockScreenForm.cpp -FORMS += \ - IdentifyForm.ui +HEADERS += AppConstants.h +HEADERS += ProMemory.h +HEADERS += MainWindowForm.h +HEADERS += IdentifyForm.h +HEADERS += LockScreenForm.h -TRANSLATIONS += \ - CasicIrisIdentify_zh_CN.ts +FORMS += MainWindowForm.ui +FORMS += IdentifyForm.ui +FORMS += LockScreenForm.ui + +RESOURCES += resource.qrc + +DISTFILES += conf/config.ini + +#TRANSLATIONS += CasicIrisIdentify_zh_CN.ts + +#INCLUDEPATH += include/spdlog +#DEPENDPATH += include/spdlog # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target + + +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lopencv_world420 +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lGxIAPICPPEx + +INCLUDEPATH += $$PWD/include/daheng +DEPENDPATH += $$PWD/include/daheng + +INCLUDEPATH += $$PWD/include +DEPENDPATH += $$PWD/include diff --git a/CasicIrisIdentify_zh_CN.ts b/CasicIrisIdentify_zh_CN.ts index 5526fe4..81900df 100644 --- a/CasicIrisIdentify_zh_CN.ts +++ b/CasicIrisIdentify_zh_CN.ts @@ -1,3 +1,12 @@ - + + + IdentifyForm + + + IdentifyForm + + + + diff --git a/IdentifyForm.cpp b/IdentifyForm.cpp index 348a897..ba1f251 100644 --- a/IdentifyForm.cpp +++ b/IdentifyForm.cpp @@ -1,4 +1,4 @@ -#include "IdentifyForm.h" +#include "IdentifyForm.h" #include "ui_IdentifyForm.h" IdentifyForm::IdentifyForm(QWidget *parent) @@ -6,6 +6,12 @@ , ui(new Ui::IdentifyForm) { ui->setupUi(this); + + // 初始化更新界面的定时器 + // 每秒执行一次 + connect(TimeCounterUtil::getInstance().clockCounter, &QTimer::timeout, this, &IdentifyForm::updateDateAndTime); + + TimeCounterUtil::getInstance().clockCounter->start(1000); } IdentifyForm::~IdentifyForm() @@ -13,3 +19,16 @@ delete ui; } +void IdentifyForm::drawIrisImageOnFrame(QImage image) +{ + // 只在识别界面才显示画面 + if (ui->wgtStacked->currentIndex() == 0) { + ui->labelVideo->setPixmap(QPixmap::fromImage(image)); + } +} + + +void IdentifyForm::updateDateAndTime() +{ + ui->labelTime->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd dddd HH:mm:ss")); +} diff --git a/IdentifyForm.h b/IdentifyForm.h index fc857a1..ae1cd22 100644 --- a/IdentifyForm.h +++ b/IdentifyForm.h @@ -1,7 +1,10 @@ -#ifndef IDENTIFYFORM_H +#ifndef IDENTIFYFORM_H #define IDENTIFYFORM_H #include +#include + +#include "utils/UtilInclude.h" QT_BEGIN_NAMESPACE namespace Ui { class IdentifyForm; } @@ -15,7 +18,14 @@ IdentifyForm(QWidget *parent = nullptr); ~IdentifyForm(); +public slots: + void drawIrisImageOnFrame(QImage image); + private: Ui::IdentifyForm *ui; + +private slots: + void updateDateAndTime(); + }; #endif // IDENTIFYFORM_H diff --git a/IdentifyForm.ui b/IdentifyForm.ui index c72a36f..879dc9a 100644 --- a/IdentifyForm.ui +++ b/IdentifyForm.ui @@ -6,13 +6,59 @@ 0 0 - 800 + 600 600 IdentifyForm + + + + 0 + 40 + 600 + 450 + + + + 0 + + + + + + 100 + 10 + 400 + 300 + + + + + + + + + + + + + + 0 + 0 + 600 + 40 + + + + TextLabel + + + Qt::AlignCenter + + diff --git a/LockScreenForm.cpp b/LockScreenForm.cpp new file mode 100644 index 0000000..58dc54b --- /dev/null +++ b/LockScreenForm.cpp @@ -0,0 +1,14 @@ +#include "LockScreenForm.h" +#include "ui_LockScreenForm.h" + +LockScreenForm::LockScreenForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::LockScreenForm) +{ + ui->setupUi(this); +} + +LockScreenForm::~LockScreenForm() +{ + delete ui; +} diff --git a/LockScreenForm.h b/LockScreenForm.h new file mode 100644 index 0000000..b5ded48 --- /dev/null +++ b/LockScreenForm.h @@ -0,0 +1,25 @@ +#ifndef LOCKSCREENFORM_H +#define LOCKSCREENFORM_H + +#include +#include + +#include "utils/UtilInclude.h" + +namespace Ui { +class LockScreenForm; +} + +class LockScreenForm : public QWidget +{ + Q_OBJECT + +public: + explicit LockScreenForm(QWidget *parent = nullptr); + ~LockScreenForm(); + +private: + Ui::LockScreenForm *ui; +}; + +#endif // LOCKSCREENFORM_H diff --git a/LockScreenForm.ui b/LockScreenForm.ui new file mode 100644 index 0000000..7f2a6db --- /dev/null +++ b/LockScreenForm.ui @@ -0,0 +1,45 @@ + + + LockScreenForm + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + 180 + 100 + 54 + 12 + + + + TextLabel + + + + + + 180 + 160 + 54 + 12 + + + + TextLabel + + + + + + diff --git a/MainWindowForm.cpp b/MainWindowForm.cpp new file mode 100644 index 0000000..84f8159 --- /dev/null +++ b/MainWindowForm.cpp @@ -0,0 +1,86 @@ +#include "MainWindowForm.h" +#include "ui_MainWindowForm.h" +#include + +MainWindowForm::MainWindowForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::MainWindowForm) +{ + ui->setupUi(this); + + // 设置窗口透明和大小、位置 + this->setWindowFlags(Qt::FramelessWindowHint); + this->move(1400, 15); + this->resize(SettingConfig::getInstance().WINDOW_WIDTH, SettingConfig::getInstance().WINDOW_HEIGHT); + + // 通过调色板的颜色来设置窗口的统一背景色 + qApp->setPalette(QPalette(QColor(SettingConfig::getInstance().WINDOW_BACKGROUND_COLOR))); + + // 加载css文件设置控件样式 + QFile file(QApplication::applicationDirPath() + "/qss/main.css"); + if (file.open(QFile::ReadOnly)) + { + QString qssStr = QLatin1String(file.readAll()); + this->setStyleSheet(qssStr); + file.close(); + } + + initFormsPtr(); + + // 设置标题文字 + ui->labelTitle->setText(SettingConfig::getInstance().WINDOW_TITLE); + ui->labelCopyright->setText(SettingConfig::getInstance().WINDOW_RIGHTS); + ui->labelVersion->setText(SettingConfig::getInstance().WINDOW_VERSION); + + // 初始化虹膜相机控制 + ProMemory::getInstance().irisCam = new IrisCameraController(this); + ProMemory::getInstance().irisCam->initIrisCamera(); + ProMemory::getInstance().irisCam->openIrisCamera(); + connect(ProMemory::getInstance().irisCam->irisCamHandler, &IrisCameraCapEventHandler::sendIrisFrameToDraw, identifyForm, &IdentifyForm::drawIrisImageOnFrame); + +// LOG_INFO(QString("应用程序启动成功[Application Startup Success]").toStdString()); + qDebug() << "应用程序启动成功[Application Startup Success]"; + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::IDENTIFY_FORM; + ui->wdgtStatced->setCurrentWidget(identifyForm); + + // 开始虹膜相机拍图 + ProMemory::getInstance().irisCam->startCapture(); +} + +MainWindowForm::~MainWindowForm() +{ + delete ui; +} + +void MainWindowForm::lockScreen() +{ + ui->wdgtStatced->setCurrentWidget(lockScreenForm); + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::LOCKSCREEN_FORM; + ProMemory::getInstance().appState = AppConstants::ApplicationState::STATE_WAIT; +} + +void MainWindowForm::keyPressEvent(QKeyEvent *event) +{ + switch (event->key()) { + case Qt::Key_Escape: + QTimer::singleShot(100, qApp, [=](){ + QApplication::quit(); + }); + + default: + QWidget::keyPressEvent(event); + } +} + +void MainWindowForm::initFormsPtr() +{ + // 初始化各个form + lockScreenForm = new LockScreenForm(this); + identifyForm = new IdentifyForm(this); + + // 将form添加到statcked widget中 + ui->wdgtStatced->addWidget(identifyForm); + ui->wdgtStatced->addWidget(lockScreenForm); + + // 绑定按钮函数 +} diff --git a/MainWindowForm.h b/MainWindowForm.h new file mode 100644 index 0000000..7fb2d89 --- /dev/null +++ b/MainWindowForm.h @@ -0,0 +1,38 @@ +#ifndef MAINWINDOWFORM_H +#define MAINWINDOWFORM_H + +#include +#include +#include + +#include "utils/UtilInclude.h" +#include "ProMemory.h" +#include "LockScreenForm.h" +#include "IdentifyForm.h" + +namespace Ui { +class MainWindowForm; +} + +class MainWindowForm : public QWidget +{ + Q_OBJECT + +public: + explicit MainWindowForm(QWidget *parent = nullptr); + ~MainWindowForm(); + +public slots: + void lockScreen(); + +private: + Ui::MainWindowForm *ui; + LockScreenForm * lockScreenForm; + IdentifyForm * identifyForm; + + void keyPressEvent(QKeyEvent *event); + + void initFormsPtr(); +}; + +#endif // MAINWINDOWFORM_H diff --git a/MainWindowForm.ui b/MainWindowForm.ui new file mode 100644 index 0000000..e793ebf --- /dev/null +++ b/MainWindowForm.ui @@ -0,0 +1,85 @@ + + + MainWindowForm + + + + 0 + 0 + 600 + 1024 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + 0 + 0 + 600 + 84 + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + + + + TextLabel + + + Qt::AlignBottom|Qt::AlignHCenter + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + diff --git a/ProMemory.cpp b/ProMemory.cpp new file mode 100644 index 0000000..19e7403 --- /dev/null +++ b/ProMemory.cpp @@ -0,0 +1,84 @@ +#include "ProMemory.h" + +ProMemory::ProMemory() +{ + +} + +ProMemory::~ProMemory() +{ + +} + +/* +void ProMemory::pushCasicIris(CasicIrisInfo irisInfo) +{ + QMutex mutex; + mutex.lock(); + if (this->irisQueue.size() > 30) + { + QStack empty; + std::swap(empty, irisQueue); + } + + irisQueue.push(irisInfo); + mutex.unlock(); +} +CasicIrisInfo ProMemory::popCasicIris() +{ + CasicIrisInfo result; + + QMutex mutex; + mutex.lock(); + if (this->irisQueue.size() > 0) + { + result = irisQueue.pop(); + } + + mutex.unlock(); + + return result; +} +*/ +int ProMemory::getIrisQueueSize() +{ + int size = 0; + + QMutex mutex; + mutex.lock(); + +// size = this->irisQueue.size(); + + mutex.unlock(); + + return size; +} +bool ProMemory::isIrisQueueEmpty() +{ + bool empty = true; + + QMutex mutex; + mutex.lock(); + +// empty = this->irisQueue.isEmpty(); + + mutex.unlock(); + + return empty; +} +void ProMemory::clearIrisQueue() +{ + QMutex mutex; + mutex.lock(); + +// QStack empty; +// std::swap(empty, irisQueue); + + mutex.unlock(); +} + + +void ProMemory::initIrisFeatures(QString personId) +{ +// irisRegistPro->sendDataToExract(QByteArray(QString("[-u]").append(personId).toLocal8Bit())); +} diff --git a/ProMemory.h b/ProMemory.h new file mode 100644 index 0000000..2ecd653 --- /dev/null +++ b/ProMemory.h @@ -0,0 +1,52 @@ +#ifndef PROMEMORY_H +#define PROMEMORY_H + +#include +#include + +#include "AppConstants.h" +//#include "casic/iris/CasicIrisInfo.h" +#include "dao/IrisDataDao.h" + +#include "device/IrisCameraController.h" +//#include "device/iris/IrisRegistProcess.h" +//#include "device/iris/IrisRecogProcess.h" + +class IrisCameraController; +class IrisRegistProcess; +class IrisRecogProcess; + +class ProMemory +{ +public: + ~ProMemory(); + ProMemory(const ProMemory&)=delete; + ProMemory& operator=(const ProMemory&)=delete; + + static ProMemory& getInstance() { + static ProMemory instance; + return instance; + } + +// void pushCasicIris(CasicIrisInfo irisInfo); +// CasicIrisInfo popCasicIris(); + int getIrisQueueSize(); + bool isIrisQueueEmpty(); + void clearIrisQueue(); + + volatile int widgeFrame = 0; // 当前显示的界面 + volatile int appState = 0; // 当前程序所处的状态 + + void initIrisFeatures(QString personId = ""); // 初始化虹膜特征值集合 + + IrisCameraController * irisCam; + IrisRecogProcess * irisRecogPro; + +private: + ProMemory(); + +// QStack irisQueue; // 虹膜信息队列 + QVector irisFeatures; // 虹膜特征值集合 +}; + +#endif // PROMEMORY_H diff --git a/conf/config.ini b/conf/config.ini new file mode 100644 index 0000000..66e46ad --- /dev/null +++ b/conf/config.ini @@ -0,0 +1,67 @@ +[recognize] +#最大允许识别时间(ms) +maxMatchTime=10000 +#识别成功界面停留时间(ms) +successTipsLast=5000 +#识别失败界面停留时间(ms) +failureTipsLast=3000 +#人脸识别最大尝试次数 +maxFaceTryCount=20 +#持续没找到人脸的最大次数 +maxFaceNotFoundCount=500 +#注册时最小人脸 +minFaceRegist=240 +#识别时最小人脸 +minFaceRecog=100 + +#虹膜识别最大尝试次数 +maxIrisTryCount=10 +#虹膜识别持续没有找到眼的最大次数 +maxEyeNotFoundCount=50 + +#识别方式[1=人脸;2=虹膜;3=双认证;4=任意] +recogType=4 + +[window] +#界面窗口宽(px) +width=600 +#界面窗口高(px) +height=1024 +#统一背景色 +backgroundColor="#FFFFFF" +#标题 +title="虹膜识别终端" + +[work] +#工作状态检测时最小人脸范围 +minFaceSize=160 +#人脸范围最小横坐标 +minFacePosX=320 +#人脸范围最大横坐标 +maxFacePosX=960 +#人脸范围最小纵坐标 +minFacePosY=180 +#人脸范围最大纵坐标 +maxFacePosY=540 +#人脸太近阈值 +faceCloseSize=360 +#人脸太远阈值 +faceFarSize=480 + +[camera] +#虹膜相机取一幅画面的时间间隔(ms) +irisFrameInterval=100 +#虹膜相机拍摄宽度 +irisFrameWidth=1440 +#虹膜相机拍摄高度 +irisFrameHeight=1080 +#虹膜图像高度 +irisWidth=640 +#虹膜图像高度 +irisHeight=480 + +[log] +#日志文件位置 +logFile="d://irisLogs//casic_log.txt" +#日志级别 +logLevel="trace" diff --git a/dao/BaseDao.cpp b/dao/BaseDao.cpp new file mode 100644 index 0000000..f51c144 --- /dev/null +++ b/dao/BaseDao.cpp @@ -0,0 +1,12 @@ +#include "BaseDao.h" +#include "dao/util/ConnectionManager.h" + +BaseDao::BaseDao(QObject *parent) : QObject(parent) +{ + +} + +BaseDao::~BaseDao() +{ + +} diff --git a/dao/BaseDao.h b/dao/BaseDao.h new file mode 100644 index 0000000..1693c88 --- /dev/null +++ b/dao/BaseDao.h @@ -0,0 +1,32 @@ +#ifndef BASEDAO_H +#define BASEDAO_H + +#include +#include +#include +#include + +#include "dao/util/ConnectionManager.h" +#include "utils/UtilInclude.h" + +class BaseDao : public QObject +{ + Q_OBJECT +public: + explicit BaseDao(QObject *parent = nullptr); + ~BaseDao(); + + virtual QVector findAllRecord() = 0; + virtual QVariantMap findRecordById(QString id) = 0; + + virtual QString save(QVariantMap object) = 0; + virtual bool edit(QVariantMap newObject, QString id) = 0; + virtual bool dele(QString id) = 0; + +private: + +signals: + +}; + +#endif // BASEDAO_H diff --git a/dao/IrisDataDao.cpp b/dao/IrisDataDao.cpp new file mode 100644 index 0000000..37a0ed6 --- /dev/null +++ b/dao/IrisDataDao.cpp @@ -0,0 +1,204 @@ +#include "IrisDataDao.h" + +IrisDataDao::IrisDataDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector IrisDataDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM IRIS_DATA"; + query.prepare(sql); + + // 执行查询 + query.exec(); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + item.insert("id", query.value("id").toString()); + item.insert("person_id", query.value("person_id").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("left_iris_code1", query.value("left_iris_code1")); + item.insert("left_iris_code2", query.value("left_iris_code2")); + item.insert("left_iris_code3", query.value("left_iris_code3")); + item.insert("right_iris_code1", query.value("right_iris_code1")); + item.insert("right_iris_code2", query.value("right_iris_code2")); + item.insert("right_iris_code3", query.value("right_iris_code3")); + + result.append(item); + } + +// LOG_DEBUG(QString("查询IRIS_DATA表的所有记录[结果数:%1]").arg(result.size()).toStdString()); + return result; +} + +QVariantMap IrisDataDao::findRecordById(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM IRIS_DATA WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + // 获取结果 + if (query.next()) + { + result.insert("id", query.value("id").toString()); + result.insert("person_id", query.value("person_id").toLongLong()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("left_iris_code1", query.value("left_iris_code1")); + result.insert("left_iris_code2", query.value("left_iris_code2")); + result.insert("left_iris_code3", query.value("left_iris_code3")); + result.insert("right_iris_code1", query.value("right_iris_code1")); + result.insert("right_iris_code2", query.value("right_iris_code2")); + result.insert("right_iris_code3", query.value("right_iris_code3")); + } + +// LOG_DEBUG(QString("根据id查询IRIS_DATA表的记录[id=%1]").arg(id).toStdString()); + return result; +} + +QVariantMap IrisDataDao::findRecordByPersonId(QString personId) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM IRIS_DATA WHERE PERSON_ID = :personId"); + query.prepare(sql); + query.bindValue(":personId", personId); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + if (query.next()) + { + result.insert("id", query.value("id").toString()); + result.insert("person_id", query.value("person_id").toLongLong()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("left_iris_code1", query.value("left_iris_code1")); + result.insert("left_iris_code2", query.value("left_iris_code2")); + result.insert("left_iris_code3", query.value("left_iris_code3")); + result.insert("right_iris_code1", query.value("right_iris_code1")); + result.insert("right_iris_code2", query.value("right_iris_code2")); + result.insert("right_iris_code3", query.value("right_iris_code3")); + } + +// LOG_DEBUG(QString("根据personId查询IRIS_DATA表的记录[personId=%1]").arg(personId).toStdString()); + return result; +} + + +QString IrisDataDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + + // INSERT语句 + QString sql = QString("INSERT INTO IRIS_DATA (ID, PERSON_ID, ID_CARD_NO, LEFT_IRIS_CODE1, RIGHT_IRIS_CODE1) VALUES (:id, :personId, :idCardNo, :left1, :right1)"); + + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":personId", object.value("person_id").toString()); + query.bindValue(":idCardNo", object.value("id_card_no").toString()); + query.bindValue(":left1", object.value("left_iris_code1")); + query.bindValue(":right1", object.value("right_iris_code1")); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(); + +// LOG_DEBUG(QString("保存虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool IrisDataDao::edit(QVariantMap newObject, QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // UPDATE语句 + if (!newObject.contains("left_iris_code1") || !newObject.contains("right_iris_code1")){ + return false; + } + QString sql = QString("UPDATE IRIS_DATA SET LEFT_IRIS_CODE1 = :left1, RIGHT_IRIS_CODE1 = :right1 WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":left1", newObject.value("left_iris_code1")); + query.bindValue(":right1", newObject.value("right_iris_code1")); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(); + +// LOG_DEBUG(QString("编辑虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; +} + + +bool IrisDataDao::dele(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + QString sql = QString("DELETE FROM IRIS_DATA WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(); + +// LOG_DEBUG(QString("删除虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; +} diff --git a/dao/IrisDataDao.h b/dao/IrisDataDao.h new file mode 100644 index 0000000..c74dbbd --- /dev/null +++ b/dao/IrisDataDao.h @@ -0,0 +1,25 @@ +#ifndef IRISDATADAO_H +#define IRISDATADAO_H + +#include +#include "BaseDao.h" + +class IrisDataDao : public BaseDao +{ + Q_OBJECT +public: + explicit IrisDataDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + QVariantMap findRecordByPersonId(QString personId); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +signals: + +}; + +#endif // IRISDATADAO_H diff --git a/dao/RecognitionRecordsDao.cpp b/dao/RecognitionRecordsDao.cpp new file mode 100644 index 0000000..40db453 --- /dev/null +++ b/dao/RecognitionRecordsDao.cpp @@ -0,0 +1,100 @@ +#include "RecognitionRecordsDao.h" + +RecognitionRecordsDao::RecognitionRecordsDao(QObject *parent) : BaseDao(parent) +{ + +} + + +QVector RecognitionRecordsDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM RECOGNITION_RECORDS"; + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + item.insert("id", query.value("id").toLongLong()); + result.append(item); + } + +// LOG_DEBUG(QString("查询RECOGNITION_RECORDS表的所有记录[记录数:%1]").arg(result.size()).toStdString()); + return result; +} + +QVariantMap RecognitionRecordsDao::findRecordById(QString id) +{ + QVariantMap item; + return item; +} + +QString RecognitionRecordsDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + + // INSERT语句 + QString sql = QString("INSERT INTO RECOGNITION_RECORDS (ID, PERSON_ID, DATETIME, REC_TYPE, DEV_CODE, DOOR_CODE, INOUT_TYPE) " + "VALUES (:id, :personId, :datetime, :recType, :devCode, :doorCode, :inoutType)"); + + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":personId", object.value("person_id").toString()); + query.bindValue(":datetime", object.value("date_time").toString()); + query.bindValue(":recType", object.value("rec_type").toString()); + query.bindValue(":devCode", object.value("dev_code").toString()); + query.bindValue(":doorCode", object.value("door_code").toString()); + query.bindValue(":inoutType", object.value("inout_type").toString()); + +// LOG_DEBUG(sql.toStdString()); + + // 插入识别的log日志 + QString logStr = QString("INSERT INTO RECOGNITION_LOGS (ID, LOG_INFO) VALUES (:id, :logInfo)"); + + QSqlQuery logQuery(ConnectionManager::getInstance()->getConnection()); + logQuery.prepare(logStr); + logQuery.bindValue(":id", id); + logQuery.bindValue(":logInfo", object.value("debug_info").toString()); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(); + logQuery.exec(); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool RecognitionRecordsDao::edit(QVariantMap newObject, QString id) +{ + return false; +} + +bool RecognitionRecordsDao::dele(QString id) +{ + return false; +} diff --git a/dao/RecognitionRecordsDao.h b/dao/RecognitionRecordsDao.h new file mode 100644 index 0000000..38de7c9 --- /dev/null +++ b/dao/RecognitionRecordsDao.h @@ -0,0 +1,23 @@ +#ifndef RECOGNITIONRECORDSDAO_H +#define RECOGNITIONRECORDSDAO_H + +#include +#include "BaseDao.h" +class RecognitionRecordsDao: public BaseDao +{ + Q_OBJECT +public: + explicit RecognitionRecordsDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +signals: + +}; + +#endif // RECOGNITIONRECORDSDAO_H diff --git a/dao/SysDeptDao.cpp b/dao/SysDeptDao.cpp new file mode 100644 index 0000000..22f9946 --- /dev/null +++ b/dao/SysDeptDao.cpp @@ -0,0 +1,88 @@ +#include "SysDeptDao.h" + +SysDeptDao::SysDeptDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector SysDeptDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_DEPT WHERE PID != '-1' ORDER BY PID, NUM"; + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + item.insert("id", query.value("id").toString()); + item.insert("pid", query.value("pid").toString()); + item.insert("pids", query.value("pids").toString()); + item.insert("simplename", query.value("simplename").toString()); + item.insert("fullname", query.value("fullname").toString()); + } + +// LOG_TRACE(QString("查询表[SYS_DEPT]的所有记录[%1][%2]").arg(result.size()).arg(sql).toStdString()); + + return result; +} + +QVariantMap SysDeptDao::findRecordById(QString id) +{ + QVariantMap item; + return item; + + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM SYS_DEPT WHERE SYS_DEPT.ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + // 获取结果集的大小 + query.last(); + int count = query.at() + 1; + + if (count >=1) + { + query.first(); + + result.insert("id", query.value("id").toString()); + result.insert("pid", query.value("pid").toString()); + result.insert("pids", query.value("pids").toString()); + result.insert("simplename", query.value("simplename").toString()); + result.insert("fullname", query.value("fullname").toString()); + } + +// LOG_TRACE(QString("根据id查询SYS_DEPT表的记录[ID=%1][%2]").arg(id).arg(sql).toStdString()); + + return result; +} + + +QString SysDeptDao::save(QVariantMap object) +{ + return "0"; +} +bool SysDeptDao::edit(QVariantMap newObject, QString id) +{ + return true; +} +bool SysDeptDao::dele(QString id) +{ + return true; +} diff --git a/dao/SysDeptDao.h b/dao/SysDeptDao.h new file mode 100644 index 0000000..e07a09f --- /dev/null +++ b/dao/SysDeptDao.h @@ -0,0 +1,24 @@ +#ifndef SYSDEPTDAO_H +#define SYSDEPTDAO_H + +#include +#include "BaseDao.h" + +class SysDeptDao : public BaseDao +{ + Q_OBJECT +public: + explicit SysDeptDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +private: + +}; + +#endif // SYSDEPTDAO_H diff --git a/dao/SysPersonDao.cpp b/dao/SysPersonDao.cpp new file mode 100644 index 0000000..dd9480f --- /dev/null +++ b/dao/SysPersonDao.cpp @@ -0,0 +1,371 @@ +#include "SysPersonDao.h" + + +SysPersonDao::SysPersonDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector SysPersonDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0'"; + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + count++; + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + result.append(item); + } + +// LOG(TRACE) << QString("查询SYS_PERSON表的所有记录[%1]").arg(count).toStdString(); +// LOG_TRACE(QString("查询SYS_PERSON表的所有记录[%1]").arg(count).toStdString()); + + return result; +} + +QVariantMap SysPersonDao::findRecordById(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0' AND SYS_PERSON.ID = '%1'").arg(id); + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVariantMap result; + + // 获取结果集的大小 + query.last(); + int count = query.at() + 1; + + if (count >=1) + { + query.first(); + + result.insert("id", query.value("id").toString()); + result.insert("delflag", query.value("delflag").toString()); + result.insert("createtime", query.value("createtime").toString()); + result.insert("updatetime", query.value("updatetime").toString()); + result.insert("name", query.value("name").toString()); + result.insert("gender", query.value("gender").toString()); + result.insert("deptid", query.value("deptid").toString()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("remarks", query.value("remarks").toString()); + result.insert("person_code", query.value("person_code").toString()); + result.insert("deptname", query.value("fullname").toString()); + result.insert("sync_id", query.value("sync_id").toString()); + result.insert("hasFace", query.value("face_valid").toString()); + result.insert("hasIris", query.value("iris_valid").toString()); + } + +// LOG(TRACE) << QString("根据id查询SYS_PERSON表的记录[id=%1][%2]").arg(id).arg(sql).toStdString(); +// LOG_TRACE(QString("根据id查询SYS_PERSON表的记录[id=%1][%2]").arg(id).arg(sql).toStdString()); + + return result; +} + +int SysPersonDao::findRecordCountByNameAndDept(QString name, QString dept) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT COUNT(P.ID) AS RECCT FROM SYS_PERSON P LEFT JOIN SYS_DEPT D ON P.DEPTID = D.ID WHERE P.DELFLAG = '0'"; + if (name.isEmpty() == false) + { + sql += " AND P.NAME LIKE '%" + name + "%'"; + } + if (dept.isEmpty() == false && dept.indexOf("-1") < 0) + { + sql += QString(" AND ((P.DEPTID = '%1') OR (D.PIDS LIKE '%,%1,%'))").arg(dept); + } + + // 执行查询 + query.exec(sql); + + // 返回结果 + int result; + + // 遍历查询结果 + if (query.next()) { + result = query.value("RECCT").toInt(); + } + +// LOG(TRACE) << QString("根据姓名和部门查询SYS_PERSON记录总数[%1][%2]").arg(result).arg(sql).toStdString(); +// LOG_TRACE(QString("根据姓名和部门查询SYS_PERSON记录总数[%1][%2]").arg(result).arg(sql).toStdString()); + + return result; +} + +QVector SysPersonDao::findRecordsByNameAndDept(QString name, QString dept, qint8 limit, qint16 offset) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON P LEFT JOIN SYS_DEPT D ON P.DEPTID = D.ID WHERE P.DELFLAG = '0'"; + if (name.isEmpty() == false) + { + sql += " AND P.NAME LIKE '%" + name + "%'"; + } + if (dept.isEmpty() == false && dept.indexOf("-1") < 0) + { + sql += QString(" AND ((P.DEPTID = '%1') OR (D.PIDS LIKE '%,%1,%'))").arg(dept); + } + + sql += QString(" LIMIT %1 OFFSET %2").arg(limit).arg(offset); + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + count++; + + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + + result.append(item); + } + +// LOG(TRACE) << QString("根据姓名和部门分页查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString(); +// LOG_TRACE(QString("根据姓名和部门分页查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString()); + + return result; +} + +QVector SysPersonDao::findRecordsByProperties(QVariantMap conditions) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0'"; + QVariantMap::iterator it; + for (it = conditions.begin(); it != conditions.end(); it++) + { + sql += QString(" AND SYS_PERSON.%1 = %2").arg(it.key()).arg(it.value().toString()); + } + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + count++; + + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + + result.append(item); + } + +// LOG(TRACE) << QString("根据属性值查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString(); +// LOG_TRACE(QString("根据属性值查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString()); + + return result; +} + +QString SysPersonDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + + // INSERT语句 + QString sql = QString("INSERT INTO SYS_PERSON " + "(ID, DELFLAG, CREATETIME, UPDATETIME, " + "NAME, GENDER, DEPTID, ID_CARD_NO, " + "REMARKS, PERSON_CODE, SYNC_ID, FACE_VALID, IRIS_VALID) " + "VALUES ('%1', '0', '%2', '%2', '%3', '%4', '%5', '%6', '%7', '%8', '%9', 0, 0)") + .arg(id).arg(tm) + .arg(object.value("name").toString()) + .arg(object.value("gender").toString()) + .arg(object.value("deptid").toString()) + .arg(object.value("id_card_no").toString()) + .arg(object.value("remarks").toString()) + .arg(object.value("person_code").toString()) + .arg(object.value("sync_id").toString()); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(sql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { +// LOG(DEBUG) << QString("保存SYS_PERSON记录成功[ID = %1][%2]").arg(id).arg(sql).toStdString(); +// LOG_DEBUG(QString("保存SYS_PERSON记录成功[ID = %1][%2]").arg(id).arg(sql).toStdString()); + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool SysPersonDao::edit(QVariantMap newObject, QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + + // UPDATE语句 + QString sql = QString("UPDATE SYS_PERSON SET UPDATETIME = '%1'").arg(tm); + if (newObject.contains("name")) + { + sql.append(QString(", NAME = '%1'").arg(newObject.value("name").toString())); + } + if (newObject.contains("gender")) + { + sql.append(QString(", GENDER = '%1'").arg(newObject.value("gender").toString())); + } + if (newObject.contains("deptid")) + { + sql.append(QString(", DEPTID = '%1'").arg(newObject.value("deptid").toString())); + } + if (newObject.contains("person_code")) + { + sql.append(QString(", PERSON_CODE = '%1'").arg(newObject.value("person_code").toString())); + } + if (newObject.contains("face_valid")) + { + sql.append(QString(", FACE_VALID = '%1'").arg(newObject.value("face_valid").toString())); + } + if (newObject.contains("iris_valid")) + { + sql.append(QString(", IRIS_VALID = '%1'").arg(newObject.value("iris_valid").toString())); + } + + sql.append(QString(" WHERE ID = '%1'").arg(id)); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(sql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + +// LOG(DEBUG) << QString("编辑人员[ID=%1][%2]").arg(id).arg(sql).toStdString(); +// LOG_DEBUG(QString("编辑人员[ID=%1][%2]").arg(id).arg(sql).toStdString()); + + // 返回结果 + return success; +} + +bool SysPersonDao::dele(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + QSqlQuery irisDel(ConnectionManager::getInstance()->getConnection()); + + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + qint64 tmms = QDateTime::currentDateTime().toMSecsSinceEpoch(); + + // UPDATE语句 + QString sql = QString("UPDATE SYS_PERSON SET UPDATETIME = :updateTime, DELFLAG = :flag WHERE ID = :id").arg(tm).arg(tmms).arg(id); + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":updateTime", tm); + query.bindValue(":flag", tmms); + + // 物理删除人员的人脸和虹膜数据 + QString delIrisSql = QString("DELETE FROM IRIS_DATA WHERE PERSON_ID = :personId"); + irisDel.prepare(delIrisSql); + irisDel.bindValue(":personId", id); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(sql); + query.exec(delIrisSql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + +// LOG_DEBUG(QString("删除人员SYS_PERSON[ID=%1][%2]").arg(id).arg(success).toStdString()); + + // 返回结果 + return success; +} diff --git a/dao/SysPersonDao.h b/dao/SysPersonDao.h new file mode 100644 index 0000000..e02e5ba --- /dev/null +++ b/dao/SysPersonDao.h @@ -0,0 +1,27 @@ +#ifndef SYSPERSONDAO_H +#define SYSPERSONDAO_H + +#include +#include "BaseDao.h" + +class SysPersonDao : public BaseDao +{ + Q_OBJECT +public: + explicit SysPersonDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + int findRecordCountByNameAndDept(QString name, QString dept); + QVector findRecordsByNameAndDept(QString name, QString dept, qint8 limit, qint16 offset); + QVector findRecordsByProperties(QVariantMap conditions); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); +signals: + +}; + +#endif // SYSPERSONDAO_H diff --git a/dao/dao.pri b/dao/dao.pri new file mode 100644 index 0000000..1e04ce4 --- /dev/null +++ b/dao/dao.pri @@ -0,0 +1,18 @@ + +HEADERS += $$PWD/BaseDao.h +HEADERS += $$PWD/IrisDataDao.h +HEADERS += $$PWD/RecognitionRecordsDao.h +HEADERS += $$PWD/SysPersonDao.h +HEADERS += $$PWD/SysDeptDao.h + +SOURCES += $$PWD/BaseDao.cpp +SOURCES += $$PWD/IrisDataDao.cpp +SOURCES += $$PWD/RecognitionRecordsDao.cpp +SOURCES += $$PWD/SysPersonDao.cpp +SOURCES += $$PWD/SysDeptDao.cpp + +HEADERS += $$PWD/util/ConnectionManager.h +SOURCES += $$PWD/util/ConnectionManager.cpp +#HEADERS += $$PWD/util/CacheManager.h +#SOURCES += $$PWD/util/CacheManager.cpp + diff --git a/dao/util/ConnectionManager.cpp b/dao/util/ConnectionManager.cpp new file mode 100644 index 0000000..84b17be --- /dev/null +++ b/dao/util/ConnectionManager.cpp @@ -0,0 +1,47 @@ +#include "ConnectionManager.h" +#include + +Q_GLOBAL_STATIC(ConnectionManager, cm) + +ConnectionManager::ConnectionManager(QObject *parent) : QObject(parent) +{ + // 初始化数据库连接 + if (QSqlDatabase::contains("qt_sql_dafault_connection")) + { + conn = QSqlDatabase::database("qt_sql_default_connection"); + } + else + { + conn = QSqlDatabase::addDatabase("QSQLITE"); + conn.setDatabaseName(QApplication::applicationDirPath() + "/data/casic.db"); + + bool succ = conn.open(); + if (succ == true) + { +// LOG_INFO(QString("打开数据库操作正常[Open Database Success]").toStdString()); + } else + { +// LOG_ERROR(QString("打开数据库操作失败[Open Database Failed]").toStdString()); + } + } +} + +ConnectionManager::~ConnectionManager() +{ + conn.close(); +} + +ConnectionManager* ConnectionManager::getInstance() +{ + return cm; +} + +QSqlDatabase ConnectionManager::getConnection() +{ + return this->conn; +} + +qint64 ConnectionManager::generateId() +{ + return this->idWorker.nextId(); +} diff --git a/dao/util/ConnectionManager.h b/dao/util/ConnectionManager.h new file mode 100644 index 0000000..84647e3 --- /dev/null +++ b/dao/util/ConnectionManager.h @@ -0,0 +1,34 @@ +#ifndef CONNECTIONMANAGER_H +#define CONNECTIONMANAGER_H + +#include +#include +#include "utils/id/IdWorker.h" +#include "utils/UtilInclude.h" + +using namespace Jiawa::Core; + +class ConnectionManager : public QObject +{ + Q_OBJECT +public: + explicit ConnectionManager(QObject *parent = nullptr); + ~ConnectionManager(); + + static ConnectionManager * getInstance(); + + QSqlDatabase getConnection(); + qint64 generateId(); + +private: + // 数据库连接 + QSqlDatabase conn; + + // 雪花id生成工具 + IdWorker &idWorker = Singleton::instance(); + +signals: + +}; + +#endif // CONNECTIONMANAGER_H diff --git a/device/IrisCameraCapEventHandler.cpp b/device/IrisCameraCapEventHandler.cpp new file mode 100644 index 0000000..45df089 --- /dev/null +++ b/device/IrisCameraCapEventHandler.cpp @@ -0,0 +1,103 @@ +#include "IrisCameraCapEventHandler.h" + +IrisCameraCapEventHandler::IrisCameraCapEventHandler(QObject *parent) : QObject(parent) +{ + +} + +void IrisCameraCapEventHandler::DoOnImageCaptured(CImageDataPointer &objImageDataPointer, void *pUserParam) +{ + if (objImageDataPointer.IsNull() == false) + { + CGXDevicePointer* cam = (CGXDevicePointer *) pUserParam; + + auto camName = cam->getPtr()->GetDeviceInfo().GetUserID(); + int width = objImageDataPointer->GetWidth(); + int height = objImageDataPointer->GetHeight(); + size_t leftKeyIndex = camName.find("left"); + size_t rightKeyIndex = camName.find("right"); + + uchar * pBuffer = (BYTE*)objImageDataPointer->GetBuffer(); + + // 相机拍摄下的图像1440*1080, 直接用于算法判断 + QImage img = QImage(pBuffer, width, height, QImage::Format_Grayscale8); // 用于展示 +// QImage imgAlgo = img.copy(0, 0, width, height); + + // 用于显示的图像需要缩小到400 * 300的尺寸 + img = img.scaled(SettingConfig::getInstance().IRIS_DISPLAY_HEIGHT, SettingConfig::getInstance().IRIS_DISPLAY_WIDTH); + img = img.transformed(QTransform().rotate(-90)); // 图像逆时针旋转90度 + + // 发送到界面进行显示 + emit sendIrisFrameToDraw(img); +// cv::Mat irisMat = ImageUtil::QImageToMat(imgAlgo); + +// irisInfo.data = imgAlgo; +// irisInfo.matData = irisMat; + +// // 将图像显示在注册页面的label上 +// // 并将虹膜信息对象存入队列中 +// ProMemory::getInstance().pushCasicIris(irisInfo); + +// if (leftKeyIndex >= 0 && leftKeyIndex < 32) +// { +// emit sendIrisFrameToDraw(img, 0); // 左眼画面 +// } else if (rightKeyIndex >= 0 && rightKeyIndex < 32) +// { +// emit sendIrisFrameToDraw(img, 1); // 右眼画面 +// } +/* + if (pBuffer != NULL) + { + // 创建虹膜信息对象 + CasicIrisInfo irisInfo; + irisInfo.hasEye = false; + if (leftKeyIndex >= 0 && leftKeyIndex < 32) + { + // 左眼相机拍摄的图像 + irisInfo.leftOrRight = "left"; + } else if (rightKeyIndex >= 0 && rightKeyIndex < 32) + { + // 右眼相机 + irisInfo.leftOrRight = "right"; + } + + if (ProMemory::getInstance().widgeFrame == CasicBioRecConst::RECOGNIZE_RESULT_FORM) + { + // 相机拍摄下的图像1280*960, 直接用于算法判断 + QImage imgDisp = QImage(pBuffer, width, height, QImage::Format_Grayscale8); + cv::Mat irisMat = ImageUtil::QImageToMat(imgDisp); + + irisInfo.data = imgDisp; + irisInfo.matData = irisMat; + + ProMemory::getInstance().pushCasicIris(irisInfo); + +// cv::imwrite(QString("D:\\irisLogs\\iristest-%1.bmp").arg(irisInfo.leftOrRight).toStdString(), irisMat); + } else if (ProMemory::getInstance().widgeFrame == CasicBioRecConst::ADD_PERSON_CAPTURE_IRIS) + { + // 相机拍摄下的图像1280*960, 直接用于算法判断 + QImage img = QImage(pBuffer, width, height, QImage::Format_Grayscale8); + QImage imgAlgo = img.copy(0, 0, width, height); + + // 用于显示的图像需要缩小到1/4的尺寸 + img = img.scaled(640, 480); + cv::Mat irisMat = ImageUtil::QImageToMat(imgAlgo); + + irisInfo.data = imgAlgo; + irisInfo.matData = irisMat; + + // 将图像显示在注册页面的label上 + // 并将虹膜信息对象存入队列中 + ProMemory::getInstance().pushCasicIris(irisInfo); + + if (leftKeyIndex >= 0 && leftKeyIndex < 32) + { + emit sendIrisFrameToDraw(img, 0); // 左眼画面 + } else if (rightKeyIndex >= 0 && rightKeyIndex < 32) + { + emit sendIrisFrameToDraw(img, 1); // 右眼画面 + } + } + }*/ + } +} diff --git a/device/IrisCameraCapEventHandler.h b/device/IrisCameraCapEventHandler.h new file mode 100644 index 0000000..ad75a97 --- /dev/null +++ b/device/IrisCameraCapEventHandler.h @@ -0,0 +1,30 @@ +#ifndef IRISCAMERACAPEVENTHANDLER_H +#define IRISCAMERACAPEVENTHANDLER_H + +#include +#include +#include "include/opencv2/opencv.hpp" +#include "include/daheng/GalaxyIncludes.h" + +//#include "casic/iris/CasicIrisInterface.h" +#include "ProMemory.h" + +#include "utils/UtilInclude.h" + +class IrisCameraCapEventHandler : public QObject, public ICaptureEventHandler +{ + Q_OBJECT +public: + explicit IrisCameraCapEventHandler(QObject *parent = nullptr); + + void DoOnImageCaptured(CImageDataPointer &objImageDataPointer, void *pUserParam); + +private: + unsigned char* pImageBuffer; + +signals: + void sendIrisFrameToDraw(QImage irisImage); + +}; + +#endif // IRISCAMERACAPEVENTHANDLER_H diff --git a/device/IrisCameraController.cpp b/device/IrisCameraController.cpp new file mode 100644 index 0000000..0928176 --- /dev/null +++ b/device/IrisCameraController.cpp @@ -0,0 +1,110 @@ +#include "IrisCameraController.h" + +IrisCameraController::IrisCameraController(QObject *parent) : QObject(parent) +{ + this->irisCamHandler = new IrisCameraCapEventHandler(this); +} +IrisCameraController::~IrisCameraController() +{ + this->closeIrisCamera(); +} + + +void IrisCameraController::initIrisCamera() +{ + IGXFactory::GetInstance().Init(); + + //枚举设备 + IGXFactory::GetInstance().UpdateDeviceList(1000, irisCamList); + + this->OpenDevice(); +} + +void IrisCameraController::openIrisCamera() +{ + //设置Buffer处理模式 + irisStreamFeaturePtr->GetEnumFeature("StreamBufferHandlingMode")->SetValue("OldestFirst"); + + //注册回调函数 + irisStreamPtr->RegisterCaptureCallback(irisCamHandler, &irisCamPtr); + + //开启流层通道 + irisStreamPtr->StartGrab(); + + //发送开采命令 + irisFeaturePtr->GetCommandFeature("AcquisitionStart")->Execute(); + + // 启动定时器 + TimeCounterUtil::getInstance().irisCapCounter->start(SettingConfig::getInstance().IRIS_FRAME_INTERVAL); // 50ms执行一次定时器 +} + +void IrisCameraController::closeIrisCamera() +{ + +} + +void IrisCameraController::startCapture() +{ + // 获取定时器, 绑定定时函数 + connect(TimeCounterUtil::getInstance().irisCapCounter, &QTimer::timeout, this, &IrisCameraController::getOneFaceFrm); +// LOG(DEBUG) << QString("[IrisCameraController][startCapture]虹膜相机拍图").toStdString(); +// LOG_DEBUG(QString("[IrisCameraController][startCapture]虹膜相机拍图").toStdString()); + +} +void IrisCameraController::stopCapture() +{ + // 获取定时器, 绑定定时函数 + disconnect(TimeCounterUtil::getInstance().irisCapCounter, &QTimer::timeout, this, &IrisCameraController::getOneFaceFrm); +// LOG(DEBUG) << QString("[IrisCameraController][stopCapture]虹膜相机停止拍图").toStdString(); +// LOG_DEBUG(QString("[IrisCameraController][stopCapture]虹膜相机停止拍图").toStdString()); + +} + +void IrisCameraController::getOneFaceFrm() +{ + // 发送软触发命令(在触发模式开启时有效) + irisFeaturePtr->GetCommandFeature("TriggerSoftware")->Execute(); +} + +void IrisCameraController::getLeftAndRightEyeFrame() +{ + irisFeaturePtr->GetCommandFeature("TriggerSoftware")->Execute(); +} + +void IrisCameraController::OpenDevice() +{ + auto device = irisCamList.at(0); + + irisCamPtr = IGXFactory::GetInstance().OpenDeviceByUserID(device.GetUserID(), GX_ACCESS_EXCLUSIVE); + irisFeaturePtr = irisCamPtr->GetRemoteFeatureControl(); + + // 判断设备流是否大于零, 如果大于零则打开流 + int nStreamCount = irisCamPtr->GetStreamCount(); + if (nStreamCount > 0) + { + irisStreamPtr = irisCamPtr->OpenStream(0); + irisStreamFeaturePtr = irisStreamPtr->GetFeatureControl(); + } + + // 建议用户在打开网络相机之后, 根据当前网络环境设置相机的流通道包长值, + // 以提高网络相机的采集性能, 设置方法参考以下代码。 + GX_DEVICE_CLASS_LIST objDeviceClass = irisCamPtr->GetDeviceInfo().GetDeviceClass(); + if(GX_DEVICE_CLASS_GEV == objDeviceClass) + { + // 判断设备是否支持流通道数据包功能 + if(true == irisFeaturePtr->IsImplemented("GevSCPSPacketSize")) + { + // 获取当前网络环境的最优包长值 + int nPacketSize = irisStreamPtr->GetOptimalPacketSize(); + // 将最优包长值设置为当前设备的流通道包长值 + irisFeaturePtr->GetIntFeature("GevSCPSPacketSize")->SetValue(nPacketSize); + } + } + + //设置采集模式为连续采集模式 + irisFeaturePtr->GetEnumFeature("AcquisitionMode")->SetValue("Continuous"); + + //设置触发模式关 + irisFeaturePtr->GetEnumFeature("TriggerMode")->SetValue("On"); + irisFeaturePtr->GetEnumFeature("TriggerSource")->SetValue("Software"); +} diff --git a/device/IrisCameraController.h b/device/IrisCameraController.h new file mode 100644 index 0000000..5d7e269 --- /dev/null +++ b/device/IrisCameraController.h @@ -0,0 +1,49 @@ +#ifndef IRISCAMERACONTROLLER_H +#define IRISCAMERACONTROLLER_H + +#include + +#include "IrisCameraCapEventHandler.h" + +class IrisCameraCapEventHandler; + +class IrisCameraController : public QObject +{ + Q_OBJECT +public: + explicit IrisCameraController(QObject *parent = nullptr); + ~IrisCameraController(); + + // 初始化并打开人脸相机 + void initIrisCamera(); + void openIrisCamera(); + void closeIrisCamera(); + + void startCapture(); + void stopCapture(); + + void getLeftAndRightEyeFrame(); + + IrisCameraCapEventHandler * irisCamHandler; + +private: + GxIAPICPP::gxdeviceinfo_vector irisCamList; + + CGXDevicePointer irisCamPtr; ///< 设备句柄 + + CGXStreamPointer irisStreamPtr; ///< 左眼设备流 + + CGXFeatureControlPointer irisFeaturePtr; ///< 左眼属性控制器 + + CGXFeatureControlPointer irisStreamFeaturePtr; ///< 左眼流层控制器对象 + + void OpenDevice(); + +signals: + +public slots: + void getOneFaceFrm(); + +}; + +#endif // IRISCAMERACONTROLLER_H diff --git a/device/device.pri b/device/device.pri new file mode 100644 index 0000000..a8417f2 --- /dev/null +++ b/device/device.pri @@ -0,0 +1,13 @@ + +HEADERS += $$PWD/IrisCameraController.h +HEADERS += $$PWD/IrisCameraCapEventHandler.h +#HEADERS += $$PWD/iris/IrisRegistProcess.h +#HEADERS += $$PWD/iris/IrisRecogProcess.h +#HEADERS += $$PWD/iris/CasicIrisRecState.h + +SOURCES += $$PWD/IrisCameraController.cpp +SOURCES += $$PWD/IrisCameraCapEventHandler.cpp +#SOURCES += $$PWD/iris/IrisRegistProcess.cpp +#SOURCES += $$PWD/iris/IrisRecogProcess.cpp +#SOURCES += $$PWD/iris/CasicIrisRecState.cpp + diff --git a/images/bg_footer.png b/images/bg_footer.png new file mode 100644 index 0000000..a3a99ab --- /dev/null +++ b/images/bg_footer.png Binary files differ diff --git a/images/bg_statcked.png b/images/bg_statcked.png new file mode 100644 index 0000000..18b63e1 --- /dev/null +++ b/images/bg_statcked.png Binary files differ diff --git a/images/bg_title.png b/images/bg_title.png new file mode 100644 index 0000000..0316e2d --- /dev/null +++ b/images/bg_title.png Binary files differ diff --git a/main.cpp b/main.cpp index 16bc45b..9052ddb 100644 --- a/main.cpp +++ b/main.cpp @@ -1,11 +1,11 @@ -#include "IdentifyForm.h" +#include "MainWindowForm.h" #include int main(int argc, char *argv[]) { QApplication a(argc, argv); - IdentifyForm w; + MainWindowForm w; w.show(); return a.exec(); } diff --git a/resource.qrc b/resource.qrc new file mode 100644 index 0000000..474586a --- /dev/null +++ b/resource.qrc @@ -0,0 +1,35 @@ + + + images/setting.png + images/user.png + images/back.png + images/home.png + images/btnPageFirst.png + images/btnPageLast.png + images/btnPageNext.png + images/btnPagePre.png + images/regist.png + images/photoEyeLeft.png + images/photoEyeRight.png + images/photoFace.png + images/save.png + images/upArrow.png + images/downArrow.png + images/faceCaped.png + images/faceNotCap.png + images/irisCaped.png + images/irisNotCap.png + images/tipsFailure.png + images/tipsSuccess.png + images/tipsConfirm.png + images/bg_recognize_result.png + images/iconRetry.png + images/bg_title.png + images/bg_footer.png + images/bg_statcked.png + + + images/add_bottom.png + images/add_top.png + + diff --git a/utils/ImageUtil.cpp b/utils/ImageUtil.cpp new file mode 100644 index 0000000..7604572 --- /dev/null +++ b/utils/ImageUtil.cpp @@ -0,0 +1,97 @@ +#include "ImageUtil.h" + +ImageUtil::ImageUtil() +{ + +} + +QImage ImageUtil::MatImageToQImage(const cv::Mat &src) +{ + //CV_8UC1 8位无符号的单通道---灰度图片 + if(src.type() == CV_8UC1) + { + QImage qImage((const unsigned char *)(src.data), src.cols, src.rows, src.cols, QImage::Format_Grayscale8); + return qImage; + } + //为3通道的彩色图片 + else if(src.type() == CV_8UC3) + { + //得到图像的的首地址 + const uchar *pSrc = (const uchar*)src.data; + //以src构造图片 + QImage qImage(pSrc, src.cols, src.rows, src.step, QImage::Format_RGB888); + //在不改变实际图像数据的条件下, 交换红蓝通道 + return qImage.rgbSwapped(); + } + //四通道图片, 带Alpha通道的RGB彩色图像 + else if(src.type() == CV_8UC4) + { + const uchar *pSrc = (const uchar*)src.data; + QImage qImage(pSrc, src.cols, src.rows, src.step, QImage::Format_ARGB32); + //返回图像的子区域作为一个新图像 + return qImage.copy(); + } + else + { + return QImage(); + } +} +/* +QImage ImageUtil::UcharToQImage(unsigned char* data, int width, int height, QImage::Format format) +{ + QImage qImage(data, width, height, format); + //在不改变实际图像数据的条件下, 交换红蓝通道 + return qImage.rgbSwapped(); +} + +cv::Mat ImageUtil::QImageToMat(QImage image) +{ + cv::Mat mat; + switch(image.format()) + { + case QImage::Format_ARGB32: + case QImage::Format_RGB32: + case QImage::Format_ARGB32_Premultiplied: + mat = cv::Mat(image.height(), image.width(), CV_8UC4, (void*)image.constBits(), image.bytesPerLine()); + break; + case QImage::Format_RGB888: + mat = cv::Mat(image.height(), image.width(), CV_8UC3, (void*)image.constBits(), image.bytesPerLine()); + cv::cvtColor(mat, mat, cv::COLOR_BGR2RGB); + break; + case QImage::Format_Indexed8: + mat = cv::Mat(image.height(), image.width(), CV_8UC1, (void*)image.constBits(), image.bytesPerLine()); + break; + case QImage::Format_Grayscale8: + mat = cv::Mat(image.height(), image.width(), CV_8UC1, (void *)image.bits(), image.bytesPerLine()); + break; + } + + mat = mat.clone(); + + return mat; +} + +QString ImageUtil::QImageToBase64(QImage image) +{ + QByteArray ba; + QBuffer buf(&ba); + image.save(&buf, "bmp"); + QString base64String = ba.toBase64(); + return base64String; +} + +cv::Mat ImageUtil::MatImageRect(const cv::Mat &src, cv::Rect rect, int delta) +{ + cv::Mat matClone = src.clone(); + cv::Rect bigRect; + + bigRect.x = rect.x - delta < 0 ? 0 : rect.x - delta; + bigRect.y = rect.y - delta < 0 ? 0 : rect.y - delta; + bigRect.width = rect.x + rect.width + 2 * delta > src.cols ? src.cols - rect.x : rect.width + 2 * delta; + bigRect.height = rect.y + rect.height + 2 * delta > src.rows ? src.rows - rect.y : rect.height + 2 * delta; + + cv::Mat roi = matClone(bigRect); + + return roi; +} +*/ diff --git a/utils/ImageUtil.h b/utils/ImageUtil.h new file mode 100644 index 0000000..dbfdd48 --- /dev/null +++ b/utils/ImageUtil.h @@ -0,0 +1,22 @@ +#ifndef IMAGEUTIL_H +#define IMAGEUTIL_H + +#include +#include +#include "opencv2/opencv.hpp" + +class ImageUtil +{ +public: + ImageUtil(); + + static QImage MatImageToQImage(const cv::Mat &src); +// static QImage UcharToQImage(unsigned char* data, int width, int height, QImage::Format format); + +// static cv::Mat QImageToMat(QImage image); +// static QString QImageToBase64(QImage image); + +// static cv::Mat MatImageRect(const cv::Mat &src, cv::Rect rect, int delta); +}; + +#endif // IMAGEUTIL_H diff --git a/AppConstants.h b/AppConstants.h new file mode 100644 index 0000000..296c53f --- /dev/null +++ b/AppConstants.h @@ -0,0 +1,28 @@ +#ifndef APPCONSTANTS_H +#define APPCONSTANTS_H + +class AppConstants +{ +public: + enum WidgeFrameName + { + MAIN_PAGE = 0, // 主页面 + PERSON_LIST_FORM = 1, // 人员列表页面 + ADD_PERSON_FORM = 2, // 添加人员页面 + ADD_PERSON_CAPTURE_FACE = 21, // 添加/编辑人员时进行人脸拍图 + ADD_PERSON_CAPTURE_IRIS = 22, // 添加/编辑人员时进行虹膜拍图 + SETTING_FORM = 3, // 设置页面 + RECOGNIZE_RESULT_FORM = 4, // 识别结果界面 + IDENTIFY_FORM = 5, // 识别界面 含识别中 和 识别结果 + LOCKSCREEN_FORM = 6 // 锁屏待机界面 + }; + + enum ApplicationState + { + STATE_WAIT = 0, // 待机 + STATE_WORKING = 1, // 工作状态 + STATE_IDENTIFYING = 2, // 识别中 + }; +}; + +#endif // APPCONSTANTS_H diff --git a/CasicIrisIdentify.pro b/CasicIrisIdentify.pro index 5d7fea6..575ce3d 100644 --- a/CasicIrisIdentify.pro +++ b/CasicIrisIdentify.pro @@ -1,4 +1,4 @@ -QT += core gui +QT += core gui sql network texttospeech greaterThan(QT_MAJOR_VERSION, 4): QT += widgets @@ -15,20 +15,46 @@ # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 -SOURCES += \ - main.cpp \ - IdentifyForm.cpp +include("dao/dao.pri") +include("device/device.pri") +include("utils/utils.pri") -HEADERS += \ - IdentifyForm.h +SOURCES += main.cpp +SOURCES += ProMemory.cpp +SOURCES += MainWindowForm.cpp +SOURCES += IdentifyForm.cpp +SOURCES += LockScreenForm.cpp -FORMS += \ - IdentifyForm.ui +HEADERS += AppConstants.h +HEADERS += ProMemory.h +HEADERS += MainWindowForm.h +HEADERS += IdentifyForm.h +HEADERS += LockScreenForm.h -TRANSLATIONS += \ - CasicIrisIdentify_zh_CN.ts +FORMS += MainWindowForm.ui +FORMS += IdentifyForm.ui +FORMS += LockScreenForm.ui + +RESOURCES += resource.qrc + +DISTFILES += conf/config.ini + +#TRANSLATIONS += CasicIrisIdentify_zh_CN.ts + +#INCLUDEPATH += include/spdlog +#DEPENDPATH += include/spdlog # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target + + +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lopencv_world420 +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lGxIAPICPPEx + +INCLUDEPATH += $$PWD/include/daheng +DEPENDPATH += $$PWD/include/daheng + +INCLUDEPATH += $$PWD/include +DEPENDPATH += $$PWD/include diff --git a/CasicIrisIdentify_zh_CN.ts b/CasicIrisIdentify_zh_CN.ts index 5526fe4..81900df 100644 --- a/CasicIrisIdentify_zh_CN.ts +++ b/CasicIrisIdentify_zh_CN.ts @@ -1,3 +1,12 @@ - + + + IdentifyForm + + + IdentifyForm + + + + diff --git a/IdentifyForm.cpp b/IdentifyForm.cpp index 348a897..ba1f251 100644 --- a/IdentifyForm.cpp +++ b/IdentifyForm.cpp @@ -1,4 +1,4 @@ -#include "IdentifyForm.h" +#include "IdentifyForm.h" #include "ui_IdentifyForm.h" IdentifyForm::IdentifyForm(QWidget *parent) @@ -6,6 +6,12 @@ , ui(new Ui::IdentifyForm) { ui->setupUi(this); + + // 初始化更新界面的定时器 + // 每秒执行一次 + connect(TimeCounterUtil::getInstance().clockCounter, &QTimer::timeout, this, &IdentifyForm::updateDateAndTime); + + TimeCounterUtil::getInstance().clockCounter->start(1000); } IdentifyForm::~IdentifyForm() @@ -13,3 +19,16 @@ delete ui; } +void IdentifyForm::drawIrisImageOnFrame(QImage image) +{ + // 只在识别界面才显示画面 + if (ui->wgtStacked->currentIndex() == 0) { + ui->labelVideo->setPixmap(QPixmap::fromImage(image)); + } +} + + +void IdentifyForm::updateDateAndTime() +{ + ui->labelTime->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd dddd HH:mm:ss")); +} diff --git a/IdentifyForm.h b/IdentifyForm.h index fc857a1..ae1cd22 100644 --- a/IdentifyForm.h +++ b/IdentifyForm.h @@ -1,7 +1,10 @@ -#ifndef IDENTIFYFORM_H +#ifndef IDENTIFYFORM_H #define IDENTIFYFORM_H #include +#include + +#include "utils/UtilInclude.h" QT_BEGIN_NAMESPACE namespace Ui { class IdentifyForm; } @@ -15,7 +18,14 @@ IdentifyForm(QWidget *parent = nullptr); ~IdentifyForm(); +public slots: + void drawIrisImageOnFrame(QImage image); + private: Ui::IdentifyForm *ui; + +private slots: + void updateDateAndTime(); + }; #endif // IDENTIFYFORM_H diff --git a/IdentifyForm.ui b/IdentifyForm.ui index c72a36f..879dc9a 100644 --- a/IdentifyForm.ui +++ b/IdentifyForm.ui @@ -6,13 +6,59 @@ 0 0 - 800 + 600 600 IdentifyForm + + + + 0 + 40 + 600 + 450 + + + + 0 + + + + + + 100 + 10 + 400 + 300 + + + + + + + + + + + + + + 0 + 0 + 600 + 40 + + + + TextLabel + + + Qt::AlignCenter + + diff --git a/LockScreenForm.cpp b/LockScreenForm.cpp new file mode 100644 index 0000000..58dc54b --- /dev/null +++ b/LockScreenForm.cpp @@ -0,0 +1,14 @@ +#include "LockScreenForm.h" +#include "ui_LockScreenForm.h" + +LockScreenForm::LockScreenForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::LockScreenForm) +{ + ui->setupUi(this); +} + +LockScreenForm::~LockScreenForm() +{ + delete ui; +} diff --git a/LockScreenForm.h b/LockScreenForm.h new file mode 100644 index 0000000..b5ded48 --- /dev/null +++ b/LockScreenForm.h @@ -0,0 +1,25 @@ +#ifndef LOCKSCREENFORM_H +#define LOCKSCREENFORM_H + +#include +#include + +#include "utils/UtilInclude.h" + +namespace Ui { +class LockScreenForm; +} + +class LockScreenForm : public QWidget +{ + Q_OBJECT + +public: + explicit LockScreenForm(QWidget *parent = nullptr); + ~LockScreenForm(); + +private: + Ui::LockScreenForm *ui; +}; + +#endif // LOCKSCREENFORM_H diff --git a/LockScreenForm.ui b/LockScreenForm.ui new file mode 100644 index 0000000..7f2a6db --- /dev/null +++ b/LockScreenForm.ui @@ -0,0 +1,45 @@ + + + LockScreenForm + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + 180 + 100 + 54 + 12 + + + + TextLabel + + + + + + 180 + 160 + 54 + 12 + + + + TextLabel + + + + + + diff --git a/MainWindowForm.cpp b/MainWindowForm.cpp new file mode 100644 index 0000000..84f8159 --- /dev/null +++ b/MainWindowForm.cpp @@ -0,0 +1,86 @@ +#include "MainWindowForm.h" +#include "ui_MainWindowForm.h" +#include + +MainWindowForm::MainWindowForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::MainWindowForm) +{ + ui->setupUi(this); + + // 设置窗口透明和大小、位置 + this->setWindowFlags(Qt::FramelessWindowHint); + this->move(1400, 15); + this->resize(SettingConfig::getInstance().WINDOW_WIDTH, SettingConfig::getInstance().WINDOW_HEIGHT); + + // 通过调色板的颜色来设置窗口的统一背景色 + qApp->setPalette(QPalette(QColor(SettingConfig::getInstance().WINDOW_BACKGROUND_COLOR))); + + // 加载css文件设置控件样式 + QFile file(QApplication::applicationDirPath() + "/qss/main.css"); + if (file.open(QFile::ReadOnly)) + { + QString qssStr = QLatin1String(file.readAll()); + this->setStyleSheet(qssStr); + file.close(); + } + + initFormsPtr(); + + // 设置标题文字 + ui->labelTitle->setText(SettingConfig::getInstance().WINDOW_TITLE); + ui->labelCopyright->setText(SettingConfig::getInstance().WINDOW_RIGHTS); + ui->labelVersion->setText(SettingConfig::getInstance().WINDOW_VERSION); + + // 初始化虹膜相机控制 + ProMemory::getInstance().irisCam = new IrisCameraController(this); + ProMemory::getInstance().irisCam->initIrisCamera(); + ProMemory::getInstance().irisCam->openIrisCamera(); + connect(ProMemory::getInstance().irisCam->irisCamHandler, &IrisCameraCapEventHandler::sendIrisFrameToDraw, identifyForm, &IdentifyForm::drawIrisImageOnFrame); + +// LOG_INFO(QString("应用程序启动成功[Application Startup Success]").toStdString()); + qDebug() << "应用程序启动成功[Application Startup Success]"; + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::IDENTIFY_FORM; + ui->wdgtStatced->setCurrentWidget(identifyForm); + + // 开始虹膜相机拍图 + ProMemory::getInstance().irisCam->startCapture(); +} + +MainWindowForm::~MainWindowForm() +{ + delete ui; +} + +void MainWindowForm::lockScreen() +{ + ui->wdgtStatced->setCurrentWidget(lockScreenForm); + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::LOCKSCREEN_FORM; + ProMemory::getInstance().appState = AppConstants::ApplicationState::STATE_WAIT; +} + +void MainWindowForm::keyPressEvent(QKeyEvent *event) +{ + switch (event->key()) { + case Qt::Key_Escape: + QTimer::singleShot(100, qApp, [=](){ + QApplication::quit(); + }); + + default: + QWidget::keyPressEvent(event); + } +} + +void MainWindowForm::initFormsPtr() +{ + // 初始化各个form + lockScreenForm = new LockScreenForm(this); + identifyForm = new IdentifyForm(this); + + // 将form添加到statcked widget中 + ui->wdgtStatced->addWidget(identifyForm); + ui->wdgtStatced->addWidget(lockScreenForm); + + // 绑定按钮函数 +} diff --git a/MainWindowForm.h b/MainWindowForm.h new file mode 100644 index 0000000..7fb2d89 --- /dev/null +++ b/MainWindowForm.h @@ -0,0 +1,38 @@ +#ifndef MAINWINDOWFORM_H +#define MAINWINDOWFORM_H + +#include +#include +#include + +#include "utils/UtilInclude.h" +#include "ProMemory.h" +#include "LockScreenForm.h" +#include "IdentifyForm.h" + +namespace Ui { +class MainWindowForm; +} + +class MainWindowForm : public QWidget +{ + Q_OBJECT + +public: + explicit MainWindowForm(QWidget *parent = nullptr); + ~MainWindowForm(); + +public slots: + void lockScreen(); + +private: + Ui::MainWindowForm *ui; + LockScreenForm * lockScreenForm; + IdentifyForm * identifyForm; + + void keyPressEvent(QKeyEvent *event); + + void initFormsPtr(); +}; + +#endif // MAINWINDOWFORM_H diff --git a/MainWindowForm.ui b/MainWindowForm.ui new file mode 100644 index 0000000..e793ebf --- /dev/null +++ b/MainWindowForm.ui @@ -0,0 +1,85 @@ + + + MainWindowForm + + + + 0 + 0 + 600 + 1024 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + 0 + 0 + 600 + 84 + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + + + + TextLabel + + + Qt::AlignBottom|Qt::AlignHCenter + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + diff --git a/ProMemory.cpp b/ProMemory.cpp new file mode 100644 index 0000000..19e7403 --- /dev/null +++ b/ProMemory.cpp @@ -0,0 +1,84 @@ +#include "ProMemory.h" + +ProMemory::ProMemory() +{ + +} + +ProMemory::~ProMemory() +{ + +} + +/* +void ProMemory::pushCasicIris(CasicIrisInfo irisInfo) +{ + QMutex mutex; + mutex.lock(); + if (this->irisQueue.size() > 30) + { + QStack empty; + std::swap(empty, irisQueue); + } + + irisQueue.push(irisInfo); + mutex.unlock(); +} +CasicIrisInfo ProMemory::popCasicIris() +{ + CasicIrisInfo result; + + QMutex mutex; + mutex.lock(); + if (this->irisQueue.size() > 0) + { + result = irisQueue.pop(); + } + + mutex.unlock(); + + return result; +} +*/ +int ProMemory::getIrisQueueSize() +{ + int size = 0; + + QMutex mutex; + mutex.lock(); + +// size = this->irisQueue.size(); + + mutex.unlock(); + + return size; +} +bool ProMemory::isIrisQueueEmpty() +{ + bool empty = true; + + QMutex mutex; + mutex.lock(); + +// empty = this->irisQueue.isEmpty(); + + mutex.unlock(); + + return empty; +} +void ProMemory::clearIrisQueue() +{ + QMutex mutex; + mutex.lock(); + +// QStack empty; +// std::swap(empty, irisQueue); + + mutex.unlock(); +} + + +void ProMemory::initIrisFeatures(QString personId) +{ +// irisRegistPro->sendDataToExract(QByteArray(QString("[-u]").append(personId).toLocal8Bit())); +} diff --git a/ProMemory.h b/ProMemory.h new file mode 100644 index 0000000..2ecd653 --- /dev/null +++ b/ProMemory.h @@ -0,0 +1,52 @@ +#ifndef PROMEMORY_H +#define PROMEMORY_H + +#include +#include + +#include "AppConstants.h" +//#include "casic/iris/CasicIrisInfo.h" +#include "dao/IrisDataDao.h" + +#include "device/IrisCameraController.h" +//#include "device/iris/IrisRegistProcess.h" +//#include "device/iris/IrisRecogProcess.h" + +class IrisCameraController; +class IrisRegistProcess; +class IrisRecogProcess; + +class ProMemory +{ +public: + ~ProMemory(); + ProMemory(const ProMemory&)=delete; + ProMemory& operator=(const ProMemory&)=delete; + + static ProMemory& getInstance() { + static ProMemory instance; + return instance; + } + +// void pushCasicIris(CasicIrisInfo irisInfo); +// CasicIrisInfo popCasicIris(); + int getIrisQueueSize(); + bool isIrisQueueEmpty(); + void clearIrisQueue(); + + volatile int widgeFrame = 0; // 当前显示的界面 + volatile int appState = 0; // 当前程序所处的状态 + + void initIrisFeatures(QString personId = ""); // 初始化虹膜特征值集合 + + IrisCameraController * irisCam; + IrisRecogProcess * irisRecogPro; + +private: + ProMemory(); + +// QStack irisQueue; // 虹膜信息队列 + QVector irisFeatures; // 虹膜特征值集合 +}; + +#endif // PROMEMORY_H diff --git a/conf/config.ini b/conf/config.ini new file mode 100644 index 0000000..66e46ad --- /dev/null +++ b/conf/config.ini @@ -0,0 +1,67 @@ +[recognize] +#最大允许识别时间(ms) +maxMatchTime=10000 +#识别成功界面停留时间(ms) +successTipsLast=5000 +#识别失败界面停留时间(ms) +failureTipsLast=3000 +#人脸识别最大尝试次数 +maxFaceTryCount=20 +#持续没找到人脸的最大次数 +maxFaceNotFoundCount=500 +#注册时最小人脸 +minFaceRegist=240 +#识别时最小人脸 +minFaceRecog=100 + +#虹膜识别最大尝试次数 +maxIrisTryCount=10 +#虹膜识别持续没有找到眼的最大次数 +maxEyeNotFoundCount=50 + +#识别方式[1=人脸;2=虹膜;3=双认证;4=任意] +recogType=4 + +[window] +#界面窗口宽(px) +width=600 +#界面窗口高(px) +height=1024 +#统一背景色 +backgroundColor="#FFFFFF" +#标题 +title="虹膜识别终端" + +[work] +#工作状态检测时最小人脸范围 +minFaceSize=160 +#人脸范围最小横坐标 +minFacePosX=320 +#人脸范围最大横坐标 +maxFacePosX=960 +#人脸范围最小纵坐标 +minFacePosY=180 +#人脸范围最大纵坐标 +maxFacePosY=540 +#人脸太近阈值 +faceCloseSize=360 +#人脸太远阈值 +faceFarSize=480 + +[camera] +#虹膜相机取一幅画面的时间间隔(ms) +irisFrameInterval=100 +#虹膜相机拍摄宽度 +irisFrameWidth=1440 +#虹膜相机拍摄高度 +irisFrameHeight=1080 +#虹膜图像高度 +irisWidth=640 +#虹膜图像高度 +irisHeight=480 + +[log] +#日志文件位置 +logFile="d://irisLogs//casic_log.txt" +#日志级别 +logLevel="trace" diff --git a/dao/BaseDao.cpp b/dao/BaseDao.cpp new file mode 100644 index 0000000..f51c144 --- /dev/null +++ b/dao/BaseDao.cpp @@ -0,0 +1,12 @@ +#include "BaseDao.h" +#include "dao/util/ConnectionManager.h" + +BaseDao::BaseDao(QObject *parent) : QObject(parent) +{ + +} + +BaseDao::~BaseDao() +{ + +} diff --git a/dao/BaseDao.h b/dao/BaseDao.h new file mode 100644 index 0000000..1693c88 --- /dev/null +++ b/dao/BaseDao.h @@ -0,0 +1,32 @@ +#ifndef BASEDAO_H +#define BASEDAO_H + +#include +#include +#include +#include + +#include "dao/util/ConnectionManager.h" +#include "utils/UtilInclude.h" + +class BaseDao : public QObject +{ + Q_OBJECT +public: + explicit BaseDao(QObject *parent = nullptr); + ~BaseDao(); + + virtual QVector findAllRecord() = 0; + virtual QVariantMap findRecordById(QString id) = 0; + + virtual QString save(QVariantMap object) = 0; + virtual bool edit(QVariantMap newObject, QString id) = 0; + virtual bool dele(QString id) = 0; + +private: + +signals: + +}; + +#endif // BASEDAO_H diff --git a/dao/IrisDataDao.cpp b/dao/IrisDataDao.cpp new file mode 100644 index 0000000..37a0ed6 --- /dev/null +++ b/dao/IrisDataDao.cpp @@ -0,0 +1,204 @@ +#include "IrisDataDao.h" + +IrisDataDao::IrisDataDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector IrisDataDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM IRIS_DATA"; + query.prepare(sql); + + // 执行查询 + query.exec(); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + item.insert("id", query.value("id").toString()); + item.insert("person_id", query.value("person_id").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("left_iris_code1", query.value("left_iris_code1")); + item.insert("left_iris_code2", query.value("left_iris_code2")); + item.insert("left_iris_code3", query.value("left_iris_code3")); + item.insert("right_iris_code1", query.value("right_iris_code1")); + item.insert("right_iris_code2", query.value("right_iris_code2")); + item.insert("right_iris_code3", query.value("right_iris_code3")); + + result.append(item); + } + +// LOG_DEBUG(QString("查询IRIS_DATA表的所有记录[结果数:%1]").arg(result.size()).toStdString()); + return result; +} + +QVariantMap IrisDataDao::findRecordById(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM IRIS_DATA WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + // 获取结果 + if (query.next()) + { + result.insert("id", query.value("id").toString()); + result.insert("person_id", query.value("person_id").toLongLong()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("left_iris_code1", query.value("left_iris_code1")); + result.insert("left_iris_code2", query.value("left_iris_code2")); + result.insert("left_iris_code3", query.value("left_iris_code3")); + result.insert("right_iris_code1", query.value("right_iris_code1")); + result.insert("right_iris_code2", query.value("right_iris_code2")); + result.insert("right_iris_code3", query.value("right_iris_code3")); + } + +// LOG_DEBUG(QString("根据id查询IRIS_DATA表的记录[id=%1]").arg(id).toStdString()); + return result; +} + +QVariantMap IrisDataDao::findRecordByPersonId(QString personId) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM IRIS_DATA WHERE PERSON_ID = :personId"); + query.prepare(sql); + query.bindValue(":personId", personId); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + if (query.next()) + { + result.insert("id", query.value("id").toString()); + result.insert("person_id", query.value("person_id").toLongLong()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("left_iris_code1", query.value("left_iris_code1")); + result.insert("left_iris_code2", query.value("left_iris_code2")); + result.insert("left_iris_code3", query.value("left_iris_code3")); + result.insert("right_iris_code1", query.value("right_iris_code1")); + result.insert("right_iris_code2", query.value("right_iris_code2")); + result.insert("right_iris_code3", query.value("right_iris_code3")); + } + +// LOG_DEBUG(QString("根据personId查询IRIS_DATA表的记录[personId=%1]").arg(personId).toStdString()); + return result; +} + + +QString IrisDataDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + + // INSERT语句 + QString sql = QString("INSERT INTO IRIS_DATA (ID, PERSON_ID, ID_CARD_NO, LEFT_IRIS_CODE1, RIGHT_IRIS_CODE1) VALUES (:id, :personId, :idCardNo, :left1, :right1)"); + + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":personId", object.value("person_id").toString()); + query.bindValue(":idCardNo", object.value("id_card_no").toString()); + query.bindValue(":left1", object.value("left_iris_code1")); + query.bindValue(":right1", object.value("right_iris_code1")); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(); + +// LOG_DEBUG(QString("保存虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool IrisDataDao::edit(QVariantMap newObject, QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // UPDATE语句 + if (!newObject.contains("left_iris_code1") || !newObject.contains("right_iris_code1")){ + return false; + } + QString sql = QString("UPDATE IRIS_DATA SET LEFT_IRIS_CODE1 = :left1, RIGHT_IRIS_CODE1 = :right1 WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":left1", newObject.value("left_iris_code1")); + query.bindValue(":right1", newObject.value("right_iris_code1")); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(); + +// LOG_DEBUG(QString("编辑虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; +} + + +bool IrisDataDao::dele(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + QString sql = QString("DELETE FROM IRIS_DATA WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(); + +// LOG_DEBUG(QString("删除虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; +} diff --git a/dao/IrisDataDao.h b/dao/IrisDataDao.h new file mode 100644 index 0000000..c74dbbd --- /dev/null +++ b/dao/IrisDataDao.h @@ -0,0 +1,25 @@ +#ifndef IRISDATADAO_H +#define IRISDATADAO_H + +#include +#include "BaseDao.h" + +class IrisDataDao : public BaseDao +{ + Q_OBJECT +public: + explicit IrisDataDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + QVariantMap findRecordByPersonId(QString personId); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +signals: + +}; + +#endif // IRISDATADAO_H diff --git a/dao/RecognitionRecordsDao.cpp b/dao/RecognitionRecordsDao.cpp new file mode 100644 index 0000000..40db453 --- /dev/null +++ b/dao/RecognitionRecordsDao.cpp @@ -0,0 +1,100 @@ +#include "RecognitionRecordsDao.h" + +RecognitionRecordsDao::RecognitionRecordsDao(QObject *parent) : BaseDao(parent) +{ + +} + + +QVector RecognitionRecordsDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM RECOGNITION_RECORDS"; + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + item.insert("id", query.value("id").toLongLong()); + result.append(item); + } + +// LOG_DEBUG(QString("查询RECOGNITION_RECORDS表的所有记录[记录数:%1]").arg(result.size()).toStdString()); + return result; +} + +QVariantMap RecognitionRecordsDao::findRecordById(QString id) +{ + QVariantMap item; + return item; +} + +QString RecognitionRecordsDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + + // INSERT语句 + QString sql = QString("INSERT INTO RECOGNITION_RECORDS (ID, PERSON_ID, DATETIME, REC_TYPE, DEV_CODE, DOOR_CODE, INOUT_TYPE) " + "VALUES (:id, :personId, :datetime, :recType, :devCode, :doorCode, :inoutType)"); + + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":personId", object.value("person_id").toString()); + query.bindValue(":datetime", object.value("date_time").toString()); + query.bindValue(":recType", object.value("rec_type").toString()); + query.bindValue(":devCode", object.value("dev_code").toString()); + query.bindValue(":doorCode", object.value("door_code").toString()); + query.bindValue(":inoutType", object.value("inout_type").toString()); + +// LOG_DEBUG(sql.toStdString()); + + // 插入识别的log日志 + QString logStr = QString("INSERT INTO RECOGNITION_LOGS (ID, LOG_INFO) VALUES (:id, :logInfo)"); + + QSqlQuery logQuery(ConnectionManager::getInstance()->getConnection()); + logQuery.prepare(logStr); + logQuery.bindValue(":id", id); + logQuery.bindValue(":logInfo", object.value("debug_info").toString()); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(); + logQuery.exec(); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool RecognitionRecordsDao::edit(QVariantMap newObject, QString id) +{ + return false; +} + +bool RecognitionRecordsDao::dele(QString id) +{ + return false; +} diff --git a/dao/RecognitionRecordsDao.h b/dao/RecognitionRecordsDao.h new file mode 100644 index 0000000..38de7c9 --- /dev/null +++ b/dao/RecognitionRecordsDao.h @@ -0,0 +1,23 @@ +#ifndef RECOGNITIONRECORDSDAO_H +#define RECOGNITIONRECORDSDAO_H + +#include +#include "BaseDao.h" +class RecognitionRecordsDao: public BaseDao +{ + Q_OBJECT +public: + explicit RecognitionRecordsDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +signals: + +}; + +#endif // RECOGNITIONRECORDSDAO_H diff --git a/dao/SysDeptDao.cpp b/dao/SysDeptDao.cpp new file mode 100644 index 0000000..22f9946 --- /dev/null +++ b/dao/SysDeptDao.cpp @@ -0,0 +1,88 @@ +#include "SysDeptDao.h" + +SysDeptDao::SysDeptDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector SysDeptDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_DEPT WHERE PID != '-1' ORDER BY PID, NUM"; + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + item.insert("id", query.value("id").toString()); + item.insert("pid", query.value("pid").toString()); + item.insert("pids", query.value("pids").toString()); + item.insert("simplename", query.value("simplename").toString()); + item.insert("fullname", query.value("fullname").toString()); + } + +// LOG_TRACE(QString("查询表[SYS_DEPT]的所有记录[%1][%2]").arg(result.size()).arg(sql).toStdString()); + + return result; +} + +QVariantMap SysDeptDao::findRecordById(QString id) +{ + QVariantMap item; + return item; + + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM SYS_DEPT WHERE SYS_DEPT.ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + // 获取结果集的大小 + query.last(); + int count = query.at() + 1; + + if (count >=1) + { + query.first(); + + result.insert("id", query.value("id").toString()); + result.insert("pid", query.value("pid").toString()); + result.insert("pids", query.value("pids").toString()); + result.insert("simplename", query.value("simplename").toString()); + result.insert("fullname", query.value("fullname").toString()); + } + +// LOG_TRACE(QString("根据id查询SYS_DEPT表的记录[ID=%1][%2]").arg(id).arg(sql).toStdString()); + + return result; +} + + +QString SysDeptDao::save(QVariantMap object) +{ + return "0"; +} +bool SysDeptDao::edit(QVariantMap newObject, QString id) +{ + return true; +} +bool SysDeptDao::dele(QString id) +{ + return true; +} diff --git a/dao/SysDeptDao.h b/dao/SysDeptDao.h new file mode 100644 index 0000000..e07a09f --- /dev/null +++ b/dao/SysDeptDao.h @@ -0,0 +1,24 @@ +#ifndef SYSDEPTDAO_H +#define SYSDEPTDAO_H + +#include +#include "BaseDao.h" + +class SysDeptDao : public BaseDao +{ + Q_OBJECT +public: + explicit SysDeptDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +private: + +}; + +#endif // SYSDEPTDAO_H diff --git a/dao/SysPersonDao.cpp b/dao/SysPersonDao.cpp new file mode 100644 index 0000000..dd9480f --- /dev/null +++ b/dao/SysPersonDao.cpp @@ -0,0 +1,371 @@ +#include "SysPersonDao.h" + + +SysPersonDao::SysPersonDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector SysPersonDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0'"; + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + count++; + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + result.append(item); + } + +// LOG(TRACE) << QString("查询SYS_PERSON表的所有记录[%1]").arg(count).toStdString(); +// LOG_TRACE(QString("查询SYS_PERSON表的所有记录[%1]").arg(count).toStdString()); + + return result; +} + +QVariantMap SysPersonDao::findRecordById(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0' AND SYS_PERSON.ID = '%1'").arg(id); + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVariantMap result; + + // 获取结果集的大小 + query.last(); + int count = query.at() + 1; + + if (count >=1) + { + query.first(); + + result.insert("id", query.value("id").toString()); + result.insert("delflag", query.value("delflag").toString()); + result.insert("createtime", query.value("createtime").toString()); + result.insert("updatetime", query.value("updatetime").toString()); + result.insert("name", query.value("name").toString()); + result.insert("gender", query.value("gender").toString()); + result.insert("deptid", query.value("deptid").toString()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("remarks", query.value("remarks").toString()); + result.insert("person_code", query.value("person_code").toString()); + result.insert("deptname", query.value("fullname").toString()); + result.insert("sync_id", query.value("sync_id").toString()); + result.insert("hasFace", query.value("face_valid").toString()); + result.insert("hasIris", query.value("iris_valid").toString()); + } + +// LOG(TRACE) << QString("根据id查询SYS_PERSON表的记录[id=%1][%2]").arg(id).arg(sql).toStdString(); +// LOG_TRACE(QString("根据id查询SYS_PERSON表的记录[id=%1][%2]").arg(id).arg(sql).toStdString()); + + return result; +} + +int SysPersonDao::findRecordCountByNameAndDept(QString name, QString dept) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT COUNT(P.ID) AS RECCT FROM SYS_PERSON P LEFT JOIN SYS_DEPT D ON P.DEPTID = D.ID WHERE P.DELFLAG = '0'"; + if (name.isEmpty() == false) + { + sql += " AND P.NAME LIKE '%" + name + "%'"; + } + if (dept.isEmpty() == false && dept.indexOf("-1") < 0) + { + sql += QString(" AND ((P.DEPTID = '%1') OR (D.PIDS LIKE '%,%1,%'))").arg(dept); + } + + // 执行查询 + query.exec(sql); + + // 返回结果 + int result; + + // 遍历查询结果 + if (query.next()) { + result = query.value("RECCT").toInt(); + } + +// LOG(TRACE) << QString("根据姓名和部门查询SYS_PERSON记录总数[%1][%2]").arg(result).arg(sql).toStdString(); +// LOG_TRACE(QString("根据姓名和部门查询SYS_PERSON记录总数[%1][%2]").arg(result).arg(sql).toStdString()); + + return result; +} + +QVector SysPersonDao::findRecordsByNameAndDept(QString name, QString dept, qint8 limit, qint16 offset) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON P LEFT JOIN SYS_DEPT D ON P.DEPTID = D.ID WHERE P.DELFLAG = '0'"; + if (name.isEmpty() == false) + { + sql += " AND P.NAME LIKE '%" + name + "%'"; + } + if (dept.isEmpty() == false && dept.indexOf("-1") < 0) + { + sql += QString(" AND ((P.DEPTID = '%1') OR (D.PIDS LIKE '%,%1,%'))").arg(dept); + } + + sql += QString(" LIMIT %1 OFFSET %2").arg(limit).arg(offset); + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + count++; + + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + + result.append(item); + } + +// LOG(TRACE) << QString("根据姓名和部门分页查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString(); +// LOG_TRACE(QString("根据姓名和部门分页查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString()); + + return result; +} + +QVector SysPersonDao::findRecordsByProperties(QVariantMap conditions) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0'"; + QVariantMap::iterator it; + for (it = conditions.begin(); it != conditions.end(); it++) + { + sql += QString(" AND SYS_PERSON.%1 = %2").arg(it.key()).arg(it.value().toString()); + } + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + count++; + + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + + result.append(item); + } + +// LOG(TRACE) << QString("根据属性值查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString(); +// LOG_TRACE(QString("根据属性值查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString()); + + return result; +} + +QString SysPersonDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + + // INSERT语句 + QString sql = QString("INSERT INTO SYS_PERSON " + "(ID, DELFLAG, CREATETIME, UPDATETIME, " + "NAME, GENDER, DEPTID, ID_CARD_NO, " + "REMARKS, PERSON_CODE, SYNC_ID, FACE_VALID, IRIS_VALID) " + "VALUES ('%1', '0', '%2', '%2', '%3', '%4', '%5', '%6', '%7', '%8', '%9', 0, 0)") + .arg(id).arg(tm) + .arg(object.value("name").toString()) + .arg(object.value("gender").toString()) + .arg(object.value("deptid").toString()) + .arg(object.value("id_card_no").toString()) + .arg(object.value("remarks").toString()) + .arg(object.value("person_code").toString()) + .arg(object.value("sync_id").toString()); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(sql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { +// LOG(DEBUG) << QString("保存SYS_PERSON记录成功[ID = %1][%2]").arg(id).arg(sql).toStdString(); +// LOG_DEBUG(QString("保存SYS_PERSON记录成功[ID = %1][%2]").arg(id).arg(sql).toStdString()); + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool SysPersonDao::edit(QVariantMap newObject, QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + + // UPDATE语句 + QString sql = QString("UPDATE SYS_PERSON SET UPDATETIME = '%1'").arg(tm); + if (newObject.contains("name")) + { + sql.append(QString(", NAME = '%1'").arg(newObject.value("name").toString())); + } + if (newObject.contains("gender")) + { + sql.append(QString(", GENDER = '%1'").arg(newObject.value("gender").toString())); + } + if (newObject.contains("deptid")) + { + sql.append(QString(", DEPTID = '%1'").arg(newObject.value("deptid").toString())); + } + if (newObject.contains("person_code")) + { + sql.append(QString(", PERSON_CODE = '%1'").arg(newObject.value("person_code").toString())); + } + if (newObject.contains("face_valid")) + { + sql.append(QString(", FACE_VALID = '%1'").arg(newObject.value("face_valid").toString())); + } + if (newObject.contains("iris_valid")) + { + sql.append(QString(", IRIS_VALID = '%1'").arg(newObject.value("iris_valid").toString())); + } + + sql.append(QString(" WHERE ID = '%1'").arg(id)); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(sql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + +// LOG(DEBUG) << QString("编辑人员[ID=%1][%2]").arg(id).arg(sql).toStdString(); +// LOG_DEBUG(QString("编辑人员[ID=%1][%2]").arg(id).arg(sql).toStdString()); + + // 返回结果 + return success; +} + +bool SysPersonDao::dele(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + QSqlQuery irisDel(ConnectionManager::getInstance()->getConnection()); + + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + qint64 tmms = QDateTime::currentDateTime().toMSecsSinceEpoch(); + + // UPDATE语句 + QString sql = QString("UPDATE SYS_PERSON SET UPDATETIME = :updateTime, DELFLAG = :flag WHERE ID = :id").arg(tm).arg(tmms).arg(id); + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":updateTime", tm); + query.bindValue(":flag", tmms); + + // 物理删除人员的人脸和虹膜数据 + QString delIrisSql = QString("DELETE FROM IRIS_DATA WHERE PERSON_ID = :personId"); + irisDel.prepare(delIrisSql); + irisDel.bindValue(":personId", id); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(sql); + query.exec(delIrisSql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + +// LOG_DEBUG(QString("删除人员SYS_PERSON[ID=%1][%2]").arg(id).arg(success).toStdString()); + + // 返回结果 + return success; +} diff --git a/dao/SysPersonDao.h b/dao/SysPersonDao.h new file mode 100644 index 0000000..e02e5ba --- /dev/null +++ b/dao/SysPersonDao.h @@ -0,0 +1,27 @@ +#ifndef SYSPERSONDAO_H +#define SYSPERSONDAO_H + +#include +#include "BaseDao.h" + +class SysPersonDao : public BaseDao +{ + Q_OBJECT +public: + explicit SysPersonDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + int findRecordCountByNameAndDept(QString name, QString dept); + QVector findRecordsByNameAndDept(QString name, QString dept, qint8 limit, qint16 offset); + QVector findRecordsByProperties(QVariantMap conditions); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); +signals: + +}; + +#endif // SYSPERSONDAO_H diff --git a/dao/dao.pri b/dao/dao.pri new file mode 100644 index 0000000..1e04ce4 --- /dev/null +++ b/dao/dao.pri @@ -0,0 +1,18 @@ + +HEADERS += $$PWD/BaseDao.h +HEADERS += $$PWD/IrisDataDao.h +HEADERS += $$PWD/RecognitionRecordsDao.h +HEADERS += $$PWD/SysPersonDao.h +HEADERS += $$PWD/SysDeptDao.h + +SOURCES += $$PWD/BaseDao.cpp +SOURCES += $$PWD/IrisDataDao.cpp +SOURCES += $$PWD/RecognitionRecordsDao.cpp +SOURCES += $$PWD/SysPersonDao.cpp +SOURCES += $$PWD/SysDeptDao.cpp + +HEADERS += $$PWD/util/ConnectionManager.h +SOURCES += $$PWD/util/ConnectionManager.cpp +#HEADERS += $$PWD/util/CacheManager.h +#SOURCES += $$PWD/util/CacheManager.cpp + diff --git a/dao/util/ConnectionManager.cpp b/dao/util/ConnectionManager.cpp new file mode 100644 index 0000000..84b17be --- /dev/null +++ b/dao/util/ConnectionManager.cpp @@ -0,0 +1,47 @@ +#include "ConnectionManager.h" +#include + +Q_GLOBAL_STATIC(ConnectionManager, cm) + +ConnectionManager::ConnectionManager(QObject *parent) : QObject(parent) +{ + // 初始化数据库连接 + if (QSqlDatabase::contains("qt_sql_dafault_connection")) + { + conn = QSqlDatabase::database("qt_sql_default_connection"); + } + else + { + conn = QSqlDatabase::addDatabase("QSQLITE"); + conn.setDatabaseName(QApplication::applicationDirPath() + "/data/casic.db"); + + bool succ = conn.open(); + if (succ == true) + { +// LOG_INFO(QString("打开数据库操作正常[Open Database Success]").toStdString()); + } else + { +// LOG_ERROR(QString("打开数据库操作失败[Open Database Failed]").toStdString()); + } + } +} + +ConnectionManager::~ConnectionManager() +{ + conn.close(); +} + +ConnectionManager* ConnectionManager::getInstance() +{ + return cm; +} + +QSqlDatabase ConnectionManager::getConnection() +{ + return this->conn; +} + +qint64 ConnectionManager::generateId() +{ + return this->idWorker.nextId(); +} diff --git a/dao/util/ConnectionManager.h b/dao/util/ConnectionManager.h new file mode 100644 index 0000000..84647e3 --- /dev/null +++ b/dao/util/ConnectionManager.h @@ -0,0 +1,34 @@ +#ifndef CONNECTIONMANAGER_H +#define CONNECTIONMANAGER_H + +#include +#include +#include "utils/id/IdWorker.h" +#include "utils/UtilInclude.h" + +using namespace Jiawa::Core; + +class ConnectionManager : public QObject +{ + Q_OBJECT +public: + explicit ConnectionManager(QObject *parent = nullptr); + ~ConnectionManager(); + + static ConnectionManager * getInstance(); + + QSqlDatabase getConnection(); + qint64 generateId(); + +private: + // 数据库连接 + QSqlDatabase conn; + + // 雪花id生成工具 + IdWorker &idWorker = Singleton::instance(); + +signals: + +}; + +#endif // CONNECTIONMANAGER_H diff --git a/device/IrisCameraCapEventHandler.cpp b/device/IrisCameraCapEventHandler.cpp new file mode 100644 index 0000000..45df089 --- /dev/null +++ b/device/IrisCameraCapEventHandler.cpp @@ -0,0 +1,103 @@ +#include "IrisCameraCapEventHandler.h" + +IrisCameraCapEventHandler::IrisCameraCapEventHandler(QObject *parent) : QObject(parent) +{ + +} + +void IrisCameraCapEventHandler::DoOnImageCaptured(CImageDataPointer &objImageDataPointer, void *pUserParam) +{ + if (objImageDataPointer.IsNull() == false) + { + CGXDevicePointer* cam = (CGXDevicePointer *) pUserParam; + + auto camName = cam->getPtr()->GetDeviceInfo().GetUserID(); + int width = objImageDataPointer->GetWidth(); + int height = objImageDataPointer->GetHeight(); + size_t leftKeyIndex = camName.find("left"); + size_t rightKeyIndex = camName.find("right"); + + uchar * pBuffer = (BYTE*)objImageDataPointer->GetBuffer(); + + // 相机拍摄下的图像1440*1080, 直接用于算法判断 + QImage img = QImage(pBuffer, width, height, QImage::Format_Grayscale8); // 用于展示 +// QImage imgAlgo = img.copy(0, 0, width, height); + + // 用于显示的图像需要缩小到400 * 300的尺寸 + img = img.scaled(SettingConfig::getInstance().IRIS_DISPLAY_HEIGHT, SettingConfig::getInstance().IRIS_DISPLAY_WIDTH); + img = img.transformed(QTransform().rotate(-90)); // 图像逆时针旋转90度 + + // 发送到界面进行显示 + emit sendIrisFrameToDraw(img); +// cv::Mat irisMat = ImageUtil::QImageToMat(imgAlgo); + +// irisInfo.data = imgAlgo; +// irisInfo.matData = irisMat; + +// // 将图像显示在注册页面的label上 +// // 并将虹膜信息对象存入队列中 +// ProMemory::getInstance().pushCasicIris(irisInfo); + +// if (leftKeyIndex >= 0 && leftKeyIndex < 32) +// { +// emit sendIrisFrameToDraw(img, 0); // 左眼画面 +// } else if (rightKeyIndex >= 0 && rightKeyIndex < 32) +// { +// emit sendIrisFrameToDraw(img, 1); // 右眼画面 +// } +/* + if (pBuffer != NULL) + { + // 创建虹膜信息对象 + CasicIrisInfo irisInfo; + irisInfo.hasEye = false; + if (leftKeyIndex >= 0 && leftKeyIndex < 32) + { + // 左眼相机拍摄的图像 + irisInfo.leftOrRight = "left"; + } else if (rightKeyIndex >= 0 && rightKeyIndex < 32) + { + // 右眼相机 + irisInfo.leftOrRight = "right"; + } + + if (ProMemory::getInstance().widgeFrame == CasicBioRecConst::RECOGNIZE_RESULT_FORM) + { + // 相机拍摄下的图像1280*960, 直接用于算法判断 + QImage imgDisp = QImage(pBuffer, width, height, QImage::Format_Grayscale8); + cv::Mat irisMat = ImageUtil::QImageToMat(imgDisp); + + irisInfo.data = imgDisp; + irisInfo.matData = irisMat; + + ProMemory::getInstance().pushCasicIris(irisInfo); + +// cv::imwrite(QString("D:\\irisLogs\\iristest-%1.bmp").arg(irisInfo.leftOrRight).toStdString(), irisMat); + } else if (ProMemory::getInstance().widgeFrame == CasicBioRecConst::ADD_PERSON_CAPTURE_IRIS) + { + // 相机拍摄下的图像1280*960, 直接用于算法判断 + QImage img = QImage(pBuffer, width, height, QImage::Format_Grayscale8); + QImage imgAlgo = img.copy(0, 0, width, height); + + // 用于显示的图像需要缩小到1/4的尺寸 + img = img.scaled(640, 480); + cv::Mat irisMat = ImageUtil::QImageToMat(imgAlgo); + + irisInfo.data = imgAlgo; + irisInfo.matData = irisMat; + + // 将图像显示在注册页面的label上 + // 并将虹膜信息对象存入队列中 + ProMemory::getInstance().pushCasicIris(irisInfo); + + if (leftKeyIndex >= 0 && leftKeyIndex < 32) + { + emit sendIrisFrameToDraw(img, 0); // 左眼画面 + } else if (rightKeyIndex >= 0 && rightKeyIndex < 32) + { + emit sendIrisFrameToDraw(img, 1); // 右眼画面 + } + } + }*/ + } +} diff --git a/device/IrisCameraCapEventHandler.h b/device/IrisCameraCapEventHandler.h new file mode 100644 index 0000000..ad75a97 --- /dev/null +++ b/device/IrisCameraCapEventHandler.h @@ -0,0 +1,30 @@ +#ifndef IRISCAMERACAPEVENTHANDLER_H +#define IRISCAMERACAPEVENTHANDLER_H + +#include +#include +#include "include/opencv2/opencv.hpp" +#include "include/daheng/GalaxyIncludes.h" + +//#include "casic/iris/CasicIrisInterface.h" +#include "ProMemory.h" + +#include "utils/UtilInclude.h" + +class IrisCameraCapEventHandler : public QObject, public ICaptureEventHandler +{ + Q_OBJECT +public: + explicit IrisCameraCapEventHandler(QObject *parent = nullptr); + + void DoOnImageCaptured(CImageDataPointer &objImageDataPointer, void *pUserParam); + +private: + unsigned char* pImageBuffer; + +signals: + void sendIrisFrameToDraw(QImage irisImage); + +}; + +#endif // IRISCAMERACAPEVENTHANDLER_H diff --git a/device/IrisCameraController.cpp b/device/IrisCameraController.cpp new file mode 100644 index 0000000..0928176 --- /dev/null +++ b/device/IrisCameraController.cpp @@ -0,0 +1,110 @@ +#include "IrisCameraController.h" + +IrisCameraController::IrisCameraController(QObject *parent) : QObject(parent) +{ + this->irisCamHandler = new IrisCameraCapEventHandler(this); +} +IrisCameraController::~IrisCameraController() +{ + this->closeIrisCamera(); +} + + +void IrisCameraController::initIrisCamera() +{ + IGXFactory::GetInstance().Init(); + + //枚举设备 + IGXFactory::GetInstance().UpdateDeviceList(1000, irisCamList); + + this->OpenDevice(); +} + +void IrisCameraController::openIrisCamera() +{ + //设置Buffer处理模式 + irisStreamFeaturePtr->GetEnumFeature("StreamBufferHandlingMode")->SetValue("OldestFirst"); + + //注册回调函数 + irisStreamPtr->RegisterCaptureCallback(irisCamHandler, &irisCamPtr); + + //开启流层通道 + irisStreamPtr->StartGrab(); + + //发送开采命令 + irisFeaturePtr->GetCommandFeature("AcquisitionStart")->Execute(); + + // 启动定时器 + TimeCounterUtil::getInstance().irisCapCounter->start(SettingConfig::getInstance().IRIS_FRAME_INTERVAL); // 50ms执行一次定时器 +} + +void IrisCameraController::closeIrisCamera() +{ + +} + +void IrisCameraController::startCapture() +{ + // 获取定时器, 绑定定时函数 + connect(TimeCounterUtil::getInstance().irisCapCounter, &QTimer::timeout, this, &IrisCameraController::getOneFaceFrm); +// LOG(DEBUG) << QString("[IrisCameraController][startCapture]虹膜相机拍图").toStdString(); +// LOG_DEBUG(QString("[IrisCameraController][startCapture]虹膜相机拍图").toStdString()); + +} +void IrisCameraController::stopCapture() +{ + // 获取定时器, 绑定定时函数 + disconnect(TimeCounterUtil::getInstance().irisCapCounter, &QTimer::timeout, this, &IrisCameraController::getOneFaceFrm); +// LOG(DEBUG) << QString("[IrisCameraController][stopCapture]虹膜相机停止拍图").toStdString(); +// LOG_DEBUG(QString("[IrisCameraController][stopCapture]虹膜相机停止拍图").toStdString()); + +} + +void IrisCameraController::getOneFaceFrm() +{ + // 发送软触发命令(在触发模式开启时有效) + irisFeaturePtr->GetCommandFeature("TriggerSoftware")->Execute(); +} + +void IrisCameraController::getLeftAndRightEyeFrame() +{ + irisFeaturePtr->GetCommandFeature("TriggerSoftware")->Execute(); +} + +void IrisCameraController::OpenDevice() +{ + auto device = irisCamList.at(0); + + irisCamPtr = IGXFactory::GetInstance().OpenDeviceByUserID(device.GetUserID(), GX_ACCESS_EXCLUSIVE); + irisFeaturePtr = irisCamPtr->GetRemoteFeatureControl(); + + // 判断设备流是否大于零, 如果大于零则打开流 + int nStreamCount = irisCamPtr->GetStreamCount(); + if (nStreamCount > 0) + { + irisStreamPtr = irisCamPtr->OpenStream(0); + irisStreamFeaturePtr = irisStreamPtr->GetFeatureControl(); + } + + // 建议用户在打开网络相机之后, 根据当前网络环境设置相机的流通道包长值, + // 以提高网络相机的采集性能, 设置方法参考以下代码。 + GX_DEVICE_CLASS_LIST objDeviceClass = irisCamPtr->GetDeviceInfo().GetDeviceClass(); + if(GX_DEVICE_CLASS_GEV == objDeviceClass) + { + // 判断设备是否支持流通道数据包功能 + if(true == irisFeaturePtr->IsImplemented("GevSCPSPacketSize")) + { + // 获取当前网络环境的最优包长值 + int nPacketSize = irisStreamPtr->GetOptimalPacketSize(); + // 将最优包长值设置为当前设备的流通道包长值 + irisFeaturePtr->GetIntFeature("GevSCPSPacketSize")->SetValue(nPacketSize); + } + } + + //设置采集模式为连续采集模式 + irisFeaturePtr->GetEnumFeature("AcquisitionMode")->SetValue("Continuous"); + + //设置触发模式关 + irisFeaturePtr->GetEnumFeature("TriggerMode")->SetValue("On"); + irisFeaturePtr->GetEnumFeature("TriggerSource")->SetValue("Software"); +} diff --git a/device/IrisCameraController.h b/device/IrisCameraController.h new file mode 100644 index 0000000..5d7e269 --- /dev/null +++ b/device/IrisCameraController.h @@ -0,0 +1,49 @@ +#ifndef IRISCAMERACONTROLLER_H +#define IRISCAMERACONTROLLER_H + +#include + +#include "IrisCameraCapEventHandler.h" + +class IrisCameraCapEventHandler; + +class IrisCameraController : public QObject +{ + Q_OBJECT +public: + explicit IrisCameraController(QObject *parent = nullptr); + ~IrisCameraController(); + + // 初始化并打开人脸相机 + void initIrisCamera(); + void openIrisCamera(); + void closeIrisCamera(); + + void startCapture(); + void stopCapture(); + + void getLeftAndRightEyeFrame(); + + IrisCameraCapEventHandler * irisCamHandler; + +private: + GxIAPICPP::gxdeviceinfo_vector irisCamList; + + CGXDevicePointer irisCamPtr; ///< 设备句柄 + + CGXStreamPointer irisStreamPtr; ///< 左眼设备流 + + CGXFeatureControlPointer irisFeaturePtr; ///< 左眼属性控制器 + + CGXFeatureControlPointer irisStreamFeaturePtr; ///< 左眼流层控制器对象 + + void OpenDevice(); + +signals: + +public slots: + void getOneFaceFrm(); + +}; + +#endif // IRISCAMERACONTROLLER_H diff --git a/device/device.pri b/device/device.pri new file mode 100644 index 0000000..a8417f2 --- /dev/null +++ b/device/device.pri @@ -0,0 +1,13 @@ + +HEADERS += $$PWD/IrisCameraController.h +HEADERS += $$PWD/IrisCameraCapEventHandler.h +#HEADERS += $$PWD/iris/IrisRegistProcess.h +#HEADERS += $$PWD/iris/IrisRecogProcess.h +#HEADERS += $$PWD/iris/CasicIrisRecState.h + +SOURCES += $$PWD/IrisCameraController.cpp +SOURCES += $$PWD/IrisCameraCapEventHandler.cpp +#SOURCES += $$PWD/iris/IrisRegistProcess.cpp +#SOURCES += $$PWD/iris/IrisRecogProcess.cpp +#SOURCES += $$PWD/iris/CasicIrisRecState.cpp + diff --git a/images/bg_footer.png b/images/bg_footer.png new file mode 100644 index 0000000..a3a99ab --- /dev/null +++ b/images/bg_footer.png Binary files differ diff --git a/images/bg_statcked.png b/images/bg_statcked.png new file mode 100644 index 0000000..18b63e1 --- /dev/null +++ b/images/bg_statcked.png Binary files differ diff --git a/images/bg_title.png b/images/bg_title.png new file mode 100644 index 0000000..0316e2d --- /dev/null +++ b/images/bg_title.png Binary files differ diff --git a/main.cpp b/main.cpp index 16bc45b..9052ddb 100644 --- a/main.cpp +++ b/main.cpp @@ -1,11 +1,11 @@ -#include "IdentifyForm.h" +#include "MainWindowForm.h" #include int main(int argc, char *argv[]) { QApplication a(argc, argv); - IdentifyForm w; + MainWindowForm w; w.show(); return a.exec(); } diff --git a/resource.qrc b/resource.qrc new file mode 100644 index 0000000..474586a --- /dev/null +++ b/resource.qrc @@ -0,0 +1,35 @@ + + + images/setting.png + images/user.png + images/back.png + images/home.png + images/btnPageFirst.png + images/btnPageLast.png + images/btnPageNext.png + images/btnPagePre.png + images/regist.png + images/photoEyeLeft.png + images/photoEyeRight.png + images/photoFace.png + images/save.png + images/upArrow.png + images/downArrow.png + images/faceCaped.png + images/faceNotCap.png + images/irisCaped.png + images/irisNotCap.png + images/tipsFailure.png + images/tipsSuccess.png + images/tipsConfirm.png + images/bg_recognize_result.png + images/iconRetry.png + images/bg_title.png + images/bg_footer.png + images/bg_statcked.png + + + images/add_bottom.png + images/add_top.png + + diff --git a/utils/ImageUtil.cpp b/utils/ImageUtil.cpp new file mode 100644 index 0000000..7604572 --- /dev/null +++ b/utils/ImageUtil.cpp @@ -0,0 +1,97 @@ +#include "ImageUtil.h" + +ImageUtil::ImageUtil() +{ + +} + +QImage ImageUtil::MatImageToQImage(const cv::Mat &src) +{ + //CV_8UC1 8位无符号的单通道---灰度图片 + if(src.type() == CV_8UC1) + { + QImage qImage((const unsigned char *)(src.data), src.cols, src.rows, src.cols, QImage::Format_Grayscale8); + return qImage; + } + //为3通道的彩色图片 + else if(src.type() == CV_8UC3) + { + //得到图像的的首地址 + const uchar *pSrc = (const uchar*)src.data; + //以src构造图片 + QImage qImage(pSrc, src.cols, src.rows, src.step, QImage::Format_RGB888); + //在不改变实际图像数据的条件下, 交换红蓝通道 + return qImage.rgbSwapped(); + } + //四通道图片, 带Alpha通道的RGB彩色图像 + else if(src.type() == CV_8UC4) + { + const uchar *pSrc = (const uchar*)src.data; + QImage qImage(pSrc, src.cols, src.rows, src.step, QImage::Format_ARGB32); + //返回图像的子区域作为一个新图像 + return qImage.copy(); + } + else + { + return QImage(); + } +} +/* +QImage ImageUtil::UcharToQImage(unsigned char* data, int width, int height, QImage::Format format) +{ + QImage qImage(data, width, height, format); + //在不改变实际图像数据的条件下, 交换红蓝通道 + return qImage.rgbSwapped(); +} + +cv::Mat ImageUtil::QImageToMat(QImage image) +{ + cv::Mat mat; + switch(image.format()) + { + case QImage::Format_ARGB32: + case QImage::Format_RGB32: + case QImage::Format_ARGB32_Premultiplied: + mat = cv::Mat(image.height(), image.width(), CV_8UC4, (void*)image.constBits(), image.bytesPerLine()); + break; + case QImage::Format_RGB888: + mat = cv::Mat(image.height(), image.width(), CV_8UC3, (void*)image.constBits(), image.bytesPerLine()); + cv::cvtColor(mat, mat, cv::COLOR_BGR2RGB); + break; + case QImage::Format_Indexed8: + mat = cv::Mat(image.height(), image.width(), CV_8UC1, (void*)image.constBits(), image.bytesPerLine()); + break; + case QImage::Format_Grayscale8: + mat = cv::Mat(image.height(), image.width(), CV_8UC1, (void *)image.bits(), image.bytesPerLine()); + break; + } + + mat = mat.clone(); + + return mat; +} + +QString ImageUtil::QImageToBase64(QImage image) +{ + QByteArray ba; + QBuffer buf(&ba); + image.save(&buf, "bmp"); + QString base64String = ba.toBase64(); + return base64String; +} + +cv::Mat ImageUtil::MatImageRect(const cv::Mat &src, cv::Rect rect, int delta) +{ + cv::Mat matClone = src.clone(); + cv::Rect bigRect; + + bigRect.x = rect.x - delta < 0 ? 0 : rect.x - delta; + bigRect.y = rect.y - delta < 0 ? 0 : rect.y - delta; + bigRect.width = rect.x + rect.width + 2 * delta > src.cols ? src.cols - rect.x : rect.width + 2 * delta; + bigRect.height = rect.y + rect.height + 2 * delta > src.rows ? src.rows - rect.y : rect.height + 2 * delta; + + cv::Mat roi = matClone(bigRect); + + return roi; +} +*/ diff --git a/utils/ImageUtil.h b/utils/ImageUtil.h new file mode 100644 index 0000000..dbfdd48 --- /dev/null +++ b/utils/ImageUtil.h @@ -0,0 +1,22 @@ +#ifndef IMAGEUTIL_H +#define IMAGEUTIL_H + +#include +#include +#include "opencv2/opencv.hpp" + +class ImageUtil +{ +public: + ImageUtil(); + + static QImage MatImageToQImage(const cv::Mat &src); +// static QImage UcharToQImage(unsigned char* data, int width, int height, QImage::Format format); + +// static cv::Mat QImageToMat(QImage image); +// static QString QImageToBase64(QImage image); + +// static cv::Mat MatImageRect(const cv::Mat &src, cv::Rect rect, int delta); +}; + +#endif // IMAGEUTIL_H diff --git a/utils/SettingConfig.cpp b/utils/SettingConfig.cpp new file mode 100644 index 0000000..d420285 --- /dev/null +++ b/utils/SettingConfig.cpp @@ -0,0 +1,44 @@ +#include "SettingConfig.h" +#include + +SettingConfig::SettingConfig() +{ + filename = QApplication::applicationDirPath() + "/conf/config.ini"; + setting = new QSettings(this->filename, QSettings::IniFormat); + + WINDOW_WIDTH = getProperty("window", "width").toInt(); + WINDOW_HEIGHT = getProperty("window", "height").toInt(); + WINDOW_BACKGROUND_COLOR = getProperty("window", "backgroundColor").toString(); + WINDOW_TITLE = getProperty("window", "title").toString(); + WINDOW_RIGHTS = getProperty("window", "copyright").toString(); + WINDOW_VERSION = getProperty("window", "version").toString(); + + IRIS_FRAME_WIDTH = getProperty("camera", "irisFrameWidth").toInt(); + IRIS_FRAME_HEIGHT = getProperty("camera", "irisFrameHeight").toInt(); + IRIS_WIDTH = getProperty("camera", "irisWidth").toInt(); + IRIS_HEIGHT = getProperty("camera", "irisHeight").toInt(); + IRIS_FRAME_INTERVAL = getProperty("camera", "irisFrameInterval").toInt(); + IRIS_DISPLAY_WIDTH = getProperty("camera", "irisDisplayWidth").toInt(); + IRIS_DISPLAY_HEIGHT = getProperty("camera", "irisDisplayHeight").toInt(); + + MAX_MATCH_TIME = getProperty("recognize", "maxMatchTime").toInt(); + SUCCESS_TIPS_LAST = getProperty("recognize", "successTipsLast").toInt(); + FAILURE_TIPS_LAST = getProperty("recognize", "failureTipsLast").toInt(); + MAX_FACE_TRY_COUNT = getProperty("recognize", "maxFaceTryCount").toInt(); + MAX_FACE_NOT_FOUND_COUNT = getProperty("recognize", "maxFaceNotFoundCount").toInt(); + MAX_IRIS_TRY_COUNT = getProperty("recognize", "maxIrisTryCount").toInt(); + MAX_EYE_NOT_FOUND_COUNT = getProperty("recognize", "maxEyeNotFoundCount").toInt(); + + MAX_CAPTURE_STACK_SIZE = getProperty("stack", "capture").toInt(); + MAX_FOUND_STACK_SIZE = getProperty("stack", "found").toInt(); + MAX_QUALIFIED_STACK_SIZE = getProperty("stack", "qualified").toInt(); + + LOG_FILE = getProperty("log", "logFile").toString(); + LOG_LEVEL = getProperty("log", "logLevel").toString(); +} + + +QVariant SettingConfig::getProperty(QString nodeName, QString keyName) { + QVariant var = this->setting->value(QString("/%1/%2").arg(nodeName).arg(keyName)); + return var; +} diff --git a/AppConstants.h b/AppConstants.h new file mode 100644 index 0000000..296c53f --- /dev/null +++ b/AppConstants.h @@ -0,0 +1,28 @@ +#ifndef APPCONSTANTS_H +#define APPCONSTANTS_H + +class AppConstants +{ +public: + enum WidgeFrameName + { + MAIN_PAGE = 0, // 主页面 + PERSON_LIST_FORM = 1, // 人员列表页面 + ADD_PERSON_FORM = 2, // 添加人员页面 + ADD_PERSON_CAPTURE_FACE = 21, // 添加/编辑人员时进行人脸拍图 + ADD_PERSON_CAPTURE_IRIS = 22, // 添加/编辑人员时进行虹膜拍图 + SETTING_FORM = 3, // 设置页面 + RECOGNIZE_RESULT_FORM = 4, // 识别结果界面 + IDENTIFY_FORM = 5, // 识别界面 含识别中 和 识别结果 + LOCKSCREEN_FORM = 6 // 锁屏待机界面 + }; + + enum ApplicationState + { + STATE_WAIT = 0, // 待机 + STATE_WORKING = 1, // 工作状态 + STATE_IDENTIFYING = 2, // 识别中 + }; +}; + +#endif // APPCONSTANTS_H diff --git a/CasicIrisIdentify.pro b/CasicIrisIdentify.pro index 5d7fea6..575ce3d 100644 --- a/CasicIrisIdentify.pro +++ b/CasicIrisIdentify.pro @@ -1,4 +1,4 @@ -QT += core gui +QT += core gui sql network texttospeech greaterThan(QT_MAJOR_VERSION, 4): QT += widgets @@ -15,20 +15,46 @@ # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 -SOURCES += \ - main.cpp \ - IdentifyForm.cpp +include("dao/dao.pri") +include("device/device.pri") +include("utils/utils.pri") -HEADERS += \ - IdentifyForm.h +SOURCES += main.cpp +SOURCES += ProMemory.cpp +SOURCES += MainWindowForm.cpp +SOURCES += IdentifyForm.cpp +SOURCES += LockScreenForm.cpp -FORMS += \ - IdentifyForm.ui +HEADERS += AppConstants.h +HEADERS += ProMemory.h +HEADERS += MainWindowForm.h +HEADERS += IdentifyForm.h +HEADERS += LockScreenForm.h -TRANSLATIONS += \ - CasicIrisIdentify_zh_CN.ts +FORMS += MainWindowForm.ui +FORMS += IdentifyForm.ui +FORMS += LockScreenForm.ui + +RESOURCES += resource.qrc + +DISTFILES += conf/config.ini + +#TRANSLATIONS += CasicIrisIdentify_zh_CN.ts + +#INCLUDEPATH += include/spdlog +#DEPENDPATH += include/spdlog # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target + + +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lopencv_world420 +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lGxIAPICPPEx + +INCLUDEPATH += $$PWD/include/daheng +DEPENDPATH += $$PWD/include/daheng + +INCLUDEPATH += $$PWD/include +DEPENDPATH += $$PWD/include diff --git a/CasicIrisIdentify_zh_CN.ts b/CasicIrisIdentify_zh_CN.ts index 5526fe4..81900df 100644 --- a/CasicIrisIdentify_zh_CN.ts +++ b/CasicIrisIdentify_zh_CN.ts @@ -1,3 +1,12 @@ - + + + IdentifyForm + + + IdentifyForm + + + + diff --git a/IdentifyForm.cpp b/IdentifyForm.cpp index 348a897..ba1f251 100644 --- a/IdentifyForm.cpp +++ b/IdentifyForm.cpp @@ -1,4 +1,4 @@ -#include "IdentifyForm.h" +#include "IdentifyForm.h" #include "ui_IdentifyForm.h" IdentifyForm::IdentifyForm(QWidget *parent) @@ -6,6 +6,12 @@ , ui(new Ui::IdentifyForm) { ui->setupUi(this); + + // 初始化更新界面的定时器 + // 每秒执行一次 + connect(TimeCounterUtil::getInstance().clockCounter, &QTimer::timeout, this, &IdentifyForm::updateDateAndTime); + + TimeCounterUtil::getInstance().clockCounter->start(1000); } IdentifyForm::~IdentifyForm() @@ -13,3 +19,16 @@ delete ui; } +void IdentifyForm::drawIrisImageOnFrame(QImage image) +{ + // 只在识别界面才显示画面 + if (ui->wgtStacked->currentIndex() == 0) { + ui->labelVideo->setPixmap(QPixmap::fromImage(image)); + } +} + + +void IdentifyForm::updateDateAndTime() +{ + ui->labelTime->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd dddd HH:mm:ss")); +} diff --git a/IdentifyForm.h b/IdentifyForm.h index fc857a1..ae1cd22 100644 --- a/IdentifyForm.h +++ b/IdentifyForm.h @@ -1,7 +1,10 @@ -#ifndef IDENTIFYFORM_H +#ifndef IDENTIFYFORM_H #define IDENTIFYFORM_H #include +#include + +#include "utils/UtilInclude.h" QT_BEGIN_NAMESPACE namespace Ui { class IdentifyForm; } @@ -15,7 +18,14 @@ IdentifyForm(QWidget *parent = nullptr); ~IdentifyForm(); +public slots: + void drawIrisImageOnFrame(QImage image); + private: Ui::IdentifyForm *ui; + +private slots: + void updateDateAndTime(); + }; #endif // IDENTIFYFORM_H diff --git a/IdentifyForm.ui b/IdentifyForm.ui index c72a36f..879dc9a 100644 --- a/IdentifyForm.ui +++ b/IdentifyForm.ui @@ -6,13 +6,59 @@ 0 0 - 800 + 600 600 IdentifyForm + + + + 0 + 40 + 600 + 450 + + + + 0 + + + + + + 100 + 10 + 400 + 300 + + + + + + + + + + + + + + 0 + 0 + 600 + 40 + + + + TextLabel + + + Qt::AlignCenter + + diff --git a/LockScreenForm.cpp b/LockScreenForm.cpp new file mode 100644 index 0000000..58dc54b --- /dev/null +++ b/LockScreenForm.cpp @@ -0,0 +1,14 @@ +#include "LockScreenForm.h" +#include "ui_LockScreenForm.h" + +LockScreenForm::LockScreenForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::LockScreenForm) +{ + ui->setupUi(this); +} + +LockScreenForm::~LockScreenForm() +{ + delete ui; +} diff --git a/LockScreenForm.h b/LockScreenForm.h new file mode 100644 index 0000000..b5ded48 --- /dev/null +++ b/LockScreenForm.h @@ -0,0 +1,25 @@ +#ifndef LOCKSCREENFORM_H +#define LOCKSCREENFORM_H + +#include +#include + +#include "utils/UtilInclude.h" + +namespace Ui { +class LockScreenForm; +} + +class LockScreenForm : public QWidget +{ + Q_OBJECT + +public: + explicit LockScreenForm(QWidget *parent = nullptr); + ~LockScreenForm(); + +private: + Ui::LockScreenForm *ui; +}; + +#endif // LOCKSCREENFORM_H diff --git a/LockScreenForm.ui b/LockScreenForm.ui new file mode 100644 index 0000000..7f2a6db --- /dev/null +++ b/LockScreenForm.ui @@ -0,0 +1,45 @@ + + + LockScreenForm + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + 180 + 100 + 54 + 12 + + + + TextLabel + + + + + + 180 + 160 + 54 + 12 + + + + TextLabel + + + + + + diff --git a/MainWindowForm.cpp b/MainWindowForm.cpp new file mode 100644 index 0000000..84f8159 --- /dev/null +++ b/MainWindowForm.cpp @@ -0,0 +1,86 @@ +#include "MainWindowForm.h" +#include "ui_MainWindowForm.h" +#include + +MainWindowForm::MainWindowForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::MainWindowForm) +{ + ui->setupUi(this); + + // 设置窗口透明和大小、位置 + this->setWindowFlags(Qt::FramelessWindowHint); + this->move(1400, 15); + this->resize(SettingConfig::getInstance().WINDOW_WIDTH, SettingConfig::getInstance().WINDOW_HEIGHT); + + // 通过调色板的颜色来设置窗口的统一背景色 + qApp->setPalette(QPalette(QColor(SettingConfig::getInstance().WINDOW_BACKGROUND_COLOR))); + + // 加载css文件设置控件样式 + QFile file(QApplication::applicationDirPath() + "/qss/main.css"); + if (file.open(QFile::ReadOnly)) + { + QString qssStr = QLatin1String(file.readAll()); + this->setStyleSheet(qssStr); + file.close(); + } + + initFormsPtr(); + + // 设置标题文字 + ui->labelTitle->setText(SettingConfig::getInstance().WINDOW_TITLE); + ui->labelCopyright->setText(SettingConfig::getInstance().WINDOW_RIGHTS); + ui->labelVersion->setText(SettingConfig::getInstance().WINDOW_VERSION); + + // 初始化虹膜相机控制 + ProMemory::getInstance().irisCam = new IrisCameraController(this); + ProMemory::getInstance().irisCam->initIrisCamera(); + ProMemory::getInstance().irisCam->openIrisCamera(); + connect(ProMemory::getInstance().irisCam->irisCamHandler, &IrisCameraCapEventHandler::sendIrisFrameToDraw, identifyForm, &IdentifyForm::drawIrisImageOnFrame); + +// LOG_INFO(QString("应用程序启动成功[Application Startup Success]").toStdString()); + qDebug() << "应用程序启动成功[Application Startup Success]"; + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::IDENTIFY_FORM; + ui->wdgtStatced->setCurrentWidget(identifyForm); + + // 开始虹膜相机拍图 + ProMemory::getInstance().irisCam->startCapture(); +} + +MainWindowForm::~MainWindowForm() +{ + delete ui; +} + +void MainWindowForm::lockScreen() +{ + ui->wdgtStatced->setCurrentWidget(lockScreenForm); + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::LOCKSCREEN_FORM; + ProMemory::getInstance().appState = AppConstants::ApplicationState::STATE_WAIT; +} + +void MainWindowForm::keyPressEvent(QKeyEvent *event) +{ + switch (event->key()) { + case Qt::Key_Escape: + QTimer::singleShot(100, qApp, [=](){ + QApplication::quit(); + }); + + default: + QWidget::keyPressEvent(event); + } +} + +void MainWindowForm::initFormsPtr() +{ + // 初始化各个form + lockScreenForm = new LockScreenForm(this); + identifyForm = new IdentifyForm(this); + + // 将form添加到statcked widget中 + ui->wdgtStatced->addWidget(identifyForm); + ui->wdgtStatced->addWidget(lockScreenForm); + + // 绑定按钮函数 +} diff --git a/MainWindowForm.h b/MainWindowForm.h new file mode 100644 index 0000000..7fb2d89 --- /dev/null +++ b/MainWindowForm.h @@ -0,0 +1,38 @@ +#ifndef MAINWINDOWFORM_H +#define MAINWINDOWFORM_H + +#include +#include +#include + +#include "utils/UtilInclude.h" +#include "ProMemory.h" +#include "LockScreenForm.h" +#include "IdentifyForm.h" + +namespace Ui { +class MainWindowForm; +} + +class MainWindowForm : public QWidget +{ + Q_OBJECT + +public: + explicit MainWindowForm(QWidget *parent = nullptr); + ~MainWindowForm(); + +public slots: + void lockScreen(); + +private: + Ui::MainWindowForm *ui; + LockScreenForm * lockScreenForm; + IdentifyForm * identifyForm; + + void keyPressEvent(QKeyEvent *event); + + void initFormsPtr(); +}; + +#endif // MAINWINDOWFORM_H diff --git a/MainWindowForm.ui b/MainWindowForm.ui new file mode 100644 index 0000000..e793ebf --- /dev/null +++ b/MainWindowForm.ui @@ -0,0 +1,85 @@ + + + MainWindowForm + + + + 0 + 0 + 600 + 1024 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + 0 + 0 + 600 + 84 + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + + + + TextLabel + + + Qt::AlignBottom|Qt::AlignHCenter + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + diff --git a/ProMemory.cpp b/ProMemory.cpp new file mode 100644 index 0000000..19e7403 --- /dev/null +++ b/ProMemory.cpp @@ -0,0 +1,84 @@ +#include "ProMemory.h" + +ProMemory::ProMemory() +{ + +} + +ProMemory::~ProMemory() +{ + +} + +/* +void ProMemory::pushCasicIris(CasicIrisInfo irisInfo) +{ + QMutex mutex; + mutex.lock(); + if (this->irisQueue.size() > 30) + { + QStack empty; + std::swap(empty, irisQueue); + } + + irisQueue.push(irisInfo); + mutex.unlock(); +} +CasicIrisInfo ProMemory::popCasicIris() +{ + CasicIrisInfo result; + + QMutex mutex; + mutex.lock(); + if (this->irisQueue.size() > 0) + { + result = irisQueue.pop(); + } + + mutex.unlock(); + + return result; +} +*/ +int ProMemory::getIrisQueueSize() +{ + int size = 0; + + QMutex mutex; + mutex.lock(); + +// size = this->irisQueue.size(); + + mutex.unlock(); + + return size; +} +bool ProMemory::isIrisQueueEmpty() +{ + bool empty = true; + + QMutex mutex; + mutex.lock(); + +// empty = this->irisQueue.isEmpty(); + + mutex.unlock(); + + return empty; +} +void ProMemory::clearIrisQueue() +{ + QMutex mutex; + mutex.lock(); + +// QStack empty; +// std::swap(empty, irisQueue); + + mutex.unlock(); +} + + +void ProMemory::initIrisFeatures(QString personId) +{ +// irisRegistPro->sendDataToExract(QByteArray(QString("[-u]").append(personId).toLocal8Bit())); +} diff --git a/ProMemory.h b/ProMemory.h new file mode 100644 index 0000000..2ecd653 --- /dev/null +++ b/ProMemory.h @@ -0,0 +1,52 @@ +#ifndef PROMEMORY_H +#define PROMEMORY_H + +#include +#include + +#include "AppConstants.h" +//#include "casic/iris/CasicIrisInfo.h" +#include "dao/IrisDataDao.h" + +#include "device/IrisCameraController.h" +//#include "device/iris/IrisRegistProcess.h" +//#include "device/iris/IrisRecogProcess.h" + +class IrisCameraController; +class IrisRegistProcess; +class IrisRecogProcess; + +class ProMemory +{ +public: + ~ProMemory(); + ProMemory(const ProMemory&)=delete; + ProMemory& operator=(const ProMemory&)=delete; + + static ProMemory& getInstance() { + static ProMemory instance; + return instance; + } + +// void pushCasicIris(CasicIrisInfo irisInfo); +// CasicIrisInfo popCasicIris(); + int getIrisQueueSize(); + bool isIrisQueueEmpty(); + void clearIrisQueue(); + + volatile int widgeFrame = 0; // 当前显示的界面 + volatile int appState = 0; // 当前程序所处的状态 + + void initIrisFeatures(QString personId = ""); // 初始化虹膜特征值集合 + + IrisCameraController * irisCam; + IrisRecogProcess * irisRecogPro; + +private: + ProMemory(); + +// QStack irisQueue; // 虹膜信息队列 + QVector irisFeatures; // 虹膜特征值集合 +}; + +#endif // PROMEMORY_H diff --git a/conf/config.ini b/conf/config.ini new file mode 100644 index 0000000..66e46ad --- /dev/null +++ b/conf/config.ini @@ -0,0 +1,67 @@ +[recognize] +#最大允许识别时间(ms) +maxMatchTime=10000 +#识别成功界面停留时间(ms) +successTipsLast=5000 +#识别失败界面停留时间(ms) +failureTipsLast=3000 +#人脸识别最大尝试次数 +maxFaceTryCount=20 +#持续没找到人脸的最大次数 +maxFaceNotFoundCount=500 +#注册时最小人脸 +minFaceRegist=240 +#识别时最小人脸 +minFaceRecog=100 + +#虹膜识别最大尝试次数 +maxIrisTryCount=10 +#虹膜识别持续没有找到眼的最大次数 +maxEyeNotFoundCount=50 + +#识别方式[1=人脸;2=虹膜;3=双认证;4=任意] +recogType=4 + +[window] +#界面窗口宽(px) +width=600 +#界面窗口高(px) +height=1024 +#统一背景色 +backgroundColor="#FFFFFF" +#标题 +title="虹膜识别终端" + +[work] +#工作状态检测时最小人脸范围 +minFaceSize=160 +#人脸范围最小横坐标 +minFacePosX=320 +#人脸范围最大横坐标 +maxFacePosX=960 +#人脸范围最小纵坐标 +minFacePosY=180 +#人脸范围最大纵坐标 +maxFacePosY=540 +#人脸太近阈值 +faceCloseSize=360 +#人脸太远阈值 +faceFarSize=480 + +[camera] +#虹膜相机取一幅画面的时间间隔(ms) +irisFrameInterval=100 +#虹膜相机拍摄宽度 +irisFrameWidth=1440 +#虹膜相机拍摄高度 +irisFrameHeight=1080 +#虹膜图像高度 +irisWidth=640 +#虹膜图像高度 +irisHeight=480 + +[log] +#日志文件位置 +logFile="d://irisLogs//casic_log.txt" +#日志级别 +logLevel="trace" diff --git a/dao/BaseDao.cpp b/dao/BaseDao.cpp new file mode 100644 index 0000000..f51c144 --- /dev/null +++ b/dao/BaseDao.cpp @@ -0,0 +1,12 @@ +#include "BaseDao.h" +#include "dao/util/ConnectionManager.h" + +BaseDao::BaseDao(QObject *parent) : QObject(parent) +{ + +} + +BaseDao::~BaseDao() +{ + +} diff --git a/dao/BaseDao.h b/dao/BaseDao.h new file mode 100644 index 0000000..1693c88 --- /dev/null +++ b/dao/BaseDao.h @@ -0,0 +1,32 @@ +#ifndef BASEDAO_H +#define BASEDAO_H + +#include +#include +#include +#include + +#include "dao/util/ConnectionManager.h" +#include "utils/UtilInclude.h" + +class BaseDao : public QObject +{ + Q_OBJECT +public: + explicit BaseDao(QObject *parent = nullptr); + ~BaseDao(); + + virtual QVector findAllRecord() = 0; + virtual QVariantMap findRecordById(QString id) = 0; + + virtual QString save(QVariantMap object) = 0; + virtual bool edit(QVariantMap newObject, QString id) = 0; + virtual bool dele(QString id) = 0; + +private: + +signals: + +}; + +#endif // BASEDAO_H diff --git a/dao/IrisDataDao.cpp b/dao/IrisDataDao.cpp new file mode 100644 index 0000000..37a0ed6 --- /dev/null +++ b/dao/IrisDataDao.cpp @@ -0,0 +1,204 @@ +#include "IrisDataDao.h" + +IrisDataDao::IrisDataDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector IrisDataDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM IRIS_DATA"; + query.prepare(sql); + + // 执行查询 + query.exec(); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + item.insert("id", query.value("id").toString()); + item.insert("person_id", query.value("person_id").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("left_iris_code1", query.value("left_iris_code1")); + item.insert("left_iris_code2", query.value("left_iris_code2")); + item.insert("left_iris_code3", query.value("left_iris_code3")); + item.insert("right_iris_code1", query.value("right_iris_code1")); + item.insert("right_iris_code2", query.value("right_iris_code2")); + item.insert("right_iris_code3", query.value("right_iris_code3")); + + result.append(item); + } + +// LOG_DEBUG(QString("查询IRIS_DATA表的所有记录[结果数:%1]").arg(result.size()).toStdString()); + return result; +} + +QVariantMap IrisDataDao::findRecordById(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM IRIS_DATA WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + // 获取结果 + if (query.next()) + { + result.insert("id", query.value("id").toString()); + result.insert("person_id", query.value("person_id").toLongLong()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("left_iris_code1", query.value("left_iris_code1")); + result.insert("left_iris_code2", query.value("left_iris_code2")); + result.insert("left_iris_code3", query.value("left_iris_code3")); + result.insert("right_iris_code1", query.value("right_iris_code1")); + result.insert("right_iris_code2", query.value("right_iris_code2")); + result.insert("right_iris_code3", query.value("right_iris_code3")); + } + +// LOG_DEBUG(QString("根据id查询IRIS_DATA表的记录[id=%1]").arg(id).toStdString()); + return result; +} + +QVariantMap IrisDataDao::findRecordByPersonId(QString personId) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM IRIS_DATA WHERE PERSON_ID = :personId"); + query.prepare(sql); + query.bindValue(":personId", personId); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + if (query.next()) + { + result.insert("id", query.value("id").toString()); + result.insert("person_id", query.value("person_id").toLongLong()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("left_iris_code1", query.value("left_iris_code1")); + result.insert("left_iris_code2", query.value("left_iris_code2")); + result.insert("left_iris_code3", query.value("left_iris_code3")); + result.insert("right_iris_code1", query.value("right_iris_code1")); + result.insert("right_iris_code2", query.value("right_iris_code2")); + result.insert("right_iris_code3", query.value("right_iris_code3")); + } + +// LOG_DEBUG(QString("根据personId查询IRIS_DATA表的记录[personId=%1]").arg(personId).toStdString()); + return result; +} + + +QString IrisDataDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + + // INSERT语句 + QString sql = QString("INSERT INTO IRIS_DATA (ID, PERSON_ID, ID_CARD_NO, LEFT_IRIS_CODE1, RIGHT_IRIS_CODE1) VALUES (:id, :personId, :idCardNo, :left1, :right1)"); + + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":personId", object.value("person_id").toString()); + query.bindValue(":idCardNo", object.value("id_card_no").toString()); + query.bindValue(":left1", object.value("left_iris_code1")); + query.bindValue(":right1", object.value("right_iris_code1")); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(); + +// LOG_DEBUG(QString("保存虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool IrisDataDao::edit(QVariantMap newObject, QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // UPDATE语句 + if (!newObject.contains("left_iris_code1") || !newObject.contains("right_iris_code1")){ + return false; + } + QString sql = QString("UPDATE IRIS_DATA SET LEFT_IRIS_CODE1 = :left1, RIGHT_IRIS_CODE1 = :right1 WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":left1", newObject.value("left_iris_code1")); + query.bindValue(":right1", newObject.value("right_iris_code1")); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(); + +// LOG_DEBUG(QString("编辑虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; +} + + +bool IrisDataDao::dele(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + QString sql = QString("DELETE FROM IRIS_DATA WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(); + +// LOG_DEBUG(QString("删除虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; +} diff --git a/dao/IrisDataDao.h b/dao/IrisDataDao.h new file mode 100644 index 0000000..c74dbbd --- /dev/null +++ b/dao/IrisDataDao.h @@ -0,0 +1,25 @@ +#ifndef IRISDATADAO_H +#define IRISDATADAO_H + +#include +#include "BaseDao.h" + +class IrisDataDao : public BaseDao +{ + Q_OBJECT +public: + explicit IrisDataDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + QVariantMap findRecordByPersonId(QString personId); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +signals: + +}; + +#endif // IRISDATADAO_H diff --git a/dao/RecognitionRecordsDao.cpp b/dao/RecognitionRecordsDao.cpp new file mode 100644 index 0000000..40db453 --- /dev/null +++ b/dao/RecognitionRecordsDao.cpp @@ -0,0 +1,100 @@ +#include "RecognitionRecordsDao.h" + +RecognitionRecordsDao::RecognitionRecordsDao(QObject *parent) : BaseDao(parent) +{ + +} + + +QVector RecognitionRecordsDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM RECOGNITION_RECORDS"; + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + item.insert("id", query.value("id").toLongLong()); + result.append(item); + } + +// LOG_DEBUG(QString("查询RECOGNITION_RECORDS表的所有记录[记录数:%1]").arg(result.size()).toStdString()); + return result; +} + +QVariantMap RecognitionRecordsDao::findRecordById(QString id) +{ + QVariantMap item; + return item; +} + +QString RecognitionRecordsDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + + // INSERT语句 + QString sql = QString("INSERT INTO RECOGNITION_RECORDS (ID, PERSON_ID, DATETIME, REC_TYPE, DEV_CODE, DOOR_CODE, INOUT_TYPE) " + "VALUES (:id, :personId, :datetime, :recType, :devCode, :doorCode, :inoutType)"); + + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":personId", object.value("person_id").toString()); + query.bindValue(":datetime", object.value("date_time").toString()); + query.bindValue(":recType", object.value("rec_type").toString()); + query.bindValue(":devCode", object.value("dev_code").toString()); + query.bindValue(":doorCode", object.value("door_code").toString()); + query.bindValue(":inoutType", object.value("inout_type").toString()); + +// LOG_DEBUG(sql.toStdString()); + + // 插入识别的log日志 + QString logStr = QString("INSERT INTO RECOGNITION_LOGS (ID, LOG_INFO) VALUES (:id, :logInfo)"); + + QSqlQuery logQuery(ConnectionManager::getInstance()->getConnection()); + logQuery.prepare(logStr); + logQuery.bindValue(":id", id); + logQuery.bindValue(":logInfo", object.value("debug_info").toString()); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(); + logQuery.exec(); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool RecognitionRecordsDao::edit(QVariantMap newObject, QString id) +{ + return false; +} + +bool RecognitionRecordsDao::dele(QString id) +{ + return false; +} diff --git a/dao/RecognitionRecordsDao.h b/dao/RecognitionRecordsDao.h new file mode 100644 index 0000000..38de7c9 --- /dev/null +++ b/dao/RecognitionRecordsDao.h @@ -0,0 +1,23 @@ +#ifndef RECOGNITIONRECORDSDAO_H +#define RECOGNITIONRECORDSDAO_H + +#include +#include "BaseDao.h" +class RecognitionRecordsDao: public BaseDao +{ + Q_OBJECT +public: + explicit RecognitionRecordsDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +signals: + +}; + +#endif // RECOGNITIONRECORDSDAO_H diff --git a/dao/SysDeptDao.cpp b/dao/SysDeptDao.cpp new file mode 100644 index 0000000..22f9946 --- /dev/null +++ b/dao/SysDeptDao.cpp @@ -0,0 +1,88 @@ +#include "SysDeptDao.h" + +SysDeptDao::SysDeptDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector SysDeptDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_DEPT WHERE PID != '-1' ORDER BY PID, NUM"; + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + item.insert("id", query.value("id").toString()); + item.insert("pid", query.value("pid").toString()); + item.insert("pids", query.value("pids").toString()); + item.insert("simplename", query.value("simplename").toString()); + item.insert("fullname", query.value("fullname").toString()); + } + +// LOG_TRACE(QString("查询表[SYS_DEPT]的所有记录[%1][%2]").arg(result.size()).arg(sql).toStdString()); + + return result; +} + +QVariantMap SysDeptDao::findRecordById(QString id) +{ + QVariantMap item; + return item; + + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM SYS_DEPT WHERE SYS_DEPT.ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + // 获取结果集的大小 + query.last(); + int count = query.at() + 1; + + if (count >=1) + { + query.first(); + + result.insert("id", query.value("id").toString()); + result.insert("pid", query.value("pid").toString()); + result.insert("pids", query.value("pids").toString()); + result.insert("simplename", query.value("simplename").toString()); + result.insert("fullname", query.value("fullname").toString()); + } + +// LOG_TRACE(QString("根据id查询SYS_DEPT表的记录[ID=%1][%2]").arg(id).arg(sql).toStdString()); + + return result; +} + + +QString SysDeptDao::save(QVariantMap object) +{ + return "0"; +} +bool SysDeptDao::edit(QVariantMap newObject, QString id) +{ + return true; +} +bool SysDeptDao::dele(QString id) +{ + return true; +} diff --git a/dao/SysDeptDao.h b/dao/SysDeptDao.h new file mode 100644 index 0000000..e07a09f --- /dev/null +++ b/dao/SysDeptDao.h @@ -0,0 +1,24 @@ +#ifndef SYSDEPTDAO_H +#define SYSDEPTDAO_H + +#include +#include "BaseDao.h" + +class SysDeptDao : public BaseDao +{ + Q_OBJECT +public: + explicit SysDeptDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +private: + +}; + +#endif // SYSDEPTDAO_H diff --git a/dao/SysPersonDao.cpp b/dao/SysPersonDao.cpp new file mode 100644 index 0000000..dd9480f --- /dev/null +++ b/dao/SysPersonDao.cpp @@ -0,0 +1,371 @@ +#include "SysPersonDao.h" + + +SysPersonDao::SysPersonDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector SysPersonDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0'"; + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + count++; + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + result.append(item); + } + +// LOG(TRACE) << QString("查询SYS_PERSON表的所有记录[%1]").arg(count).toStdString(); +// LOG_TRACE(QString("查询SYS_PERSON表的所有记录[%1]").arg(count).toStdString()); + + return result; +} + +QVariantMap SysPersonDao::findRecordById(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0' AND SYS_PERSON.ID = '%1'").arg(id); + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVariantMap result; + + // 获取结果集的大小 + query.last(); + int count = query.at() + 1; + + if (count >=1) + { + query.first(); + + result.insert("id", query.value("id").toString()); + result.insert("delflag", query.value("delflag").toString()); + result.insert("createtime", query.value("createtime").toString()); + result.insert("updatetime", query.value("updatetime").toString()); + result.insert("name", query.value("name").toString()); + result.insert("gender", query.value("gender").toString()); + result.insert("deptid", query.value("deptid").toString()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("remarks", query.value("remarks").toString()); + result.insert("person_code", query.value("person_code").toString()); + result.insert("deptname", query.value("fullname").toString()); + result.insert("sync_id", query.value("sync_id").toString()); + result.insert("hasFace", query.value("face_valid").toString()); + result.insert("hasIris", query.value("iris_valid").toString()); + } + +// LOG(TRACE) << QString("根据id查询SYS_PERSON表的记录[id=%1][%2]").arg(id).arg(sql).toStdString(); +// LOG_TRACE(QString("根据id查询SYS_PERSON表的记录[id=%1][%2]").arg(id).arg(sql).toStdString()); + + return result; +} + +int SysPersonDao::findRecordCountByNameAndDept(QString name, QString dept) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT COUNT(P.ID) AS RECCT FROM SYS_PERSON P LEFT JOIN SYS_DEPT D ON P.DEPTID = D.ID WHERE P.DELFLAG = '0'"; + if (name.isEmpty() == false) + { + sql += " AND P.NAME LIKE '%" + name + "%'"; + } + if (dept.isEmpty() == false && dept.indexOf("-1") < 0) + { + sql += QString(" AND ((P.DEPTID = '%1') OR (D.PIDS LIKE '%,%1,%'))").arg(dept); + } + + // 执行查询 + query.exec(sql); + + // 返回结果 + int result; + + // 遍历查询结果 + if (query.next()) { + result = query.value("RECCT").toInt(); + } + +// LOG(TRACE) << QString("根据姓名和部门查询SYS_PERSON记录总数[%1][%2]").arg(result).arg(sql).toStdString(); +// LOG_TRACE(QString("根据姓名和部门查询SYS_PERSON记录总数[%1][%2]").arg(result).arg(sql).toStdString()); + + return result; +} + +QVector SysPersonDao::findRecordsByNameAndDept(QString name, QString dept, qint8 limit, qint16 offset) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON P LEFT JOIN SYS_DEPT D ON P.DEPTID = D.ID WHERE P.DELFLAG = '0'"; + if (name.isEmpty() == false) + { + sql += " AND P.NAME LIKE '%" + name + "%'"; + } + if (dept.isEmpty() == false && dept.indexOf("-1") < 0) + { + sql += QString(" AND ((P.DEPTID = '%1') OR (D.PIDS LIKE '%,%1,%'))").arg(dept); + } + + sql += QString(" LIMIT %1 OFFSET %2").arg(limit).arg(offset); + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + count++; + + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + + result.append(item); + } + +// LOG(TRACE) << QString("根据姓名和部门分页查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString(); +// LOG_TRACE(QString("根据姓名和部门分页查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString()); + + return result; +} + +QVector SysPersonDao::findRecordsByProperties(QVariantMap conditions) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0'"; + QVariantMap::iterator it; + for (it = conditions.begin(); it != conditions.end(); it++) + { + sql += QString(" AND SYS_PERSON.%1 = %2").arg(it.key()).arg(it.value().toString()); + } + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + count++; + + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + + result.append(item); + } + +// LOG(TRACE) << QString("根据属性值查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString(); +// LOG_TRACE(QString("根据属性值查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString()); + + return result; +} + +QString SysPersonDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + + // INSERT语句 + QString sql = QString("INSERT INTO SYS_PERSON " + "(ID, DELFLAG, CREATETIME, UPDATETIME, " + "NAME, GENDER, DEPTID, ID_CARD_NO, " + "REMARKS, PERSON_CODE, SYNC_ID, FACE_VALID, IRIS_VALID) " + "VALUES ('%1', '0', '%2', '%2', '%3', '%4', '%5', '%6', '%7', '%8', '%9', 0, 0)") + .arg(id).arg(tm) + .arg(object.value("name").toString()) + .arg(object.value("gender").toString()) + .arg(object.value("deptid").toString()) + .arg(object.value("id_card_no").toString()) + .arg(object.value("remarks").toString()) + .arg(object.value("person_code").toString()) + .arg(object.value("sync_id").toString()); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(sql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { +// LOG(DEBUG) << QString("保存SYS_PERSON记录成功[ID = %1][%2]").arg(id).arg(sql).toStdString(); +// LOG_DEBUG(QString("保存SYS_PERSON记录成功[ID = %1][%2]").arg(id).arg(sql).toStdString()); + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool SysPersonDao::edit(QVariantMap newObject, QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + + // UPDATE语句 + QString sql = QString("UPDATE SYS_PERSON SET UPDATETIME = '%1'").arg(tm); + if (newObject.contains("name")) + { + sql.append(QString(", NAME = '%1'").arg(newObject.value("name").toString())); + } + if (newObject.contains("gender")) + { + sql.append(QString(", GENDER = '%1'").arg(newObject.value("gender").toString())); + } + if (newObject.contains("deptid")) + { + sql.append(QString(", DEPTID = '%1'").arg(newObject.value("deptid").toString())); + } + if (newObject.contains("person_code")) + { + sql.append(QString(", PERSON_CODE = '%1'").arg(newObject.value("person_code").toString())); + } + if (newObject.contains("face_valid")) + { + sql.append(QString(", FACE_VALID = '%1'").arg(newObject.value("face_valid").toString())); + } + if (newObject.contains("iris_valid")) + { + sql.append(QString(", IRIS_VALID = '%1'").arg(newObject.value("iris_valid").toString())); + } + + sql.append(QString(" WHERE ID = '%1'").arg(id)); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(sql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + +// LOG(DEBUG) << QString("编辑人员[ID=%1][%2]").arg(id).arg(sql).toStdString(); +// LOG_DEBUG(QString("编辑人员[ID=%1][%2]").arg(id).arg(sql).toStdString()); + + // 返回结果 + return success; +} + +bool SysPersonDao::dele(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + QSqlQuery irisDel(ConnectionManager::getInstance()->getConnection()); + + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + qint64 tmms = QDateTime::currentDateTime().toMSecsSinceEpoch(); + + // UPDATE语句 + QString sql = QString("UPDATE SYS_PERSON SET UPDATETIME = :updateTime, DELFLAG = :flag WHERE ID = :id").arg(tm).arg(tmms).arg(id); + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":updateTime", tm); + query.bindValue(":flag", tmms); + + // 物理删除人员的人脸和虹膜数据 + QString delIrisSql = QString("DELETE FROM IRIS_DATA WHERE PERSON_ID = :personId"); + irisDel.prepare(delIrisSql); + irisDel.bindValue(":personId", id); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(sql); + query.exec(delIrisSql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + +// LOG_DEBUG(QString("删除人员SYS_PERSON[ID=%1][%2]").arg(id).arg(success).toStdString()); + + // 返回结果 + return success; +} diff --git a/dao/SysPersonDao.h b/dao/SysPersonDao.h new file mode 100644 index 0000000..e02e5ba --- /dev/null +++ b/dao/SysPersonDao.h @@ -0,0 +1,27 @@ +#ifndef SYSPERSONDAO_H +#define SYSPERSONDAO_H + +#include +#include "BaseDao.h" + +class SysPersonDao : public BaseDao +{ + Q_OBJECT +public: + explicit SysPersonDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + int findRecordCountByNameAndDept(QString name, QString dept); + QVector findRecordsByNameAndDept(QString name, QString dept, qint8 limit, qint16 offset); + QVector findRecordsByProperties(QVariantMap conditions); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); +signals: + +}; + +#endif // SYSPERSONDAO_H diff --git a/dao/dao.pri b/dao/dao.pri new file mode 100644 index 0000000..1e04ce4 --- /dev/null +++ b/dao/dao.pri @@ -0,0 +1,18 @@ + +HEADERS += $$PWD/BaseDao.h +HEADERS += $$PWD/IrisDataDao.h +HEADERS += $$PWD/RecognitionRecordsDao.h +HEADERS += $$PWD/SysPersonDao.h +HEADERS += $$PWD/SysDeptDao.h + +SOURCES += $$PWD/BaseDao.cpp +SOURCES += $$PWD/IrisDataDao.cpp +SOURCES += $$PWD/RecognitionRecordsDao.cpp +SOURCES += $$PWD/SysPersonDao.cpp +SOURCES += $$PWD/SysDeptDao.cpp + +HEADERS += $$PWD/util/ConnectionManager.h +SOURCES += $$PWD/util/ConnectionManager.cpp +#HEADERS += $$PWD/util/CacheManager.h +#SOURCES += $$PWD/util/CacheManager.cpp + diff --git a/dao/util/ConnectionManager.cpp b/dao/util/ConnectionManager.cpp new file mode 100644 index 0000000..84b17be --- /dev/null +++ b/dao/util/ConnectionManager.cpp @@ -0,0 +1,47 @@ +#include "ConnectionManager.h" +#include + +Q_GLOBAL_STATIC(ConnectionManager, cm) + +ConnectionManager::ConnectionManager(QObject *parent) : QObject(parent) +{ + // 初始化数据库连接 + if (QSqlDatabase::contains("qt_sql_dafault_connection")) + { + conn = QSqlDatabase::database("qt_sql_default_connection"); + } + else + { + conn = QSqlDatabase::addDatabase("QSQLITE"); + conn.setDatabaseName(QApplication::applicationDirPath() + "/data/casic.db"); + + bool succ = conn.open(); + if (succ == true) + { +// LOG_INFO(QString("打开数据库操作正常[Open Database Success]").toStdString()); + } else + { +// LOG_ERROR(QString("打开数据库操作失败[Open Database Failed]").toStdString()); + } + } +} + +ConnectionManager::~ConnectionManager() +{ + conn.close(); +} + +ConnectionManager* ConnectionManager::getInstance() +{ + return cm; +} + +QSqlDatabase ConnectionManager::getConnection() +{ + return this->conn; +} + +qint64 ConnectionManager::generateId() +{ + return this->idWorker.nextId(); +} diff --git a/dao/util/ConnectionManager.h b/dao/util/ConnectionManager.h new file mode 100644 index 0000000..84647e3 --- /dev/null +++ b/dao/util/ConnectionManager.h @@ -0,0 +1,34 @@ +#ifndef CONNECTIONMANAGER_H +#define CONNECTIONMANAGER_H + +#include +#include +#include "utils/id/IdWorker.h" +#include "utils/UtilInclude.h" + +using namespace Jiawa::Core; + +class ConnectionManager : public QObject +{ + Q_OBJECT +public: + explicit ConnectionManager(QObject *parent = nullptr); + ~ConnectionManager(); + + static ConnectionManager * getInstance(); + + QSqlDatabase getConnection(); + qint64 generateId(); + +private: + // 数据库连接 + QSqlDatabase conn; + + // 雪花id生成工具 + IdWorker &idWorker = Singleton::instance(); + +signals: + +}; + +#endif // CONNECTIONMANAGER_H diff --git a/device/IrisCameraCapEventHandler.cpp b/device/IrisCameraCapEventHandler.cpp new file mode 100644 index 0000000..45df089 --- /dev/null +++ b/device/IrisCameraCapEventHandler.cpp @@ -0,0 +1,103 @@ +#include "IrisCameraCapEventHandler.h" + +IrisCameraCapEventHandler::IrisCameraCapEventHandler(QObject *parent) : QObject(parent) +{ + +} + +void IrisCameraCapEventHandler::DoOnImageCaptured(CImageDataPointer &objImageDataPointer, void *pUserParam) +{ + if (objImageDataPointer.IsNull() == false) + { + CGXDevicePointer* cam = (CGXDevicePointer *) pUserParam; + + auto camName = cam->getPtr()->GetDeviceInfo().GetUserID(); + int width = objImageDataPointer->GetWidth(); + int height = objImageDataPointer->GetHeight(); + size_t leftKeyIndex = camName.find("left"); + size_t rightKeyIndex = camName.find("right"); + + uchar * pBuffer = (BYTE*)objImageDataPointer->GetBuffer(); + + // 相机拍摄下的图像1440*1080, 直接用于算法判断 + QImage img = QImage(pBuffer, width, height, QImage::Format_Grayscale8); // 用于展示 +// QImage imgAlgo = img.copy(0, 0, width, height); + + // 用于显示的图像需要缩小到400 * 300的尺寸 + img = img.scaled(SettingConfig::getInstance().IRIS_DISPLAY_HEIGHT, SettingConfig::getInstance().IRIS_DISPLAY_WIDTH); + img = img.transformed(QTransform().rotate(-90)); // 图像逆时针旋转90度 + + // 发送到界面进行显示 + emit sendIrisFrameToDraw(img); +// cv::Mat irisMat = ImageUtil::QImageToMat(imgAlgo); + +// irisInfo.data = imgAlgo; +// irisInfo.matData = irisMat; + +// // 将图像显示在注册页面的label上 +// // 并将虹膜信息对象存入队列中 +// ProMemory::getInstance().pushCasicIris(irisInfo); + +// if (leftKeyIndex >= 0 && leftKeyIndex < 32) +// { +// emit sendIrisFrameToDraw(img, 0); // 左眼画面 +// } else if (rightKeyIndex >= 0 && rightKeyIndex < 32) +// { +// emit sendIrisFrameToDraw(img, 1); // 右眼画面 +// } +/* + if (pBuffer != NULL) + { + // 创建虹膜信息对象 + CasicIrisInfo irisInfo; + irisInfo.hasEye = false; + if (leftKeyIndex >= 0 && leftKeyIndex < 32) + { + // 左眼相机拍摄的图像 + irisInfo.leftOrRight = "left"; + } else if (rightKeyIndex >= 0 && rightKeyIndex < 32) + { + // 右眼相机 + irisInfo.leftOrRight = "right"; + } + + if (ProMemory::getInstance().widgeFrame == CasicBioRecConst::RECOGNIZE_RESULT_FORM) + { + // 相机拍摄下的图像1280*960, 直接用于算法判断 + QImage imgDisp = QImage(pBuffer, width, height, QImage::Format_Grayscale8); + cv::Mat irisMat = ImageUtil::QImageToMat(imgDisp); + + irisInfo.data = imgDisp; + irisInfo.matData = irisMat; + + ProMemory::getInstance().pushCasicIris(irisInfo); + +// cv::imwrite(QString("D:\\irisLogs\\iristest-%1.bmp").arg(irisInfo.leftOrRight).toStdString(), irisMat); + } else if (ProMemory::getInstance().widgeFrame == CasicBioRecConst::ADD_PERSON_CAPTURE_IRIS) + { + // 相机拍摄下的图像1280*960, 直接用于算法判断 + QImage img = QImage(pBuffer, width, height, QImage::Format_Grayscale8); + QImage imgAlgo = img.copy(0, 0, width, height); + + // 用于显示的图像需要缩小到1/4的尺寸 + img = img.scaled(640, 480); + cv::Mat irisMat = ImageUtil::QImageToMat(imgAlgo); + + irisInfo.data = imgAlgo; + irisInfo.matData = irisMat; + + // 将图像显示在注册页面的label上 + // 并将虹膜信息对象存入队列中 + ProMemory::getInstance().pushCasicIris(irisInfo); + + if (leftKeyIndex >= 0 && leftKeyIndex < 32) + { + emit sendIrisFrameToDraw(img, 0); // 左眼画面 + } else if (rightKeyIndex >= 0 && rightKeyIndex < 32) + { + emit sendIrisFrameToDraw(img, 1); // 右眼画面 + } + } + }*/ + } +} diff --git a/device/IrisCameraCapEventHandler.h b/device/IrisCameraCapEventHandler.h new file mode 100644 index 0000000..ad75a97 --- /dev/null +++ b/device/IrisCameraCapEventHandler.h @@ -0,0 +1,30 @@ +#ifndef IRISCAMERACAPEVENTHANDLER_H +#define IRISCAMERACAPEVENTHANDLER_H + +#include +#include +#include "include/opencv2/opencv.hpp" +#include "include/daheng/GalaxyIncludes.h" + +//#include "casic/iris/CasicIrisInterface.h" +#include "ProMemory.h" + +#include "utils/UtilInclude.h" + +class IrisCameraCapEventHandler : public QObject, public ICaptureEventHandler +{ + Q_OBJECT +public: + explicit IrisCameraCapEventHandler(QObject *parent = nullptr); + + void DoOnImageCaptured(CImageDataPointer &objImageDataPointer, void *pUserParam); + +private: + unsigned char* pImageBuffer; + +signals: + void sendIrisFrameToDraw(QImage irisImage); + +}; + +#endif // IRISCAMERACAPEVENTHANDLER_H diff --git a/device/IrisCameraController.cpp b/device/IrisCameraController.cpp new file mode 100644 index 0000000..0928176 --- /dev/null +++ b/device/IrisCameraController.cpp @@ -0,0 +1,110 @@ +#include "IrisCameraController.h" + +IrisCameraController::IrisCameraController(QObject *parent) : QObject(parent) +{ + this->irisCamHandler = new IrisCameraCapEventHandler(this); +} +IrisCameraController::~IrisCameraController() +{ + this->closeIrisCamera(); +} + + +void IrisCameraController::initIrisCamera() +{ + IGXFactory::GetInstance().Init(); + + //枚举设备 + IGXFactory::GetInstance().UpdateDeviceList(1000, irisCamList); + + this->OpenDevice(); +} + +void IrisCameraController::openIrisCamera() +{ + //设置Buffer处理模式 + irisStreamFeaturePtr->GetEnumFeature("StreamBufferHandlingMode")->SetValue("OldestFirst"); + + //注册回调函数 + irisStreamPtr->RegisterCaptureCallback(irisCamHandler, &irisCamPtr); + + //开启流层通道 + irisStreamPtr->StartGrab(); + + //发送开采命令 + irisFeaturePtr->GetCommandFeature("AcquisitionStart")->Execute(); + + // 启动定时器 + TimeCounterUtil::getInstance().irisCapCounter->start(SettingConfig::getInstance().IRIS_FRAME_INTERVAL); // 50ms执行一次定时器 +} + +void IrisCameraController::closeIrisCamera() +{ + +} + +void IrisCameraController::startCapture() +{ + // 获取定时器, 绑定定时函数 + connect(TimeCounterUtil::getInstance().irisCapCounter, &QTimer::timeout, this, &IrisCameraController::getOneFaceFrm); +// LOG(DEBUG) << QString("[IrisCameraController][startCapture]虹膜相机拍图").toStdString(); +// LOG_DEBUG(QString("[IrisCameraController][startCapture]虹膜相机拍图").toStdString()); + +} +void IrisCameraController::stopCapture() +{ + // 获取定时器, 绑定定时函数 + disconnect(TimeCounterUtil::getInstance().irisCapCounter, &QTimer::timeout, this, &IrisCameraController::getOneFaceFrm); +// LOG(DEBUG) << QString("[IrisCameraController][stopCapture]虹膜相机停止拍图").toStdString(); +// LOG_DEBUG(QString("[IrisCameraController][stopCapture]虹膜相机停止拍图").toStdString()); + +} + +void IrisCameraController::getOneFaceFrm() +{ + // 发送软触发命令(在触发模式开启时有效) + irisFeaturePtr->GetCommandFeature("TriggerSoftware")->Execute(); +} + +void IrisCameraController::getLeftAndRightEyeFrame() +{ + irisFeaturePtr->GetCommandFeature("TriggerSoftware")->Execute(); +} + +void IrisCameraController::OpenDevice() +{ + auto device = irisCamList.at(0); + + irisCamPtr = IGXFactory::GetInstance().OpenDeviceByUserID(device.GetUserID(), GX_ACCESS_EXCLUSIVE); + irisFeaturePtr = irisCamPtr->GetRemoteFeatureControl(); + + // 判断设备流是否大于零, 如果大于零则打开流 + int nStreamCount = irisCamPtr->GetStreamCount(); + if (nStreamCount > 0) + { + irisStreamPtr = irisCamPtr->OpenStream(0); + irisStreamFeaturePtr = irisStreamPtr->GetFeatureControl(); + } + + // 建议用户在打开网络相机之后, 根据当前网络环境设置相机的流通道包长值, + // 以提高网络相机的采集性能, 设置方法参考以下代码。 + GX_DEVICE_CLASS_LIST objDeviceClass = irisCamPtr->GetDeviceInfo().GetDeviceClass(); + if(GX_DEVICE_CLASS_GEV == objDeviceClass) + { + // 判断设备是否支持流通道数据包功能 + if(true == irisFeaturePtr->IsImplemented("GevSCPSPacketSize")) + { + // 获取当前网络环境的最优包长值 + int nPacketSize = irisStreamPtr->GetOptimalPacketSize(); + // 将最优包长值设置为当前设备的流通道包长值 + irisFeaturePtr->GetIntFeature("GevSCPSPacketSize")->SetValue(nPacketSize); + } + } + + //设置采集模式为连续采集模式 + irisFeaturePtr->GetEnumFeature("AcquisitionMode")->SetValue("Continuous"); + + //设置触发模式关 + irisFeaturePtr->GetEnumFeature("TriggerMode")->SetValue("On"); + irisFeaturePtr->GetEnumFeature("TriggerSource")->SetValue("Software"); +} diff --git a/device/IrisCameraController.h b/device/IrisCameraController.h new file mode 100644 index 0000000..5d7e269 --- /dev/null +++ b/device/IrisCameraController.h @@ -0,0 +1,49 @@ +#ifndef IRISCAMERACONTROLLER_H +#define IRISCAMERACONTROLLER_H + +#include + +#include "IrisCameraCapEventHandler.h" + +class IrisCameraCapEventHandler; + +class IrisCameraController : public QObject +{ + Q_OBJECT +public: + explicit IrisCameraController(QObject *parent = nullptr); + ~IrisCameraController(); + + // 初始化并打开人脸相机 + void initIrisCamera(); + void openIrisCamera(); + void closeIrisCamera(); + + void startCapture(); + void stopCapture(); + + void getLeftAndRightEyeFrame(); + + IrisCameraCapEventHandler * irisCamHandler; + +private: + GxIAPICPP::gxdeviceinfo_vector irisCamList; + + CGXDevicePointer irisCamPtr; ///< 设备句柄 + + CGXStreamPointer irisStreamPtr; ///< 左眼设备流 + + CGXFeatureControlPointer irisFeaturePtr; ///< 左眼属性控制器 + + CGXFeatureControlPointer irisStreamFeaturePtr; ///< 左眼流层控制器对象 + + void OpenDevice(); + +signals: + +public slots: + void getOneFaceFrm(); + +}; + +#endif // IRISCAMERACONTROLLER_H diff --git a/device/device.pri b/device/device.pri new file mode 100644 index 0000000..a8417f2 --- /dev/null +++ b/device/device.pri @@ -0,0 +1,13 @@ + +HEADERS += $$PWD/IrisCameraController.h +HEADERS += $$PWD/IrisCameraCapEventHandler.h +#HEADERS += $$PWD/iris/IrisRegistProcess.h +#HEADERS += $$PWD/iris/IrisRecogProcess.h +#HEADERS += $$PWD/iris/CasicIrisRecState.h + +SOURCES += $$PWD/IrisCameraController.cpp +SOURCES += $$PWD/IrisCameraCapEventHandler.cpp +#SOURCES += $$PWD/iris/IrisRegistProcess.cpp +#SOURCES += $$PWD/iris/IrisRecogProcess.cpp +#SOURCES += $$PWD/iris/CasicIrisRecState.cpp + diff --git a/images/bg_footer.png b/images/bg_footer.png new file mode 100644 index 0000000..a3a99ab --- /dev/null +++ b/images/bg_footer.png Binary files differ diff --git a/images/bg_statcked.png b/images/bg_statcked.png new file mode 100644 index 0000000..18b63e1 --- /dev/null +++ b/images/bg_statcked.png Binary files differ diff --git a/images/bg_title.png b/images/bg_title.png new file mode 100644 index 0000000..0316e2d --- /dev/null +++ b/images/bg_title.png Binary files differ diff --git a/main.cpp b/main.cpp index 16bc45b..9052ddb 100644 --- a/main.cpp +++ b/main.cpp @@ -1,11 +1,11 @@ -#include "IdentifyForm.h" +#include "MainWindowForm.h" #include int main(int argc, char *argv[]) { QApplication a(argc, argv); - IdentifyForm w; + MainWindowForm w; w.show(); return a.exec(); } diff --git a/resource.qrc b/resource.qrc new file mode 100644 index 0000000..474586a --- /dev/null +++ b/resource.qrc @@ -0,0 +1,35 @@ + + + images/setting.png + images/user.png + images/back.png + images/home.png + images/btnPageFirst.png + images/btnPageLast.png + images/btnPageNext.png + images/btnPagePre.png + images/regist.png + images/photoEyeLeft.png + images/photoEyeRight.png + images/photoFace.png + images/save.png + images/upArrow.png + images/downArrow.png + images/faceCaped.png + images/faceNotCap.png + images/irisCaped.png + images/irisNotCap.png + images/tipsFailure.png + images/tipsSuccess.png + images/tipsConfirm.png + images/bg_recognize_result.png + images/iconRetry.png + images/bg_title.png + images/bg_footer.png + images/bg_statcked.png + + + images/add_bottom.png + images/add_top.png + + diff --git a/utils/ImageUtil.cpp b/utils/ImageUtil.cpp new file mode 100644 index 0000000..7604572 --- /dev/null +++ b/utils/ImageUtil.cpp @@ -0,0 +1,97 @@ +#include "ImageUtil.h" + +ImageUtil::ImageUtil() +{ + +} + +QImage ImageUtil::MatImageToQImage(const cv::Mat &src) +{ + //CV_8UC1 8位无符号的单通道---灰度图片 + if(src.type() == CV_8UC1) + { + QImage qImage((const unsigned char *)(src.data), src.cols, src.rows, src.cols, QImage::Format_Grayscale8); + return qImage; + } + //为3通道的彩色图片 + else if(src.type() == CV_8UC3) + { + //得到图像的的首地址 + const uchar *pSrc = (const uchar*)src.data; + //以src构造图片 + QImage qImage(pSrc, src.cols, src.rows, src.step, QImage::Format_RGB888); + //在不改变实际图像数据的条件下, 交换红蓝通道 + return qImage.rgbSwapped(); + } + //四通道图片, 带Alpha通道的RGB彩色图像 + else if(src.type() == CV_8UC4) + { + const uchar *pSrc = (const uchar*)src.data; + QImage qImage(pSrc, src.cols, src.rows, src.step, QImage::Format_ARGB32); + //返回图像的子区域作为一个新图像 + return qImage.copy(); + } + else + { + return QImage(); + } +} +/* +QImage ImageUtil::UcharToQImage(unsigned char* data, int width, int height, QImage::Format format) +{ + QImage qImage(data, width, height, format); + //在不改变实际图像数据的条件下, 交换红蓝通道 + return qImage.rgbSwapped(); +} + +cv::Mat ImageUtil::QImageToMat(QImage image) +{ + cv::Mat mat; + switch(image.format()) + { + case QImage::Format_ARGB32: + case QImage::Format_RGB32: + case QImage::Format_ARGB32_Premultiplied: + mat = cv::Mat(image.height(), image.width(), CV_8UC4, (void*)image.constBits(), image.bytesPerLine()); + break; + case QImage::Format_RGB888: + mat = cv::Mat(image.height(), image.width(), CV_8UC3, (void*)image.constBits(), image.bytesPerLine()); + cv::cvtColor(mat, mat, cv::COLOR_BGR2RGB); + break; + case QImage::Format_Indexed8: + mat = cv::Mat(image.height(), image.width(), CV_8UC1, (void*)image.constBits(), image.bytesPerLine()); + break; + case QImage::Format_Grayscale8: + mat = cv::Mat(image.height(), image.width(), CV_8UC1, (void *)image.bits(), image.bytesPerLine()); + break; + } + + mat = mat.clone(); + + return mat; +} + +QString ImageUtil::QImageToBase64(QImage image) +{ + QByteArray ba; + QBuffer buf(&ba); + image.save(&buf, "bmp"); + QString base64String = ba.toBase64(); + return base64String; +} + +cv::Mat ImageUtil::MatImageRect(const cv::Mat &src, cv::Rect rect, int delta) +{ + cv::Mat matClone = src.clone(); + cv::Rect bigRect; + + bigRect.x = rect.x - delta < 0 ? 0 : rect.x - delta; + bigRect.y = rect.y - delta < 0 ? 0 : rect.y - delta; + bigRect.width = rect.x + rect.width + 2 * delta > src.cols ? src.cols - rect.x : rect.width + 2 * delta; + bigRect.height = rect.y + rect.height + 2 * delta > src.rows ? src.rows - rect.y : rect.height + 2 * delta; + + cv::Mat roi = matClone(bigRect); + + return roi; +} +*/ diff --git a/utils/ImageUtil.h b/utils/ImageUtil.h new file mode 100644 index 0000000..dbfdd48 --- /dev/null +++ b/utils/ImageUtil.h @@ -0,0 +1,22 @@ +#ifndef IMAGEUTIL_H +#define IMAGEUTIL_H + +#include +#include +#include "opencv2/opencv.hpp" + +class ImageUtil +{ +public: + ImageUtil(); + + static QImage MatImageToQImage(const cv::Mat &src); +// static QImage UcharToQImage(unsigned char* data, int width, int height, QImage::Format format); + +// static cv::Mat QImageToMat(QImage image); +// static QString QImageToBase64(QImage image); + +// static cv::Mat MatImageRect(const cv::Mat &src, cv::Rect rect, int delta); +}; + +#endif // IMAGEUTIL_H diff --git a/utils/SettingConfig.cpp b/utils/SettingConfig.cpp new file mode 100644 index 0000000..d420285 --- /dev/null +++ b/utils/SettingConfig.cpp @@ -0,0 +1,44 @@ +#include "SettingConfig.h" +#include + +SettingConfig::SettingConfig() +{ + filename = QApplication::applicationDirPath() + "/conf/config.ini"; + setting = new QSettings(this->filename, QSettings::IniFormat); + + WINDOW_WIDTH = getProperty("window", "width").toInt(); + WINDOW_HEIGHT = getProperty("window", "height").toInt(); + WINDOW_BACKGROUND_COLOR = getProperty("window", "backgroundColor").toString(); + WINDOW_TITLE = getProperty("window", "title").toString(); + WINDOW_RIGHTS = getProperty("window", "copyright").toString(); + WINDOW_VERSION = getProperty("window", "version").toString(); + + IRIS_FRAME_WIDTH = getProperty("camera", "irisFrameWidth").toInt(); + IRIS_FRAME_HEIGHT = getProperty("camera", "irisFrameHeight").toInt(); + IRIS_WIDTH = getProperty("camera", "irisWidth").toInt(); + IRIS_HEIGHT = getProperty("camera", "irisHeight").toInt(); + IRIS_FRAME_INTERVAL = getProperty("camera", "irisFrameInterval").toInt(); + IRIS_DISPLAY_WIDTH = getProperty("camera", "irisDisplayWidth").toInt(); + IRIS_DISPLAY_HEIGHT = getProperty("camera", "irisDisplayHeight").toInt(); + + MAX_MATCH_TIME = getProperty("recognize", "maxMatchTime").toInt(); + SUCCESS_TIPS_LAST = getProperty("recognize", "successTipsLast").toInt(); + FAILURE_TIPS_LAST = getProperty("recognize", "failureTipsLast").toInt(); + MAX_FACE_TRY_COUNT = getProperty("recognize", "maxFaceTryCount").toInt(); + MAX_FACE_NOT_FOUND_COUNT = getProperty("recognize", "maxFaceNotFoundCount").toInt(); + MAX_IRIS_TRY_COUNT = getProperty("recognize", "maxIrisTryCount").toInt(); + MAX_EYE_NOT_FOUND_COUNT = getProperty("recognize", "maxEyeNotFoundCount").toInt(); + + MAX_CAPTURE_STACK_SIZE = getProperty("stack", "capture").toInt(); + MAX_FOUND_STACK_SIZE = getProperty("stack", "found").toInt(); + MAX_QUALIFIED_STACK_SIZE = getProperty("stack", "qualified").toInt(); + + LOG_FILE = getProperty("log", "logFile").toString(); + LOG_LEVEL = getProperty("log", "logLevel").toString(); +} + + +QVariant SettingConfig::getProperty(QString nodeName, QString keyName) { + QVariant var = this->setting->value(QString("/%1/%2").arg(nodeName).arg(keyName)); + return var; +} diff --git a/utils/SettingConfig.h b/utils/SettingConfig.h new file mode 100644 index 0000000..30c3bec --- /dev/null +++ b/utils/SettingConfig.h @@ -0,0 +1,66 @@ +#ifndef SETTINGCONFIG_H +#define SETTINGCONFIG_H + +#include +#include + +class SettingConfig : public QObject +{ +public: + ~SettingConfig() {}; + SettingConfig(const SettingConfig&)=delete; + SettingConfig& operator=(const SettingConfig&)=delete; + + static SettingConfig& getInstance() { + static SettingConfig instance; + return instance; + } + + /** + * @brief get + * @param nodeName + * @param keyName + * @return QVariant + * @title + */ + QVariant getProperty(QString nodeName, QString keyName); + + /******** 以下为需要的各类参数 ********/ + int WINDOW_WIDTH; + int WINDOW_HEIGHT; + QString WINDOW_BACKGROUND_COLOR; + QString WINDOW_TITLE; + QString WINDOW_RIGHTS; + QString WINDOW_VERSION; + + int IRIS_FRAME_INTERVAL; + int IRIS_FRAME_WIDTH; + int IRIS_FRAME_HEIGHT; + int IRIS_WIDTH; + int IRIS_HEIGHT; + int IRIS_DISPLAY_WIDTH; + int IRIS_DISPLAY_HEIGHT; + + int MAX_MATCH_TIME; + int SUCCESS_TIPS_LAST; + int FAILURE_TIPS_LAST; + int MAX_FACE_TRY_COUNT; + int MAX_FACE_NOT_FOUND_COUNT; + int MAX_IRIS_TRY_COUNT; + int MAX_EYE_NOT_FOUND_COUNT; + + int MAX_CAPTURE_STACK_SIZE; + int MAX_FOUND_STACK_SIZE; + int MAX_QUALIFIED_STACK_SIZE; + + QString LOG_FILE; + QString LOG_LEVEL; + +private: + SettingConfig(); + + QString filename; + QSettings* setting; +}; + +#endif // SETTINGCONFIG_H diff --git a/AppConstants.h b/AppConstants.h new file mode 100644 index 0000000..296c53f --- /dev/null +++ b/AppConstants.h @@ -0,0 +1,28 @@ +#ifndef APPCONSTANTS_H +#define APPCONSTANTS_H + +class AppConstants +{ +public: + enum WidgeFrameName + { + MAIN_PAGE = 0, // 主页面 + PERSON_LIST_FORM = 1, // 人员列表页面 + ADD_PERSON_FORM = 2, // 添加人员页面 + ADD_PERSON_CAPTURE_FACE = 21, // 添加/编辑人员时进行人脸拍图 + ADD_PERSON_CAPTURE_IRIS = 22, // 添加/编辑人员时进行虹膜拍图 + SETTING_FORM = 3, // 设置页面 + RECOGNIZE_RESULT_FORM = 4, // 识别结果界面 + IDENTIFY_FORM = 5, // 识别界面 含识别中 和 识别结果 + LOCKSCREEN_FORM = 6 // 锁屏待机界面 + }; + + enum ApplicationState + { + STATE_WAIT = 0, // 待机 + STATE_WORKING = 1, // 工作状态 + STATE_IDENTIFYING = 2, // 识别中 + }; +}; + +#endif // APPCONSTANTS_H diff --git a/CasicIrisIdentify.pro b/CasicIrisIdentify.pro index 5d7fea6..575ce3d 100644 --- a/CasicIrisIdentify.pro +++ b/CasicIrisIdentify.pro @@ -1,4 +1,4 @@ -QT += core gui +QT += core gui sql network texttospeech greaterThan(QT_MAJOR_VERSION, 4): QT += widgets @@ -15,20 +15,46 @@ # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 -SOURCES += \ - main.cpp \ - IdentifyForm.cpp +include("dao/dao.pri") +include("device/device.pri") +include("utils/utils.pri") -HEADERS += \ - IdentifyForm.h +SOURCES += main.cpp +SOURCES += ProMemory.cpp +SOURCES += MainWindowForm.cpp +SOURCES += IdentifyForm.cpp +SOURCES += LockScreenForm.cpp -FORMS += \ - IdentifyForm.ui +HEADERS += AppConstants.h +HEADERS += ProMemory.h +HEADERS += MainWindowForm.h +HEADERS += IdentifyForm.h +HEADERS += LockScreenForm.h -TRANSLATIONS += \ - CasicIrisIdentify_zh_CN.ts +FORMS += MainWindowForm.ui +FORMS += IdentifyForm.ui +FORMS += LockScreenForm.ui + +RESOURCES += resource.qrc + +DISTFILES += conf/config.ini + +#TRANSLATIONS += CasicIrisIdentify_zh_CN.ts + +#INCLUDEPATH += include/spdlog +#DEPENDPATH += include/spdlog # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target + + +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lopencv_world420 +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lGxIAPICPPEx + +INCLUDEPATH += $$PWD/include/daheng +DEPENDPATH += $$PWD/include/daheng + +INCLUDEPATH += $$PWD/include +DEPENDPATH += $$PWD/include diff --git a/CasicIrisIdentify_zh_CN.ts b/CasicIrisIdentify_zh_CN.ts index 5526fe4..81900df 100644 --- a/CasicIrisIdentify_zh_CN.ts +++ b/CasicIrisIdentify_zh_CN.ts @@ -1,3 +1,12 @@ - + + + IdentifyForm + + + IdentifyForm + + + + diff --git a/IdentifyForm.cpp b/IdentifyForm.cpp index 348a897..ba1f251 100644 --- a/IdentifyForm.cpp +++ b/IdentifyForm.cpp @@ -1,4 +1,4 @@ -#include "IdentifyForm.h" +#include "IdentifyForm.h" #include "ui_IdentifyForm.h" IdentifyForm::IdentifyForm(QWidget *parent) @@ -6,6 +6,12 @@ , ui(new Ui::IdentifyForm) { ui->setupUi(this); + + // 初始化更新界面的定时器 + // 每秒执行一次 + connect(TimeCounterUtil::getInstance().clockCounter, &QTimer::timeout, this, &IdentifyForm::updateDateAndTime); + + TimeCounterUtil::getInstance().clockCounter->start(1000); } IdentifyForm::~IdentifyForm() @@ -13,3 +19,16 @@ delete ui; } +void IdentifyForm::drawIrisImageOnFrame(QImage image) +{ + // 只在识别界面才显示画面 + if (ui->wgtStacked->currentIndex() == 0) { + ui->labelVideo->setPixmap(QPixmap::fromImage(image)); + } +} + + +void IdentifyForm::updateDateAndTime() +{ + ui->labelTime->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd dddd HH:mm:ss")); +} diff --git a/IdentifyForm.h b/IdentifyForm.h index fc857a1..ae1cd22 100644 --- a/IdentifyForm.h +++ b/IdentifyForm.h @@ -1,7 +1,10 @@ -#ifndef IDENTIFYFORM_H +#ifndef IDENTIFYFORM_H #define IDENTIFYFORM_H #include +#include + +#include "utils/UtilInclude.h" QT_BEGIN_NAMESPACE namespace Ui { class IdentifyForm; } @@ -15,7 +18,14 @@ IdentifyForm(QWidget *parent = nullptr); ~IdentifyForm(); +public slots: + void drawIrisImageOnFrame(QImage image); + private: Ui::IdentifyForm *ui; + +private slots: + void updateDateAndTime(); + }; #endif // IDENTIFYFORM_H diff --git a/IdentifyForm.ui b/IdentifyForm.ui index c72a36f..879dc9a 100644 --- a/IdentifyForm.ui +++ b/IdentifyForm.ui @@ -6,13 +6,59 @@ 0 0 - 800 + 600 600 IdentifyForm + + + + 0 + 40 + 600 + 450 + + + + 0 + + + + + + 100 + 10 + 400 + 300 + + + + + + + + + + + + + + 0 + 0 + 600 + 40 + + + + TextLabel + + + Qt::AlignCenter + + diff --git a/LockScreenForm.cpp b/LockScreenForm.cpp new file mode 100644 index 0000000..58dc54b --- /dev/null +++ b/LockScreenForm.cpp @@ -0,0 +1,14 @@ +#include "LockScreenForm.h" +#include "ui_LockScreenForm.h" + +LockScreenForm::LockScreenForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::LockScreenForm) +{ + ui->setupUi(this); +} + +LockScreenForm::~LockScreenForm() +{ + delete ui; +} diff --git a/LockScreenForm.h b/LockScreenForm.h new file mode 100644 index 0000000..b5ded48 --- /dev/null +++ b/LockScreenForm.h @@ -0,0 +1,25 @@ +#ifndef LOCKSCREENFORM_H +#define LOCKSCREENFORM_H + +#include +#include + +#include "utils/UtilInclude.h" + +namespace Ui { +class LockScreenForm; +} + +class LockScreenForm : public QWidget +{ + Q_OBJECT + +public: + explicit LockScreenForm(QWidget *parent = nullptr); + ~LockScreenForm(); + +private: + Ui::LockScreenForm *ui; +}; + +#endif // LOCKSCREENFORM_H diff --git a/LockScreenForm.ui b/LockScreenForm.ui new file mode 100644 index 0000000..7f2a6db --- /dev/null +++ b/LockScreenForm.ui @@ -0,0 +1,45 @@ + + + LockScreenForm + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + 180 + 100 + 54 + 12 + + + + TextLabel + + + + + + 180 + 160 + 54 + 12 + + + + TextLabel + + + + + + diff --git a/MainWindowForm.cpp b/MainWindowForm.cpp new file mode 100644 index 0000000..84f8159 --- /dev/null +++ b/MainWindowForm.cpp @@ -0,0 +1,86 @@ +#include "MainWindowForm.h" +#include "ui_MainWindowForm.h" +#include + +MainWindowForm::MainWindowForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::MainWindowForm) +{ + ui->setupUi(this); + + // 设置窗口透明和大小、位置 + this->setWindowFlags(Qt::FramelessWindowHint); + this->move(1400, 15); + this->resize(SettingConfig::getInstance().WINDOW_WIDTH, SettingConfig::getInstance().WINDOW_HEIGHT); + + // 通过调色板的颜色来设置窗口的统一背景色 + qApp->setPalette(QPalette(QColor(SettingConfig::getInstance().WINDOW_BACKGROUND_COLOR))); + + // 加载css文件设置控件样式 + QFile file(QApplication::applicationDirPath() + "/qss/main.css"); + if (file.open(QFile::ReadOnly)) + { + QString qssStr = QLatin1String(file.readAll()); + this->setStyleSheet(qssStr); + file.close(); + } + + initFormsPtr(); + + // 设置标题文字 + ui->labelTitle->setText(SettingConfig::getInstance().WINDOW_TITLE); + ui->labelCopyright->setText(SettingConfig::getInstance().WINDOW_RIGHTS); + ui->labelVersion->setText(SettingConfig::getInstance().WINDOW_VERSION); + + // 初始化虹膜相机控制 + ProMemory::getInstance().irisCam = new IrisCameraController(this); + ProMemory::getInstance().irisCam->initIrisCamera(); + ProMemory::getInstance().irisCam->openIrisCamera(); + connect(ProMemory::getInstance().irisCam->irisCamHandler, &IrisCameraCapEventHandler::sendIrisFrameToDraw, identifyForm, &IdentifyForm::drawIrisImageOnFrame); + +// LOG_INFO(QString("应用程序启动成功[Application Startup Success]").toStdString()); + qDebug() << "应用程序启动成功[Application Startup Success]"; + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::IDENTIFY_FORM; + ui->wdgtStatced->setCurrentWidget(identifyForm); + + // 开始虹膜相机拍图 + ProMemory::getInstance().irisCam->startCapture(); +} + +MainWindowForm::~MainWindowForm() +{ + delete ui; +} + +void MainWindowForm::lockScreen() +{ + ui->wdgtStatced->setCurrentWidget(lockScreenForm); + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::LOCKSCREEN_FORM; + ProMemory::getInstance().appState = AppConstants::ApplicationState::STATE_WAIT; +} + +void MainWindowForm::keyPressEvent(QKeyEvent *event) +{ + switch (event->key()) { + case Qt::Key_Escape: + QTimer::singleShot(100, qApp, [=](){ + QApplication::quit(); + }); + + default: + QWidget::keyPressEvent(event); + } +} + +void MainWindowForm::initFormsPtr() +{ + // 初始化各个form + lockScreenForm = new LockScreenForm(this); + identifyForm = new IdentifyForm(this); + + // 将form添加到statcked widget中 + ui->wdgtStatced->addWidget(identifyForm); + ui->wdgtStatced->addWidget(lockScreenForm); + + // 绑定按钮函数 +} diff --git a/MainWindowForm.h b/MainWindowForm.h new file mode 100644 index 0000000..7fb2d89 --- /dev/null +++ b/MainWindowForm.h @@ -0,0 +1,38 @@ +#ifndef MAINWINDOWFORM_H +#define MAINWINDOWFORM_H + +#include +#include +#include + +#include "utils/UtilInclude.h" +#include "ProMemory.h" +#include "LockScreenForm.h" +#include "IdentifyForm.h" + +namespace Ui { +class MainWindowForm; +} + +class MainWindowForm : public QWidget +{ + Q_OBJECT + +public: + explicit MainWindowForm(QWidget *parent = nullptr); + ~MainWindowForm(); + +public slots: + void lockScreen(); + +private: + Ui::MainWindowForm *ui; + LockScreenForm * lockScreenForm; + IdentifyForm * identifyForm; + + void keyPressEvent(QKeyEvent *event); + + void initFormsPtr(); +}; + +#endif // MAINWINDOWFORM_H diff --git a/MainWindowForm.ui b/MainWindowForm.ui new file mode 100644 index 0000000..e793ebf --- /dev/null +++ b/MainWindowForm.ui @@ -0,0 +1,85 @@ + + + MainWindowForm + + + + 0 + 0 + 600 + 1024 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + 0 + 0 + 600 + 84 + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + + + + TextLabel + + + Qt::AlignBottom|Qt::AlignHCenter + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + diff --git a/ProMemory.cpp b/ProMemory.cpp new file mode 100644 index 0000000..19e7403 --- /dev/null +++ b/ProMemory.cpp @@ -0,0 +1,84 @@ +#include "ProMemory.h" + +ProMemory::ProMemory() +{ + +} + +ProMemory::~ProMemory() +{ + +} + +/* +void ProMemory::pushCasicIris(CasicIrisInfo irisInfo) +{ + QMutex mutex; + mutex.lock(); + if (this->irisQueue.size() > 30) + { + QStack empty; + std::swap(empty, irisQueue); + } + + irisQueue.push(irisInfo); + mutex.unlock(); +} +CasicIrisInfo ProMemory::popCasicIris() +{ + CasicIrisInfo result; + + QMutex mutex; + mutex.lock(); + if (this->irisQueue.size() > 0) + { + result = irisQueue.pop(); + } + + mutex.unlock(); + + return result; +} +*/ +int ProMemory::getIrisQueueSize() +{ + int size = 0; + + QMutex mutex; + mutex.lock(); + +// size = this->irisQueue.size(); + + mutex.unlock(); + + return size; +} +bool ProMemory::isIrisQueueEmpty() +{ + bool empty = true; + + QMutex mutex; + mutex.lock(); + +// empty = this->irisQueue.isEmpty(); + + mutex.unlock(); + + return empty; +} +void ProMemory::clearIrisQueue() +{ + QMutex mutex; + mutex.lock(); + +// QStack empty; +// std::swap(empty, irisQueue); + + mutex.unlock(); +} + + +void ProMemory::initIrisFeatures(QString personId) +{ +// irisRegistPro->sendDataToExract(QByteArray(QString("[-u]").append(personId).toLocal8Bit())); +} diff --git a/ProMemory.h b/ProMemory.h new file mode 100644 index 0000000..2ecd653 --- /dev/null +++ b/ProMemory.h @@ -0,0 +1,52 @@ +#ifndef PROMEMORY_H +#define PROMEMORY_H + +#include +#include + +#include "AppConstants.h" +//#include "casic/iris/CasicIrisInfo.h" +#include "dao/IrisDataDao.h" + +#include "device/IrisCameraController.h" +//#include "device/iris/IrisRegistProcess.h" +//#include "device/iris/IrisRecogProcess.h" + +class IrisCameraController; +class IrisRegistProcess; +class IrisRecogProcess; + +class ProMemory +{ +public: + ~ProMemory(); + ProMemory(const ProMemory&)=delete; + ProMemory& operator=(const ProMemory&)=delete; + + static ProMemory& getInstance() { + static ProMemory instance; + return instance; + } + +// void pushCasicIris(CasicIrisInfo irisInfo); +// CasicIrisInfo popCasicIris(); + int getIrisQueueSize(); + bool isIrisQueueEmpty(); + void clearIrisQueue(); + + volatile int widgeFrame = 0; // 当前显示的界面 + volatile int appState = 0; // 当前程序所处的状态 + + void initIrisFeatures(QString personId = ""); // 初始化虹膜特征值集合 + + IrisCameraController * irisCam; + IrisRecogProcess * irisRecogPro; + +private: + ProMemory(); + +// QStack irisQueue; // 虹膜信息队列 + QVector irisFeatures; // 虹膜特征值集合 +}; + +#endif // PROMEMORY_H diff --git a/conf/config.ini b/conf/config.ini new file mode 100644 index 0000000..66e46ad --- /dev/null +++ b/conf/config.ini @@ -0,0 +1,67 @@ +[recognize] +#最大允许识别时间(ms) +maxMatchTime=10000 +#识别成功界面停留时间(ms) +successTipsLast=5000 +#识别失败界面停留时间(ms) +failureTipsLast=3000 +#人脸识别最大尝试次数 +maxFaceTryCount=20 +#持续没找到人脸的最大次数 +maxFaceNotFoundCount=500 +#注册时最小人脸 +minFaceRegist=240 +#识别时最小人脸 +minFaceRecog=100 + +#虹膜识别最大尝试次数 +maxIrisTryCount=10 +#虹膜识别持续没有找到眼的最大次数 +maxEyeNotFoundCount=50 + +#识别方式[1=人脸;2=虹膜;3=双认证;4=任意] +recogType=4 + +[window] +#界面窗口宽(px) +width=600 +#界面窗口高(px) +height=1024 +#统一背景色 +backgroundColor="#FFFFFF" +#标题 +title="虹膜识别终端" + +[work] +#工作状态检测时最小人脸范围 +minFaceSize=160 +#人脸范围最小横坐标 +minFacePosX=320 +#人脸范围最大横坐标 +maxFacePosX=960 +#人脸范围最小纵坐标 +minFacePosY=180 +#人脸范围最大纵坐标 +maxFacePosY=540 +#人脸太近阈值 +faceCloseSize=360 +#人脸太远阈值 +faceFarSize=480 + +[camera] +#虹膜相机取一幅画面的时间间隔(ms) +irisFrameInterval=100 +#虹膜相机拍摄宽度 +irisFrameWidth=1440 +#虹膜相机拍摄高度 +irisFrameHeight=1080 +#虹膜图像高度 +irisWidth=640 +#虹膜图像高度 +irisHeight=480 + +[log] +#日志文件位置 +logFile="d://irisLogs//casic_log.txt" +#日志级别 +logLevel="trace" diff --git a/dao/BaseDao.cpp b/dao/BaseDao.cpp new file mode 100644 index 0000000..f51c144 --- /dev/null +++ b/dao/BaseDao.cpp @@ -0,0 +1,12 @@ +#include "BaseDao.h" +#include "dao/util/ConnectionManager.h" + +BaseDao::BaseDao(QObject *parent) : QObject(parent) +{ + +} + +BaseDao::~BaseDao() +{ + +} diff --git a/dao/BaseDao.h b/dao/BaseDao.h new file mode 100644 index 0000000..1693c88 --- /dev/null +++ b/dao/BaseDao.h @@ -0,0 +1,32 @@ +#ifndef BASEDAO_H +#define BASEDAO_H + +#include +#include +#include +#include + +#include "dao/util/ConnectionManager.h" +#include "utils/UtilInclude.h" + +class BaseDao : public QObject +{ + Q_OBJECT +public: + explicit BaseDao(QObject *parent = nullptr); + ~BaseDao(); + + virtual QVector findAllRecord() = 0; + virtual QVariantMap findRecordById(QString id) = 0; + + virtual QString save(QVariantMap object) = 0; + virtual bool edit(QVariantMap newObject, QString id) = 0; + virtual bool dele(QString id) = 0; + +private: + +signals: + +}; + +#endif // BASEDAO_H diff --git a/dao/IrisDataDao.cpp b/dao/IrisDataDao.cpp new file mode 100644 index 0000000..37a0ed6 --- /dev/null +++ b/dao/IrisDataDao.cpp @@ -0,0 +1,204 @@ +#include "IrisDataDao.h" + +IrisDataDao::IrisDataDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector IrisDataDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM IRIS_DATA"; + query.prepare(sql); + + // 执行查询 + query.exec(); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + item.insert("id", query.value("id").toString()); + item.insert("person_id", query.value("person_id").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("left_iris_code1", query.value("left_iris_code1")); + item.insert("left_iris_code2", query.value("left_iris_code2")); + item.insert("left_iris_code3", query.value("left_iris_code3")); + item.insert("right_iris_code1", query.value("right_iris_code1")); + item.insert("right_iris_code2", query.value("right_iris_code2")); + item.insert("right_iris_code3", query.value("right_iris_code3")); + + result.append(item); + } + +// LOG_DEBUG(QString("查询IRIS_DATA表的所有记录[结果数:%1]").arg(result.size()).toStdString()); + return result; +} + +QVariantMap IrisDataDao::findRecordById(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM IRIS_DATA WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + // 获取结果 + if (query.next()) + { + result.insert("id", query.value("id").toString()); + result.insert("person_id", query.value("person_id").toLongLong()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("left_iris_code1", query.value("left_iris_code1")); + result.insert("left_iris_code2", query.value("left_iris_code2")); + result.insert("left_iris_code3", query.value("left_iris_code3")); + result.insert("right_iris_code1", query.value("right_iris_code1")); + result.insert("right_iris_code2", query.value("right_iris_code2")); + result.insert("right_iris_code3", query.value("right_iris_code3")); + } + +// LOG_DEBUG(QString("根据id查询IRIS_DATA表的记录[id=%1]").arg(id).toStdString()); + return result; +} + +QVariantMap IrisDataDao::findRecordByPersonId(QString personId) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM IRIS_DATA WHERE PERSON_ID = :personId"); + query.prepare(sql); + query.bindValue(":personId", personId); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + if (query.next()) + { + result.insert("id", query.value("id").toString()); + result.insert("person_id", query.value("person_id").toLongLong()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("left_iris_code1", query.value("left_iris_code1")); + result.insert("left_iris_code2", query.value("left_iris_code2")); + result.insert("left_iris_code3", query.value("left_iris_code3")); + result.insert("right_iris_code1", query.value("right_iris_code1")); + result.insert("right_iris_code2", query.value("right_iris_code2")); + result.insert("right_iris_code3", query.value("right_iris_code3")); + } + +// LOG_DEBUG(QString("根据personId查询IRIS_DATA表的记录[personId=%1]").arg(personId).toStdString()); + return result; +} + + +QString IrisDataDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + + // INSERT语句 + QString sql = QString("INSERT INTO IRIS_DATA (ID, PERSON_ID, ID_CARD_NO, LEFT_IRIS_CODE1, RIGHT_IRIS_CODE1) VALUES (:id, :personId, :idCardNo, :left1, :right1)"); + + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":personId", object.value("person_id").toString()); + query.bindValue(":idCardNo", object.value("id_card_no").toString()); + query.bindValue(":left1", object.value("left_iris_code1")); + query.bindValue(":right1", object.value("right_iris_code1")); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(); + +// LOG_DEBUG(QString("保存虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool IrisDataDao::edit(QVariantMap newObject, QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // UPDATE语句 + if (!newObject.contains("left_iris_code1") || !newObject.contains("right_iris_code1")){ + return false; + } + QString sql = QString("UPDATE IRIS_DATA SET LEFT_IRIS_CODE1 = :left1, RIGHT_IRIS_CODE1 = :right1 WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":left1", newObject.value("left_iris_code1")); + query.bindValue(":right1", newObject.value("right_iris_code1")); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(); + +// LOG_DEBUG(QString("编辑虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; +} + + +bool IrisDataDao::dele(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + QString sql = QString("DELETE FROM IRIS_DATA WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(); + +// LOG_DEBUG(QString("删除虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; +} diff --git a/dao/IrisDataDao.h b/dao/IrisDataDao.h new file mode 100644 index 0000000..c74dbbd --- /dev/null +++ b/dao/IrisDataDao.h @@ -0,0 +1,25 @@ +#ifndef IRISDATADAO_H +#define IRISDATADAO_H + +#include +#include "BaseDao.h" + +class IrisDataDao : public BaseDao +{ + Q_OBJECT +public: + explicit IrisDataDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + QVariantMap findRecordByPersonId(QString personId); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +signals: + +}; + +#endif // IRISDATADAO_H diff --git a/dao/RecognitionRecordsDao.cpp b/dao/RecognitionRecordsDao.cpp new file mode 100644 index 0000000..40db453 --- /dev/null +++ b/dao/RecognitionRecordsDao.cpp @@ -0,0 +1,100 @@ +#include "RecognitionRecordsDao.h" + +RecognitionRecordsDao::RecognitionRecordsDao(QObject *parent) : BaseDao(parent) +{ + +} + + +QVector RecognitionRecordsDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM RECOGNITION_RECORDS"; + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + item.insert("id", query.value("id").toLongLong()); + result.append(item); + } + +// LOG_DEBUG(QString("查询RECOGNITION_RECORDS表的所有记录[记录数:%1]").arg(result.size()).toStdString()); + return result; +} + +QVariantMap RecognitionRecordsDao::findRecordById(QString id) +{ + QVariantMap item; + return item; +} + +QString RecognitionRecordsDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + + // INSERT语句 + QString sql = QString("INSERT INTO RECOGNITION_RECORDS (ID, PERSON_ID, DATETIME, REC_TYPE, DEV_CODE, DOOR_CODE, INOUT_TYPE) " + "VALUES (:id, :personId, :datetime, :recType, :devCode, :doorCode, :inoutType)"); + + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":personId", object.value("person_id").toString()); + query.bindValue(":datetime", object.value("date_time").toString()); + query.bindValue(":recType", object.value("rec_type").toString()); + query.bindValue(":devCode", object.value("dev_code").toString()); + query.bindValue(":doorCode", object.value("door_code").toString()); + query.bindValue(":inoutType", object.value("inout_type").toString()); + +// LOG_DEBUG(sql.toStdString()); + + // 插入识别的log日志 + QString logStr = QString("INSERT INTO RECOGNITION_LOGS (ID, LOG_INFO) VALUES (:id, :logInfo)"); + + QSqlQuery logQuery(ConnectionManager::getInstance()->getConnection()); + logQuery.prepare(logStr); + logQuery.bindValue(":id", id); + logQuery.bindValue(":logInfo", object.value("debug_info").toString()); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(); + logQuery.exec(); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool RecognitionRecordsDao::edit(QVariantMap newObject, QString id) +{ + return false; +} + +bool RecognitionRecordsDao::dele(QString id) +{ + return false; +} diff --git a/dao/RecognitionRecordsDao.h b/dao/RecognitionRecordsDao.h new file mode 100644 index 0000000..38de7c9 --- /dev/null +++ b/dao/RecognitionRecordsDao.h @@ -0,0 +1,23 @@ +#ifndef RECOGNITIONRECORDSDAO_H +#define RECOGNITIONRECORDSDAO_H + +#include +#include "BaseDao.h" +class RecognitionRecordsDao: public BaseDao +{ + Q_OBJECT +public: + explicit RecognitionRecordsDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +signals: + +}; + +#endif // RECOGNITIONRECORDSDAO_H diff --git a/dao/SysDeptDao.cpp b/dao/SysDeptDao.cpp new file mode 100644 index 0000000..22f9946 --- /dev/null +++ b/dao/SysDeptDao.cpp @@ -0,0 +1,88 @@ +#include "SysDeptDao.h" + +SysDeptDao::SysDeptDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector SysDeptDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_DEPT WHERE PID != '-1' ORDER BY PID, NUM"; + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + item.insert("id", query.value("id").toString()); + item.insert("pid", query.value("pid").toString()); + item.insert("pids", query.value("pids").toString()); + item.insert("simplename", query.value("simplename").toString()); + item.insert("fullname", query.value("fullname").toString()); + } + +// LOG_TRACE(QString("查询表[SYS_DEPT]的所有记录[%1][%2]").arg(result.size()).arg(sql).toStdString()); + + return result; +} + +QVariantMap SysDeptDao::findRecordById(QString id) +{ + QVariantMap item; + return item; + + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM SYS_DEPT WHERE SYS_DEPT.ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + // 获取结果集的大小 + query.last(); + int count = query.at() + 1; + + if (count >=1) + { + query.first(); + + result.insert("id", query.value("id").toString()); + result.insert("pid", query.value("pid").toString()); + result.insert("pids", query.value("pids").toString()); + result.insert("simplename", query.value("simplename").toString()); + result.insert("fullname", query.value("fullname").toString()); + } + +// LOG_TRACE(QString("根据id查询SYS_DEPT表的记录[ID=%1][%2]").arg(id).arg(sql).toStdString()); + + return result; +} + + +QString SysDeptDao::save(QVariantMap object) +{ + return "0"; +} +bool SysDeptDao::edit(QVariantMap newObject, QString id) +{ + return true; +} +bool SysDeptDao::dele(QString id) +{ + return true; +} diff --git a/dao/SysDeptDao.h b/dao/SysDeptDao.h new file mode 100644 index 0000000..e07a09f --- /dev/null +++ b/dao/SysDeptDao.h @@ -0,0 +1,24 @@ +#ifndef SYSDEPTDAO_H +#define SYSDEPTDAO_H + +#include +#include "BaseDao.h" + +class SysDeptDao : public BaseDao +{ + Q_OBJECT +public: + explicit SysDeptDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +private: + +}; + +#endif // SYSDEPTDAO_H diff --git a/dao/SysPersonDao.cpp b/dao/SysPersonDao.cpp new file mode 100644 index 0000000..dd9480f --- /dev/null +++ b/dao/SysPersonDao.cpp @@ -0,0 +1,371 @@ +#include "SysPersonDao.h" + + +SysPersonDao::SysPersonDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector SysPersonDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0'"; + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + count++; + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + result.append(item); + } + +// LOG(TRACE) << QString("查询SYS_PERSON表的所有记录[%1]").arg(count).toStdString(); +// LOG_TRACE(QString("查询SYS_PERSON表的所有记录[%1]").arg(count).toStdString()); + + return result; +} + +QVariantMap SysPersonDao::findRecordById(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0' AND SYS_PERSON.ID = '%1'").arg(id); + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVariantMap result; + + // 获取结果集的大小 + query.last(); + int count = query.at() + 1; + + if (count >=1) + { + query.first(); + + result.insert("id", query.value("id").toString()); + result.insert("delflag", query.value("delflag").toString()); + result.insert("createtime", query.value("createtime").toString()); + result.insert("updatetime", query.value("updatetime").toString()); + result.insert("name", query.value("name").toString()); + result.insert("gender", query.value("gender").toString()); + result.insert("deptid", query.value("deptid").toString()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("remarks", query.value("remarks").toString()); + result.insert("person_code", query.value("person_code").toString()); + result.insert("deptname", query.value("fullname").toString()); + result.insert("sync_id", query.value("sync_id").toString()); + result.insert("hasFace", query.value("face_valid").toString()); + result.insert("hasIris", query.value("iris_valid").toString()); + } + +// LOG(TRACE) << QString("根据id查询SYS_PERSON表的记录[id=%1][%2]").arg(id).arg(sql).toStdString(); +// LOG_TRACE(QString("根据id查询SYS_PERSON表的记录[id=%1][%2]").arg(id).arg(sql).toStdString()); + + return result; +} + +int SysPersonDao::findRecordCountByNameAndDept(QString name, QString dept) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT COUNT(P.ID) AS RECCT FROM SYS_PERSON P LEFT JOIN SYS_DEPT D ON P.DEPTID = D.ID WHERE P.DELFLAG = '0'"; + if (name.isEmpty() == false) + { + sql += " AND P.NAME LIKE '%" + name + "%'"; + } + if (dept.isEmpty() == false && dept.indexOf("-1") < 0) + { + sql += QString(" AND ((P.DEPTID = '%1') OR (D.PIDS LIKE '%,%1,%'))").arg(dept); + } + + // 执行查询 + query.exec(sql); + + // 返回结果 + int result; + + // 遍历查询结果 + if (query.next()) { + result = query.value("RECCT").toInt(); + } + +// LOG(TRACE) << QString("根据姓名和部门查询SYS_PERSON记录总数[%1][%2]").arg(result).arg(sql).toStdString(); +// LOG_TRACE(QString("根据姓名和部门查询SYS_PERSON记录总数[%1][%2]").arg(result).arg(sql).toStdString()); + + return result; +} + +QVector SysPersonDao::findRecordsByNameAndDept(QString name, QString dept, qint8 limit, qint16 offset) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON P LEFT JOIN SYS_DEPT D ON P.DEPTID = D.ID WHERE P.DELFLAG = '0'"; + if (name.isEmpty() == false) + { + sql += " AND P.NAME LIKE '%" + name + "%'"; + } + if (dept.isEmpty() == false && dept.indexOf("-1") < 0) + { + sql += QString(" AND ((P.DEPTID = '%1') OR (D.PIDS LIKE '%,%1,%'))").arg(dept); + } + + sql += QString(" LIMIT %1 OFFSET %2").arg(limit).arg(offset); + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + count++; + + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + + result.append(item); + } + +// LOG(TRACE) << QString("根据姓名和部门分页查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString(); +// LOG_TRACE(QString("根据姓名和部门分页查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString()); + + return result; +} + +QVector SysPersonDao::findRecordsByProperties(QVariantMap conditions) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0'"; + QVariantMap::iterator it; + for (it = conditions.begin(); it != conditions.end(); it++) + { + sql += QString(" AND SYS_PERSON.%1 = %2").arg(it.key()).arg(it.value().toString()); + } + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + count++; + + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + + result.append(item); + } + +// LOG(TRACE) << QString("根据属性值查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString(); +// LOG_TRACE(QString("根据属性值查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString()); + + return result; +} + +QString SysPersonDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + + // INSERT语句 + QString sql = QString("INSERT INTO SYS_PERSON " + "(ID, DELFLAG, CREATETIME, UPDATETIME, " + "NAME, GENDER, DEPTID, ID_CARD_NO, " + "REMARKS, PERSON_CODE, SYNC_ID, FACE_VALID, IRIS_VALID) " + "VALUES ('%1', '0', '%2', '%2', '%3', '%4', '%5', '%6', '%7', '%8', '%9', 0, 0)") + .arg(id).arg(tm) + .arg(object.value("name").toString()) + .arg(object.value("gender").toString()) + .arg(object.value("deptid").toString()) + .arg(object.value("id_card_no").toString()) + .arg(object.value("remarks").toString()) + .arg(object.value("person_code").toString()) + .arg(object.value("sync_id").toString()); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(sql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { +// LOG(DEBUG) << QString("保存SYS_PERSON记录成功[ID = %1][%2]").arg(id).arg(sql).toStdString(); +// LOG_DEBUG(QString("保存SYS_PERSON记录成功[ID = %1][%2]").arg(id).arg(sql).toStdString()); + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool SysPersonDao::edit(QVariantMap newObject, QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + + // UPDATE语句 + QString sql = QString("UPDATE SYS_PERSON SET UPDATETIME = '%1'").arg(tm); + if (newObject.contains("name")) + { + sql.append(QString(", NAME = '%1'").arg(newObject.value("name").toString())); + } + if (newObject.contains("gender")) + { + sql.append(QString(", GENDER = '%1'").arg(newObject.value("gender").toString())); + } + if (newObject.contains("deptid")) + { + sql.append(QString(", DEPTID = '%1'").arg(newObject.value("deptid").toString())); + } + if (newObject.contains("person_code")) + { + sql.append(QString(", PERSON_CODE = '%1'").arg(newObject.value("person_code").toString())); + } + if (newObject.contains("face_valid")) + { + sql.append(QString(", FACE_VALID = '%1'").arg(newObject.value("face_valid").toString())); + } + if (newObject.contains("iris_valid")) + { + sql.append(QString(", IRIS_VALID = '%1'").arg(newObject.value("iris_valid").toString())); + } + + sql.append(QString(" WHERE ID = '%1'").arg(id)); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(sql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + +// LOG(DEBUG) << QString("编辑人员[ID=%1][%2]").arg(id).arg(sql).toStdString(); +// LOG_DEBUG(QString("编辑人员[ID=%1][%2]").arg(id).arg(sql).toStdString()); + + // 返回结果 + return success; +} + +bool SysPersonDao::dele(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + QSqlQuery irisDel(ConnectionManager::getInstance()->getConnection()); + + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + qint64 tmms = QDateTime::currentDateTime().toMSecsSinceEpoch(); + + // UPDATE语句 + QString sql = QString("UPDATE SYS_PERSON SET UPDATETIME = :updateTime, DELFLAG = :flag WHERE ID = :id").arg(tm).arg(tmms).arg(id); + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":updateTime", tm); + query.bindValue(":flag", tmms); + + // 物理删除人员的人脸和虹膜数据 + QString delIrisSql = QString("DELETE FROM IRIS_DATA WHERE PERSON_ID = :personId"); + irisDel.prepare(delIrisSql); + irisDel.bindValue(":personId", id); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(sql); + query.exec(delIrisSql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + +// LOG_DEBUG(QString("删除人员SYS_PERSON[ID=%1][%2]").arg(id).arg(success).toStdString()); + + // 返回结果 + return success; +} diff --git a/dao/SysPersonDao.h b/dao/SysPersonDao.h new file mode 100644 index 0000000..e02e5ba --- /dev/null +++ b/dao/SysPersonDao.h @@ -0,0 +1,27 @@ +#ifndef SYSPERSONDAO_H +#define SYSPERSONDAO_H + +#include +#include "BaseDao.h" + +class SysPersonDao : public BaseDao +{ + Q_OBJECT +public: + explicit SysPersonDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + int findRecordCountByNameAndDept(QString name, QString dept); + QVector findRecordsByNameAndDept(QString name, QString dept, qint8 limit, qint16 offset); + QVector findRecordsByProperties(QVariantMap conditions); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); +signals: + +}; + +#endif // SYSPERSONDAO_H diff --git a/dao/dao.pri b/dao/dao.pri new file mode 100644 index 0000000..1e04ce4 --- /dev/null +++ b/dao/dao.pri @@ -0,0 +1,18 @@ + +HEADERS += $$PWD/BaseDao.h +HEADERS += $$PWD/IrisDataDao.h +HEADERS += $$PWD/RecognitionRecordsDao.h +HEADERS += $$PWD/SysPersonDao.h +HEADERS += $$PWD/SysDeptDao.h + +SOURCES += $$PWD/BaseDao.cpp +SOURCES += $$PWD/IrisDataDao.cpp +SOURCES += $$PWD/RecognitionRecordsDao.cpp +SOURCES += $$PWD/SysPersonDao.cpp +SOURCES += $$PWD/SysDeptDao.cpp + +HEADERS += $$PWD/util/ConnectionManager.h +SOURCES += $$PWD/util/ConnectionManager.cpp +#HEADERS += $$PWD/util/CacheManager.h +#SOURCES += $$PWD/util/CacheManager.cpp + diff --git a/dao/util/ConnectionManager.cpp b/dao/util/ConnectionManager.cpp new file mode 100644 index 0000000..84b17be --- /dev/null +++ b/dao/util/ConnectionManager.cpp @@ -0,0 +1,47 @@ +#include "ConnectionManager.h" +#include + +Q_GLOBAL_STATIC(ConnectionManager, cm) + +ConnectionManager::ConnectionManager(QObject *parent) : QObject(parent) +{ + // 初始化数据库连接 + if (QSqlDatabase::contains("qt_sql_dafault_connection")) + { + conn = QSqlDatabase::database("qt_sql_default_connection"); + } + else + { + conn = QSqlDatabase::addDatabase("QSQLITE"); + conn.setDatabaseName(QApplication::applicationDirPath() + "/data/casic.db"); + + bool succ = conn.open(); + if (succ == true) + { +// LOG_INFO(QString("打开数据库操作正常[Open Database Success]").toStdString()); + } else + { +// LOG_ERROR(QString("打开数据库操作失败[Open Database Failed]").toStdString()); + } + } +} + +ConnectionManager::~ConnectionManager() +{ + conn.close(); +} + +ConnectionManager* ConnectionManager::getInstance() +{ + return cm; +} + +QSqlDatabase ConnectionManager::getConnection() +{ + return this->conn; +} + +qint64 ConnectionManager::generateId() +{ + return this->idWorker.nextId(); +} diff --git a/dao/util/ConnectionManager.h b/dao/util/ConnectionManager.h new file mode 100644 index 0000000..84647e3 --- /dev/null +++ b/dao/util/ConnectionManager.h @@ -0,0 +1,34 @@ +#ifndef CONNECTIONMANAGER_H +#define CONNECTIONMANAGER_H + +#include +#include +#include "utils/id/IdWorker.h" +#include "utils/UtilInclude.h" + +using namespace Jiawa::Core; + +class ConnectionManager : public QObject +{ + Q_OBJECT +public: + explicit ConnectionManager(QObject *parent = nullptr); + ~ConnectionManager(); + + static ConnectionManager * getInstance(); + + QSqlDatabase getConnection(); + qint64 generateId(); + +private: + // 数据库连接 + QSqlDatabase conn; + + // 雪花id生成工具 + IdWorker &idWorker = Singleton::instance(); + +signals: + +}; + +#endif // CONNECTIONMANAGER_H diff --git a/device/IrisCameraCapEventHandler.cpp b/device/IrisCameraCapEventHandler.cpp new file mode 100644 index 0000000..45df089 --- /dev/null +++ b/device/IrisCameraCapEventHandler.cpp @@ -0,0 +1,103 @@ +#include "IrisCameraCapEventHandler.h" + +IrisCameraCapEventHandler::IrisCameraCapEventHandler(QObject *parent) : QObject(parent) +{ + +} + +void IrisCameraCapEventHandler::DoOnImageCaptured(CImageDataPointer &objImageDataPointer, void *pUserParam) +{ + if (objImageDataPointer.IsNull() == false) + { + CGXDevicePointer* cam = (CGXDevicePointer *) pUserParam; + + auto camName = cam->getPtr()->GetDeviceInfo().GetUserID(); + int width = objImageDataPointer->GetWidth(); + int height = objImageDataPointer->GetHeight(); + size_t leftKeyIndex = camName.find("left"); + size_t rightKeyIndex = camName.find("right"); + + uchar * pBuffer = (BYTE*)objImageDataPointer->GetBuffer(); + + // 相机拍摄下的图像1440*1080, 直接用于算法判断 + QImage img = QImage(pBuffer, width, height, QImage::Format_Grayscale8); // 用于展示 +// QImage imgAlgo = img.copy(0, 0, width, height); + + // 用于显示的图像需要缩小到400 * 300的尺寸 + img = img.scaled(SettingConfig::getInstance().IRIS_DISPLAY_HEIGHT, SettingConfig::getInstance().IRIS_DISPLAY_WIDTH); + img = img.transformed(QTransform().rotate(-90)); // 图像逆时针旋转90度 + + // 发送到界面进行显示 + emit sendIrisFrameToDraw(img); +// cv::Mat irisMat = ImageUtil::QImageToMat(imgAlgo); + +// irisInfo.data = imgAlgo; +// irisInfo.matData = irisMat; + +// // 将图像显示在注册页面的label上 +// // 并将虹膜信息对象存入队列中 +// ProMemory::getInstance().pushCasicIris(irisInfo); + +// if (leftKeyIndex >= 0 && leftKeyIndex < 32) +// { +// emit sendIrisFrameToDraw(img, 0); // 左眼画面 +// } else if (rightKeyIndex >= 0 && rightKeyIndex < 32) +// { +// emit sendIrisFrameToDraw(img, 1); // 右眼画面 +// } +/* + if (pBuffer != NULL) + { + // 创建虹膜信息对象 + CasicIrisInfo irisInfo; + irisInfo.hasEye = false; + if (leftKeyIndex >= 0 && leftKeyIndex < 32) + { + // 左眼相机拍摄的图像 + irisInfo.leftOrRight = "left"; + } else if (rightKeyIndex >= 0 && rightKeyIndex < 32) + { + // 右眼相机 + irisInfo.leftOrRight = "right"; + } + + if (ProMemory::getInstance().widgeFrame == CasicBioRecConst::RECOGNIZE_RESULT_FORM) + { + // 相机拍摄下的图像1280*960, 直接用于算法判断 + QImage imgDisp = QImage(pBuffer, width, height, QImage::Format_Grayscale8); + cv::Mat irisMat = ImageUtil::QImageToMat(imgDisp); + + irisInfo.data = imgDisp; + irisInfo.matData = irisMat; + + ProMemory::getInstance().pushCasicIris(irisInfo); + +// cv::imwrite(QString("D:\\irisLogs\\iristest-%1.bmp").arg(irisInfo.leftOrRight).toStdString(), irisMat); + } else if (ProMemory::getInstance().widgeFrame == CasicBioRecConst::ADD_PERSON_CAPTURE_IRIS) + { + // 相机拍摄下的图像1280*960, 直接用于算法判断 + QImage img = QImage(pBuffer, width, height, QImage::Format_Grayscale8); + QImage imgAlgo = img.copy(0, 0, width, height); + + // 用于显示的图像需要缩小到1/4的尺寸 + img = img.scaled(640, 480); + cv::Mat irisMat = ImageUtil::QImageToMat(imgAlgo); + + irisInfo.data = imgAlgo; + irisInfo.matData = irisMat; + + // 将图像显示在注册页面的label上 + // 并将虹膜信息对象存入队列中 + ProMemory::getInstance().pushCasicIris(irisInfo); + + if (leftKeyIndex >= 0 && leftKeyIndex < 32) + { + emit sendIrisFrameToDraw(img, 0); // 左眼画面 + } else if (rightKeyIndex >= 0 && rightKeyIndex < 32) + { + emit sendIrisFrameToDraw(img, 1); // 右眼画面 + } + } + }*/ + } +} diff --git a/device/IrisCameraCapEventHandler.h b/device/IrisCameraCapEventHandler.h new file mode 100644 index 0000000..ad75a97 --- /dev/null +++ b/device/IrisCameraCapEventHandler.h @@ -0,0 +1,30 @@ +#ifndef IRISCAMERACAPEVENTHANDLER_H +#define IRISCAMERACAPEVENTHANDLER_H + +#include +#include +#include "include/opencv2/opencv.hpp" +#include "include/daheng/GalaxyIncludes.h" + +//#include "casic/iris/CasicIrisInterface.h" +#include "ProMemory.h" + +#include "utils/UtilInclude.h" + +class IrisCameraCapEventHandler : public QObject, public ICaptureEventHandler +{ + Q_OBJECT +public: + explicit IrisCameraCapEventHandler(QObject *parent = nullptr); + + void DoOnImageCaptured(CImageDataPointer &objImageDataPointer, void *pUserParam); + +private: + unsigned char* pImageBuffer; + +signals: + void sendIrisFrameToDraw(QImage irisImage); + +}; + +#endif // IRISCAMERACAPEVENTHANDLER_H diff --git a/device/IrisCameraController.cpp b/device/IrisCameraController.cpp new file mode 100644 index 0000000..0928176 --- /dev/null +++ b/device/IrisCameraController.cpp @@ -0,0 +1,110 @@ +#include "IrisCameraController.h" + +IrisCameraController::IrisCameraController(QObject *parent) : QObject(parent) +{ + this->irisCamHandler = new IrisCameraCapEventHandler(this); +} +IrisCameraController::~IrisCameraController() +{ + this->closeIrisCamera(); +} + + +void IrisCameraController::initIrisCamera() +{ + IGXFactory::GetInstance().Init(); + + //枚举设备 + IGXFactory::GetInstance().UpdateDeviceList(1000, irisCamList); + + this->OpenDevice(); +} + +void IrisCameraController::openIrisCamera() +{ + //设置Buffer处理模式 + irisStreamFeaturePtr->GetEnumFeature("StreamBufferHandlingMode")->SetValue("OldestFirst"); + + //注册回调函数 + irisStreamPtr->RegisterCaptureCallback(irisCamHandler, &irisCamPtr); + + //开启流层通道 + irisStreamPtr->StartGrab(); + + //发送开采命令 + irisFeaturePtr->GetCommandFeature("AcquisitionStart")->Execute(); + + // 启动定时器 + TimeCounterUtil::getInstance().irisCapCounter->start(SettingConfig::getInstance().IRIS_FRAME_INTERVAL); // 50ms执行一次定时器 +} + +void IrisCameraController::closeIrisCamera() +{ + +} + +void IrisCameraController::startCapture() +{ + // 获取定时器, 绑定定时函数 + connect(TimeCounterUtil::getInstance().irisCapCounter, &QTimer::timeout, this, &IrisCameraController::getOneFaceFrm); +// LOG(DEBUG) << QString("[IrisCameraController][startCapture]虹膜相机拍图").toStdString(); +// LOG_DEBUG(QString("[IrisCameraController][startCapture]虹膜相机拍图").toStdString()); + +} +void IrisCameraController::stopCapture() +{ + // 获取定时器, 绑定定时函数 + disconnect(TimeCounterUtil::getInstance().irisCapCounter, &QTimer::timeout, this, &IrisCameraController::getOneFaceFrm); +// LOG(DEBUG) << QString("[IrisCameraController][stopCapture]虹膜相机停止拍图").toStdString(); +// LOG_DEBUG(QString("[IrisCameraController][stopCapture]虹膜相机停止拍图").toStdString()); + +} + +void IrisCameraController::getOneFaceFrm() +{ + // 发送软触发命令(在触发模式开启时有效) + irisFeaturePtr->GetCommandFeature("TriggerSoftware")->Execute(); +} + +void IrisCameraController::getLeftAndRightEyeFrame() +{ + irisFeaturePtr->GetCommandFeature("TriggerSoftware")->Execute(); +} + +void IrisCameraController::OpenDevice() +{ + auto device = irisCamList.at(0); + + irisCamPtr = IGXFactory::GetInstance().OpenDeviceByUserID(device.GetUserID(), GX_ACCESS_EXCLUSIVE); + irisFeaturePtr = irisCamPtr->GetRemoteFeatureControl(); + + // 判断设备流是否大于零, 如果大于零则打开流 + int nStreamCount = irisCamPtr->GetStreamCount(); + if (nStreamCount > 0) + { + irisStreamPtr = irisCamPtr->OpenStream(0); + irisStreamFeaturePtr = irisStreamPtr->GetFeatureControl(); + } + + // 建议用户在打开网络相机之后, 根据当前网络环境设置相机的流通道包长值, + // 以提高网络相机的采集性能, 设置方法参考以下代码。 + GX_DEVICE_CLASS_LIST objDeviceClass = irisCamPtr->GetDeviceInfo().GetDeviceClass(); + if(GX_DEVICE_CLASS_GEV == objDeviceClass) + { + // 判断设备是否支持流通道数据包功能 + if(true == irisFeaturePtr->IsImplemented("GevSCPSPacketSize")) + { + // 获取当前网络环境的最优包长值 + int nPacketSize = irisStreamPtr->GetOptimalPacketSize(); + // 将最优包长值设置为当前设备的流通道包长值 + irisFeaturePtr->GetIntFeature("GevSCPSPacketSize")->SetValue(nPacketSize); + } + } + + //设置采集模式为连续采集模式 + irisFeaturePtr->GetEnumFeature("AcquisitionMode")->SetValue("Continuous"); + + //设置触发模式关 + irisFeaturePtr->GetEnumFeature("TriggerMode")->SetValue("On"); + irisFeaturePtr->GetEnumFeature("TriggerSource")->SetValue("Software"); +} diff --git a/device/IrisCameraController.h b/device/IrisCameraController.h new file mode 100644 index 0000000..5d7e269 --- /dev/null +++ b/device/IrisCameraController.h @@ -0,0 +1,49 @@ +#ifndef IRISCAMERACONTROLLER_H +#define IRISCAMERACONTROLLER_H + +#include + +#include "IrisCameraCapEventHandler.h" + +class IrisCameraCapEventHandler; + +class IrisCameraController : public QObject +{ + Q_OBJECT +public: + explicit IrisCameraController(QObject *parent = nullptr); + ~IrisCameraController(); + + // 初始化并打开人脸相机 + void initIrisCamera(); + void openIrisCamera(); + void closeIrisCamera(); + + void startCapture(); + void stopCapture(); + + void getLeftAndRightEyeFrame(); + + IrisCameraCapEventHandler * irisCamHandler; + +private: + GxIAPICPP::gxdeviceinfo_vector irisCamList; + + CGXDevicePointer irisCamPtr; ///< 设备句柄 + + CGXStreamPointer irisStreamPtr; ///< 左眼设备流 + + CGXFeatureControlPointer irisFeaturePtr; ///< 左眼属性控制器 + + CGXFeatureControlPointer irisStreamFeaturePtr; ///< 左眼流层控制器对象 + + void OpenDevice(); + +signals: + +public slots: + void getOneFaceFrm(); + +}; + +#endif // IRISCAMERACONTROLLER_H diff --git a/device/device.pri b/device/device.pri new file mode 100644 index 0000000..a8417f2 --- /dev/null +++ b/device/device.pri @@ -0,0 +1,13 @@ + +HEADERS += $$PWD/IrisCameraController.h +HEADERS += $$PWD/IrisCameraCapEventHandler.h +#HEADERS += $$PWD/iris/IrisRegistProcess.h +#HEADERS += $$PWD/iris/IrisRecogProcess.h +#HEADERS += $$PWD/iris/CasicIrisRecState.h + +SOURCES += $$PWD/IrisCameraController.cpp +SOURCES += $$PWD/IrisCameraCapEventHandler.cpp +#SOURCES += $$PWD/iris/IrisRegistProcess.cpp +#SOURCES += $$PWD/iris/IrisRecogProcess.cpp +#SOURCES += $$PWD/iris/CasicIrisRecState.cpp + diff --git a/images/bg_footer.png b/images/bg_footer.png new file mode 100644 index 0000000..a3a99ab --- /dev/null +++ b/images/bg_footer.png Binary files differ diff --git a/images/bg_statcked.png b/images/bg_statcked.png new file mode 100644 index 0000000..18b63e1 --- /dev/null +++ b/images/bg_statcked.png Binary files differ diff --git a/images/bg_title.png b/images/bg_title.png new file mode 100644 index 0000000..0316e2d --- /dev/null +++ b/images/bg_title.png Binary files differ diff --git a/main.cpp b/main.cpp index 16bc45b..9052ddb 100644 --- a/main.cpp +++ b/main.cpp @@ -1,11 +1,11 @@ -#include "IdentifyForm.h" +#include "MainWindowForm.h" #include int main(int argc, char *argv[]) { QApplication a(argc, argv); - IdentifyForm w; + MainWindowForm w; w.show(); return a.exec(); } diff --git a/resource.qrc b/resource.qrc new file mode 100644 index 0000000..474586a --- /dev/null +++ b/resource.qrc @@ -0,0 +1,35 @@ + + + images/setting.png + images/user.png + images/back.png + images/home.png + images/btnPageFirst.png + images/btnPageLast.png + images/btnPageNext.png + images/btnPagePre.png + images/regist.png + images/photoEyeLeft.png + images/photoEyeRight.png + images/photoFace.png + images/save.png + images/upArrow.png + images/downArrow.png + images/faceCaped.png + images/faceNotCap.png + images/irisCaped.png + images/irisNotCap.png + images/tipsFailure.png + images/tipsSuccess.png + images/tipsConfirm.png + images/bg_recognize_result.png + images/iconRetry.png + images/bg_title.png + images/bg_footer.png + images/bg_statcked.png + + + images/add_bottom.png + images/add_top.png + + diff --git a/utils/ImageUtil.cpp b/utils/ImageUtil.cpp new file mode 100644 index 0000000..7604572 --- /dev/null +++ b/utils/ImageUtil.cpp @@ -0,0 +1,97 @@ +#include "ImageUtil.h" + +ImageUtil::ImageUtil() +{ + +} + +QImage ImageUtil::MatImageToQImage(const cv::Mat &src) +{ + //CV_8UC1 8位无符号的单通道---灰度图片 + if(src.type() == CV_8UC1) + { + QImage qImage((const unsigned char *)(src.data), src.cols, src.rows, src.cols, QImage::Format_Grayscale8); + return qImage; + } + //为3通道的彩色图片 + else if(src.type() == CV_8UC3) + { + //得到图像的的首地址 + const uchar *pSrc = (const uchar*)src.data; + //以src构造图片 + QImage qImage(pSrc, src.cols, src.rows, src.step, QImage::Format_RGB888); + //在不改变实际图像数据的条件下, 交换红蓝通道 + return qImage.rgbSwapped(); + } + //四通道图片, 带Alpha通道的RGB彩色图像 + else if(src.type() == CV_8UC4) + { + const uchar *pSrc = (const uchar*)src.data; + QImage qImage(pSrc, src.cols, src.rows, src.step, QImage::Format_ARGB32); + //返回图像的子区域作为一个新图像 + return qImage.copy(); + } + else + { + return QImage(); + } +} +/* +QImage ImageUtil::UcharToQImage(unsigned char* data, int width, int height, QImage::Format format) +{ + QImage qImage(data, width, height, format); + //在不改变实际图像数据的条件下, 交换红蓝通道 + return qImage.rgbSwapped(); +} + +cv::Mat ImageUtil::QImageToMat(QImage image) +{ + cv::Mat mat; + switch(image.format()) + { + case QImage::Format_ARGB32: + case QImage::Format_RGB32: + case QImage::Format_ARGB32_Premultiplied: + mat = cv::Mat(image.height(), image.width(), CV_8UC4, (void*)image.constBits(), image.bytesPerLine()); + break; + case QImage::Format_RGB888: + mat = cv::Mat(image.height(), image.width(), CV_8UC3, (void*)image.constBits(), image.bytesPerLine()); + cv::cvtColor(mat, mat, cv::COLOR_BGR2RGB); + break; + case QImage::Format_Indexed8: + mat = cv::Mat(image.height(), image.width(), CV_8UC1, (void*)image.constBits(), image.bytesPerLine()); + break; + case QImage::Format_Grayscale8: + mat = cv::Mat(image.height(), image.width(), CV_8UC1, (void *)image.bits(), image.bytesPerLine()); + break; + } + + mat = mat.clone(); + + return mat; +} + +QString ImageUtil::QImageToBase64(QImage image) +{ + QByteArray ba; + QBuffer buf(&ba); + image.save(&buf, "bmp"); + QString base64String = ba.toBase64(); + return base64String; +} + +cv::Mat ImageUtil::MatImageRect(const cv::Mat &src, cv::Rect rect, int delta) +{ + cv::Mat matClone = src.clone(); + cv::Rect bigRect; + + bigRect.x = rect.x - delta < 0 ? 0 : rect.x - delta; + bigRect.y = rect.y - delta < 0 ? 0 : rect.y - delta; + bigRect.width = rect.x + rect.width + 2 * delta > src.cols ? src.cols - rect.x : rect.width + 2 * delta; + bigRect.height = rect.y + rect.height + 2 * delta > src.rows ? src.rows - rect.y : rect.height + 2 * delta; + + cv::Mat roi = matClone(bigRect); + + return roi; +} +*/ diff --git a/utils/ImageUtil.h b/utils/ImageUtil.h new file mode 100644 index 0000000..dbfdd48 --- /dev/null +++ b/utils/ImageUtil.h @@ -0,0 +1,22 @@ +#ifndef IMAGEUTIL_H +#define IMAGEUTIL_H + +#include +#include +#include "opencv2/opencv.hpp" + +class ImageUtil +{ +public: + ImageUtil(); + + static QImage MatImageToQImage(const cv::Mat &src); +// static QImage UcharToQImage(unsigned char* data, int width, int height, QImage::Format format); + +// static cv::Mat QImageToMat(QImage image); +// static QString QImageToBase64(QImage image); + +// static cv::Mat MatImageRect(const cv::Mat &src, cv::Rect rect, int delta); +}; + +#endif // IMAGEUTIL_H diff --git a/utils/SettingConfig.cpp b/utils/SettingConfig.cpp new file mode 100644 index 0000000..d420285 --- /dev/null +++ b/utils/SettingConfig.cpp @@ -0,0 +1,44 @@ +#include "SettingConfig.h" +#include + +SettingConfig::SettingConfig() +{ + filename = QApplication::applicationDirPath() + "/conf/config.ini"; + setting = new QSettings(this->filename, QSettings::IniFormat); + + WINDOW_WIDTH = getProperty("window", "width").toInt(); + WINDOW_HEIGHT = getProperty("window", "height").toInt(); + WINDOW_BACKGROUND_COLOR = getProperty("window", "backgroundColor").toString(); + WINDOW_TITLE = getProperty("window", "title").toString(); + WINDOW_RIGHTS = getProperty("window", "copyright").toString(); + WINDOW_VERSION = getProperty("window", "version").toString(); + + IRIS_FRAME_WIDTH = getProperty("camera", "irisFrameWidth").toInt(); + IRIS_FRAME_HEIGHT = getProperty("camera", "irisFrameHeight").toInt(); + IRIS_WIDTH = getProperty("camera", "irisWidth").toInt(); + IRIS_HEIGHT = getProperty("camera", "irisHeight").toInt(); + IRIS_FRAME_INTERVAL = getProperty("camera", "irisFrameInterval").toInt(); + IRIS_DISPLAY_WIDTH = getProperty("camera", "irisDisplayWidth").toInt(); + IRIS_DISPLAY_HEIGHT = getProperty("camera", "irisDisplayHeight").toInt(); + + MAX_MATCH_TIME = getProperty("recognize", "maxMatchTime").toInt(); + SUCCESS_TIPS_LAST = getProperty("recognize", "successTipsLast").toInt(); + FAILURE_TIPS_LAST = getProperty("recognize", "failureTipsLast").toInt(); + MAX_FACE_TRY_COUNT = getProperty("recognize", "maxFaceTryCount").toInt(); + MAX_FACE_NOT_FOUND_COUNT = getProperty("recognize", "maxFaceNotFoundCount").toInt(); + MAX_IRIS_TRY_COUNT = getProperty("recognize", "maxIrisTryCount").toInt(); + MAX_EYE_NOT_FOUND_COUNT = getProperty("recognize", "maxEyeNotFoundCount").toInt(); + + MAX_CAPTURE_STACK_SIZE = getProperty("stack", "capture").toInt(); + MAX_FOUND_STACK_SIZE = getProperty("stack", "found").toInt(); + MAX_QUALIFIED_STACK_SIZE = getProperty("stack", "qualified").toInt(); + + LOG_FILE = getProperty("log", "logFile").toString(); + LOG_LEVEL = getProperty("log", "logLevel").toString(); +} + + +QVariant SettingConfig::getProperty(QString nodeName, QString keyName) { + QVariant var = this->setting->value(QString("/%1/%2").arg(nodeName).arg(keyName)); + return var; +} diff --git a/utils/SettingConfig.h b/utils/SettingConfig.h new file mode 100644 index 0000000..30c3bec --- /dev/null +++ b/utils/SettingConfig.h @@ -0,0 +1,66 @@ +#ifndef SETTINGCONFIG_H +#define SETTINGCONFIG_H + +#include +#include + +class SettingConfig : public QObject +{ +public: + ~SettingConfig() {}; + SettingConfig(const SettingConfig&)=delete; + SettingConfig& operator=(const SettingConfig&)=delete; + + static SettingConfig& getInstance() { + static SettingConfig instance; + return instance; + } + + /** + * @brief get + * @param nodeName + * @param keyName + * @return QVariant + * @title + */ + QVariant getProperty(QString nodeName, QString keyName); + + /******** 以下为需要的各类参数 ********/ + int WINDOW_WIDTH; + int WINDOW_HEIGHT; + QString WINDOW_BACKGROUND_COLOR; + QString WINDOW_TITLE; + QString WINDOW_RIGHTS; + QString WINDOW_VERSION; + + int IRIS_FRAME_INTERVAL; + int IRIS_FRAME_WIDTH; + int IRIS_FRAME_HEIGHT; + int IRIS_WIDTH; + int IRIS_HEIGHT; + int IRIS_DISPLAY_WIDTH; + int IRIS_DISPLAY_HEIGHT; + + int MAX_MATCH_TIME; + int SUCCESS_TIPS_LAST; + int FAILURE_TIPS_LAST; + int MAX_FACE_TRY_COUNT; + int MAX_FACE_NOT_FOUND_COUNT; + int MAX_IRIS_TRY_COUNT; + int MAX_EYE_NOT_FOUND_COUNT; + + int MAX_CAPTURE_STACK_SIZE; + int MAX_FOUND_STACK_SIZE; + int MAX_QUALIFIED_STACK_SIZE; + + QString LOG_FILE; + QString LOG_LEVEL; + +private: + SettingConfig(); + + QString filename; + QSettings* setting; +}; + +#endif // SETTINGCONFIG_H diff --git a/utils/TimeCounterUtil.cpp b/utils/TimeCounterUtil.cpp new file mode 100644 index 0000000..275945f --- /dev/null +++ b/utils/TimeCounterUtil.cpp @@ -0,0 +1,8 @@ +#include "TimeCounterUtil.h" + +TimeCounterUtil::TimeCounterUtil() +{ + faceCapCounter = new QTimer(); + irisCapCounter = new QTimer(); + clockCounter = new QTimer(); +} diff --git a/AppConstants.h b/AppConstants.h new file mode 100644 index 0000000..296c53f --- /dev/null +++ b/AppConstants.h @@ -0,0 +1,28 @@ +#ifndef APPCONSTANTS_H +#define APPCONSTANTS_H + +class AppConstants +{ +public: + enum WidgeFrameName + { + MAIN_PAGE = 0, // 主页面 + PERSON_LIST_FORM = 1, // 人员列表页面 + ADD_PERSON_FORM = 2, // 添加人员页面 + ADD_PERSON_CAPTURE_FACE = 21, // 添加/编辑人员时进行人脸拍图 + ADD_PERSON_CAPTURE_IRIS = 22, // 添加/编辑人员时进行虹膜拍图 + SETTING_FORM = 3, // 设置页面 + RECOGNIZE_RESULT_FORM = 4, // 识别结果界面 + IDENTIFY_FORM = 5, // 识别界面 含识别中 和 识别结果 + LOCKSCREEN_FORM = 6 // 锁屏待机界面 + }; + + enum ApplicationState + { + STATE_WAIT = 0, // 待机 + STATE_WORKING = 1, // 工作状态 + STATE_IDENTIFYING = 2, // 识别中 + }; +}; + +#endif // APPCONSTANTS_H diff --git a/CasicIrisIdentify.pro b/CasicIrisIdentify.pro index 5d7fea6..575ce3d 100644 --- a/CasicIrisIdentify.pro +++ b/CasicIrisIdentify.pro @@ -1,4 +1,4 @@ -QT += core gui +QT += core gui sql network texttospeech greaterThan(QT_MAJOR_VERSION, 4): QT += widgets @@ -15,20 +15,46 @@ # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 -SOURCES += \ - main.cpp \ - IdentifyForm.cpp +include("dao/dao.pri") +include("device/device.pri") +include("utils/utils.pri") -HEADERS += \ - IdentifyForm.h +SOURCES += main.cpp +SOURCES += ProMemory.cpp +SOURCES += MainWindowForm.cpp +SOURCES += IdentifyForm.cpp +SOURCES += LockScreenForm.cpp -FORMS += \ - IdentifyForm.ui +HEADERS += AppConstants.h +HEADERS += ProMemory.h +HEADERS += MainWindowForm.h +HEADERS += IdentifyForm.h +HEADERS += LockScreenForm.h -TRANSLATIONS += \ - CasicIrisIdentify_zh_CN.ts +FORMS += MainWindowForm.ui +FORMS += IdentifyForm.ui +FORMS += LockScreenForm.ui + +RESOURCES += resource.qrc + +DISTFILES += conf/config.ini + +#TRANSLATIONS += CasicIrisIdentify_zh_CN.ts + +#INCLUDEPATH += include/spdlog +#DEPENDPATH += include/spdlog # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target + + +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lopencv_world420 +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lGxIAPICPPEx + +INCLUDEPATH += $$PWD/include/daheng +DEPENDPATH += $$PWD/include/daheng + +INCLUDEPATH += $$PWD/include +DEPENDPATH += $$PWD/include diff --git a/CasicIrisIdentify_zh_CN.ts b/CasicIrisIdentify_zh_CN.ts index 5526fe4..81900df 100644 --- a/CasicIrisIdentify_zh_CN.ts +++ b/CasicIrisIdentify_zh_CN.ts @@ -1,3 +1,12 @@ - + + + IdentifyForm + + + IdentifyForm + + + + diff --git a/IdentifyForm.cpp b/IdentifyForm.cpp index 348a897..ba1f251 100644 --- a/IdentifyForm.cpp +++ b/IdentifyForm.cpp @@ -1,4 +1,4 @@ -#include "IdentifyForm.h" +#include "IdentifyForm.h" #include "ui_IdentifyForm.h" IdentifyForm::IdentifyForm(QWidget *parent) @@ -6,6 +6,12 @@ , ui(new Ui::IdentifyForm) { ui->setupUi(this); + + // 初始化更新界面的定时器 + // 每秒执行一次 + connect(TimeCounterUtil::getInstance().clockCounter, &QTimer::timeout, this, &IdentifyForm::updateDateAndTime); + + TimeCounterUtil::getInstance().clockCounter->start(1000); } IdentifyForm::~IdentifyForm() @@ -13,3 +19,16 @@ delete ui; } +void IdentifyForm::drawIrisImageOnFrame(QImage image) +{ + // 只在识别界面才显示画面 + if (ui->wgtStacked->currentIndex() == 0) { + ui->labelVideo->setPixmap(QPixmap::fromImage(image)); + } +} + + +void IdentifyForm::updateDateAndTime() +{ + ui->labelTime->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd dddd HH:mm:ss")); +} diff --git a/IdentifyForm.h b/IdentifyForm.h index fc857a1..ae1cd22 100644 --- a/IdentifyForm.h +++ b/IdentifyForm.h @@ -1,7 +1,10 @@ -#ifndef IDENTIFYFORM_H +#ifndef IDENTIFYFORM_H #define IDENTIFYFORM_H #include +#include + +#include "utils/UtilInclude.h" QT_BEGIN_NAMESPACE namespace Ui { class IdentifyForm; } @@ -15,7 +18,14 @@ IdentifyForm(QWidget *parent = nullptr); ~IdentifyForm(); +public slots: + void drawIrisImageOnFrame(QImage image); + private: Ui::IdentifyForm *ui; + +private slots: + void updateDateAndTime(); + }; #endif // IDENTIFYFORM_H diff --git a/IdentifyForm.ui b/IdentifyForm.ui index c72a36f..879dc9a 100644 --- a/IdentifyForm.ui +++ b/IdentifyForm.ui @@ -6,13 +6,59 @@ 0 0 - 800 + 600 600 IdentifyForm + + + + 0 + 40 + 600 + 450 + + + + 0 + + + + + + 100 + 10 + 400 + 300 + + + + + + + + + + + + + + 0 + 0 + 600 + 40 + + + + TextLabel + + + Qt::AlignCenter + + diff --git a/LockScreenForm.cpp b/LockScreenForm.cpp new file mode 100644 index 0000000..58dc54b --- /dev/null +++ b/LockScreenForm.cpp @@ -0,0 +1,14 @@ +#include "LockScreenForm.h" +#include "ui_LockScreenForm.h" + +LockScreenForm::LockScreenForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::LockScreenForm) +{ + ui->setupUi(this); +} + +LockScreenForm::~LockScreenForm() +{ + delete ui; +} diff --git a/LockScreenForm.h b/LockScreenForm.h new file mode 100644 index 0000000..b5ded48 --- /dev/null +++ b/LockScreenForm.h @@ -0,0 +1,25 @@ +#ifndef LOCKSCREENFORM_H +#define LOCKSCREENFORM_H + +#include +#include + +#include "utils/UtilInclude.h" + +namespace Ui { +class LockScreenForm; +} + +class LockScreenForm : public QWidget +{ + Q_OBJECT + +public: + explicit LockScreenForm(QWidget *parent = nullptr); + ~LockScreenForm(); + +private: + Ui::LockScreenForm *ui; +}; + +#endif // LOCKSCREENFORM_H diff --git a/LockScreenForm.ui b/LockScreenForm.ui new file mode 100644 index 0000000..7f2a6db --- /dev/null +++ b/LockScreenForm.ui @@ -0,0 +1,45 @@ + + + LockScreenForm + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + 180 + 100 + 54 + 12 + + + + TextLabel + + + + + + 180 + 160 + 54 + 12 + + + + TextLabel + + + + + + diff --git a/MainWindowForm.cpp b/MainWindowForm.cpp new file mode 100644 index 0000000..84f8159 --- /dev/null +++ b/MainWindowForm.cpp @@ -0,0 +1,86 @@ +#include "MainWindowForm.h" +#include "ui_MainWindowForm.h" +#include + +MainWindowForm::MainWindowForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::MainWindowForm) +{ + ui->setupUi(this); + + // 设置窗口透明和大小、位置 + this->setWindowFlags(Qt::FramelessWindowHint); + this->move(1400, 15); + this->resize(SettingConfig::getInstance().WINDOW_WIDTH, SettingConfig::getInstance().WINDOW_HEIGHT); + + // 通过调色板的颜色来设置窗口的统一背景色 + qApp->setPalette(QPalette(QColor(SettingConfig::getInstance().WINDOW_BACKGROUND_COLOR))); + + // 加载css文件设置控件样式 + QFile file(QApplication::applicationDirPath() + "/qss/main.css"); + if (file.open(QFile::ReadOnly)) + { + QString qssStr = QLatin1String(file.readAll()); + this->setStyleSheet(qssStr); + file.close(); + } + + initFormsPtr(); + + // 设置标题文字 + ui->labelTitle->setText(SettingConfig::getInstance().WINDOW_TITLE); + ui->labelCopyright->setText(SettingConfig::getInstance().WINDOW_RIGHTS); + ui->labelVersion->setText(SettingConfig::getInstance().WINDOW_VERSION); + + // 初始化虹膜相机控制 + ProMemory::getInstance().irisCam = new IrisCameraController(this); + ProMemory::getInstance().irisCam->initIrisCamera(); + ProMemory::getInstance().irisCam->openIrisCamera(); + connect(ProMemory::getInstance().irisCam->irisCamHandler, &IrisCameraCapEventHandler::sendIrisFrameToDraw, identifyForm, &IdentifyForm::drawIrisImageOnFrame); + +// LOG_INFO(QString("应用程序启动成功[Application Startup Success]").toStdString()); + qDebug() << "应用程序启动成功[Application Startup Success]"; + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::IDENTIFY_FORM; + ui->wdgtStatced->setCurrentWidget(identifyForm); + + // 开始虹膜相机拍图 + ProMemory::getInstance().irisCam->startCapture(); +} + +MainWindowForm::~MainWindowForm() +{ + delete ui; +} + +void MainWindowForm::lockScreen() +{ + ui->wdgtStatced->setCurrentWidget(lockScreenForm); + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::LOCKSCREEN_FORM; + ProMemory::getInstance().appState = AppConstants::ApplicationState::STATE_WAIT; +} + +void MainWindowForm::keyPressEvent(QKeyEvent *event) +{ + switch (event->key()) { + case Qt::Key_Escape: + QTimer::singleShot(100, qApp, [=](){ + QApplication::quit(); + }); + + default: + QWidget::keyPressEvent(event); + } +} + +void MainWindowForm::initFormsPtr() +{ + // 初始化各个form + lockScreenForm = new LockScreenForm(this); + identifyForm = new IdentifyForm(this); + + // 将form添加到statcked widget中 + ui->wdgtStatced->addWidget(identifyForm); + ui->wdgtStatced->addWidget(lockScreenForm); + + // 绑定按钮函数 +} diff --git a/MainWindowForm.h b/MainWindowForm.h new file mode 100644 index 0000000..7fb2d89 --- /dev/null +++ b/MainWindowForm.h @@ -0,0 +1,38 @@ +#ifndef MAINWINDOWFORM_H +#define MAINWINDOWFORM_H + +#include +#include +#include + +#include "utils/UtilInclude.h" +#include "ProMemory.h" +#include "LockScreenForm.h" +#include "IdentifyForm.h" + +namespace Ui { +class MainWindowForm; +} + +class MainWindowForm : public QWidget +{ + Q_OBJECT + +public: + explicit MainWindowForm(QWidget *parent = nullptr); + ~MainWindowForm(); + +public slots: + void lockScreen(); + +private: + Ui::MainWindowForm *ui; + LockScreenForm * lockScreenForm; + IdentifyForm * identifyForm; + + void keyPressEvent(QKeyEvent *event); + + void initFormsPtr(); +}; + +#endif // MAINWINDOWFORM_H diff --git a/MainWindowForm.ui b/MainWindowForm.ui new file mode 100644 index 0000000..e793ebf --- /dev/null +++ b/MainWindowForm.ui @@ -0,0 +1,85 @@ + + + MainWindowForm + + + + 0 + 0 + 600 + 1024 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + 0 + 0 + 600 + 84 + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + + + + TextLabel + + + Qt::AlignBottom|Qt::AlignHCenter + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + diff --git a/ProMemory.cpp b/ProMemory.cpp new file mode 100644 index 0000000..19e7403 --- /dev/null +++ b/ProMemory.cpp @@ -0,0 +1,84 @@ +#include "ProMemory.h" + +ProMemory::ProMemory() +{ + +} + +ProMemory::~ProMemory() +{ + +} + +/* +void ProMemory::pushCasicIris(CasicIrisInfo irisInfo) +{ + QMutex mutex; + mutex.lock(); + if (this->irisQueue.size() > 30) + { + QStack empty; + std::swap(empty, irisQueue); + } + + irisQueue.push(irisInfo); + mutex.unlock(); +} +CasicIrisInfo ProMemory::popCasicIris() +{ + CasicIrisInfo result; + + QMutex mutex; + mutex.lock(); + if (this->irisQueue.size() > 0) + { + result = irisQueue.pop(); + } + + mutex.unlock(); + + return result; +} +*/ +int ProMemory::getIrisQueueSize() +{ + int size = 0; + + QMutex mutex; + mutex.lock(); + +// size = this->irisQueue.size(); + + mutex.unlock(); + + return size; +} +bool ProMemory::isIrisQueueEmpty() +{ + bool empty = true; + + QMutex mutex; + mutex.lock(); + +// empty = this->irisQueue.isEmpty(); + + mutex.unlock(); + + return empty; +} +void ProMemory::clearIrisQueue() +{ + QMutex mutex; + mutex.lock(); + +// QStack empty; +// std::swap(empty, irisQueue); + + mutex.unlock(); +} + + +void ProMemory::initIrisFeatures(QString personId) +{ +// irisRegistPro->sendDataToExract(QByteArray(QString("[-u]").append(personId).toLocal8Bit())); +} diff --git a/ProMemory.h b/ProMemory.h new file mode 100644 index 0000000..2ecd653 --- /dev/null +++ b/ProMemory.h @@ -0,0 +1,52 @@ +#ifndef PROMEMORY_H +#define PROMEMORY_H + +#include +#include + +#include "AppConstants.h" +//#include "casic/iris/CasicIrisInfo.h" +#include "dao/IrisDataDao.h" + +#include "device/IrisCameraController.h" +//#include "device/iris/IrisRegistProcess.h" +//#include "device/iris/IrisRecogProcess.h" + +class IrisCameraController; +class IrisRegistProcess; +class IrisRecogProcess; + +class ProMemory +{ +public: + ~ProMemory(); + ProMemory(const ProMemory&)=delete; + ProMemory& operator=(const ProMemory&)=delete; + + static ProMemory& getInstance() { + static ProMemory instance; + return instance; + } + +// void pushCasicIris(CasicIrisInfo irisInfo); +// CasicIrisInfo popCasicIris(); + int getIrisQueueSize(); + bool isIrisQueueEmpty(); + void clearIrisQueue(); + + volatile int widgeFrame = 0; // 当前显示的界面 + volatile int appState = 0; // 当前程序所处的状态 + + void initIrisFeatures(QString personId = ""); // 初始化虹膜特征值集合 + + IrisCameraController * irisCam; + IrisRecogProcess * irisRecogPro; + +private: + ProMemory(); + +// QStack irisQueue; // 虹膜信息队列 + QVector irisFeatures; // 虹膜特征值集合 +}; + +#endif // PROMEMORY_H diff --git a/conf/config.ini b/conf/config.ini new file mode 100644 index 0000000..66e46ad --- /dev/null +++ b/conf/config.ini @@ -0,0 +1,67 @@ +[recognize] +#最大允许识别时间(ms) +maxMatchTime=10000 +#识别成功界面停留时间(ms) +successTipsLast=5000 +#识别失败界面停留时间(ms) +failureTipsLast=3000 +#人脸识别最大尝试次数 +maxFaceTryCount=20 +#持续没找到人脸的最大次数 +maxFaceNotFoundCount=500 +#注册时最小人脸 +minFaceRegist=240 +#识别时最小人脸 +minFaceRecog=100 + +#虹膜识别最大尝试次数 +maxIrisTryCount=10 +#虹膜识别持续没有找到眼的最大次数 +maxEyeNotFoundCount=50 + +#识别方式[1=人脸;2=虹膜;3=双认证;4=任意] +recogType=4 + +[window] +#界面窗口宽(px) +width=600 +#界面窗口高(px) +height=1024 +#统一背景色 +backgroundColor="#FFFFFF" +#标题 +title="虹膜识别终端" + +[work] +#工作状态检测时最小人脸范围 +minFaceSize=160 +#人脸范围最小横坐标 +minFacePosX=320 +#人脸范围最大横坐标 +maxFacePosX=960 +#人脸范围最小纵坐标 +minFacePosY=180 +#人脸范围最大纵坐标 +maxFacePosY=540 +#人脸太近阈值 +faceCloseSize=360 +#人脸太远阈值 +faceFarSize=480 + +[camera] +#虹膜相机取一幅画面的时间间隔(ms) +irisFrameInterval=100 +#虹膜相机拍摄宽度 +irisFrameWidth=1440 +#虹膜相机拍摄高度 +irisFrameHeight=1080 +#虹膜图像高度 +irisWidth=640 +#虹膜图像高度 +irisHeight=480 + +[log] +#日志文件位置 +logFile="d://irisLogs//casic_log.txt" +#日志级别 +logLevel="trace" diff --git a/dao/BaseDao.cpp b/dao/BaseDao.cpp new file mode 100644 index 0000000..f51c144 --- /dev/null +++ b/dao/BaseDao.cpp @@ -0,0 +1,12 @@ +#include "BaseDao.h" +#include "dao/util/ConnectionManager.h" + +BaseDao::BaseDao(QObject *parent) : QObject(parent) +{ + +} + +BaseDao::~BaseDao() +{ + +} diff --git a/dao/BaseDao.h b/dao/BaseDao.h new file mode 100644 index 0000000..1693c88 --- /dev/null +++ b/dao/BaseDao.h @@ -0,0 +1,32 @@ +#ifndef BASEDAO_H +#define BASEDAO_H + +#include +#include +#include +#include + +#include "dao/util/ConnectionManager.h" +#include "utils/UtilInclude.h" + +class BaseDao : public QObject +{ + Q_OBJECT +public: + explicit BaseDao(QObject *parent = nullptr); + ~BaseDao(); + + virtual QVector findAllRecord() = 0; + virtual QVariantMap findRecordById(QString id) = 0; + + virtual QString save(QVariantMap object) = 0; + virtual bool edit(QVariantMap newObject, QString id) = 0; + virtual bool dele(QString id) = 0; + +private: + +signals: + +}; + +#endif // BASEDAO_H diff --git a/dao/IrisDataDao.cpp b/dao/IrisDataDao.cpp new file mode 100644 index 0000000..37a0ed6 --- /dev/null +++ b/dao/IrisDataDao.cpp @@ -0,0 +1,204 @@ +#include "IrisDataDao.h" + +IrisDataDao::IrisDataDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector IrisDataDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM IRIS_DATA"; + query.prepare(sql); + + // 执行查询 + query.exec(); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + item.insert("id", query.value("id").toString()); + item.insert("person_id", query.value("person_id").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("left_iris_code1", query.value("left_iris_code1")); + item.insert("left_iris_code2", query.value("left_iris_code2")); + item.insert("left_iris_code3", query.value("left_iris_code3")); + item.insert("right_iris_code1", query.value("right_iris_code1")); + item.insert("right_iris_code2", query.value("right_iris_code2")); + item.insert("right_iris_code3", query.value("right_iris_code3")); + + result.append(item); + } + +// LOG_DEBUG(QString("查询IRIS_DATA表的所有记录[结果数:%1]").arg(result.size()).toStdString()); + return result; +} + +QVariantMap IrisDataDao::findRecordById(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM IRIS_DATA WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + // 获取结果 + if (query.next()) + { + result.insert("id", query.value("id").toString()); + result.insert("person_id", query.value("person_id").toLongLong()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("left_iris_code1", query.value("left_iris_code1")); + result.insert("left_iris_code2", query.value("left_iris_code2")); + result.insert("left_iris_code3", query.value("left_iris_code3")); + result.insert("right_iris_code1", query.value("right_iris_code1")); + result.insert("right_iris_code2", query.value("right_iris_code2")); + result.insert("right_iris_code3", query.value("right_iris_code3")); + } + +// LOG_DEBUG(QString("根据id查询IRIS_DATA表的记录[id=%1]").arg(id).toStdString()); + return result; +} + +QVariantMap IrisDataDao::findRecordByPersonId(QString personId) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM IRIS_DATA WHERE PERSON_ID = :personId"); + query.prepare(sql); + query.bindValue(":personId", personId); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + if (query.next()) + { + result.insert("id", query.value("id").toString()); + result.insert("person_id", query.value("person_id").toLongLong()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("left_iris_code1", query.value("left_iris_code1")); + result.insert("left_iris_code2", query.value("left_iris_code2")); + result.insert("left_iris_code3", query.value("left_iris_code3")); + result.insert("right_iris_code1", query.value("right_iris_code1")); + result.insert("right_iris_code2", query.value("right_iris_code2")); + result.insert("right_iris_code3", query.value("right_iris_code3")); + } + +// LOG_DEBUG(QString("根据personId查询IRIS_DATA表的记录[personId=%1]").arg(personId).toStdString()); + return result; +} + + +QString IrisDataDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + + // INSERT语句 + QString sql = QString("INSERT INTO IRIS_DATA (ID, PERSON_ID, ID_CARD_NO, LEFT_IRIS_CODE1, RIGHT_IRIS_CODE1) VALUES (:id, :personId, :idCardNo, :left1, :right1)"); + + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":personId", object.value("person_id").toString()); + query.bindValue(":idCardNo", object.value("id_card_no").toString()); + query.bindValue(":left1", object.value("left_iris_code1")); + query.bindValue(":right1", object.value("right_iris_code1")); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(); + +// LOG_DEBUG(QString("保存虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool IrisDataDao::edit(QVariantMap newObject, QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // UPDATE语句 + if (!newObject.contains("left_iris_code1") || !newObject.contains("right_iris_code1")){ + return false; + } + QString sql = QString("UPDATE IRIS_DATA SET LEFT_IRIS_CODE1 = :left1, RIGHT_IRIS_CODE1 = :right1 WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":left1", newObject.value("left_iris_code1")); + query.bindValue(":right1", newObject.value("right_iris_code1")); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(); + +// LOG_DEBUG(QString("编辑虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; +} + + +bool IrisDataDao::dele(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + QString sql = QString("DELETE FROM IRIS_DATA WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(); + +// LOG_DEBUG(QString("删除虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; +} diff --git a/dao/IrisDataDao.h b/dao/IrisDataDao.h new file mode 100644 index 0000000..c74dbbd --- /dev/null +++ b/dao/IrisDataDao.h @@ -0,0 +1,25 @@ +#ifndef IRISDATADAO_H +#define IRISDATADAO_H + +#include +#include "BaseDao.h" + +class IrisDataDao : public BaseDao +{ + Q_OBJECT +public: + explicit IrisDataDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + QVariantMap findRecordByPersonId(QString personId); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +signals: + +}; + +#endif // IRISDATADAO_H diff --git a/dao/RecognitionRecordsDao.cpp b/dao/RecognitionRecordsDao.cpp new file mode 100644 index 0000000..40db453 --- /dev/null +++ b/dao/RecognitionRecordsDao.cpp @@ -0,0 +1,100 @@ +#include "RecognitionRecordsDao.h" + +RecognitionRecordsDao::RecognitionRecordsDao(QObject *parent) : BaseDao(parent) +{ + +} + + +QVector RecognitionRecordsDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM RECOGNITION_RECORDS"; + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + item.insert("id", query.value("id").toLongLong()); + result.append(item); + } + +// LOG_DEBUG(QString("查询RECOGNITION_RECORDS表的所有记录[记录数:%1]").arg(result.size()).toStdString()); + return result; +} + +QVariantMap RecognitionRecordsDao::findRecordById(QString id) +{ + QVariantMap item; + return item; +} + +QString RecognitionRecordsDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + + // INSERT语句 + QString sql = QString("INSERT INTO RECOGNITION_RECORDS (ID, PERSON_ID, DATETIME, REC_TYPE, DEV_CODE, DOOR_CODE, INOUT_TYPE) " + "VALUES (:id, :personId, :datetime, :recType, :devCode, :doorCode, :inoutType)"); + + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":personId", object.value("person_id").toString()); + query.bindValue(":datetime", object.value("date_time").toString()); + query.bindValue(":recType", object.value("rec_type").toString()); + query.bindValue(":devCode", object.value("dev_code").toString()); + query.bindValue(":doorCode", object.value("door_code").toString()); + query.bindValue(":inoutType", object.value("inout_type").toString()); + +// LOG_DEBUG(sql.toStdString()); + + // 插入识别的log日志 + QString logStr = QString("INSERT INTO RECOGNITION_LOGS (ID, LOG_INFO) VALUES (:id, :logInfo)"); + + QSqlQuery logQuery(ConnectionManager::getInstance()->getConnection()); + logQuery.prepare(logStr); + logQuery.bindValue(":id", id); + logQuery.bindValue(":logInfo", object.value("debug_info").toString()); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(); + logQuery.exec(); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool RecognitionRecordsDao::edit(QVariantMap newObject, QString id) +{ + return false; +} + +bool RecognitionRecordsDao::dele(QString id) +{ + return false; +} diff --git a/dao/RecognitionRecordsDao.h b/dao/RecognitionRecordsDao.h new file mode 100644 index 0000000..38de7c9 --- /dev/null +++ b/dao/RecognitionRecordsDao.h @@ -0,0 +1,23 @@ +#ifndef RECOGNITIONRECORDSDAO_H +#define RECOGNITIONRECORDSDAO_H + +#include +#include "BaseDao.h" +class RecognitionRecordsDao: public BaseDao +{ + Q_OBJECT +public: + explicit RecognitionRecordsDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +signals: + +}; + +#endif // RECOGNITIONRECORDSDAO_H diff --git a/dao/SysDeptDao.cpp b/dao/SysDeptDao.cpp new file mode 100644 index 0000000..22f9946 --- /dev/null +++ b/dao/SysDeptDao.cpp @@ -0,0 +1,88 @@ +#include "SysDeptDao.h" + +SysDeptDao::SysDeptDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector SysDeptDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_DEPT WHERE PID != '-1' ORDER BY PID, NUM"; + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + item.insert("id", query.value("id").toString()); + item.insert("pid", query.value("pid").toString()); + item.insert("pids", query.value("pids").toString()); + item.insert("simplename", query.value("simplename").toString()); + item.insert("fullname", query.value("fullname").toString()); + } + +// LOG_TRACE(QString("查询表[SYS_DEPT]的所有记录[%1][%2]").arg(result.size()).arg(sql).toStdString()); + + return result; +} + +QVariantMap SysDeptDao::findRecordById(QString id) +{ + QVariantMap item; + return item; + + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM SYS_DEPT WHERE SYS_DEPT.ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + // 获取结果集的大小 + query.last(); + int count = query.at() + 1; + + if (count >=1) + { + query.first(); + + result.insert("id", query.value("id").toString()); + result.insert("pid", query.value("pid").toString()); + result.insert("pids", query.value("pids").toString()); + result.insert("simplename", query.value("simplename").toString()); + result.insert("fullname", query.value("fullname").toString()); + } + +// LOG_TRACE(QString("根据id查询SYS_DEPT表的记录[ID=%1][%2]").arg(id).arg(sql).toStdString()); + + return result; +} + + +QString SysDeptDao::save(QVariantMap object) +{ + return "0"; +} +bool SysDeptDao::edit(QVariantMap newObject, QString id) +{ + return true; +} +bool SysDeptDao::dele(QString id) +{ + return true; +} diff --git a/dao/SysDeptDao.h b/dao/SysDeptDao.h new file mode 100644 index 0000000..e07a09f --- /dev/null +++ b/dao/SysDeptDao.h @@ -0,0 +1,24 @@ +#ifndef SYSDEPTDAO_H +#define SYSDEPTDAO_H + +#include +#include "BaseDao.h" + +class SysDeptDao : public BaseDao +{ + Q_OBJECT +public: + explicit SysDeptDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +private: + +}; + +#endif // SYSDEPTDAO_H diff --git a/dao/SysPersonDao.cpp b/dao/SysPersonDao.cpp new file mode 100644 index 0000000..dd9480f --- /dev/null +++ b/dao/SysPersonDao.cpp @@ -0,0 +1,371 @@ +#include "SysPersonDao.h" + + +SysPersonDao::SysPersonDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector SysPersonDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0'"; + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + count++; + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + result.append(item); + } + +// LOG(TRACE) << QString("查询SYS_PERSON表的所有记录[%1]").arg(count).toStdString(); +// LOG_TRACE(QString("查询SYS_PERSON表的所有记录[%1]").arg(count).toStdString()); + + return result; +} + +QVariantMap SysPersonDao::findRecordById(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0' AND SYS_PERSON.ID = '%1'").arg(id); + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVariantMap result; + + // 获取结果集的大小 + query.last(); + int count = query.at() + 1; + + if (count >=1) + { + query.first(); + + result.insert("id", query.value("id").toString()); + result.insert("delflag", query.value("delflag").toString()); + result.insert("createtime", query.value("createtime").toString()); + result.insert("updatetime", query.value("updatetime").toString()); + result.insert("name", query.value("name").toString()); + result.insert("gender", query.value("gender").toString()); + result.insert("deptid", query.value("deptid").toString()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("remarks", query.value("remarks").toString()); + result.insert("person_code", query.value("person_code").toString()); + result.insert("deptname", query.value("fullname").toString()); + result.insert("sync_id", query.value("sync_id").toString()); + result.insert("hasFace", query.value("face_valid").toString()); + result.insert("hasIris", query.value("iris_valid").toString()); + } + +// LOG(TRACE) << QString("根据id查询SYS_PERSON表的记录[id=%1][%2]").arg(id).arg(sql).toStdString(); +// LOG_TRACE(QString("根据id查询SYS_PERSON表的记录[id=%1][%2]").arg(id).arg(sql).toStdString()); + + return result; +} + +int SysPersonDao::findRecordCountByNameAndDept(QString name, QString dept) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT COUNT(P.ID) AS RECCT FROM SYS_PERSON P LEFT JOIN SYS_DEPT D ON P.DEPTID = D.ID WHERE P.DELFLAG = '0'"; + if (name.isEmpty() == false) + { + sql += " AND P.NAME LIKE '%" + name + "%'"; + } + if (dept.isEmpty() == false && dept.indexOf("-1") < 0) + { + sql += QString(" AND ((P.DEPTID = '%1') OR (D.PIDS LIKE '%,%1,%'))").arg(dept); + } + + // 执行查询 + query.exec(sql); + + // 返回结果 + int result; + + // 遍历查询结果 + if (query.next()) { + result = query.value("RECCT").toInt(); + } + +// LOG(TRACE) << QString("根据姓名和部门查询SYS_PERSON记录总数[%1][%2]").arg(result).arg(sql).toStdString(); +// LOG_TRACE(QString("根据姓名和部门查询SYS_PERSON记录总数[%1][%2]").arg(result).arg(sql).toStdString()); + + return result; +} + +QVector SysPersonDao::findRecordsByNameAndDept(QString name, QString dept, qint8 limit, qint16 offset) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON P LEFT JOIN SYS_DEPT D ON P.DEPTID = D.ID WHERE P.DELFLAG = '0'"; + if (name.isEmpty() == false) + { + sql += " AND P.NAME LIKE '%" + name + "%'"; + } + if (dept.isEmpty() == false && dept.indexOf("-1") < 0) + { + sql += QString(" AND ((P.DEPTID = '%1') OR (D.PIDS LIKE '%,%1,%'))").arg(dept); + } + + sql += QString(" LIMIT %1 OFFSET %2").arg(limit).arg(offset); + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + count++; + + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + + result.append(item); + } + +// LOG(TRACE) << QString("根据姓名和部门分页查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString(); +// LOG_TRACE(QString("根据姓名和部门分页查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString()); + + return result; +} + +QVector SysPersonDao::findRecordsByProperties(QVariantMap conditions) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0'"; + QVariantMap::iterator it; + for (it = conditions.begin(); it != conditions.end(); it++) + { + sql += QString(" AND SYS_PERSON.%1 = %2").arg(it.key()).arg(it.value().toString()); + } + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + count++; + + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + + result.append(item); + } + +// LOG(TRACE) << QString("根据属性值查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString(); +// LOG_TRACE(QString("根据属性值查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString()); + + return result; +} + +QString SysPersonDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + + // INSERT语句 + QString sql = QString("INSERT INTO SYS_PERSON " + "(ID, DELFLAG, CREATETIME, UPDATETIME, " + "NAME, GENDER, DEPTID, ID_CARD_NO, " + "REMARKS, PERSON_CODE, SYNC_ID, FACE_VALID, IRIS_VALID) " + "VALUES ('%1', '0', '%2', '%2', '%3', '%4', '%5', '%6', '%7', '%8', '%9', 0, 0)") + .arg(id).arg(tm) + .arg(object.value("name").toString()) + .arg(object.value("gender").toString()) + .arg(object.value("deptid").toString()) + .arg(object.value("id_card_no").toString()) + .arg(object.value("remarks").toString()) + .arg(object.value("person_code").toString()) + .arg(object.value("sync_id").toString()); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(sql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { +// LOG(DEBUG) << QString("保存SYS_PERSON记录成功[ID = %1][%2]").arg(id).arg(sql).toStdString(); +// LOG_DEBUG(QString("保存SYS_PERSON记录成功[ID = %1][%2]").arg(id).arg(sql).toStdString()); + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool SysPersonDao::edit(QVariantMap newObject, QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + + // UPDATE语句 + QString sql = QString("UPDATE SYS_PERSON SET UPDATETIME = '%1'").arg(tm); + if (newObject.contains("name")) + { + sql.append(QString(", NAME = '%1'").arg(newObject.value("name").toString())); + } + if (newObject.contains("gender")) + { + sql.append(QString(", GENDER = '%1'").arg(newObject.value("gender").toString())); + } + if (newObject.contains("deptid")) + { + sql.append(QString(", DEPTID = '%1'").arg(newObject.value("deptid").toString())); + } + if (newObject.contains("person_code")) + { + sql.append(QString(", PERSON_CODE = '%1'").arg(newObject.value("person_code").toString())); + } + if (newObject.contains("face_valid")) + { + sql.append(QString(", FACE_VALID = '%1'").arg(newObject.value("face_valid").toString())); + } + if (newObject.contains("iris_valid")) + { + sql.append(QString(", IRIS_VALID = '%1'").arg(newObject.value("iris_valid").toString())); + } + + sql.append(QString(" WHERE ID = '%1'").arg(id)); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(sql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + +// LOG(DEBUG) << QString("编辑人员[ID=%1][%2]").arg(id).arg(sql).toStdString(); +// LOG_DEBUG(QString("编辑人员[ID=%1][%2]").arg(id).arg(sql).toStdString()); + + // 返回结果 + return success; +} + +bool SysPersonDao::dele(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + QSqlQuery irisDel(ConnectionManager::getInstance()->getConnection()); + + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + qint64 tmms = QDateTime::currentDateTime().toMSecsSinceEpoch(); + + // UPDATE语句 + QString sql = QString("UPDATE SYS_PERSON SET UPDATETIME = :updateTime, DELFLAG = :flag WHERE ID = :id").arg(tm).arg(tmms).arg(id); + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":updateTime", tm); + query.bindValue(":flag", tmms); + + // 物理删除人员的人脸和虹膜数据 + QString delIrisSql = QString("DELETE FROM IRIS_DATA WHERE PERSON_ID = :personId"); + irisDel.prepare(delIrisSql); + irisDel.bindValue(":personId", id); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(sql); + query.exec(delIrisSql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + +// LOG_DEBUG(QString("删除人员SYS_PERSON[ID=%1][%2]").arg(id).arg(success).toStdString()); + + // 返回结果 + return success; +} diff --git a/dao/SysPersonDao.h b/dao/SysPersonDao.h new file mode 100644 index 0000000..e02e5ba --- /dev/null +++ b/dao/SysPersonDao.h @@ -0,0 +1,27 @@ +#ifndef SYSPERSONDAO_H +#define SYSPERSONDAO_H + +#include +#include "BaseDao.h" + +class SysPersonDao : public BaseDao +{ + Q_OBJECT +public: + explicit SysPersonDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + int findRecordCountByNameAndDept(QString name, QString dept); + QVector findRecordsByNameAndDept(QString name, QString dept, qint8 limit, qint16 offset); + QVector findRecordsByProperties(QVariantMap conditions); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); +signals: + +}; + +#endif // SYSPERSONDAO_H diff --git a/dao/dao.pri b/dao/dao.pri new file mode 100644 index 0000000..1e04ce4 --- /dev/null +++ b/dao/dao.pri @@ -0,0 +1,18 @@ + +HEADERS += $$PWD/BaseDao.h +HEADERS += $$PWD/IrisDataDao.h +HEADERS += $$PWD/RecognitionRecordsDao.h +HEADERS += $$PWD/SysPersonDao.h +HEADERS += $$PWD/SysDeptDao.h + +SOURCES += $$PWD/BaseDao.cpp +SOURCES += $$PWD/IrisDataDao.cpp +SOURCES += $$PWD/RecognitionRecordsDao.cpp +SOURCES += $$PWD/SysPersonDao.cpp +SOURCES += $$PWD/SysDeptDao.cpp + +HEADERS += $$PWD/util/ConnectionManager.h +SOURCES += $$PWD/util/ConnectionManager.cpp +#HEADERS += $$PWD/util/CacheManager.h +#SOURCES += $$PWD/util/CacheManager.cpp + diff --git a/dao/util/ConnectionManager.cpp b/dao/util/ConnectionManager.cpp new file mode 100644 index 0000000..84b17be --- /dev/null +++ b/dao/util/ConnectionManager.cpp @@ -0,0 +1,47 @@ +#include "ConnectionManager.h" +#include + +Q_GLOBAL_STATIC(ConnectionManager, cm) + +ConnectionManager::ConnectionManager(QObject *parent) : QObject(parent) +{ + // 初始化数据库连接 + if (QSqlDatabase::contains("qt_sql_dafault_connection")) + { + conn = QSqlDatabase::database("qt_sql_default_connection"); + } + else + { + conn = QSqlDatabase::addDatabase("QSQLITE"); + conn.setDatabaseName(QApplication::applicationDirPath() + "/data/casic.db"); + + bool succ = conn.open(); + if (succ == true) + { +// LOG_INFO(QString("打开数据库操作正常[Open Database Success]").toStdString()); + } else + { +// LOG_ERROR(QString("打开数据库操作失败[Open Database Failed]").toStdString()); + } + } +} + +ConnectionManager::~ConnectionManager() +{ + conn.close(); +} + +ConnectionManager* ConnectionManager::getInstance() +{ + return cm; +} + +QSqlDatabase ConnectionManager::getConnection() +{ + return this->conn; +} + +qint64 ConnectionManager::generateId() +{ + return this->idWorker.nextId(); +} diff --git a/dao/util/ConnectionManager.h b/dao/util/ConnectionManager.h new file mode 100644 index 0000000..84647e3 --- /dev/null +++ b/dao/util/ConnectionManager.h @@ -0,0 +1,34 @@ +#ifndef CONNECTIONMANAGER_H +#define CONNECTIONMANAGER_H + +#include +#include +#include "utils/id/IdWorker.h" +#include "utils/UtilInclude.h" + +using namespace Jiawa::Core; + +class ConnectionManager : public QObject +{ + Q_OBJECT +public: + explicit ConnectionManager(QObject *parent = nullptr); + ~ConnectionManager(); + + static ConnectionManager * getInstance(); + + QSqlDatabase getConnection(); + qint64 generateId(); + +private: + // 数据库连接 + QSqlDatabase conn; + + // 雪花id生成工具 + IdWorker &idWorker = Singleton::instance(); + +signals: + +}; + +#endif // CONNECTIONMANAGER_H diff --git a/device/IrisCameraCapEventHandler.cpp b/device/IrisCameraCapEventHandler.cpp new file mode 100644 index 0000000..45df089 --- /dev/null +++ b/device/IrisCameraCapEventHandler.cpp @@ -0,0 +1,103 @@ +#include "IrisCameraCapEventHandler.h" + +IrisCameraCapEventHandler::IrisCameraCapEventHandler(QObject *parent) : QObject(parent) +{ + +} + +void IrisCameraCapEventHandler::DoOnImageCaptured(CImageDataPointer &objImageDataPointer, void *pUserParam) +{ + if (objImageDataPointer.IsNull() == false) + { + CGXDevicePointer* cam = (CGXDevicePointer *) pUserParam; + + auto camName = cam->getPtr()->GetDeviceInfo().GetUserID(); + int width = objImageDataPointer->GetWidth(); + int height = objImageDataPointer->GetHeight(); + size_t leftKeyIndex = camName.find("left"); + size_t rightKeyIndex = camName.find("right"); + + uchar * pBuffer = (BYTE*)objImageDataPointer->GetBuffer(); + + // 相机拍摄下的图像1440*1080, 直接用于算法判断 + QImage img = QImage(pBuffer, width, height, QImage::Format_Grayscale8); // 用于展示 +// QImage imgAlgo = img.copy(0, 0, width, height); + + // 用于显示的图像需要缩小到400 * 300的尺寸 + img = img.scaled(SettingConfig::getInstance().IRIS_DISPLAY_HEIGHT, SettingConfig::getInstance().IRIS_DISPLAY_WIDTH); + img = img.transformed(QTransform().rotate(-90)); // 图像逆时针旋转90度 + + // 发送到界面进行显示 + emit sendIrisFrameToDraw(img); +// cv::Mat irisMat = ImageUtil::QImageToMat(imgAlgo); + +// irisInfo.data = imgAlgo; +// irisInfo.matData = irisMat; + +// // 将图像显示在注册页面的label上 +// // 并将虹膜信息对象存入队列中 +// ProMemory::getInstance().pushCasicIris(irisInfo); + +// if (leftKeyIndex >= 0 && leftKeyIndex < 32) +// { +// emit sendIrisFrameToDraw(img, 0); // 左眼画面 +// } else if (rightKeyIndex >= 0 && rightKeyIndex < 32) +// { +// emit sendIrisFrameToDraw(img, 1); // 右眼画面 +// } +/* + if (pBuffer != NULL) + { + // 创建虹膜信息对象 + CasicIrisInfo irisInfo; + irisInfo.hasEye = false; + if (leftKeyIndex >= 0 && leftKeyIndex < 32) + { + // 左眼相机拍摄的图像 + irisInfo.leftOrRight = "left"; + } else if (rightKeyIndex >= 0 && rightKeyIndex < 32) + { + // 右眼相机 + irisInfo.leftOrRight = "right"; + } + + if (ProMemory::getInstance().widgeFrame == CasicBioRecConst::RECOGNIZE_RESULT_FORM) + { + // 相机拍摄下的图像1280*960, 直接用于算法判断 + QImage imgDisp = QImage(pBuffer, width, height, QImage::Format_Grayscale8); + cv::Mat irisMat = ImageUtil::QImageToMat(imgDisp); + + irisInfo.data = imgDisp; + irisInfo.matData = irisMat; + + ProMemory::getInstance().pushCasicIris(irisInfo); + +// cv::imwrite(QString("D:\\irisLogs\\iristest-%1.bmp").arg(irisInfo.leftOrRight).toStdString(), irisMat); + } else if (ProMemory::getInstance().widgeFrame == CasicBioRecConst::ADD_PERSON_CAPTURE_IRIS) + { + // 相机拍摄下的图像1280*960, 直接用于算法判断 + QImage img = QImage(pBuffer, width, height, QImage::Format_Grayscale8); + QImage imgAlgo = img.copy(0, 0, width, height); + + // 用于显示的图像需要缩小到1/4的尺寸 + img = img.scaled(640, 480); + cv::Mat irisMat = ImageUtil::QImageToMat(imgAlgo); + + irisInfo.data = imgAlgo; + irisInfo.matData = irisMat; + + // 将图像显示在注册页面的label上 + // 并将虹膜信息对象存入队列中 + ProMemory::getInstance().pushCasicIris(irisInfo); + + if (leftKeyIndex >= 0 && leftKeyIndex < 32) + { + emit sendIrisFrameToDraw(img, 0); // 左眼画面 + } else if (rightKeyIndex >= 0 && rightKeyIndex < 32) + { + emit sendIrisFrameToDraw(img, 1); // 右眼画面 + } + } + }*/ + } +} diff --git a/device/IrisCameraCapEventHandler.h b/device/IrisCameraCapEventHandler.h new file mode 100644 index 0000000..ad75a97 --- /dev/null +++ b/device/IrisCameraCapEventHandler.h @@ -0,0 +1,30 @@ +#ifndef IRISCAMERACAPEVENTHANDLER_H +#define IRISCAMERACAPEVENTHANDLER_H + +#include +#include +#include "include/opencv2/opencv.hpp" +#include "include/daheng/GalaxyIncludes.h" + +//#include "casic/iris/CasicIrisInterface.h" +#include "ProMemory.h" + +#include "utils/UtilInclude.h" + +class IrisCameraCapEventHandler : public QObject, public ICaptureEventHandler +{ + Q_OBJECT +public: + explicit IrisCameraCapEventHandler(QObject *parent = nullptr); + + void DoOnImageCaptured(CImageDataPointer &objImageDataPointer, void *pUserParam); + +private: + unsigned char* pImageBuffer; + +signals: + void sendIrisFrameToDraw(QImage irisImage); + +}; + +#endif // IRISCAMERACAPEVENTHANDLER_H diff --git a/device/IrisCameraController.cpp b/device/IrisCameraController.cpp new file mode 100644 index 0000000..0928176 --- /dev/null +++ b/device/IrisCameraController.cpp @@ -0,0 +1,110 @@ +#include "IrisCameraController.h" + +IrisCameraController::IrisCameraController(QObject *parent) : QObject(parent) +{ + this->irisCamHandler = new IrisCameraCapEventHandler(this); +} +IrisCameraController::~IrisCameraController() +{ + this->closeIrisCamera(); +} + + +void IrisCameraController::initIrisCamera() +{ + IGXFactory::GetInstance().Init(); + + //枚举设备 + IGXFactory::GetInstance().UpdateDeviceList(1000, irisCamList); + + this->OpenDevice(); +} + +void IrisCameraController::openIrisCamera() +{ + //设置Buffer处理模式 + irisStreamFeaturePtr->GetEnumFeature("StreamBufferHandlingMode")->SetValue("OldestFirst"); + + //注册回调函数 + irisStreamPtr->RegisterCaptureCallback(irisCamHandler, &irisCamPtr); + + //开启流层通道 + irisStreamPtr->StartGrab(); + + //发送开采命令 + irisFeaturePtr->GetCommandFeature("AcquisitionStart")->Execute(); + + // 启动定时器 + TimeCounterUtil::getInstance().irisCapCounter->start(SettingConfig::getInstance().IRIS_FRAME_INTERVAL); // 50ms执行一次定时器 +} + +void IrisCameraController::closeIrisCamera() +{ + +} + +void IrisCameraController::startCapture() +{ + // 获取定时器, 绑定定时函数 + connect(TimeCounterUtil::getInstance().irisCapCounter, &QTimer::timeout, this, &IrisCameraController::getOneFaceFrm); +// LOG(DEBUG) << QString("[IrisCameraController][startCapture]虹膜相机拍图").toStdString(); +// LOG_DEBUG(QString("[IrisCameraController][startCapture]虹膜相机拍图").toStdString()); + +} +void IrisCameraController::stopCapture() +{ + // 获取定时器, 绑定定时函数 + disconnect(TimeCounterUtil::getInstance().irisCapCounter, &QTimer::timeout, this, &IrisCameraController::getOneFaceFrm); +// LOG(DEBUG) << QString("[IrisCameraController][stopCapture]虹膜相机停止拍图").toStdString(); +// LOG_DEBUG(QString("[IrisCameraController][stopCapture]虹膜相机停止拍图").toStdString()); + +} + +void IrisCameraController::getOneFaceFrm() +{ + // 发送软触发命令(在触发模式开启时有效) + irisFeaturePtr->GetCommandFeature("TriggerSoftware")->Execute(); +} + +void IrisCameraController::getLeftAndRightEyeFrame() +{ + irisFeaturePtr->GetCommandFeature("TriggerSoftware")->Execute(); +} + +void IrisCameraController::OpenDevice() +{ + auto device = irisCamList.at(0); + + irisCamPtr = IGXFactory::GetInstance().OpenDeviceByUserID(device.GetUserID(), GX_ACCESS_EXCLUSIVE); + irisFeaturePtr = irisCamPtr->GetRemoteFeatureControl(); + + // 判断设备流是否大于零, 如果大于零则打开流 + int nStreamCount = irisCamPtr->GetStreamCount(); + if (nStreamCount > 0) + { + irisStreamPtr = irisCamPtr->OpenStream(0); + irisStreamFeaturePtr = irisStreamPtr->GetFeatureControl(); + } + + // 建议用户在打开网络相机之后, 根据当前网络环境设置相机的流通道包长值, + // 以提高网络相机的采集性能, 设置方法参考以下代码。 + GX_DEVICE_CLASS_LIST objDeviceClass = irisCamPtr->GetDeviceInfo().GetDeviceClass(); + if(GX_DEVICE_CLASS_GEV == objDeviceClass) + { + // 判断设备是否支持流通道数据包功能 + if(true == irisFeaturePtr->IsImplemented("GevSCPSPacketSize")) + { + // 获取当前网络环境的最优包长值 + int nPacketSize = irisStreamPtr->GetOptimalPacketSize(); + // 将最优包长值设置为当前设备的流通道包长值 + irisFeaturePtr->GetIntFeature("GevSCPSPacketSize")->SetValue(nPacketSize); + } + } + + //设置采集模式为连续采集模式 + irisFeaturePtr->GetEnumFeature("AcquisitionMode")->SetValue("Continuous"); + + //设置触发模式关 + irisFeaturePtr->GetEnumFeature("TriggerMode")->SetValue("On"); + irisFeaturePtr->GetEnumFeature("TriggerSource")->SetValue("Software"); +} diff --git a/device/IrisCameraController.h b/device/IrisCameraController.h new file mode 100644 index 0000000..5d7e269 --- /dev/null +++ b/device/IrisCameraController.h @@ -0,0 +1,49 @@ +#ifndef IRISCAMERACONTROLLER_H +#define IRISCAMERACONTROLLER_H + +#include + +#include "IrisCameraCapEventHandler.h" + +class IrisCameraCapEventHandler; + +class IrisCameraController : public QObject +{ + Q_OBJECT +public: + explicit IrisCameraController(QObject *parent = nullptr); + ~IrisCameraController(); + + // 初始化并打开人脸相机 + void initIrisCamera(); + void openIrisCamera(); + void closeIrisCamera(); + + void startCapture(); + void stopCapture(); + + void getLeftAndRightEyeFrame(); + + IrisCameraCapEventHandler * irisCamHandler; + +private: + GxIAPICPP::gxdeviceinfo_vector irisCamList; + + CGXDevicePointer irisCamPtr; ///< 设备句柄 + + CGXStreamPointer irisStreamPtr; ///< 左眼设备流 + + CGXFeatureControlPointer irisFeaturePtr; ///< 左眼属性控制器 + + CGXFeatureControlPointer irisStreamFeaturePtr; ///< 左眼流层控制器对象 + + void OpenDevice(); + +signals: + +public slots: + void getOneFaceFrm(); + +}; + +#endif // IRISCAMERACONTROLLER_H diff --git a/device/device.pri b/device/device.pri new file mode 100644 index 0000000..a8417f2 --- /dev/null +++ b/device/device.pri @@ -0,0 +1,13 @@ + +HEADERS += $$PWD/IrisCameraController.h +HEADERS += $$PWD/IrisCameraCapEventHandler.h +#HEADERS += $$PWD/iris/IrisRegistProcess.h +#HEADERS += $$PWD/iris/IrisRecogProcess.h +#HEADERS += $$PWD/iris/CasicIrisRecState.h + +SOURCES += $$PWD/IrisCameraController.cpp +SOURCES += $$PWD/IrisCameraCapEventHandler.cpp +#SOURCES += $$PWD/iris/IrisRegistProcess.cpp +#SOURCES += $$PWD/iris/IrisRecogProcess.cpp +#SOURCES += $$PWD/iris/CasicIrisRecState.cpp + diff --git a/images/bg_footer.png b/images/bg_footer.png new file mode 100644 index 0000000..a3a99ab --- /dev/null +++ b/images/bg_footer.png Binary files differ diff --git a/images/bg_statcked.png b/images/bg_statcked.png new file mode 100644 index 0000000..18b63e1 --- /dev/null +++ b/images/bg_statcked.png Binary files differ diff --git a/images/bg_title.png b/images/bg_title.png new file mode 100644 index 0000000..0316e2d --- /dev/null +++ b/images/bg_title.png Binary files differ diff --git a/main.cpp b/main.cpp index 16bc45b..9052ddb 100644 --- a/main.cpp +++ b/main.cpp @@ -1,11 +1,11 @@ -#include "IdentifyForm.h" +#include "MainWindowForm.h" #include int main(int argc, char *argv[]) { QApplication a(argc, argv); - IdentifyForm w; + MainWindowForm w; w.show(); return a.exec(); } diff --git a/resource.qrc b/resource.qrc new file mode 100644 index 0000000..474586a --- /dev/null +++ b/resource.qrc @@ -0,0 +1,35 @@ + + + images/setting.png + images/user.png + images/back.png + images/home.png + images/btnPageFirst.png + images/btnPageLast.png + images/btnPageNext.png + images/btnPagePre.png + images/regist.png + images/photoEyeLeft.png + images/photoEyeRight.png + images/photoFace.png + images/save.png + images/upArrow.png + images/downArrow.png + images/faceCaped.png + images/faceNotCap.png + images/irisCaped.png + images/irisNotCap.png + images/tipsFailure.png + images/tipsSuccess.png + images/tipsConfirm.png + images/bg_recognize_result.png + images/iconRetry.png + images/bg_title.png + images/bg_footer.png + images/bg_statcked.png + + + images/add_bottom.png + images/add_top.png + + diff --git a/utils/ImageUtil.cpp b/utils/ImageUtil.cpp new file mode 100644 index 0000000..7604572 --- /dev/null +++ b/utils/ImageUtil.cpp @@ -0,0 +1,97 @@ +#include "ImageUtil.h" + +ImageUtil::ImageUtil() +{ + +} + +QImage ImageUtil::MatImageToQImage(const cv::Mat &src) +{ + //CV_8UC1 8位无符号的单通道---灰度图片 + if(src.type() == CV_8UC1) + { + QImage qImage((const unsigned char *)(src.data), src.cols, src.rows, src.cols, QImage::Format_Grayscale8); + return qImage; + } + //为3通道的彩色图片 + else if(src.type() == CV_8UC3) + { + //得到图像的的首地址 + const uchar *pSrc = (const uchar*)src.data; + //以src构造图片 + QImage qImage(pSrc, src.cols, src.rows, src.step, QImage::Format_RGB888); + //在不改变实际图像数据的条件下, 交换红蓝通道 + return qImage.rgbSwapped(); + } + //四通道图片, 带Alpha通道的RGB彩色图像 + else if(src.type() == CV_8UC4) + { + const uchar *pSrc = (const uchar*)src.data; + QImage qImage(pSrc, src.cols, src.rows, src.step, QImage::Format_ARGB32); + //返回图像的子区域作为一个新图像 + return qImage.copy(); + } + else + { + return QImage(); + } +} +/* +QImage ImageUtil::UcharToQImage(unsigned char* data, int width, int height, QImage::Format format) +{ + QImage qImage(data, width, height, format); + //在不改变实际图像数据的条件下, 交换红蓝通道 + return qImage.rgbSwapped(); +} + +cv::Mat ImageUtil::QImageToMat(QImage image) +{ + cv::Mat mat; + switch(image.format()) + { + case QImage::Format_ARGB32: + case QImage::Format_RGB32: + case QImage::Format_ARGB32_Premultiplied: + mat = cv::Mat(image.height(), image.width(), CV_8UC4, (void*)image.constBits(), image.bytesPerLine()); + break; + case QImage::Format_RGB888: + mat = cv::Mat(image.height(), image.width(), CV_8UC3, (void*)image.constBits(), image.bytesPerLine()); + cv::cvtColor(mat, mat, cv::COLOR_BGR2RGB); + break; + case QImage::Format_Indexed8: + mat = cv::Mat(image.height(), image.width(), CV_8UC1, (void*)image.constBits(), image.bytesPerLine()); + break; + case QImage::Format_Grayscale8: + mat = cv::Mat(image.height(), image.width(), CV_8UC1, (void *)image.bits(), image.bytesPerLine()); + break; + } + + mat = mat.clone(); + + return mat; +} + +QString ImageUtil::QImageToBase64(QImage image) +{ + QByteArray ba; + QBuffer buf(&ba); + image.save(&buf, "bmp"); + QString base64String = ba.toBase64(); + return base64String; +} + +cv::Mat ImageUtil::MatImageRect(const cv::Mat &src, cv::Rect rect, int delta) +{ + cv::Mat matClone = src.clone(); + cv::Rect bigRect; + + bigRect.x = rect.x - delta < 0 ? 0 : rect.x - delta; + bigRect.y = rect.y - delta < 0 ? 0 : rect.y - delta; + bigRect.width = rect.x + rect.width + 2 * delta > src.cols ? src.cols - rect.x : rect.width + 2 * delta; + bigRect.height = rect.y + rect.height + 2 * delta > src.rows ? src.rows - rect.y : rect.height + 2 * delta; + + cv::Mat roi = matClone(bigRect); + + return roi; +} +*/ diff --git a/utils/ImageUtil.h b/utils/ImageUtil.h new file mode 100644 index 0000000..dbfdd48 --- /dev/null +++ b/utils/ImageUtil.h @@ -0,0 +1,22 @@ +#ifndef IMAGEUTIL_H +#define IMAGEUTIL_H + +#include +#include +#include "opencv2/opencv.hpp" + +class ImageUtil +{ +public: + ImageUtil(); + + static QImage MatImageToQImage(const cv::Mat &src); +// static QImage UcharToQImage(unsigned char* data, int width, int height, QImage::Format format); + +// static cv::Mat QImageToMat(QImage image); +// static QString QImageToBase64(QImage image); + +// static cv::Mat MatImageRect(const cv::Mat &src, cv::Rect rect, int delta); +}; + +#endif // IMAGEUTIL_H diff --git a/utils/SettingConfig.cpp b/utils/SettingConfig.cpp new file mode 100644 index 0000000..d420285 --- /dev/null +++ b/utils/SettingConfig.cpp @@ -0,0 +1,44 @@ +#include "SettingConfig.h" +#include + +SettingConfig::SettingConfig() +{ + filename = QApplication::applicationDirPath() + "/conf/config.ini"; + setting = new QSettings(this->filename, QSettings::IniFormat); + + WINDOW_WIDTH = getProperty("window", "width").toInt(); + WINDOW_HEIGHT = getProperty("window", "height").toInt(); + WINDOW_BACKGROUND_COLOR = getProperty("window", "backgroundColor").toString(); + WINDOW_TITLE = getProperty("window", "title").toString(); + WINDOW_RIGHTS = getProperty("window", "copyright").toString(); + WINDOW_VERSION = getProperty("window", "version").toString(); + + IRIS_FRAME_WIDTH = getProperty("camera", "irisFrameWidth").toInt(); + IRIS_FRAME_HEIGHT = getProperty("camera", "irisFrameHeight").toInt(); + IRIS_WIDTH = getProperty("camera", "irisWidth").toInt(); + IRIS_HEIGHT = getProperty("camera", "irisHeight").toInt(); + IRIS_FRAME_INTERVAL = getProperty("camera", "irisFrameInterval").toInt(); + IRIS_DISPLAY_WIDTH = getProperty("camera", "irisDisplayWidth").toInt(); + IRIS_DISPLAY_HEIGHT = getProperty("camera", "irisDisplayHeight").toInt(); + + MAX_MATCH_TIME = getProperty("recognize", "maxMatchTime").toInt(); + SUCCESS_TIPS_LAST = getProperty("recognize", "successTipsLast").toInt(); + FAILURE_TIPS_LAST = getProperty("recognize", "failureTipsLast").toInt(); + MAX_FACE_TRY_COUNT = getProperty("recognize", "maxFaceTryCount").toInt(); + MAX_FACE_NOT_FOUND_COUNT = getProperty("recognize", "maxFaceNotFoundCount").toInt(); + MAX_IRIS_TRY_COUNT = getProperty("recognize", "maxIrisTryCount").toInt(); + MAX_EYE_NOT_FOUND_COUNT = getProperty("recognize", "maxEyeNotFoundCount").toInt(); + + MAX_CAPTURE_STACK_SIZE = getProperty("stack", "capture").toInt(); + MAX_FOUND_STACK_SIZE = getProperty("stack", "found").toInt(); + MAX_QUALIFIED_STACK_SIZE = getProperty("stack", "qualified").toInt(); + + LOG_FILE = getProperty("log", "logFile").toString(); + LOG_LEVEL = getProperty("log", "logLevel").toString(); +} + + +QVariant SettingConfig::getProperty(QString nodeName, QString keyName) { + QVariant var = this->setting->value(QString("/%1/%2").arg(nodeName).arg(keyName)); + return var; +} diff --git a/utils/SettingConfig.h b/utils/SettingConfig.h new file mode 100644 index 0000000..30c3bec --- /dev/null +++ b/utils/SettingConfig.h @@ -0,0 +1,66 @@ +#ifndef SETTINGCONFIG_H +#define SETTINGCONFIG_H + +#include +#include + +class SettingConfig : public QObject +{ +public: + ~SettingConfig() {}; + SettingConfig(const SettingConfig&)=delete; + SettingConfig& operator=(const SettingConfig&)=delete; + + static SettingConfig& getInstance() { + static SettingConfig instance; + return instance; + } + + /** + * @brief get + * @param nodeName + * @param keyName + * @return QVariant + * @title + */ + QVariant getProperty(QString nodeName, QString keyName); + + /******** 以下为需要的各类参数 ********/ + int WINDOW_WIDTH; + int WINDOW_HEIGHT; + QString WINDOW_BACKGROUND_COLOR; + QString WINDOW_TITLE; + QString WINDOW_RIGHTS; + QString WINDOW_VERSION; + + int IRIS_FRAME_INTERVAL; + int IRIS_FRAME_WIDTH; + int IRIS_FRAME_HEIGHT; + int IRIS_WIDTH; + int IRIS_HEIGHT; + int IRIS_DISPLAY_WIDTH; + int IRIS_DISPLAY_HEIGHT; + + int MAX_MATCH_TIME; + int SUCCESS_TIPS_LAST; + int FAILURE_TIPS_LAST; + int MAX_FACE_TRY_COUNT; + int MAX_FACE_NOT_FOUND_COUNT; + int MAX_IRIS_TRY_COUNT; + int MAX_EYE_NOT_FOUND_COUNT; + + int MAX_CAPTURE_STACK_SIZE; + int MAX_FOUND_STACK_SIZE; + int MAX_QUALIFIED_STACK_SIZE; + + QString LOG_FILE; + QString LOG_LEVEL; + +private: + SettingConfig(); + + QString filename; + QSettings* setting; +}; + +#endif // SETTINGCONFIG_H diff --git a/utils/TimeCounterUtil.cpp b/utils/TimeCounterUtil.cpp new file mode 100644 index 0000000..275945f --- /dev/null +++ b/utils/TimeCounterUtil.cpp @@ -0,0 +1,8 @@ +#include "TimeCounterUtil.h" + +TimeCounterUtil::TimeCounterUtil() +{ + faceCapCounter = new QTimer(); + irisCapCounter = new QTimer(); + clockCounter = new QTimer(); +} diff --git a/utils/TimeCounterUtil.h b/utils/TimeCounterUtil.h new file mode 100644 index 0000000..28b29f1 --- /dev/null +++ b/utils/TimeCounterUtil.h @@ -0,0 +1,29 @@ +#ifndef TIMECOUNTERUTIL_H +#define TIMECOUNTERUTIL_H + +#include +#include + +class TimeCounterUtil : public QObject +{ +public: + + ~TimeCounterUtil() {}; + TimeCounterUtil(const TimeCounterUtil&)=delete; + TimeCounterUtil& operator=(const TimeCounterUtil&)=delete; + + static TimeCounterUtil& getInstance() { + static TimeCounterUtil instance; + return instance; + } + + QTimer * faceCapCounter; + QTimer * irisCapCounter; + QTimer * clockCounter; + +private: + TimeCounterUtil(); + +}; + +#endif // TIMECOUNTERUTIL_H diff --git a/AppConstants.h b/AppConstants.h new file mode 100644 index 0000000..296c53f --- /dev/null +++ b/AppConstants.h @@ -0,0 +1,28 @@ +#ifndef APPCONSTANTS_H +#define APPCONSTANTS_H + +class AppConstants +{ +public: + enum WidgeFrameName + { + MAIN_PAGE = 0, // 主页面 + PERSON_LIST_FORM = 1, // 人员列表页面 + ADD_PERSON_FORM = 2, // 添加人员页面 + ADD_PERSON_CAPTURE_FACE = 21, // 添加/编辑人员时进行人脸拍图 + ADD_PERSON_CAPTURE_IRIS = 22, // 添加/编辑人员时进行虹膜拍图 + SETTING_FORM = 3, // 设置页面 + RECOGNIZE_RESULT_FORM = 4, // 识别结果界面 + IDENTIFY_FORM = 5, // 识别界面 含识别中 和 识别结果 + LOCKSCREEN_FORM = 6 // 锁屏待机界面 + }; + + enum ApplicationState + { + STATE_WAIT = 0, // 待机 + STATE_WORKING = 1, // 工作状态 + STATE_IDENTIFYING = 2, // 识别中 + }; +}; + +#endif // APPCONSTANTS_H diff --git a/CasicIrisIdentify.pro b/CasicIrisIdentify.pro index 5d7fea6..575ce3d 100644 --- a/CasicIrisIdentify.pro +++ b/CasicIrisIdentify.pro @@ -1,4 +1,4 @@ -QT += core gui +QT += core gui sql network texttospeech greaterThan(QT_MAJOR_VERSION, 4): QT += widgets @@ -15,20 +15,46 @@ # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 -SOURCES += \ - main.cpp \ - IdentifyForm.cpp +include("dao/dao.pri") +include("device/device.pri") +include("utils/utils.pri") -HEADERS += \ - IdentifyForm.h +SOURCES += main.cpp +SOURCES += ProMemory.cpp +SOURCES += MainWindowForm.cpp +SOURCES += IdentifyForm.cpp +SOURCES += LockScreenForm.cpp -FORMS += \ - IdentifyForm.ui +HEADERS += AppConstants.h +HEADERS += ProMemory.h +HEADERS += MainWindowForm.h +HEADERS += IdentifyForm.h +HEADERS += LockScreenForm.h -TRANSLATIONS += \ - CasicIrisIdentify_zh_CN.ts +FORMS += MainWindowForm.ui +FORMS += IdentifyForm.ui +FORMS += LockScreenForm.ui + +RESOURCES += resource.qrc + +DISTFILES += conf/config.ini + +#TRANSLATIONS += CasicIrisIdentify_zh_CN.ts + +#INCLUDEPATH += include/spdlog +#DEPENDPATH += include/spdlog # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target + + +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lopencv_world420 +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lGxIAPICPPEx + +INCLUDEPATH += $$PWD/include/daheng +DEPENDPATH += $$PWD/include/daheng + +INCLUDEPATH += $$PWD/include +DEPENDPATH += $$PWD/include diff --git a/CasicIrisIdentify_zh_CN.ts b/CasicIrisIdentify_zh_CN.ts index 5526fe4..81900df 100644 --- a/CasicIrisIdentify_zh_CN.ts +++ b/CasicIrisIdentify_zh_CN.ts @@ -1,3 +1,12 @@ - + + + IdentifyForm + + + IdentifyForm + + + + diff --git a/IdentifyForm.cpp b/IdentifyForm.cpp index 348a897..ba1f251 100644 --- a/IdentifyForm.cpp +++ b/IdentifyForm.cpp @@ -1,4 +1,4 @@ -#include "IdentifyForm.h" +#include "IdentifyForm.h" #include "ui_IdentifyForm.h" IdentifyForm::IdentifyForm(QWidget *parent) @@ -6,6 +6,12 @@ , ui(new Ui::IdentifyForm) { ui->setupUi(this); + + // 初始化更新界面的定时器 + // 每秒执行一次 + connect(TimeCounterUtil::getInstance().clockCounter, &QTimer::timeout, this, &IdentifyForm::updateDateAndTime); + + TimeCounterUtil::getInstance().clockCounter->start(1000); } IdentifyForm::~IdentifyForm() @@ -13,3 +19,16 @@ delete ui; } +void IdentifyForm::drawIrisImageOnFrame(QImage image) +{ + // 只在识别界面才显示画面 + if (ui->wgtStacked->currentIndex() == 0) { + ui->labelVideo->setPixmap(QPixmap::fromImage(image)); + } +} + + +void IdentifyForm::updateDateAndTime() +{ + ui->labelTime->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd dddd HH:mm:ss")); +} diff --git a/IdentifyForm.h b/IdentifyForm.h index fc857a1..ae1cd22 100644 --- a/IdentifyForm.h +++ b/IdentifyForm.h @@ -1,7 +1,10 @@ -#ifndef IDENTIFYFORM_H +#ifndef IDENTIFYFORM_H #define IDENTIFYFORM_H #include +#include + +#include "utils/UtilInclude.h" QT_BEGIN_NAMESPACE namespace Ui { class IdentifyForm; } @@ -15,7 +18,14 @@ IdentifyForm(QWidget *parent = nullptr); ~IdentifyForm(); +public slots: + void drawIrisImageOnFrame(QImage image); + private: Ui::IdentifyForm *ui; + +private slots: + void updateDateAndTime(); + }; #endif // IDENTIFYFORM_H diff --git a/IdentifyForm.ui b/IdentifyForm.ui index c72a36f..879dc9a 100644 --- a/IdentifyForm.ui +++ b/IdentifyForm.ui @@ -6,13 +6,59 @@ 0 0 - 800 + 600 600 IdentifyForm + + + + 0 + 40 + 600 + 450 + + + + 0 + + + + + + 100 + 10 + 400 + 300 + + + + + + + + + + + + + + 0 + 0 + 600 + 40 + + + + TextLabel + + + Qt::AlignCenter + + diff --git a/LockScreenForm.cpp b/LockScreenForm.cpp new file mode 100644 index 0000000..58dc54b --- /dev/null +++ b/LockScreenForm.cpp @@ -0,0 +1,14 @@ +#include "LockScreenForm.h" +#include "ui_LockScreenForm.h" + +LockScreenForm::LockScreenForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::LockScreenForm) +{ + ui->setupUi(this); +} + +LockScreenForm::~LockScreenForm() +{ + delete ui; +} diff --git a/LockScreenForm.h b/LockScreenForm.h new file mode 100644 index 0000000..b5ded48 --- /dev/null +++ b/LockScreenForm.h @@ -0,0 +1,25 @@ +#ifndef LOCKSCREENFORM_H +#define LOCKSCREENFORM_H + +#include +#include + +#include "utils/UtilInclude.h" + +namespace Ui { +class LockScreenForm; +} + +class LockScreenForm : public QWidget +{ + Q_OBJECT + +public: + explicit LockScreenForm(QWidget *parent = nullptr); + ~LockScreenForm(); + +private: + Ui::LockScreenForm *ui; +}; + +#endif // LOCKSCREENFORM_H diff --git a/LockScreenForm.ui b/LockScreenForm.ui new file mode 100644 index 0000000..7f2a6db --- /dev/null +++ b/LockScreenForm.ui @@ -0,0 +1,45 @@ + + + LockScreenForm + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + 180 + 100 + 54 + 12 + + + + TextLabel + + + + + + 180 + 160 + 54 + 12 + + + + TextLabel + + + + + + diff --git a/MainWindowForm.cpp b/MainWindowForm.cpp new file mode 100644 index 0000000..84f8159 --- /dev/null +++ b/MainWindowForm.cpp @@ -0,0 +1,86 @@ +#include "MainWindowForm.h" +#include "ui_MainWindowForm.h" +#include + +MainWindowForm::MainWindowForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::MainWindowForm) +{ + ui->setupUi(this); + + // 设置窗口透明和大小、位置 + this->setWindowFlags(Qt::FramelessWindowHint); + this->move(1400, 15); + this->resize(SettingConfig::getInstance().WINDOW_WIDTH, SettingConfig::getInstance().WINDOW_HEIGHT); + + // 通过调色板的颜色来设置窗口的统一背景色 + qApp->setPalette(QPalette(QColor(SettingConfig::getInstance().WINDOW_BACKGROUND_COLOR))); + + // 加载css文件设置控件样式 + QFile file(QApplication::applicationDirPath() + "/qss/main.css"); + if (file.open(QFile::ReadOnly)) + { + QString qssStr = QLatin1String(file.readAll()); + this->setStyleSheet(qssStr); + file.close(); + } + + initFormsPtr(); + + // 设置标题文字 + ui->labelTitle->setText(SettingConfig::getInstance().WINDOW_TITLE); + ui->labelCopyright->setText(SettingConfig::getInstance().WINDOW_RIGHTS); + ui->labelVersion->setText(SettingConfig::getInstance().WINDOW_VERSION); + + // 初始化虹膜相机控制 + ProMemory::getInstance().irisCam = new IrisCameraController(this); + ProMemory::getInstance().irisCam->initIrisCamera(); + ProMemory::getInstance().irisCam->openIrisCamera(); + connect(ProMemory::getInstance().irisCam->irisCamHandler, &IrisCameraCapEventHandler::sendIrisFrameToDraw, identifyForm, &IdentifyForm::drawIrisImageOnFrame); + +// LOG_INFO(QString("应用程序启动成功[Application Startup Success]").toStdString()); + qDebug() << "应用程序启动成功[Application Startup Success]"; + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::IDENTIFY_FORM; + ui->wdgtStatced->setCurrentWidget(identifyForm); + + // 开始虹膜相机拍图 + ProMemory::getInstance().irisCam->startCapture(); +} + +MainWindowForm::~MainWindowForm() +{ + delete ui; +} + +void MainWindowForm::lockScreen() +{ + ui->wdgtStatced->setCurrentWidget(lockScreenForm); + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::LOCKSCREEN_FORM; + ProMemory::getInstance().appState = AppConstants::ApplicationState::STATE_WAIT; +} + +void MainWindowForm::keyPressEvent(QKeyEvent *event) +{ + switch (event->key()) { + case Qt::Key_Escape: + QTimer::singleShot(100, qApp, [=](){ + QApplication::quit(); + }); + + default: + QWidget::keyPressEvent(event); + } +} + +void MainWindowForm::initFormsPtr() +{ + // 初始化各个form + lockScreenForm = new LockScreenForm(this); + identifyForm = new IdentifyForm(this); + + // 将form添加到statcked widget中 + ui->wdgtStatced->addWidget(identifyForm); + ui->wdgtStatced->addWidget(lockScreenForm); + + // 绑定按钮函数 +} diff --git a/MainWindowForm.h b/MainWindowForm.h new file mode 100644 index 0000000..7fb2d89 --- /dev/null +++ b/MainWindowForm.h @@ -0,0 +1,38 @@ +#ifndef MAINWINDOWFORM_H +#define MAINWINDOWFORM_H + +#include +#include +#include + +#include "utils/UtilInclude.h" +#include "ProMemory.h" +#include "LockScreenForm.h" +#include "IdentifyForm.h" + +namespace Ui { +class MainWindowForm; +} + +class MainWindowForm : public QWidget +{ + Q_OBJECT + +public: + explicit MainWindowForm(QWidget *parent = nullptr); + ~MainWindowForm(); + +public slots: + void lockScreen(); + +private: + Ui::MainWindowForm *ui; + LockScreenForm * lockScreenForm; + IdentifyForm * identifyForm; + + void keyPressEvent(QKeyEvent *event); + + void initFormsPtr(); +}; + +#endif // MAINWINDOWFORM_H diff --git a/MainWindowForm.ui b/MainWindowForm.ui new file mode 100644 index 0000000..e793ebf --- /dev/null +++ b/MainWindowForm.ui @@ -0,0 +1,85 @@ + + + MainWindowForm + + + + 0 + 0 + 600 + 1024 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + 0 + 0 + 600 + 84 + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + + + + TextLabel + + + Qt::AlignBottom|Qt::AlignHCenter + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + diff --git a/ProMemory.cpp b/ProMemory.cpp new file mode 100644 index 0000000..19e7403 --- /dev/null +++ b/ProMemory.cpp @@ -0,0 +1,84 @@ +#include "ProMemory.h" + +ProMemory::ProMemory() +{ + +} + +ProMemory::~ProMemory() +{ + +} + +/* +void ProMemory::pushCasicIris(CasicIrisInfo irisInfo) +{ + QMutex mutex; + mutex.lock(); + if (this->irisQueue.size() > 30) + { + QStack empty; + std::swap(empty, irisQueue); + } + + irisQueue.push(irisInfo); + mutex.unlock(); +} +CasicIrisInfo ProMemory::popCasicIris() +{ + CasicIrisInfo result; + + QMutex mutex; + mutex.lock(); + if (this->irisQueue.size() > 0) + { + result = irisQueue.pop(); + } + + mutex.unlock(); + + return result; +} +*/ +int ProMemory::getIrisQueueSize() +{ + int size = 0; + + QMutex mutex; + mutex.lock(); + +// size = this->irisQueue.size(); + + mutex.unlock(); + + return size; +} +bool ProMemory::isIrisQueueEmpty() +{ + bool empty = true; + + QMutex mutex; + mutex.lock(); + +// empty = this->irisQueue.isEmpty(); + + mutex.unlock(); + + return empty; +} +void ProMemory::clearIrisQueue() +{ + QMutex mutex; + mutex.lock(); + +// QStack empty; +// std::swap(empty, irisQueue); + + mutex.unlock(); +} + + +void ProMemory::initIrisFeatures(QString personId) +{ +// irisRegistPro->sendDataToExract(QByteArray(QString("[-u]").append(personId).toLocal8Bit())); +} diff --git a/ProMemory.h b/ProMemory.h new file mode 100644 index 0000000..2ecd653 --- /dev/null +++ b/ProMemory.h @@ -0,0 +1,52 @@ +#ifndef PROMEMORY_H +#define PROMEMORY_H + +#include +#include + +#include "AppConstants.h" +//#include "casic/iris/CasicIrisInfo.h" +#include "dao/IrisDataDao.h" + +#include "device/IrisCameraController.h" +//#include "device/iris/IrisRegistProcess.h" +//#include "device/iris/IrisRecogProcess.h" + +class IrisCameraController; +class IrisRegistProcess; +class IrisRecogProcess; + +class ProMemory +{ +public: + ~ProMemory(); + ProMemory(const ProMemory&)=delete; + ProMemory& operator=(const ProMemory&)=delete; + + static ProMemory& getInstance() { + static ProMemory instance; + return instance; + } + +// void pushCasicIris(CasicIrisInfo irisInfo); +// CasicIrisInfo popCasicIris(); + int getIrisQueueSize(); + bool isIrisQueueEmpty(); + void clearIrisQueue(); + + volatile int widgeFrame = 0; // 当前显示的界面 + volatile int appState = 0; // 当前程序所处的状态 + + void initIrisFeatures(QString personId = ""); // 初始化虹膜特征值集合 + + IrisCameraController * irisCam; + IrisRecogProcess * irisRecogPro; + +private: + ProMemory(); + +// QStack irisQueue; // 虹膜信息队列 + QVector irisFeatures; // 虹膜特征值集合 +}; + +#endif // PROMEMORY_H diff --git a/conf/config.ini b/conf/config.ini new file mode 100644 index 0000000..66e46ad --- /dev/null +++ b/conf/config.ini @@ -0,0 +1,67 @@ +[recognize] +#最大允许识别时间(ms) +maxMatchTime=10000 +#识别成功界面停留时间(ms) +successTipsLast=5000 +#识别失败界面停留时间(ms) +failureTipsLast=3000 +#人脸识别最大尝试次数 +maxFaceTryCount=20 +#持续没找到人脸的最大次数 +maxFaceNotFoundCount=500 +#注册时最小人脸 +minFaceRegist=240 +#识别时最小人脸 +minFaceRecog=100 + +#虹膜识别最大尝试次数 +maxIrisTryCount=10 +#虹膜识别持续没有找到眼的最大次数 +maxEyeNotFoundCount=50 + +#识别方式[1=人脸;2=虹膜;3=双认证;4=任意] +recogType=4 + +[window] +#界面窗口宽(px) +width=600 +#界面窗口高(px) +height=1024 +#统一背景色 +backgroundColor="#FFFFFF" +#标题 +title="虹膜识别终端" + +[work] +#工作状态检测时最小人脸范围 +minFaceSize=160 +#人脸范围最小横坐标 +minFacePosX=320 +#人脸范围最大横坐标 +maxFacePosX=960 +#人脸范围最小纵坐标 +minFacePosY=180 +#人脸范围最大纵坐标 +maxFacePosY=540 +#人脸太近阈值 +faceCloseSize=360 +#人脸太远阈值 +faceFarSize=480 + +[camera] +#虹膜相机取一幅画面的时间间隔(ms) +irisFrameInterval=100 +#虹膜相机拍摄宽度 +irisFrameWidth=1440 +#虹膜相机拍摄高度 +irisFrameHeight=1080 +#虹膜图像高度 +irisWidth=640 +#虹膜图像高度 +irisHeight=480 + +[log] +#日志文件位置 +logFile="d://irisLogs//casic_log.txt" +#日志级别 +logLevel="trace" diff --git a/dao/BaseDao.cpp b/dao/BaseDao.cpp new file mode 100644 index 0000000..f51c144 --- /dev/null +++ b/dao/BaseDao.cpp @@ -0,0 +1,12 @@ +#include "BaseDao.h" +#include "dao/util/ConnectionManager.h" + +BaseDao::BaseDao(QObject *parent) : QObject(parent) +{ + +} + +BaseDao::~BaseDao() +{ + +} diff --git a/dao/BaseDao.h b/dao/BaseDao.h new file mode 100644 index 0000000..1693c88 --- /dev/null +++ b/dao/BaseDao.h @@ -0,0 +1,32 @@ +#ifndef BASEDAO_H +#define BASEDAO_H + +#include +#include +#include +#include + +#include "dao/util/ConnectionManager.h" +#include "utils/UtilInclude.h" + +class BaseDao : public QObject +{ + Q_OBJECT +public: + explicit BaseDao(QObject *parent = nullptr); + ~BaseDao(); + + virtual QVector findAllRecord() = 0; + virtual QVariantMap findRecordById(QString id) = 0; + + virtual QString save(QVariantMap object) = 0; + virtual bool edit(QVariantMap newObject, QString id) = 0; + virtual bool dele(QString id) = 0; + +private: + +signals: + +}; + +#endif // BASEDAO_H diff --git a/dao/IrisDataDao.cpp b/dao/IrisDataDao.cpp new file mode 100644 index 0000000..37a0ed6 --- /dev/null +++ b/dao/IrisDataDao.cpp @@ -0,0 +1,204 @@ +#include "IrisDataDao.h" + +IrisDataDao::IrisDataDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector IrisDataDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM IRIS_DATA"; + query.prepare(sql); + + // 执行查询 + query.exec(); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + item.insert("id", query.value("id").toString()); + item.insert("person_id", query.value("person_id").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("left_iris_code1", query.value("left_iris_code1")); + item.insert("left_iris_code2", query.value("left_iris_code2")); + item.insert("left_iris_code3", query.value("left_iris_code3")); + item.insert("right_iris_code1", query.value("right_iris_code1")); + item.insert("right_iris_code2", query.value("right_iris_code2")); + item.insert("right_iris_code3", query.value("right_iris_code3")); + + result.append(item); + } + +// LOG_DEBUG(QString("查询IRIS_DATA表的所有记录[结果数:%1]").arg(result.size()).toStdString()); + return result; +} + +QVariantMap IrisDataDao::findRecordById(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM IRIS_DATA WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + // 获取结果 + if (query.next()) + { + result.insert("id", query.value("id").toString()); + result.insert("person_id", query.value("person_id").toLongLong()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("left_iris_code1", query.value("left_iris_code1")); + result.insert("left_iris_code2", query.value("left_iris_code2")); + result.insert("left_iris_code3", query.value("left_iris_code3")); + result.insert("right_iris_code1", query.value("right_iris_code1")); + result.insert("right_iris_code2", query.value("right_iris_code2")); + result.insert("right_iris_code3", query.value("right_iris_code3")); + } + +// LOG_DEBUG(QString("根据id查询IRIS_DATA表的记录[id=%1]").arg(id).toStdString()); + return result; +} + +QVariantMap IrisDataDao::findRecordByPersonId(QString personId) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM IRIS_DATA WHERE PERSON_ID = :personId"); + query.prepare(sql); + query.bindValue(":personId", personId); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + if (query.next()) + { + result.insert("id", query.value("id").toString()); + result.insert("person_id", query.value("person_id").toLongLong()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("left_iris_code1", query.value("left_iris_code1")); + result.insert("left_iris_code2", query.value("left_iris_code2")); + result.insert("left_iris_code3", query.value("left_iris_code3")); + result.insert("right_iris_code1", query.value("right_iris_code1")); + result.insert("right_iris_code2", query.value("right_iris_code2")); + result.insert("right_iris_code3", query.value("right_iris_code3")); + } + +// LOG_DEBUG(QString("根据personId查询IRIS_DATA表的记录[personId=%1]").arg(personId).toStdString()); + return result; +} + + +QString IrisDataDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + + // INSERT语句 + QString sql = QString("INSERT INTO IRIS_DATA (ID, PERSON_ID, ID_CARD_NO, LEFT_IRIS_CODE1, RIGHT_IRIS_CODE1) VALUES (:id, :personId, :idCardNo, :left1, :right1)"); + + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":personId", object.value("person_id").toString()); + query.bindValue(":idCardNo", object.value("id_card_no").toString()); + query.bindValue(":left1", object.value("left_iris_code1")); + query.bindValue(":right1", object.value("right_iris_code1")); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(); + +// LOG_DEBUG(QString("保存虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool IrisDataDao::edit(QVariantMap newObject, QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // UPDATE语句 + if (!newObject.contains("left_iris_code1") || !newObject.contains("right_iris_code1")){ + return false; + } + QString sql = QString("UPDATE IRIS_DATA SET LEFT_IRIS_CODE1 = :left1, RIGHT_IRIS_CODE1 = :right1 WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":left1", newObject.value("left_iris_code1")); + query.bindValue(":right1", newObject.value("right_iris_code1")); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(); + +// LOG_DEBUG(QString("编辑虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; +} + + +bool IrisDataDao::dele(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + QString sql = QString("DELETE FROM IRIS_DATA WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(); + +// LOG_DEBUG(QString("删除虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; +} diff --git a/dao/IrisDataDao.h b/dao/IrisDataDao.h new file mode 100644 index 0000000..c74dbbd --- /dev/null +++ b/dao/IrisDataDao.h @@ -0,0 +1,25 @@ +#ifndef IRISDATADAO_H +#define IRISDATADAO_H + +#include +#include "BaseDao.h" + +class IrisDataDao : public BaseDao +{ + Q_OBJECT +public: + explicit IrisDataDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + QVariantMap findRecordByPersonId(QString personId); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +signals: + +}; + +#endif // IRISDATADAO_H diff --git a/dao/RecognitionRecordsDao.cpp b/dao/RecognitionRecordsDao.cpp new file mode 100644 index 0000000..40db453 --- /dev/null +++ b/dao/RecognitionRecordsDao.cpp @@ -0,0 +1,100 @@ +#include "RecognitionRecordsDao.h" + +RecognitionRecordsDao::RecognitionRecordsDao(QObject *parent) : BaseDao(parent) +{ + +} + + +QVector RecognitionRecordsDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM RECOGNITION_RECORDS"; + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + item.insert("id", query.value("id").toLongLong()); + result.append(item); + } + +// LOG_DEBUG(QString("查询RECOGNITION_RECORDS表的所有记录[记录数:%1]").arg(result.size()).toStdString()); + return result; +} + +QVariantMap RecognitionRecordsDao::findRecordById(QString id) +{ + QVariantMap item; + return item; +} + +QString RecognitionRecordsDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + + // INSERT语句 + QString sql = QString("INSERT INTO RECOGNITION_RECORDS (ID, PERSON_ID, DATETIME, REC_TYPE, DEV_CODE, DOOR_CODE, INOUT_TYPE) " + "VALUES (:id, :personId, :datetime, :recType, :devCode, :doorCode, :inoutType)"); + + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":personId", object.value("person_id").toString()); + query.bindValue(":datetime", object.value("date_time").toString()); + query.bindValue(":recType", object.value("rec_type").toString()); + query.bindValue(":devCode", object.value("dev_code").toString()); + query.bindValue(":doorCode", object.value("door_code").toString()); + query.bindValue(":inoutType", object.value("inout_type").toString()); + +// LOG_DEBUG(sql.toStdString()); + + // 插入识别的log日志 + QString logStr = QString("INSERT INTO RECOGNITION_LOGS (ID, LOG_INFO) VALUES (:id, :logInfo)"); + + QSqlQuery logQuery(ConnectionManager::getInstance()->getConnection()); + logQuery.prepare(logStr); + logQuery.bindValue(":id", id); + logQuery.bindValue(":logInfo", object.value("debug_info").toString()); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(); + logQuery.exec(); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool RecognitionRecordsDao::edit(QVariantMap newObject, QString id) +{ + return false; +} + +bool RecognitionRecordsDao::dele(QString id) +{ + return false; +} diff --git a/dao/RecognitionRecordsDao.h b/dao/RecognitionRecordsDao.h new file mode 100644 index 0000000..38de7c9 --- /dev/null +++ b/dao/RecognitionRecordsDao.h @@ -0,0 +1,23 @@ +#ifndef RECOGNITIONRECORDSDAO_H +#define RECOGNITIONRECORDSDAO_H + +#include +#include "BaseDao.h" +class RecognitionRecordsDao: public BaseDao +{ + Q_OBJECT +public: + explicit RecognitionRecordsDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +signals: + +}; + +#endif // RECOGNITIONRECORDSDAO_H diff --git a/dao/SysDeptDao.cpp b/dao/SysDeptDao.cpp new file mode 100644 index 0000000..22f9946 --- /dev/null +++ b/dao/SysDeptDao.cpp @@ -0,0 +1,88 @@ +#include "SysDeptDao.h" + +SysDeptDao::SysDeptDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector SysDeptDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_DEPT WHERE PID != '-1' ORDER BY PID, NUM"; + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + item.insert("id", query.value("id").toString()); + item.insert("pid", query.value("pid").toString()); + item.insert("pids", query.value("pids").toString()); + item.insert("simplename", query.value("simplename").toString()); + item.insert("fullname", query.value("fullname").toString()); + } + +// LOG_TRACE(QString("查询表[SYS_DEPT]的所有记录[%1][%2]").arg(result.size()).arg(sql).toStdString()); + + return result; +} + +QVariantMap SysDeptDao::findRecordById(QString id) +{ + QVariantMap item; + return item; + + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM SYS_DEPT WHERE SYS_DEPT.ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + // 获取结果集的大小 + query.last(); + int count = query.at() + 1; + + if (count >=1) + { + query.first(); + + result.insert("id", query.value("id").toString()); + result.insert("pid", query.value("pid").toString()); + result.insert("pids", query.value("pids").toString()); + result.insert("simplename", query.value("simplename").toString()); + result.insert("fullname", query.value("fullname").toString()); + } + +// LOG_TRACE(QString("根据id查询SYS_DEPT表的记录[ID=%1][%2]").arg(id).arg(sql).toStdString()); + + return result; +} + + +QString SysDeptDao::save(QVariantMap object) +{ + return "0"; +} +bool SysDeptDao::edit(QVariantMap newObject, QString id) +{ + return true; +} +bool SysDeptDao::dele(QString id) +{ + return true; +} diff --git a/dao/SysDeptDao.h b/dao/SysDeptDao.h new file mode 100644 index 0000000..e07a09f --- /dev/null +++ b/dao/SysDeptDao.h @@ -0,0 +1,24 @@ +#ifndef SYSDEPTDAO_H +#define SYSDEPTDAO_H + +#include +#include "BaseDao.h" + +class SysDeptDao : public BaseDao +{ + Q_OBJECT +public: + explicit SysDeptDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +private: + +}; + +#endif // SYSDEPTDAO_H diff --git a/dao/SysPersonDao.cpp b/dao/SysPersonDao.cpp new file mode 100644 index 0000000..dd9480f --- /dev/null +++ b/dao/SysPersonDao.cpp @@ -0,0 +1,371 @@ +#include "SysPersonDao.h" + + +SysPersonDao::SysPersonDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector SysPersonDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0'"; + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + count++; + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + result.append(item); + } + +// LOG(TRACE) << QString("查询SYS_PERSON表的所有记录[%1]").arg(count).toStdString(); +// LOG_TRACE(QString("查询SYS_PERSON表的所有记录[%1]").arg(count).toStdString()); + + return result; +} + +QVariantMap SysPersonDao::findRecordById(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0' AND SYS_PERSON.ID = '%1'").arg(id); + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVariantMap result; + + // 获取结果集的大小 + query.last(); + int count = query.at() + 1; + + if (count >=1) + { + query.first(); + + result.insert("id", query.value("id").toString()); + result.insert("delflag", query.value("delflag").toString()); + result.insert("createtime", query.value("createtime").toString()); + result.insert("updatetime", query.value("updatetime").toString()); + result.insert("name", query.value("name").toString()); + result.insert("gender", query.value("gender").toString()); + result.insert("deptid", query.value("deptid").toString()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("remarks", query.value("remarks").toString()); + result.insert("person_code", query.value("person_code").toString()); + result.insert("deptname", query.value("fullname").toString()); + result.insert("sync_id", query.value("sync_id").toString()); + result.insert("hasFace", query.value("face_valid").toString()); + result.insert("hasIris", query.value("iris_valid").toString()); + } + +// LOG(TRACE) << QString("根据id查询SYS_PERSON表的记录[id=%1][%2]").arg(id).arg(sql).toStdString(); +// LOG_TRACE(QString("根据id查询SYS_PERSON表的记录[id=%1][%2]").arg(id).arg(sql).toStdString()); + + return result; +} + +int SysPersonDao::findRecordCountByNameAndDept(QString name, QString dept) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT COUNT(P.ID) AS RECCT FROM SYS_PERSON P LEFT JOIN SYS_DEPT D ON P.DEPTID = D.ID WHERE P.DELFLAG = '0'"; + if (name.isEmpty() == false) + { + sql += " AND P.NAME LIKE '%" + name + "%'"; + } + if (dept.isEmpty() == false && dept.indexOf("-1") < 0) + { + sql += QString(" AND ((P.DEPTID = '%1') OR (D.PIDS LIKE '%,%1,%'))").arg(dept); + } + + // 执行查询 + query.exec(sql); + + // 返回结果 + int result; + + // 遍历查询结果 + if (query.next()) { + result = query.value("RECCT").toInt(); + } + +// LOG(TRACE) << QString("根据姓名和部门查询SYS_PERSON记录总数[%1][%2]").arg(result).arg(sql).toStdString(); +// LOG_TRACE(QString("根据姓名和部门查询SYS_PERSON记录总数[%1][%2]").arg(result).arg(sql).toStdString()); + + return result; +} + +QVector SysPersonDao::findRecordsByNameAndDept(QString name, QString dept, qint8 limit, qint16 offset) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON P LEFT JOIN SYS_DEPT D ON P.DEPTID = D.ID WHERE P.DELFLAG = '0'"; + if (name.isEmpty() == false) + { + sql += " AND P.NAME LIKE '%" + name + "%'"; + } + if (dept.isEmpty() == false && dept.indexOf("-1") < 0) + { + sql += QString(" AND ((P.DEPTID = '%1') OR (D.PIDS LIKE '%,%1,%'))").arg(dept); + } + + sql += QString(" LIMIT %1 OFFSET %2").arg(limit).arg(offset); + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + count++; + + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + + result.append(item); + } + +// LOG(TRACE) << QString("根据姓名和部门分页查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString(); +// LOG_TRACE(QString("根据姓名和部门分页查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString()); + + return result; +} + +QVector SysPersonDao::findRecordsByProperties(QVariantMap conditions) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0'"; + QVariantMap::iterator it; + for (it = conditions.begin(); it != conditions.end(); it++) + { + sql += QString(" AND SYS_PERSON.%1 = %2").arg(it.key()).arg(it.value().toString()); + } + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + count++; + + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + + result.append(item); + } + +// LOG(TRACE) << QString("根据属性值查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString(); +// LOG_TRACE(QString("根据属性值查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString()); + + return result; +} + +QString SysPersonDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + + // INSERT语句 + QString sql = QString("INSERT INTO SYS_PERSON " + "(ID, DELFLAG, CREATETIME, UPDATETIME, " + "NAME, GENDER, DEPTID, ID_CARD_NO, " + "REMARKS, PERSON_CODE, SYNC_ID, FACE_VALID, IRIS_VALID) " + "VALUES ('%1', '0', '%2', '%2', '%3', '%4', '%5', '%6', '%7', '%8', '%9', 0, 0)") + .arg(id).arg(tm) + .arg(object.value("name").toString()) + .arg(object.value("gender").toString()) + .arg(object.value("deptid").toString()) + .arg(object.value("id_card_no").toString()) + .arg(object.value("remarks").toString()) + .arg(object.value("person_code").toString()) + .arg(object.value("sync_id").toString()); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(sql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { +// LOG(DEBUG) << QString("保存SYS_PERSON记录成功[ID = %1][%2]").arg(id).arg(sql).toStdString(); +// LOG_DEBUG(QString("保存SYS_PERSON记录成功[ID = %1][%2]").arg(id).arg(sql).toStdString()); + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool SysPersonDao::edit(QVariantMap newObject, QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + + // UPDATE语句 + QString sql = QString("UPDATE SYS_PERSON SET UPDATETIME = '%1'").arg(tm); + if (newObject.contains("name")) + { + sql.append(QString(", NAME = '%1'").arg(newObject.value("name").toString())); + } + if (newObject.contains("gender")) + { + sql.append(QString(", GENDER = '%1'").arg(newObject.value("gender").toString())); + } + if (newObject.contains("deptid")) + { + sql.append(QString(", DEPTID = '%1'").arg(newObject.value("deptid").toString())); + } + if (newObject.contains("person_code")) + { + sql.append(QString(", PERSON_CODE = '%1'").arg(newObject.value("person_code").toString())); + } + if (newObject.contains("face_valid")) + { + sql.append(QString(", FACE_VALID = '%1'").arg(newObject.value("face_valid").toString())); + } + if (newObject.contains("iris_valid")) + { + sql.append(QString(", IRIS_VALID = '%1'").arg(newObject.value("iris_valid").toString())); + } + + sql.append(QString(" WHERE ID = '%1'").arg(id)); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(sql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + +// LOG(DEBUG) << QString("编辑人员[ID=%1][%2]").arg(id).arg(sql).toStdString(); +// LOG_DEBUG(QString("编辑人员[ID=%1][%2]").arg(id).arg(sql).toStdString()); + + // 返回结果 + return success; +} + +bool SysPersonDao::dele(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + QSqlQuery irisDel(ConnectionManager::getInstance()->getConnection()); + + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + qint64 tmms = QDateTime::currentDateTime().toMSecsSinceEpoch(); + + // UPDATE语句 + QString sql = QString("UPDATE SYS_PERSON SET UPDATETIME = :updateTime, DELFLAG = :flag WHERE ID = :id").arg(tm).arg(tmms).arg(id); + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":updateTime", tm); + query.bindValue(":flag", tmms); + + // 物理删除人员的人脸和虹膜数据 + QString delIrisSql = QString("DELETE FROM IRIS_DATA WHERE PERSON_ID = :personId"); + irisDel.prepare(delIrisSql); + irisDel.bindValue(":personId", id); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(sql); + query.exec(delIrisSql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + +// LOG_DEBUG(QString("删除人员SYS_PERSON[ID=%1][%2]").arg(id).arg(success).toStdString()); + + // 返回结果 + return success; +} diff --git a/dao/SysPersonDao.h b/dao/SysPersonDao.h new file mode 100644 index 0000000..e02e5ba --- /dev/null +++ b/dao/SysPersonDao.h @@ -0,0 +1,27 @@ +#ifndef SYSPERSONDAO_H +#define SYSPERSONDAO_H + +#include +#include "BaseDao.h" + +class SysPersonDao : public BaseDao +{ + Q_OBJECT +public: + explicit SysPersonDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + int findRecordCountByNameAndDept(QString name, QString dept); + QVector findRecordsByNameAndDept(QString name, QString dept, qint8 limit, qint16 offset); + QVector findRecordsByProperties(QVariantMap conditions); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); +signals: + +}; + +#endif // SYSPERSONDAO_H diff --git a/dao/dao.pri b/dao/dao.pri new file mode 100644 index 0000000..1e04ce4 --- /dev/null +++ b/dao/dao.pri @@ -0,0 +1,18 @@ + +HEADERS += $$PWD/BaseDao.h +HEADERS += $$PWD/IrisDataDao.h +HEADERS += $$PWD/RecognitionRecordsDao.h +HEADERS += $$PWD/SysPersonDao.h +HEADERS += $$PWD/SysDeptDao.h + +SOURCES += $$PWD/BaseDao.cpp +SOURCES += $$PWD/IrisDataDao.cpp +SOURCES += $$PWD/RecognitionRecordsDao.cpp +SOURCES += $$PWD/SysPersonDao.cpp +SOURCES += $$PWD/SysDeptDao.cpp + +HEADERS += $$PWD/util/ConnectionManager.h +SOURCES += $$PWD/util/ConnectionManager.cpp +#HEADERS += $$PWD/util/CacheManager.h +#SOURCES += $$PWD/util/CacheManager.cpp + diff --git a/dao/util/ConnectionManager.cpp b/dao/util/ConnectionManager.cpp new file mode 100644 index 0000000..84b17be --- /dev/null +++ b/dao/util/ConnectionManager.cpp @@ -0,0 +1,47 @@ +#include "ConnectionManager.h" +#include + +Q_GLOBAL_STATIC(ConnectionManager, cm) + +ConnectionManager::ConnectionManager(QObject *parent) : QObject(parent) +{ + // 初始化数据库连接 + if (QSqlDatabase::contains("qt_sql_dafault_connection")) + { + conn = QSqlDatabase::database("qt_sql_default_connection"); + } + else + { + conn = QSqlDatabase::addDatabase("QSQLITE"); + conn.setDatabaseName(QApplication::applicationDirPath() + "/data/casic.db"); + + bool succ = conn.open(); + if (succ == true) + { +// LOG_INFO(QString("打开数据库操作正常[Open Database Success]").toStdString()); + } else + { +// LOG_ERROR(QString("打开数据库操作失败[Open Database Failed]").toStdString()); + } + } +} + +ConnectionManager::~ConnectionManager() +{ + conn.close(); +} + +ConnectionManager* ConnectionManager::getInstance() +{ + return cm; +} + +QSqlDatabase ConnectionManager::getConnection() +{ + return this->conn; +} + +qint64 ConnectionManager::generateId() +{ + return this->idWorker.nextId(); +} diff --git a/dao/util/ConnectionManager.h b/dao/util/ConnectionManager.h new file mode 100644 index 0000000..84647e3 --- /dev/null +++ b/dao/util/ConnectionManager.h @@ -0,0 +1,34 @@ +#ifndef CONNECTIONMANAGER_H +#define CONNECTIONMANAGER_H + +#include +#include +#include "utils/id/IdWorker.h" +#include "utils/UtilInclude.h" + +using namespace Jiawa::Core; + +class ConnectionManager : public QObject +{ + Q_OBJECT +public: + explicit ConnectionManager(QObject *parent = nullptr); + ~ConnectionManager(); + + static ConnectionManager * getInstance(); + + QSqlDatabase getConnection(); + qint64 generateId(); + +private: + // 数据库连接 + QSqlDatabase conn; + + // 雪花id生成工具 + IdWorker &idWorker = Singleton::instance(); + +signals: + +}; + +#endif // CONNECTIONMANAGER_H diff --git a/device/IrisCameraCapEventHandler.cpp b/device/IrisCameraCapEventHandler.cpp new file mode 100644 index 0000000..45df089 --- /dev/null +++ b/device/IrisCameraCapEventHandler.cpp @@ -0,0 +1,103 @@ +#include "IrisCameraCapEventHandler.h" + +IrisCameraCapEventHandler::IrisCameraCapEventHandler(QObject *parent) : QObject(parent) +{ + +} + +void IrisCameraCapEventHandler::DoOnImageCaptured(CImageDataPointer &objImageDataPointer, void *pUserParam) +{ + if (objImageDataPointer.IsNull() == false) + { + CGXDevicePointer* cam = (CGXDevicePointer *) pUserParam; + + auto camName = cam->getPtr()->GetDeviceInfo().GetUserID(); + int width = objImageDataPointer->GetWidth(); + int height = objImageDataPointer->GetHeight(); + size_t leftKeyIndex = camName.find("left"); + size_t rightKeyIndex = camName.find("right"); + + uchar * pBuffer = (BYTE*)objImageDataPointer->GetBuffer(); + + // 相机拍摄下的图像1440*1080, 直接用于算法判断 + QImage img = QImage(pBuffer, width, height, QImage::Format_Grayscale8); // 用于展示 +// QImage imgAlgo = img.copy(0, 0, width, height); + + // 用于显示的图像需要缩小到400 * 300的尺寸 + img = img.scaled(SettingConfig::getInstance().IRIS_DISPLAY_HEIGHT, SettingConfig::getInstance().IRIS_DISPLAY_WIDTH); + img = img.transformed(QTransform().rotate(-90)); // 图像逆时针旋转90度 + + // 发送到界面进行显示 + emit sendIrisFrameToDraw(img); +// cv::Mat irisMat = ImageUtil::QImageToMat(imgAlgo); + +// irisInfo.data = imgAlgo; +// irisInfo.matData = irisMat; + +// // 将图像显示在注册页面的label上 +// // 并将虹膜信息对象存入队列中 +// ProMemory::getInstance().pushCasicIris(irisInfo); + +// if (leftKeyIndex >= 0 && leftKeyIndex < 32) +// { +// emit sendIrisFrameToDraw(img, 0); // 左眼画面 +// } else if (rightKeyIndex >= 0 && rightKeyIndex < 32) +// { +// emit sendIrisFrameToDraw(img, 1); // 右眼画面 +// } +/* + if (pBuffer != NULL) + { + // 创建虹膜信息对象 + CasicIrisInfo irisInfo; + irisInfo.hasEye = false; + if (leftKeyIndex >= 0 && leftKeyIndex < 32) + { + // 左眼相机拍摄的图像 + irisInfo.leftOrRight = "left"; + } else if (rightKeyIndex >= 0 && rightKeyIndex < 32) + { + // 右眼相机 + irisInfo.leftOrRight = "right"; + } + + if (ProMemory::getInstance().widgeFrame == CasicBioRecConst::RECOGNIZE_RESULT_FORM) + { + // 相机拍摄下的图像1280*960, 直接用于算法判断 + QImage imgDisp = QImage(pBuffer, width, height, QImage::Format_Grayscale8); + cv::Mat irisMat = ImageUtil::QImageToMat(imgDisp); + + irisInfo.data = imgDisp; + irisInfo.matData = irisMat; + + ProMemory::getInstance().pushCasicIris(irisInfo); + +// cv::imwrite(QString("D:\\irisLogs\\iristest-%1.bmp").arg(irisInfo.leftOrRight).toStdString(), irisMat); + } else if (ProMemory::getInstance().widgeFrame == CasicBioRecConst::ADD_PERSON_CAPTURE_IRIS) + { + // 相机拍摄下的图像1280*960, 直接用于算法判断 + QImage img = QImage(pBuffer, width, height, QImage::Format_Grayscale8); + QImage imgAlgo = img.copy(0, 0, width, height); + + // 用于显示的图像需要缩小到1/4的尺寸 + img = img.scaled(640, 480); + cv::Mat irisMat = ImageUtil::QImageToMat(imgAlgo); + + irisInfo.data = imgAlgo; + irisInfo.matData = irisMat; + + // 将图像显示在注册页面的label上 + // 并将虹膜信息对象存入队列中 + ProMemory::getInstance().pushCasicIris(irisInfo); + + if (leftKeyIndex >= 0 && leftKeyIndex < 32) + { + emit sendIrisFrameToDraw(img, 0); // 左眼画面 + } else if (rightKeyIndex >= 0 && rightKeyIndex < 32) + { + emit sendIrisFrameToDraw(img, 1); // 右眼画面 + } + } + }*/ + } +} diff --git a/device/IrisCameraCapEventHandler.h b/device/IrisCameraCapEventHandler.h new file mode 100644 index 0000000..ad75a97 --- /dev/null +++ b/device/IrisCameraCapEventHandler.h @@ -0,0 +1,30 @@ +#ifndef IRISCAMERACAPEVENTHANDLER_H +#define IRISCAMERACAPEVENTHANDLER_H + +#include +#include +#include "include/opencv2/opencv.hpp" +#include "include/daheng/GalaxyIncludes.h" + +//#include "casic/iris/CasicIrisInterface.h" +#include "ProMemory.h" + +#include "utils/UtilInclude.h" + +class IrisCameraCapEventHandler : public QObject, public ICaptureEventHandler +{ + Q_OBJECT +public: + explicit IrisCameraCapEventHandler(QObject *parent = nullptr); + + void DoOnImageCaptured(CImageDataPointer &objImageDataPointer, void *pUserParam); + +private: + unsigned char* pImageBuffer; + +signals: + void sendIrisFrameToDraw(QImage irisImage); + +}; + +#endif // IRISCAMERACAPEVENTHANDLER_H diff --git a/device/IrisCameraController.cpp b/device/IrisCameraController.cpp new file mode 100644 index 0000000..0928176 --- /dev/null +++ b/device/IrisCameraController.cpp @@ -0,0 +1,110 @@ +#include "IrisCameraController.h" + +IrisCameraController::IrisCameraController(QObject *parent) : QObject(parent) +{ + this->irisCamHandler = new IrisCameraCapEventHandler(this); +} +IrisCameraController::~IrisCameraController() +{ + this->closeIrisCamera(); +} + + +void IrisCameraController::initIrisCamera() +{ + IGXFactory::GetInstance().Init(); + + //枚举设备 + IGXFactory::GetInstance().UpdateDeviceList(1000, irisCamList); + + this->OpenDevice(); +} + +void IrisCameraController::openIrisCamera() +{ + //设置Buffer处理模式 + irisStreamFeaturePtr->GetEnumFeature("StreamBufferHandlingMode")->SetValue("OldestFirst"); + + //注册回调函数 + irisStreamPtr->RegisterCaptureCallback(irisCamHandler, &irisCamPtr); + + //开启流层通道 + irisStreamPtr->StartGrab(); + + //发送开采命令 + irisFeaturePtr->GetCommandFeature("AcquisitionStart")->Execute(); + + // 启动定时器 + TimeCounterUtil::getInstance().irisCapCounter->start(SettingConfig::getInstance().IRIS_FRAME_INTERVAL); // 50ms执行一次定时器 +} + +void IrisCameraController::closeIrisCamera() +{ + +} + +void IrisCameraController::startCapture() +{ + // 获取定时器, 绑定定时函数 + connect(TimeCounterUtil::getInstance().irisCapCounter, &QTimer::timeout, this, &IrisCameraController::getOneFaceFrm); +// LOG(DEBUG) << QString("[IrisCameraController][startCapture]虹膜相机拍图").toStdString(); +// LOG_DEBUG(QString("[IrisCameraController][startCapture]虹膜相机拍图").toStdString()); + +} +void IrisCameraController::stopCapture() +{ + // 获取定时器, 绑定定时函数 + disconnect(TimeCounterUtil::getInstance().irisCapCounter, &QTimer::timeout, this, &IrisCameraController::getOneFaceFrm); +// LOG(DEBUG) << QString("[IrisCameraController][stopCapture]虹膜相机停止拍图").toStdString(); +// LOG_DEBUG(QString("[IrisCameraController][stopCapture]虹膜相机停止拍图").toStdString()); + +} + +void IrisCameraController::getOneFaceFrm() +{ + // 发送软触发命令(在触发模式开启时有效) + irisFeaturePtr->GetCommandFeature("TriggerSoftware")->Execute(); +} + +void IrisCameraController::getLeftAndRightEyeFrame() +{ + irisFeaturePtr->GetCommandFeature("TriggerSoftware")->Execute(); +} + +void IrisCameraController::OpenDevice() +{ + auto device = irisCamList.at(0); + + irisCamPtr = IGXFactory::GetInstance().OpenDeviceByUserID(device.GetUserID(), GX_ACCESS_EXCLUSIVE); + irisFeaturePtr = irisCamPtr->GetRemoteFeatureControl(); + + // 判断设备流是否大于零, 如果大于零则打开流 + int nStreamCount = irisCamPtr->GetStreamCount(); + if (nStreamCount > 0) + { + irisStreamPtr = irisCamPtr->OpenStream(0); + irisStreamFeaturePtr = irisStreamPtr->GetFeatureControl(); + } + + // 建议用户在打开网络相机之后, 根据当前网络环境设置相机的流通道包长值, + // 以提高网络相机的采集性能, 设置方法参考以下代码。 + GX_DEVICE_CLASS_LIST objDeviceClass = irisCamPtr->GetDeviceInfo().GetDeviceClass(); + if(GX_DEVICE_CLASS_GEV == objDeviceClass) + { + // 判断设备是否支持流通道数据包功能 + if(true == irisFeaturePtr->IsImplemented("GevSCPSPacketSize")) + { + // 获取当前网络环境的最优包长值 + int nPacketSize = irisStreamPtr->GetOptimalPacketSize(); + // 将最优包长值设置为当前设备的流通道包长值 + irisFeaturePtr->GetIntFeature("GevSCPSPacketSize")->SetValue(nPacketSize); + } + } + + //设置采集模式为连续采集模式 + irisFeaturePtr->GetEnumFeature("AcquisitionMode")->SetValue("Continuous"); + + //设置触发模式关 + irisFeaturePtr->GetEnumFeature("TriggerMode")->SetValue("On"); + irisFeaturePtr->GetEnumFeature("TriggerSource")->SetValue("Software"); +} diff --git a/device/IrisCameraController.h b/device/IrisCameraController.h new file mode 100644 index 0000000..5d7e269 --- /dev/null +++ b/device/IrisCameraController.h @@ -0,0 +1,49 @@ +#ifndef IRISCAMERACONTROLLER_H +#define IRISCAMERACONTROLLER_H + +#include + +#include "IrisCameraCapEventHandler.h" + +class IrisCameraCapEventHandler; + +class IrisCameraController : public QObject +{ + Q_OBJECT +public: + explicit IrisCameraController(QObject *parent = nullptr); + ~IrisCameraController(); + + // 初始化并打开人脸相机 + void initIrisCamera(); + void openIrisCamera(); + void closeIrisCamera(); + + void startCapture(); + void stopCapture(); + + void getLeftAndRightEyeFrame(); + + IrisCameraCapEventHandler * irisCamHandler; + +private: + GxIAPICPP::gxdeviceinfo_vector irisCamList; + + CGXDevicePointer irisCamPtr; ///< 设备句柄 + + CGXStreamPointer irisStreamPtr; ///< 左眼设备流 + + CGXFeatureControlPointer irisFeaturePtr; ///< 左眼属性控制器 + + CGXFeatureControlPointer irisStreamFeaturePtr; ///< 左眼流层控制器对象 + + void OpenDevice(); + +signals: + +public slots: + void getOneFaceFrm(); + +}; + +#endif // IRISCAMERACONTROLLER_H diff --git a/device/device.pri b/device/device.pri new file mode 100644 index 0000000..a8417f2 --- /dev/null +++ b/device/device.pri @@ -0,0 +1,13 @@ + +HEADERS += $$PWD/IrisCameraController.h +HEADERS += $$PWD/IrisCameraCapEventHandler.h +#HEADERS += $$PWD/iris/IrisRegistProcess.h +#HEADERS += $$PWD/iris/IrisRecogProcess.h +#HEADERS += $$PWD/iris/CasicIrisRecState.h + +SOURCES += $$PWD/IrisCameraController.cpp +SOURCES += $$PWD/IrisCameraCapEventHandler.cpp +#SOURCES += $$PWD/iris/IrisRegistProcess.cpp +#SOURCES += $$PWD/iris/IrisRecogProcess.cpp +#SOURCES += $$PWD/iris/CasicIrisRecState.cpp + diff --git a/images/bg_footer.png b/images/bg_footer.png new file mode 100644 index 0000000..a3a99ab --- /dev/null +++ b/images/bg_footer.png Binary files differ diff --git a/images/bg_statcked.png b/images/bg_statcked.png new file mode 100644 index 0000000..18b63e1 --- /dev/null +++ b/images/bg_statcked.png Binary files differ diff --git a/images/bg_title.png b/images/bg_title.png new file mode 100644 index 0000000..0316e2d --- /dev/null +++ b/images/bg_title.png Binary files differ diff --git a/main.cpp b/main.cpp index 16bc45b..9052ddb 100644 --- a/main.cpp +++ b/main.cpp @@ -1,11 +1,11 @@ -#include "IdentifyForm.h" +#include "MainWindowForm.h" #include int main(int argc, char *argv[]) { QApplication a(argc, argv); - IdentifyForm w; + MainWindowForm w; w.show(); return a.exec(); } diff --git a/resource.qrc b/resource.qrc new file mode 100644 index 0000000..474586a --- /dev/null +++ b/resource.qrc @@ -0,0 +1,35 @@ + + + images/setting.png + images/user.png + images/back.png + images/home.png + images/btnPageFirst.png + images/btnPageLast.png + images/btnPageNext.png + images/btnPagePre.png + images/regist.png + images/photoEyeLeft.png + images/photoEyeRight.png + images/photoFace.png + images/save.png + images/upArrow.png + images/downArrow.png + images/faceCaped.png + images/faceNotCap.png + images/irisCaped.png + images/irisNotCap.png + images/tipsFailure.png + images/tipsSuccess.png + images/tipsConfirm.png + images/bg_recognize_result.png + images/iconRetry.png + images/bg_title.png + images/bg_footer.png + images/bg_statcked.png + + + images/add_bottom.png + images/add_top.png + + diff --git a/utils/ImageUtil.cpp b/utils/ImageUtil.cpp new file mode 100644 index 0000000..7604572 --- /dev/null +++ b/utils/ImageUtil.cpp @@ -0,0 +1,97 @@ +#include "ImageUtil.h" + +ImageUtil::ImageUtil() +{ + +} + +QImage ImageUtil::MatImageToQImage(const cv::Mat &src) +{ + //CV_8UC1 8位无符号的单通道---灰度图片 + if(src.type() == CV_8UC1) + { + QImage qImage((const unsigned char *)(src.data), src.cols, src.rows, src.cols, QImage::Format_Grayscale8); + return qImage; + } + //为3通道的彩色图片 + else if(src.type() == CV_8UC3) + { + //得到图像的的首地址 + const uchar *pSrc = (const uchar*)src.data; + //以src构造图片 + QImage qImage(pSrc, src.cols, src.rows, src.step, QImage::Format_RGB888); + //在不改变实际图像数据的条件下, 交换红蓝通道 + return qImage.rgbSwapped(); + } + //四通道图片, 带Alpha通道的RGB彩色图像 + else if(src.type() == CV_8UC4) + { + const uchar *pSrc = (const uchar*)src.data; + QImage qImage(pSrc, src.cols, src.rows, src.step, QImage::Format_ARGB32); + //返回图像的子区域作为一个新图像 + return qImage.copy(); + } + else + { + return QImage(); + } +} +/* +QImage ImageUtil::UcharToQImage(unsigned char* data, int width, int height, QImage::Format format) +{ + QImage qImage(data, width, height, format); + //在不改变实际图像数据的条件下, 交换红蓝通道 + return qImage.rgbSwapped(); +} + +cv::Mat ImageUtil::QImageToMat(QImage image) +{ + cv::Mat mat; + switch(image.format()) + { + case QImage::Format_ARGB32: + case QImage::Format_RGB32: + case QImage::Format_ARGB32_Premultiplied: + mat = cv::Mat(image.height(), image.width(), CV_8UC4, (void*)image.constBits(), image.bytesPerLine()); + break; + case QImage::Format_RGB888: + mat = cv::Mat(image.height(), image.width(), CV_8UC3, (void*)image.constBits(), image.bytesPerLine()); + cv::cvtColor(mat, mat, cv::COLOR_BGR2RGB); + break; + case QImage::Format_Indexed8: + mat = cv::Mat(image.height(), image.width(), CV_8UC1, (void*)image.constBits(), image.bytesPerLine()); + break; + case QImage::Format_Grayscale8: + mat = cv::Mat(image.height(), image.width(), CV_8UC1, (void *)image.bits(), image.bytesPerLine()); + break; + } + + mat = mat.clone(); + + return mat; +} + +QString ImageUtil::QImageToBase64(QImage image) +{ + QByteArray ba; + QBuffer buf(&ba); + image.save(&buf, "bmp"); + QString base64String = ba.toBase64(); + return base64String; +} + +cv::Mat ImageUtil::MatImageRect(const cv::Mat &src, cv::Rect rect, int delta) +{ + cv::Mat matClone = src.clone(); + cv::Rect bigRect; + + bigRect.x = rect.x - delta < 0 ? 0 : rect.x - delta; + bigRect.y = rect.y - delta < 0 ? 0 : rect.y - delta; + bigRect.width = rect.x + rect.width + 2 * delta > src.cols ? src.cols - rect.x : rect.width + 2 * delta; + bigRect.height = rect.y + rect.height + 2 * delta > src.rows ? src.rows - rect.y : rect.height + 2 * delta; + + cv::Mat roi = matClone(bigRect); + + return roi; +} +*/ diff --git a/utils/ImageUtil.h b/utils/ImageUtil.h new file mode 100644 index 0000000..dbfdd48 --- /dev/null +++ b/utils/ImageUtil.h @@ -0,0 +1,22 @@ +#ifndef IMAGEUTIL_H +#define IMAGEUTIL_H + +#include +#include +#include "opencv2/opencv.hpp" + +class ImageUtil +{ +public: + ImageUtil(); + + static QImage MatImageToQImage(const cv::Mat &src); +// static QImage UcharToQImage(unsigned char* data, int width, int height, QImage::Format format); + +// static cv::Mat QImageToMat(QImage image); +// static QString QImageToBase64(QImage image); + +// static cv::Mat MatImageRect(const cv::Mat &src, cv::Rect rect, int delta); +}; + +#endif // IMAGEUTIL_H diff --git a/utils/SettingConfig.cpp b/utils/SettingConfig.cpp new file mode 100644 index 0000000..d420285 --- /dev/null +++ b/utils/SettingConfig.cpp @@ -0,0 +1,44 @@ +#include "SettingConfig.h" +#include + +SettingConfig::SettingConfig() +{ + filename = QApplication::applicationDirPath() + "/conf/config.ini"; + setting = new QSettings(this->filename, QSettings::IniFormat); + + WINDOW_WIDTH = getProperty("window", "width").toInt(); + WINDOW_HEIGHT = getProperty("window", "height").toInt(); + WINDOW_BACKGROUND_COLOR = getProperty("window", "backgroundColor").toString(); + WINDOW_TITLE = getProperty("window", "title").toString(); + WINDOW_RIGHTS = getProperty("window", "copyright").toString(); + WINDOW_VERSION = getProperty("window", "version").toString(); + + IRIS_FRAME_WIDTH = getProperty("camera", "irisFrameWidth").toInt(); + IRIS_FRAME_HEIGHT = getProperty("camera", "irisFrameHeight").toInt(); + IRIS_WIDTH = getProperty("camera", "irisWidth").toInt(); + IRIS_HEIGHT = getProperty("camera", "irisHeight").toInt(); + IRIS_FRAME_INTERVAL = getProperty("camera", "irisFrameInterval").toInt(); + IRIS_DISPLAY_WIDTH = getProperty("camera", "irisDisplayWidth").toInt(); + IRIS_DISPLAY_HEIGHT = getProperty("camera", "irisDisplayHeight").toInt(); + + MAX_MATCH_TIME = getProperty("recognize", "maxMatchTime").toInt(); + SUCCESS_TIPS_LAST = getProperty("recognize", "successTipsLast").toInt(); + FAILURE_TIPS_LAST = getProperty("recognize", "failureTipsLast").toInt(); + MAX_FACE_TRY_COUNT = getProperty("recognize", "maxFaceTryCount").toInt(); + MAX_FACE_NOT_FOUND_COUNT = getProperty("recognize", "maxFaceNotFoundCount").toInt(); + MAX_IRIS_TRY_COUNT = getProperty("recognize", "maxIrisTryCount").toInt(); + MAX_EYE_NOT_FOUND_COUNT = getProperty("recognize", "maxEyeNotFoundCount").toInt(); + + MAX_CAPTURE_STACK_SIZE = getProperty("stack", "capture").toInt(); + MAX_FOUND_STACK_SIZE = getProperty("stack", "found").toInt(); + MAX_QUALIFIED_STACK_SIZE = getProperty("stack", "qualified").toInt(); + + LOG_FILE = getProperty("log", "logFile").toString(); + LOG_LEVEL = getProperty("log", "logLevel").toString(); +} + + +QVariant SettingConfig::getProperty(QString nodeName, QString keyName) { + QVariant var = this->setting->value(QString("/%1/%2").arg(nodeName).arg(keyName)); + return var; +} diff --git a/utils/SettingConfig.h b/utils/SettingConfig.h new file mode 100644 index 0000000..30c3bec --- /dev/null +++ b/utils/SettingConfig.h @@ -0,0 +1,66 @@ +#ifndef SETTINGCONFIG_H +#define SETTINGCONFIG_H + +#include +#include + +class SettingConfig : public QObject +{ +public: + ~SettingConfig() {}; + SettingConfig(const SettingConfig&)=delete; + SettingConfig& operator=(const SettingConfig&)=delete; + + static SettingConfig& getInstance() { + static SettingConfig instance; + return instance; + } + + /** + * @brief get + * @param nodeName + * @param keyName + * @return QVariant + * @title + */ + QVariant getProperty(QString nodeName, QString keyName); + + /******** 以下为需要的各类参数 ********/ + int WINDOW_WIDTH; + int WINDOW_HEIGHT; + QString WINDOW_BACKGROUND_COLOR; + QString WINDOW_TITLE; + QString WINDOW_RIGHTS; + QString WINDOW_VERSION; + + int IRIS_FRAME_INTERVAL; + int IRIS_FRAME_WIDTH; + int IRIS_FRAME_HEIGHT; + int IRIS_WIDTH; + int IRIS_HEIGHT; + int IRIS_DISPLAY_WIDTH; + int IRIS_DISPLAY_HEIGHT; + + int MAX_MATCH_TIME; + int SUCCESS_TIPS_LAST; + int FAILURE_TIPS_LAST; + int MAX_FACE_TRY_COUNT; + int MAX_FACE_NOT_FOUND_COUNT; + int MAX_IRIS_TRY_COUNT; + int MAX_EYE_NOT_FOUND_COUNT; + + int MAX_CAPTURE_STACK_SIZE; + int MAX_FOUND_STACK_SIZE; + int MAX_QUALIFIED_STACK_SIZE; + + QString LOG_FILE; + QString LOG_LEVEL; + +private: + SettingConfig(); + + QString filename; + QSettings* setting; +}; + +#endif // SETTINGCONFIG_H diff --git a/utils/TimeCounterUtil.cpp b/utils/TimeCounterUtil.cpp new file mode 100644 index 0000000..275945f --- /dev/null +++ b/utils/TimeCounterUtil.cpp @@ -0,0 +1,8 @@ +#include "TimeCounterUtil.h" + +TimeCounterUtil::TimeCounterUtil() +{ + faceCapCounter = new QTimer(); + irisCapCounter = new QTimer(); + clockCounter = new QTimer(); +} diff --git a/utils/TimeCounterUtil.h b/utils/TimeCounterUtil.h new file mode 100644 index 0000000..28b29f1 --- /dev/null +++ b/utils/TimeCounterUtil.h @@ -0,0 +1,29 @@ +#ifndef TIMECOUNTERUTIL_H +#define TIMECOUNTERUTIL_H + +#include +#include + +class TimeCounterUtil : public QObject +{ +public: + + ~TimeCounterUtil() {}; + TimeCounterUtil(const TimeCounterUtil&)=delete; + TimeCounterUtil& operator=(const TimeCounterUtil&)=delete; + + static TimeCounterUtil& getInstance() { + static TimeCounterUtil instance; + return instance; + } + + QTimer * faceCapCounter; + QTimer * irisCapCounter; + QTimer * clockCounter; + +private: + TimeCounterUtil(); + +}; + +#endif // TIMECOUNTERUTIL_H diff --git a/utils/UtilInclude.h b/utils/UtilInclude.h new file mode 100644 index 0000000..e7b899a --- /dev/null +++ b/utils/UtilInclude.h @@ -0,0 +1,13 @@ +#ifndef UTILINCLUDE_H +#define UTILINCLUDE_H + +//#include "ByteUtil.h" +#include "ImageUtil.h" +//#include "LogUtil.h" +#include "SettingConfig.h" +//#include "SpeakerUtil.h" +#include "TimeCounterUtil.h" +//#include "UDPClientUtil.h" +//#include "HttpRequestUtil.h" + +#endif // UTILINCLUDE_H diff --git a/AppConstants.h b/AppConstants.h new file mode 100644 index 0000000..296c53f --- /dev/null +++ b/AppConstants.h @@ -0,0 +1,28 @@ +#ifndef APPCONSTANTS_H +#define APPCONSTANTS_H + +class AppConstants +{ +public: + enum WidgeFrameName + { + MAIN_PAGE = 0, // 主页面 + PERSON_LIST_FORM = 1, // 人员列表页面 + ADD_PERSON_FORM = 2, // 添加人员页面 + ADD_PERSON_CAPTURE_FACE = 21, // 添加/编辑人员时进行人脸拍图 + ADD_PERSON_CAPTURE_IRIS = 22, // 添加/编辑人员时进行虹膜拍图 + SETTING_FORM = 3, // 设置页面 + RECOGNIZE_RESULT_FORM = 4, // 识别结果界面 + IDENTIFY_FORM = 5, // 识别界面 含识别中 和 识别结果 + LOCKSCREEN_FORM = 6 // 锁屏待机界面 + }; + + enum ApplicationState + { + STATE_WAIT = 0, // 待机 + STATE_WORKING = 1, // 工作状态 + STATE_IDENTIFYING = 2, // 识别中 + }; +}; + +#endif // APPCONSTANTS_H diff --git a/CasicIrisIdentify.pro b/CasicIrisIdentify.pro index 5d7fea6..575ce3d 100644 --- a/CasicIrisIdentify.pro +++ b/CasicIrisIdentify.pro @@ -1,4 +1,4 @@ -QT += core gui +QT += core gui sql network texttospeech greaterThan(QT_MAJOR_VERSION, 4): QT += widgets @@ -15,20 +15,46 @@ # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 -SOURCES += \ - main.cpp \ - IdentifyForm.cpp +include("dao/dao.pri") +include("device/device.pri") +include("utils/utils.pri") -HEADERS += \ - IdentifyForm.h +SOURCES += main.cpp +SOURCES += ProMemory.cpp +SOURCES += MainWindowForm.cpp +SOURCES += IdentifyForm.cpp +SOURCES += LockScreenForm.cpp -FORMS += \ - IdentifyForm.ui +HEADERS += AppConstants.h +HEADERS += ProMemory.h +HEADERS += MainWindowForm.h +HEADERS += IdentifyForm.h +HEADERS += LockScreenForm.h -TRANSLATIONS += \ - CasicIrisIdentify_zh_CN.ts +FORMS += MainWindowForm.ui +FORMS += IdentifyForm.ui +FORMS += LockScreenForm.ui + +RESOURCES += resource.qrc + +DISTFILES += conf/config.ini + +#TRANSLATIONS += CasicIrisIdentify_zh_CN.ts + +#INCLUDEPATH += include/spdlog +#DEPENDPATH += include/spdlog # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target + + +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lopencv_world420 +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lGxIAPICPPEx + +INCLUDEPATH += $$PWD/include/daheng +DEPENDPATH += $$PWD/include/daheng + +INCLUDEPATH += $$PWD/include +DEPENDPATH += $$PWD/include diff --git a/CasicIrisIdentify_zh_CN.ts b/CasicIrisIdentify_zh_CN.ts index 5526fe4..81900df 100644 --- a/CasicIrisIdentify_zh_CN.ts +++ b/CasicIrisIdentify_zh_CN.ts @@ -1,3 +1,12 @@ - + + + IdentifyForm + + + IdentifyForm + + + + diff --git a/IdentifyForm.cpp b/IdentifyForm.cpp index 348a897..ba1f251 100644 --- a/IdentifyForm.cpp +++ b/IdentifyForm.cpp @@ -1,4 +1,4 @@ -#include "IdentifyForm.h" +#include "IdentifyForm.h" #include "ui_IdentifyForm.h" IdentifyForm::IdentifyForm(QWidget *parent) @@ -6,6 +6,12 @@ , ui(new Ui::IdentifyForm) { ui->setupUi(this); + + // 初始化更新界面的定时器 + // 每秒执行一次 + connect(TimeCounterUtil::getInstance().clockCounter, &QTimer::timeout, this, &IdentifyForm::updateDateAndTime); + + TimeCounterUtil::getInstance().clockCounter->start(1000); } IdentifyForm::~IdentifyForm() @@ -13,3 +19,16 @@ delete ui; } +void IdentifyForm::drawIrisImageOnFrame(QImage image) +{ + // 只在识别界面才显示画面 + if (ui->wgtStacked->currentIndex() == 0) { + ui->labelVideo->setPixmap(QPixmap::fromImage(image)); + } +} + + +void IdentifyForm::updateDateAndTime() +{ + ui->labelTime->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd dddd HH:mm:ss")); +} diff --git a/IdentifyForm.h b/IdentifyForm.h index fc857a1..ae1cd22 100644 --- a/IdentifyForm.h +++ b/IdentifyForm.h @@ -1,7 +1,10 @@ -#ifndef IDENTIFYFORM_H +#ifndef IDENTIFYFORM_H #define IDENTIFYFORM_H #include +#include + +#include "utils/UtilInclude.h" QT_BEGIN_NAMESPACE namespace Ui { class IdentifyForm; } @@ -15,7 +18,14 @@ IdentifyForm(QWidget *parent = nullptr); ~IdentifyForm(); +public slots: + void drawIrisImageOnFrame(QImage image); + private: Ui::IdentifyForm *ui; + +private slots: + void updateDateAndTime(); + }; #endif // IDENTIFYFORM_H diff --git a/IdentifyForm.ui b/IdentifyForm.ui index c72a36f..879dc9a 100644 --- a/IdentifyForm.ui +++ b/IdentifyForm.ui @@ -6,13 +6,59 @@ 0 0 - 800 + 600 600 IdentifyForm + + + + 0 + 40 + 600 + 450 + + + + 0 + + + + + + 100 + 10 + 400 + 300 + + + + + + + + + + + + + + 0 + 0 + 600 + 40 + + + + TextLabel + + + Qt::AlignCenter + + diff --git a/LockScreenForm.cpp b/LockScreenForm.cpp new file mode 100644 index 0000000..58dc54b --- /dev/null +++ b/LockScreenForm.cpp @@ -0,0 +1,14 @@ +#include "LockScreenForm.h" +#include "ui_LockScreenForm.h" + +LockScreenForm::LockScreenForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::LockScreenForm) +{ + ui->setupUi(this); +} + +LockScreenForm::~LockScreenForm() +{ + delete ui; +} diff --git a/LockScreenForm.h b/LockScreenForm.h new file mode 100644 index 0000000..b5ded48 --- /dev/null +++ b/LockScreenForm.h @@ -0,0 +1,25 @@ +#ifndef LOCKSCREENFORM_H +#define LOCKSCREENFORM_H + +#include +#include + +#include "utils/UtilInclude.h" + +namespace Ui { +class LockScreenForm; +} + +class LockScreenForm : public QWidget +{ + Q_OBJECT + +public: + explicit LockScreenForm(QWidget *parent = nullptr); + ~LockScreenForm(); + +private: + Ui::LockScreenForm *ui; +}; + +#endif // LOCKSCREENFORM_H diff --git a/LockScreenForm.ui b/LockScreenForm.ui new file mode 100644 index 0000000..7f2a6db --- /dev/null +++ b/LockScreenForm.ui @@ -0,0 +1,45 @@ + + + LockScreenForm + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + 180 + 100 + 54 + 12 + + + + TextLabel + + + + + + 180 + 160 + 54 + 12 + + + + TextLabel + + + + + + diff --git a/MainWindowForm.cpp b/MainWindowForm.cpp new file mode 100644 index 0000000..84f8159 --- /dev/null +++ b/MainWindowForm.cpp @@ -0,0 +1,86 @@ +#include "MainWindowForm.h" +#include "ui_MainWindowForm.h" +#include + +MainWindowForm::MainWindowForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::MainWindowForm) +{ + ui->setupUi(this); + + // 设置窗口透明和大小、位置 + this->setWindowFlags(Qt::FramelessWindowHint); + this->move(1400, 15); + this->resize(SettingConfig::getInstance().WINDOW_WIDTH, SettingConfig::getInstance().WINDOW_HEIGHT); + + // 通过调色板的颜色来设置窗口的统一背景色 + qApp->setPalette(QPalette(QColor(SettingConfig::getInstance().WINDOW_BACKGROUND_COLOR))); + + // 加载css文件设置控件样式 + QFile file(QApplication::applicationDirPath() + "/qss/main.css"); + if (file.open(QFile::ReadOnly)) + { + QString qssStr = QLatin1String(file.readAll()); + this->setStyleSheet(qssStr); + file.close(); + } + + initFormsPtr(); + + // 设置标题文字 + ui->labelTitle->setText(SettingConfig::getInstance().WINDOW_TITLE); + ui->labelCopyright->setText(SettingConfig::getInstance().WINDOW_RIGHTS); + ui->labelVersion->setText(SettingConfig::getInstance().WINDOW_VERSION); + + // 初始化虹膜相机控制 + ProMemory::getInstance().irisCam = new IrisCameraController(this); + ProMemory::getInstance().irisCam->initIrisCamera(); + ProMemory::getInstance().irisCam->openIrisCamera(); + connect(ProMemory::getInstance().irisCam->irisCamHandler, &IrisCameraCapEventHandler::sendIrisFrameToDraw, identifyForm, &IdentifyForm::drawIrisImageOnFrame); + +// LOG_INFO(QString("应用程序启动成功[Application Startup Success]").toStdString()); + qDebug() << "应用程序启动成功[Application Startup Success]"; + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::IDENTIFY_FORM; + ui->wdgtStatced->setCurrentWidget(identifyForm); + + // 开始虹膜相机拍图 + ProMemory::getInstance().irisCam->startCapture(); +} + +MainWindowForm::~MainWindowForm() +{ + delete ui; +} + +void MainWindowForm::lockScreen() +{ + ui->wdgtStatced->setCurrentWidget(lockScreenForm); + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::LOCKSCREEN_FORM; + ProMemory::getInstance().appState = AppConstants::ApplicationState::STATE_WAIT; +} + +void MainWindowForm::keyPressEvent(QKeyEvent *event) +{ + switch (event->key()) { + case Qt::Key_Escape: + QTimer::singleShot(100, qApp, [=](){ + QApplication::quit(); + }); + + default: + QWidget::keyPressEvent(event); + } +} + +void MainWindowForm::initFormsPtr() +{ + // 初始化各个form + lockScreenForm = new LockScreenForm(this); + identifyForm = new IdentifyForm(this); + + // 将form添加到statcked widget中 + ui->wdgtStatced->addWidget(identifyForm); + ui->wdgtStatced->addWidget(lockScreenForm); + + // 绑定按钮函数 +} diff --git a/MainWindowForm.h b/MainWindowForm.h new file mode 100644 index 0000000..7fb2d89 --- /dev/null +++ b/MainWindowForm.h @@ -0,0 +1,38 @@ +#ifndef MAINWINDOWFORM_H +#define MAINWINDOWFORM_H + +#include +#include +#include + +#include "utils/UtilInclude.h" +#include "ProMemory.h" +#include "LockScreenForm.h" +#include "IdentifyForm.h" + +namespace Ui { +class MainWindowForm; +} + +class MainWindowForm : public QWidget +{ + Q_OBJECT + +public: + explicit MainWindowForm(QWidget *parent = nullptr); + ~MainWindowForm(); + +public slots: + void lockScreen(); + +private: + Ui::MainWindowForm *ui; + LockScreenForm * lockScreenForm; + IdentifyForm * identifyForm; + + void keyPressEvent(QKeyEvent *event); + + void initFormsPtr(); +}; + +#endif // MAINWINDOWFORM_H diff --git a/MainWindowForm.ui b/MainWindowForm.ui new file mode 100644 index 0000000..e793ebf --- /dev/null +++ b/MainWindowForm.ui @@ -0,0 +1,85 @@ + + + MainWindowForm + + + + 0 + 0 + 600 + 1024 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + 0 + 0 + 600 + 84 + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + + + + TextLabel + + + Qt::AlignBottom|Qt::AlignHCenter + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + diff --git a/ProMemory.cpp b/ProMemory.cpp new file mode 100644 index 0000000..19e7403 --- /dev/null +++ b/ProMemory.cpp @@ -0,0 +1,84 @@ +#include "ProMemory.h" + +ProMemory::ProMemory() +{ + +} + +ProMemory::~ProMemory() +{ + +} + +/* +void ProMemory::pushCasicIris(CasicIrisInfo irisInfo) +{ + QMutex mutex; + mutex.lock(); + if (this->irisQueue.size() > 30) + { + QStack empty; + std::swap(empty, irisQueue); + } + + irisQueue.push(irisInfo); + mutex.unlock(); +} +CasicIrisInfo ProMemory::popCasicIris() +{ + CasicIrisInfo result; + + QMutex mutex; + mutex.lock(); + if (this->irisQueue.size() > 0) + { + result = irisQueue.pop(); + } + + mutex.unlock(); + + return result; +} +*/ +int ProMemory::getIrisQueueSize() +{ + int size = 0; + + QMutex mutex; + mutex.lock(); + +// size = this->irisQueue.size(); + + mutex.unlock(); + + return size; +} +bool ProMemory::isIrisQueueEmpty() +{ + bool empty = true; + + QMutex mutex; + mutex.lock(); + +// empty = this->irisQueue.isEmpty(); + + mutex.unlock(); + + return empty; +} +void ProMemory::clearIrisQueue() +{ + QMutex mutex; + mutex.lock(); + +// QStack empty; +// std::swap(empty, irisQueue); + + mutex.unlock(); +} + + +void ProMemory::initIrisFeatures(QString personId) +{ +// irisRegistPro->sendDataToExract(QByteArray(QString("[-u]").append(personId).toLocal8Bit())); +} diff --git a/ProMemory.h b/ProMemory.h new file mode 100644 index 0000000..2ecd653 --- /dev/null +++ b/ProMemory.h @@ -0,0 +1,52 @@ +#ifndef PROMEMORY_H +#define PROMEMORY_H + +#include +#include + +#include "AppConstants.h" +//#include "casic/iris/CasicIrisInfo.h" +#include "dao/IrisDataDao.h" + +#include "device/IrisCameraController.h" +//#include "device/iris/IrisRegistProcess.h" +//#include "device/iris/IrisRecogProcess.h" + +class IrisCameraController; +class IrisRegistProcess; +class IrisRecogProcess; + +class ProMemory +{ +public: + ~ProMemory(); + ProMemory(const ProMemory&)=delete; + ProMemory& operator=(const ProMemory&)=delete; + + static ProMemory& getInstance() { + static ProMemory instance; + return instance; + } + +// void pushCasicIris(CasicIrisInfo irisInfo); +// CasicIrisInfo popCasicIris(); + int getIrisQueueSize(); + bool isIrisQueueEmpty(); + void clearIrisQueue(); + + volatile int widgeFrame = 0; // 当前显示的界面 + volatile int appState = 0; // 当前程序所处的状态 + + void initIrisFeatures(QString personId = ""); // 初始化虹膜特征值集合 + + IrisCameraController * irisCam; + IrisRecogProcess * irisRecogPro; + +private: + ProMemory(); + +// QStack irisQueue; // 虹膜信息队列 + QVector irisFeatures; // 虹膜特征值集合 +}; + +#endif // PROMEMORY_H diff --git a/conf/config.ini b/conf/config.ini new file mode 100644 index 0000000..66e46ad --- /dev/null +++ b/conf/config.ini @@ -0,0 +1,67 @@ +[recognize] +#最大允许识别时间(ms) +maxMatchTime=10000 +#识别成功界面停留时间(ms) +successTipsLast=5000 +#识别失败界面停留时间(ms) +failureTipsLast=3000 +#人脸识别最大尝试次数 +maxFaceTryCount=20 +#持续没找到人脸的最大次数 +maxFaceNotFoundCount=500 +#注册时最小人脸 +minFaceRegist=240 +#识别时最小人脸 +minFaceRecog=100 + +#虹膜识别最大尝试次数 +maxIrisTryCount=10 +#虹膜识别持续没有找到眼的最大次数 +maxEyeNotFoundCount=50 + +#识别方式[1=人脸;2=虹膜;3=双认证;4=任意] +recogType=4 + +[window] +#界面窗口宽(px) +width=600 +#界面窗口高(px) +height=1024 +#统一背景色 +backgroundColor="#FFFFFF" +#标题 +title="虹膜识别终端" + +[work] +#工作状态检测时最小人脸范围 +minFaceSize=160 +#人脸范围最小横坐标 +minFacePosX=320 +#人脸范围最大横坐标 +maxFacePosX=960 +#人脸范围最小纵坐标 +minFacePosY=180 +#人脸范围最大纵坐标 +maxFacePosY=540 +#人脸太近阈值 +faceCloseSize=360 +#人脸太远阈值 +faceFarSize=480 + +[camera] +#虹膜相机取一幅画面的时间间隔(ms) +irisFrameInterval=100 +#虹膜相机拍摄宽度 +irisFrameWidth=1440 +#虹膜相机拍摄高度 +irisFrameHeight=1080 +#虹膜图像高度 +irisWidth=640 +#虹膜图像高度 +irisHeight=480 + +[log] +#日志文件位置 +logFile="d://irisLogs//casic_log.txt" +#日志级别 +logLevel="trace" diff --git a/dao/BaseDao.cpp b/dao/BaseDao.cpp new file mode 100644 index 0000000..f51c144 --- /dev/null +++ b/dao/BaseDao.cpp @@ -0,0 +1,12 @@ +#include "BaseDao.h" +#include "dao/util/ConnectionManager.h" + +BaseDao::BaseDao(QObject *parent) : QObject(parent) +{ + +} + +BaseDao::~BaseDao() +{ + +} diff --git a/dao/BaseDao.h b/dao/BaseDao.h new file mode 100644 index 0000000..1693c88 --- /dev/null +++ b/dao/BaseDao.h @@ -0,0 +1,32 @@ +#ifndef BASEDAO_H +#define BASEDAO_H + +#include +#include +#include +#include + +#include "dao/util/ConnectionManager.h" +#include "utils/UtilInclude.h" + +class BaseDao : public QObject +{ + Q_OBJECT +public: + explicit BaseDao(QObject *parent = nullptr); + ~BaseDao(); + + virtual QVector findAllRecord() = 0; + virtual QVariantMap findRecordById(QString id) = 0; + + virtual QString save(QVariantMap object) = 0; + virtual bool edit(QVariantMap newObject, QString id) = 0; + virtual bool dele(QString id) = 0; + +private: + +signals: + +}; + +#endif // BASEDAO_H diff --git a/dao/IrisDataDao.cpp b/dao/IrisDataDao.cpp new file mode 100644 index 0000000..37a0ed6 --- /dev/null +++ b/dao/IrisDataDao.cpp @@ -0,0 +1,204 @@ +#include "IrisDataDao.h" + +IrisDataDao::IrisDataDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector IrisDataDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM IRIS_DATA"; + query.prepare(sql); + + // 执行查询 + query.exec(); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + item.insert("id", query.value("id").toString()); + item.insert("person_id", query.value("person_id").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("left_iris_code1", query.value("left_iris_code1")); + item.insert("left_iris_code2", query.value("left_iris_code2")); + item.insert("left_iris_code3", query.value("left_iris_code3")); + item.insert("right_iris_code1", query.value("right_iris_code1")); + item.insert("right_iris_code2", query.value("right_iris_code2")); + item.insert("right_iris_code3", query.value("right_iris_code3")); + + result.append(item); + } + +// LOG_DEBUG(QString("查询IRIS_DATA表的所有记录[结果数:%1]").arg(result.size()).toStdString()); + return result; +} + +QVariantMap IrisDataDao::findRecordById(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM IRIS_DATA WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + // 获取结果 + if (query.next()) + { + result.insert("id", query.value("id").toString()); + result.insert("person_id", query.value("person_id").toLongLong()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("left_iris_code1", query.value("left_iris_code1")); + result.insert("left_iris_code2", query.value("left_iris_code2")); + result.insert("left_iris_code3", query.value("left_iris_code3")); + result.insert("right_iris_code1", query.value("right_iris_code1")); + result.insert("right_iris_code2", query.value("right_iris_code2")); + result.insert("right_iris_code3", query.value("right_iris_code3")); + } + +// LOG_DEBUG(QString("根据id查询IRIS_DATA表的记录[id=%1]").arg(id).toStdString()); + return result; +} + +QVariantMap IrisDataDao::findRecordByPersonId(QString personId) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM IRIS_DATA WHERE PERSON_ID = :personId"); + query.prepare(sql); + query.bindValue(":personId", personId); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + if (query.next()) + { + result.insert("id", query.value("id").toString()); + result.insert("person_id", query.value("person_id").toLongLong()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("left_iris_code1", query.value("left_iris_code1")); + result.insert("left_iris_code2", query.value("left_iris_code2")); + result.insert("left_iris_code3", query.value("left_iris_code3")); + result.insert("right_iris_code1", query.value("right_iris_code1")); + result.insert("right_iris_code2", query.value("right_iris_code2")); + result.insert("right_iris_code3", query.value("right_iris_code3")); + } + +// LOG_DEBUG(QString("根据personId查询IRIS_DATA表的记录[personId=%1]").arg(personId).toStdString()); + return result; +} + + +QString IrisDataDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + + // INSERT语句 + QString sql = QString("INSERT INTO IRIS_DATA (ID, PERSON_ID, ID_CARD_NO, LEFT_IRIS_CODE1, RIGHT_IRIS_CODE1) VALUES (:id, :personId, :idCardNo, :left1, :right1)"); + + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":personId", object.value("person_id").toString()); + query.bindValue(":idCardNo", object.value("id_card_no").toString()); + query.bindValue(":left1", object.value("left_iris_code1")); + query.bindValue(":right1", object.value("right_iris_code1")); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(); + +// LOG_DEBUG(QString("保存虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool IrisDataDao::edit(QVariantMap newObject, QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // UPDATE语句 + if (!newObject.contains("left_iris_code1") || !newObject.contains("right_iris_code1")){ + return false; + } + QString sql = QString("UPDATE IRIS_DATA SET LEFT_IRIS_CODE1 = :left1, RIGHT_IRIS_CODE1 = :right1 WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":left1", newObject.value("left_iris_code1")); + query.bindValue(":right1", newObject.value("right_iris_code1")); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(); + +// LOG_DEBUG(QString("编辑虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; +} + + +bool IrisDataDao::dele(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + QString sql = QString("DELETE FROM IRIS_DATA WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(); + +// LOG_DEBUG(QString("删除虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; +} diff --git a/dao/IrisDataDao.h b/dao/IrisDataDao.h new file mode 100644 index 0000000..c74dbbd --- /dev/null +++ b/dao/IrisDataDao.h @@ -0,0 +1,25 @@ +#ifndef IRISDATADAO_H +#define IRISDATADAO_H + +#include +#include "BaseDao.h" + +class IrisDataDao : public BaseDao +{ + Q_OBJECT +public: + explicit IrisDataDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + QVariantMap findRecordByPersonId(QString personId); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +signals: + +}; + +#endif // IRISDATADAO_H diff --git a/dao/RecognitionRecordsDao.cpp b/dao/RecognitionRecordsDao.cpp new file mode 100644 index 0000000..40db453 --- /dev/null +++ b/dao/RecognitionRecordsDao.cpp @@ -0,0 +1,100 @@ +#include "RecognitionRecordsDao.h" + +RecognitionRecordsDao::RecognitionRecordsDao(QObject *parent) : BaseDao(parent) +{ + +} + + +QVector RecognitionRecordsDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM RECOGNITION_RECORDS"; + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + item.insert("id", query.value("id").toLongLong()); + result.append(item); + } + +// LOG_DEBUG(QString("查询RECOGNITION_RECORDS表的所有记录[记录数:%1]").arg(result.size()).toStdString()); + return result; +} + +QVariantMap RecognitionRecordsDao::findRecordById(QString id) +{ + QVariantMap item; + return item; +} + +QString RecognitionRecordsDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + + // INSERT语句 + QString sql = QString("INSERT INTO RECOGNITION_RECORDS (ID, PERSON_ID, DATETIME, REC_TYPE, DEV_CODE, DOOR_CODE, INOUT_TYPE) " + "VALUES (:id, :personId, :datetime, :recType, :devCode, :doorCode, :inoutType)"); + + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":personId", object.value("person_id").toString()); + query.bindValue(":datetime", object.value("date_time").toString()); + query.bindValue(":recType", object.value("rec_type").toString()); + query.bindValue(":devCode", object.value("dev_code").toString()); + query.bindValue(":doorCode", object.value("door_code").toString()); + query.bindValue(":inoutType", object.value("inout_type").toString()); + +// LOG_DEBUG(sql.toStdString()); + + // 插入识别的log日志 + QString logStr = QString("INSERT INTO RECOGNITION_LOGS (ID, LOG_INFO) VALUES (:id, :logInfo)"); + + QSqlQuery logQuery(ConnectionManager::getInstance()->getConnection()); + logQuery.prepare(logStr); + logQuery.bindValue(":id", id); + logQuery.bindValue(":logInfo", object.value("debug_info").toString()); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(); + logQuery.exec(); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool RecognitionRecordsDao::edit(QVariantMap newObject, QString id) +{ + return false; +} + +bool RecognitionRecordsDao::dele(QString id) +{ + return false; +} diff --git a/dao/RecognitionRecordsDao.h b/dao/RecognitionRecordsDao.h new file mode 100644 index 0000000..38de7c9 --- /dev/null +++ b/dao/RecognitionRecordsDao.h @@ -0,0 +1,23 @@ +#ifndef RECOGNITIONRECORDSDAO_H +#define RECOGNITIONRECORDSDAO_H + +#include +#include "BaseDao.h" +class RecognitionRecordsDao: public BaseDao +{ + Q_OBJECT +public: + explicit RecognitionRecordsDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +signals: + +}; + +#endif // RECOGNITIONRECORDSDAO_H diff --git a/dao/SysDeptDao.cpp b/dao/SysDeptDao.cpp new file mode 100644 index 0000000..22f9946 --- /dev/null +++ b/dao/SysDeptDao.cpp @@ -0,0 +1,88 @@ +#include "SysDeptDao.h" + +SysDeptDao::SysDeptDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector SysDeptDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_DEPT WHERE PID != '-1' ORDER BY PID, NUM"; + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + item.insert("id", query.value("id").toString()); + item.insert("pid", query.value("pid").toString()); + item.insert("pids", query.value("pids").toString()); + item.insert("simplename", query.value("simplename").toString()); + item.insert("fullname", query.value("fullname").toString()); + } + +// LOG_TRACE(QString("查询表[SYS_DEPT]的所有记录[%1][%2]").arg(result.size()).arg(sql).toStdString()); + + return result; +} + +QVariantMap SysDeptDao::findRecordById(QString id) +{ + QVariantMap item; + return item; + + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM SYS_DEPT WHERE SYS_DEPT.ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + // 获取结果集的大小 + query.last(); + int count = query.at() + 1; + + if (count >=1) + { + query.first(); + + result.insert("id", query.value("id").toString()); + result.insert("pid", query.value("pid").toString()); + result.insert("pids", query.value("pids").toString()); + result.insert("simplename", query.value("simplename").toString()); + result.insert("fullname", query.value("fullname").toString()); + } + +// LOG_TRACE(QString("根据id查询SYS_DEPT表的记录[ID=%1][%2]").arg(id).arg(sql).toStdString()); + + return result; +} + + +QString SysDeptDao::save(QVariantMap object) +{ + return "0"; +} +bool SysDeptDao::edit(QVariantMap newObject, QString id) +{ + return true; +} +bool SysDeptDao::dele(QString id) +{ + return true; +} diff --git a/dao/SysDeptDao.h b/dao/SysDeptDao.h new file mode 100644 index 0000000..e07a09f --- /dev/null +++ b/dao/SysDeptDao.h @@ -0,0 +1,24 @@ +#ifndef SYSDEPTDAO_H +#define SYSDEPTDAO_H + +#include +#include "BaseDao.h" + +class SysDeptDao : public BaseDao +{ + Q_OBJECT +public: + explicit SysDeptDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +private: + +}; + +#endif // SYSDEPTDAO_H diff --git a/dao/SysPersonDao.cpp b/dao/SysPersonDao.cpp new file mode 100644 index 0000000..dd9480f --- /dev/null +++ b/dao/SysPersonDao.cpp @@ -0,0 +1,371 @@ +#include "SysPersonDao.h" + + +SysPersonDao::SysPersonDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector SysPersonDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0'"; + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + count++; + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + result.append(item); + } + +// LOG(TRACE) << QString("查询SYS_PERSON表的所有记录[%1]").arg(count).toStdString(); +// LOG_TRACE(QString("查询SYS_PERSON表的所有记录[%1]").arg(count).toStdString()); + + return result; +} + +QVariantMap SysPersonDao::findRecordById(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0' AND SYS_PERSON.ID = '%1'").arg(id); + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVariantMap result; + + // 获取结果集的大小 + query.last(); + int count = query.at() + 1; + + if (count >=1) + { + query.first(); + + result.insert("id", query.value("id").toString()); + result.insert("delflag", query.value("delflag").toString()); + result.insert("createtime", query.value("createtime").toString()); + result.insert("updatetime", query.value("updatetime").toString()); + result.insert("name", query.value("name").toString()); + result.insert("gender", query.value("gender").toString()); + result.insert("deptid", query.value("deptid").toString()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("remarks", query.value("remarks").toString()); + result.insert("person_code", query.value("person_code").toString()); + result.insert("deptname", query.value("fullname").toString()); + result.insert("sync_id", query.value("sync_id").toString()); + result.insert("hasFace", query.value("face_valid").toString()); + result.insert("hasIris", query.value("iris_valid").toString()); + } + +// LOG(TRACE) << QString("根据id查询SYS_PERSON表的记录[id=%1][%2]").arg(id).arg(sql).toStdString(); +// LOG_TRACE(QString("根据id查询SYS_PERSON表的记录[id=%1][%2]").arg(id).arg(sql).toStdString()); + + return result; +} + +int SysPersonDao::findRecordCountByNameAndDept(QString name, QString dept) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT COUNT(P.ID) AS RECCT FROM SYS_PERSON P LEFT JOIN SYS_DEPT D ON P.DEPTID = D.ID WHERE P.DELFLAG = '0'"; + if (name.isEmpty() == false) + { + sql += " AND P.NAME LIKE '%" + name + "%'"; + } + if (dept.isEmpty() == false && dept.indexOf("-1") < 0) + { + sql += QString(" AND ((P.DEPTID = '%1') OR (D.PIDS LIKE '%,%1,%'))").arg(dept); + } + + // 执行查询 + query.exec(sql); + + // 返回结果 + int result; + + // 遍历查询结果 + if (query.next()) { + result = query.value("RECCT").toInt(); + } + +// LOG(TRACE) << QString("根据姓名和部门查询SYS_PERSON记录总数[%1][%2]").arg(result).arg(sql).toStdString(); +// LOG_TRACE(QString("根据姓名和部门查询SYS_PERSON记录总数[%1][%2]").arg(result).arg(sql).toStdString()); + + return result; +} + +QVector SysPersonDao::findRecordsByNameAndDept(QString name, QString dept, qint8 limit, qint16 offset) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON P LEFT JOIN SYS_DEPT D ON P.DEPTID = D.ID WHERE P.DELFLAG = '0'"; + if (name.isEmpty() == false) + { + sql += " AND P.NAME LIKE '%" + name + "%'"; + } + if (dept.isEmpty() == false && dept.indexOf("-1") < 0) + { + sql += QString(" AND ((P.DEPTID = '%1') OR (D.PIDS LIKE '%,%1,%'))").arg(dept); + } + + sql += QString(" LIMIT %1 OFFSET %2").arg(limit).arg(offset); + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + count++; + + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + + result.append(item); + } + +// LOG(TRACE) << QString("根据姓名和部门分页查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString(); +// LOG_TRACE(QString("根据姓名和部门分页查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString()); + + return result; +} + +QVector SysPersonDao::findRecordsByProperties(QVariantMap conditions) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0'"; + QVariantMap::iterator it; + for (it = conditions.begin(); it != conditions.end(); it++) + { + sql += QString(" AND SYS_PERSON.%1 = %2").arg(it.key()).arg(it.value().toString()); + } + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + count++; + + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + + result.append(item); + } + +// LOG(TRACE) << QString("根据属性值查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString(); +// LOG_TRACE(QString("根据属性值查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString()); + + return result; +} + +QString SysPersonDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + + // INSERT语句 + QString sql = QString("INSERT INTO SYS_PERSON " + "(ID, DELFLAG, CREATETIME, UPDATETIME, " + "NAME, GENDER, DEPTID, ID_CARD_NO, " + "REMARKS, PERSON_CODE, SYNC_ID, FACE_VALID, IRIS_VALID) " + "VALUES ('%1', '0', '%2', '%2', '%3', '%4', '%5', '%6', '%7', '%8', '%9', 0, 0)") + .arg(id).arg(tm) + .arg(object.value("name").toString()) + .arg(object.value("gender").toString()) + .arg(object.value("deptid").toString()) + .arg(object.value("id_card_no").toString()) + .arg(object.value("remarks").toString()) + .arg(object.value("person_code").toString()) + .arg(object.value("sync_id").toString()); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(sql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { +// LOG(DEBUG) << QString("保存SYS_PERSON记录成功[ID = %1][%2]").arg(id).arg(sql).toStdString(); +// LOG_DEBUG(QString("保存SYS_PERSON记录成功[ID = %1][%2]").arg(id).arg(sql).toStdString()); + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool SysPersonDao::edit(QVariantMap newObject, QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + + // UPDATE语句 + QString sql = QString("UPDATE SYS_PERSON SET UPDATETIME = '%1'").arg(tm); + if (newObject.contains("name")) + { + sql.append(QString(", NAME = '%1'").arg(newObject.value("name").toString())); + } + if (newObject.contains("gender")) + { + sql.append(QString(", GENDER = '%1'").arg(newObject.value("gender").toString())); + } + if (newObject.contains("deptid")) + { + sql.append(QString(", DEPTID = '%1'").arg(newObject.value("deptid").toString())); + } + if (newObject.contains("person_code")) + { + sql.append(QString(", PERSON_CODE = '%1'").arg(newObject.value("person_code").toString())); + } + if (newObject.contains("face_valid")) + { + sql.append(QString(", FACE_VALID = '%1'").arg(newObject.value("face_valid").toString())); + } + if (newObject.contains("iris_valid")) + { + sql.append(QString(", IRIS_VALID = '%1'").arg(newObject.value("iris_valid").toString())); + } + + sql.append(QString(" WHERE ID = '%1'").arg(id)); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(sql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + +// LOG(DEBUG) << QString("编辑人员[ID=%1][%2]").arg(id).arg(sql).toStdString(); +// LOG_DEBUG(QString("编辑人员[ID=%1][%2]").arg(id).arg(sql).toStdString()); + + // 返回结果 + return success; +} + +bool SysPersonDao::dele(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + QSqlQuery irisDel(ConnectionManager::getInstance()->getConnection()); + + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + qint64 tmms = QDateTime::currentDateTime().toMSecsSinceEpoch(); + + // UPDATE语句 + QString sql = QString("UPDATE SYS_PERSON SET UPDATETIME = :updateTime, DELFLAG = :flag WHERE ID = :id").arg(tm).arg(tmms).arg(id); + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":updateTime", tm); + query.bindValue(":flag", tmms); + + // 物理删除人员的人脸和虹膜数据 + QString delIrisSql = QString("DELETE FROM IRIS_DATA WHERE PERSON_ID = :personId"); + irisDel.prepare(delIrisSql); + irisDel.bindValue(":personId", id); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(sql); + query.exec(delIrisSql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + +// LOG_DEBUG(QString("删除人员SYS_PERSON[ID=%1][%2]").arg(id).arg(success).toStdString()); + + // 返回结果 + return success; +} diff --git a/dao/SysPersonDao.h b/dao/SysPersonDao.h new file mode 100644 index 0000000..e02e5ba --- /dev/null +++ b/dao/SysPersonDao.h @@ -0,0 +1,27 @@ +#ifndef SYSPERSONDAO_H +#define SYSPERSONDAO_H + +#include +#include "BaseDao.h" + +class SysPersonDao : public BaseDao +{ + Q_OBJECT +public: + explicit SysPersonDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + int findRecordCountByNameAndDept(QString name, QString dept); + QVector findRecordsByNameAndDept(QString name, QString dept, qint8 limit, qint16 offset); + QVector findRecordsByProperties(QVariantMap conditions); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); +signals: + +}; + +#endif // SYSPERSONDAO_H diff --git a/dao/dao.pri b/dao/dao.pri new file mode 100644 index 0000000..1e04ce4 --- /dev/null +++ b/dao/dao.pri @@ -0,0 +1,18 @@ + +HEADERS += $$PWD/BaseDao.h +HEADERS += $$PWD/IrisDataDao.h +HEADERS += $$PWD/RecognitionRecordsDao.h +HEADERS += $$PWD/SysPersonDao.h +HEADERS += $$PWD/SysDeptDao.h + +SOURCES += $$PWD/BaseDao.cpp +SOURCES += $$PWD/IrisDataDao.cpp +SOURCES += $$PWD/RecognitionRecordsDao.cpp +SOURCES += $$PWD/SysPersonDao.cpp +SOURCES += $$PWD/SysDeptDao.cpp + +HEADERS += $$PWD/util/ConnectionManager.h +SOURCES += $$PWD/util/ConnectionManager.cpp +#HEADERS += $$PWD/util/CacheManager.h +#SOURCES += $$PWD/util/CacheManager.cpp + diff --git a/dao/util/ConnectionManager.cpp b/dao/util/ConnectionManager.cpp new file mode 100644 index 0000000..84b17be --- /dev/null +++ b/dao/util/ConnectionManager.cpp @@ -0,0 +1,47 @@ +#include "ConnectionManager.h" +#include + +Q_GLOBAL_STATIC(ConnectionManager, cm) + +ConnectionManager::ConnectionManager(QObject *parent) : QObject(parent) +{ + // 初始化数据库连接 + if (QSqlDatabase::contains("qt_sql_dafault_connection")) + { + conn = QSqlDatabase::database("qt_sql_default_connection"); + } + else + { + conn = QSqlDatabase::addDatabase("QSQLITE"); + conn.setDatabaseName(QApplication::applicationDirPath() + "/data/casic.db"); + + bool succ = conn.open(); + if (succ == true) + { +// LOG_INFO(QString("打开数据库操作正常[Open Database Success]").toStdString()); + } else + { +// LOG_ERROR(QString("打开数据库操作失败[Open Database Failed]").toStdString()); + } + } +} + +ConnectionManager::~ConnectionManager() +{ + conn.close(); +} + +ConnectionManager* ConnectionManager::getInstance() +{ + return cm; +} + +QSqlDatabase ConnectionManager::getConnection() +{ + return this->conn; +} + +qint64 ConnectionManager::generateId() +{ + return this->idWorker.nextId(); +} diff --git a/dao/util/ConnectionManager.h b/dao/util/ConnectionManager.h new file mode 100644 index 0000000..84647e3 --- /dev/null +++ b/dao/util/ConnectionManager.h @@ -0,0 +1,34 @@ +#ifndef CONNECTIONMANAGER_H +#define CONNECTIONMANAGER_H + +#include +#include +#include "utils/id/IdWorker.h" +#include "utils/UtilInclude.h" + +using namespace Jiawa::Core; + +class ConnectionManager : public QObject +{ + Q_OBJECT +public: + explicit ConnectionManager(QObject *parent = nullptr); + ~ConnectionManager(); + + static ConnectionManager * getInstance(); + + QSqlDatabase getConnection(); + qint64 generateId(); + +private: + // 数据库连接 + QSqlDatabase conn; + + // 雪花id生成工具 + IdWorker &idWorker = Singleton::instance(); + +signals: + +}; + +#endif // CONNECTIONMANAGER_H diff --git a/device/IrisCameraCapEventHandler.cpp b/device/IrisCameraCapEventHandler.cpp new file mode 100644 index 0000000..45df089 --- /dev/null +++ b/device/IrisCameraCapEventHandler.cpp @@ -0,0 +1,103 @@ +#include "IrisCameraCapEventHandler.h" + +IrisCameraCapEventHandler::IrisCameraCapEventHandler(QObject *parent) : QObject(parent) +{ + +} + +void IrisCameraCapEventHandler::DoOnImageCaptured(CImageDataPointer &objImageDataPointer, void *pUserParam) +{ + if (objImageDataPointer.IsNull() == false) + { + CGXDevicePointer* cam = (CGXDevicePointer *) pUserParam; + + auto camName = cam->getPtr()->GetDeviceInfo().GetUserID(); + int width = objImageDataPointer->GetWidth(); + int height = objImageDataPointer->GetHeight(); + size_t leftKeyIndex = camName.find("left"); + size_t rightKeyIndex = camName.find("right"); + + uchar * pBuffer = (BYTE*)objImageDataPointer->GetBuffer(); + + // 相机拍摄下的图像1440*1080, 直接用于算法判断 + QImage img = QImage(pBuffer, width, height, QImage::Format_Grayscale8); // 用于展示 +// QImage imgAlgo = img.copy(0, 0, width, height); + + // 用于显示的图像需要缩小到400 * 300的尺寸 + img = img.scaled(SettingConfig::getInstance().IRIS_DISPLAY_HEIGHT, SettingConfig::getInstance().IRIS_DISPLAY_WIDTH); + img = img.transformed(QTransform().rotate(-90)); // 图像逆时针旋转90度 + + // 发送到界面进行显示 + emit sendIrisFrameToDraw(img); +// cv::Mat irisMat = ImageUtil::QImageToMat(imgAlgo); + +// irisInfo.data = imgAlgo; +// irisInfo.matData = irisMat; + +// // 将图像显示在注册页面的label上 +// // 并将虹膜信息对象存入队列中 +// ProMemory::getInstance().pushCasicIris(irisInfo); + +// if (leftKeyIndex >= 0 && leftKeyIndex < 32) +// { +// emit sendIrisFrameToDraw(img, 0); // 左眼画面 +// } else if (rightKeyIndex >= 0 && rightKeyIndex < 32) +// { +// emit sendIrisFrameToDraw(img, 1); // 右眼画面 +// } +/* + if (pBuffer != NULL) + { + // 创建虹膜信息对象 + CasicIrisInfo irisInfo; + irisInfo.hasEye = false; + if (leftKeyIndex >= 0 && leftKeyIndex < 32) + { + // 左眼相机拍摄的图像 + irisInfo.leftOrRight = "left"; + } else if (rightKeyIndex >= 0 && rightKeyIndex < 32) + { + // 右眼相机 + irisInfo.leftOrRight = "right"; + } + + if (ProMemory::getInstance().widgeFrame == CasicBioRecConst::RECOGNIZE_RESULT_FORM) + { + // 相机拍摄下的图像1280*960, 直接用于算法判断 + QImage imgDisp = QImage(pBuffer, width, height, QImage::Format_Grayscale8); + cv::Mat irisMat = ImageUtil::QImageToMat(imgDisp); + + irisInfo.data = imgDisp; + irisInfo.matData = irisMat; + + ProMemory::getInstance().pushCasicIris(irisInfo); + +// cv::imwrite(QString("D:\\irisLogs\\iristest-%1.bmp").arg(irisInfo.leftOrRight).toStdString(), irisMat); + } else if (ProMemory::getInstance().widgeFrame == CasicBioRecConst::ADD_PERSON_CAPTURE_IRIS) + { + // 相机拍摄下的图像1280*960, 直接用于算法判断 + QImage img = QImage(pBuffer, width, height, QImage::Format_Grayscale8); + QImage imgAlgo = img.copy(0, 0, width, height); + + // 用于显示的图像需要缩小到1/4的尺寸 + img = img.scaled(640, 480); + cv::Mat irisMat = ImageUtil::QImageToMat(imgAlgo); + + irisInfo.data = imgAlgo; + irisInfo.matData = irisMat; + + // 将图像显示在注册页面的label上 + // 并将虹膜信息对象存入队列中 + ProMemory::getInstance().pushCasicIris(irisInfo); + + if (leftKeyIndex >= 0 && leftKeyIndex < 32) + { + emit sendIrisFrameToDraw(img, 0); // 左眼画面 + } else if (rightKeyIndex >= 0 && rightKeyIndex < 32) + { + emit sendIrisFrameToDraw(img, 1); // 右眼画面 + } + } + }*/ + } +} diff --git a/device/IrisCameraCapEventHandler.h b/device/IrisCameraCapEventHandler.h new file mode 100644 index 0000000..ad75a97 --- /dev/null +++ b/device/IrisCameraCapEventHandler.h @@ -0,0 +1,30 @@ +#ifndef IRISCAMERACAPEVENTHANDLER_H +#define IRISCAMERACAPEVENTHANDLER_H + +#include +#include +#include "include/opencv2/opencv.hpp" +#include "include/daheng/GalaxyIncludes.h" + +//#include "casic/iris/CasicIrisInterface.h" +#include "ProMemory.h" + +#include "utils/UtilInclude.h" + +class IrisCameraCapEventHandler : public QObject, public ICaptureEventHandler +{ + Q_OBJECT +public: + explicit IrisCameraCapEventHandler(QObject *parent = nullptr); + + void DoOnImageCaptured(CImageDataPointer &objImageDataPointer, void *pUserParam); + +private: + unsigned char* pImageBuffer; + +signals: + void sendIrisFrameToDraw(QImage irisImage); + +}; + +#endif // IRISCAMERACAPEVENTHANDLER_H diff --git a/device/IrisCameraController.cpp b/device/IrisCameraController.cpp new file mode 100644 index 0000000..0928176 --- /dev/null +++ b/device/IrisCameraController.cpp @@ -0,0 +1,110 @@ +#include "IrisCameraController.h" + +IrisCameraController::IrisCameraController(QObject *parent) : QObject(parent) +{ + this->irisCamHandler = new IrisCameraCapEventHandler(this); +} +IrisCameraController::~IrisCameraController() +{ + this->closeIrisCamera(); +} + + +void IrisCameraController::initIrisCamera() +{ + IGXFactory::GetInstance().Init(); + + //枚举设备 + IGXFactory::GetInstance().UpdateDeviceList(1000, irisCamList); + + this->OpenDevice(); +} + +void IrisCameraController::openIrisCamera() +{ + //设置Buffer处理模式 + irisStreamFeaturePtr->GetEnumFeature("StreamBufferHandlingMode")->SetValue("OldestFirst"); + + //注册回调函数 + irisStreamPtr->RegisterCaptureCallback(irisCamHandler, &irisCamPtr); + + //开启流层通道 + irisStreamPtr->StartGrab(); + + //发送开采命令 + irisFeaturePtr->GetCommandFeature("AcquisitionStart")->Execute(); + + // 启动定时器 + TimeCounterUtil::getInstance().irisCapCounter->start(SettingConfig::getInstance().IRIS_FRAME_INTERVAL); // 50ms执行一次定时器 +} + +void IrisCameraController::closeIrisCamera() +{ + +} + +void IrisCameraController::startCapture() +{ + // 获取定时器, 绑定定时函数 + connect(TimeCounterUtil::getInstance().irisCapCounter, &QTimer::timeout, this, &IrisCameraController::getOneFaceFrm); +// LOG(DEBUG) << QString("[IrisCameraController][startCapture]虹膜相机拍图").toStdString(); +// LOG_DEBUG(QString("[IrisCameraController][startCapture]虹膜相机拍图").toStdString()); + +} +void IrisCameraController::stopCapture() +{ + // 获取定时器, 绑定定时函数 + disconnect(TimeCounterUtil::getInstance().irisCapCounter, &QTimer::timeout, this, &IrisCameraController::getOneFaceFrm); +// LOG(DEBUG) << QString("[IrisCameraController][stopCapture]虹膜相机停止拍图").toStdString(); +// LOG_DEBUG(QString("[IrisCameraController][stopCapture]虹膜相机停止拍图").toStdString()); + +} + +void IrisCameraController::getOneFaceFrm() +{ + // 发送软触发命令(在触发模式开启时有效) + irisFeaturePtr->GetCommandFeature("TriggerSoftware")->Execute(); +} + +void IrisCameraController::getLeftAndRightEyeFrame() +{ + irisFeaturePtr->GetCommandFeature("TriggerSoftware")->Execute(); +} + +void IrisCameraController::OpenDevice() +{ + auto device = irisCamList.at(0); + + irisCamPtr = IGXFactory::GetInstance().OpenDeviceByUserID(device.GetUserID(), GX_ACCESS_EXCLUSIVE); + irisFeaturePtr = irisCamPtr->GetRemoteFeatureControl(); + + // 判断设备流是否大于零, 如果大于零则打开流 + int nStreamCount = irisCamPtr->GetStreamCount(); + if (nStreamCount > 0) + { + irisStreamPtr = irisCamPtr->OpenStream(0); + irisStreamFeaturePtr = irisStreamPtr->GetFeatureControl(); + } + + // 建议用户在打开网络相机之后, 根据当前网络环境设置相机的流通道包长值, + // 以提高网络相机的采集性能, 设置方法参考以下代码。 + GX_DEVICE_CLASS_LIST objDeviceClass = irisCamPtr->GetDeviceInfo().GetDeviceClass(); + if(GX_DEVICE_CLASS_GEV == objDeviceClass) + { + // 判断设备是否支持流通道数据包功能 + if(true == irisFeaturePtr->IsImplemented("GevSCPSPacketSize")) + { + // 获取当前网络环境的最优包长值 + int nPacketSize = irisStreamPtr->GetOptimalPacketSize(); + // 将最优包长值设置为当前设备的流通道包长值 + irisFeaturePtr->GetIntFeature("GevSCPSPacketSize")->SetValue(nPacketSize); + } + } + + //设置采集模式为连续采集模式 + irisFeaturePtr->GetEnumFeature("AcquisitionMode")->SetValue("Continuous"); + + //设置触发模式关 + irisFeaturePtr->GetEnumFeature("TriggerMode")->SetValue("On"); + irisFeaturePtr->GetEnumFeature("TriggerSource")->SetValue("Software"); +} diff --git a/device/IrisCameraController.h b/device/IrisCameraController.h new file mode 100644 index 0000000..5d7e269 --- /dev/null +++ b/device/IrisCameraController.h @@ -0,0 +1,49 @@ +#ifndef IRISCAMERACONTROLLER_H +#define IRISCAMERACONTROLLER_H + +#include + +#include "IrisCameraCapEventHandler.h" + +class IrisCameraCapEventHandler; + +class IrisCameraController : public QObject +{ + Q_OBJECT +public: + explicit IrisCameraController(QObject *parent = nullptr); + ~IrisCameraController(); + + // 初始化并打开人脸相机 + void initIrisCamera(); + void openIrisCamera(); + void closeIrisCamera(); + + void startCapture(); + void stopCapture(); + + void getLeftAndRightEyeFrame(); + + IrisCameraCapEventHandler * irisCamHandler; + +private: + GxIAPICPP::gxdeviceinfo_vector irisCamList; + + CGXDevicePointer irisCamPtr; ///< 设备句柄 + + CGXStreamPointer irisStreamPtr; ///< 左眼设备流 + + CGXFeatureControlPointer irisFeaturePtr; ///< 左眼属性控制器 + + CGXFeatureControlPointer irisStreamFeaturePtr; ///< 左眼流层控制器对象 + + void OpenDevice(); + +signals: + +public slots: + void getOneFaceFrm(); + +}; + +#endif // IRISCAMERACONTROLLER_H diff --git a/device/device.pri b/device/device.pri new file mode 100644 index 0000000..a8417f2 --- /dev/null +++ b/device/device.pri @@ -0,0 +1,13 @@ + +HEADERS += $$PWD/IrisCameraController.h +HEADERS += $$PWD/IrisCameraCapEventHandler.h +#HEADERS += $$PWD/iris/IrisRegistProcess.h +#HEADERS += $$PWD/iris/IrisRecogProcess.h +#HEADERS += $$PWD/iris/CasicIrisRecState.h + +SOURCES += $$PWD/IrisCameraController.cpp +SOURCES += $$PWD/IrisCameraCapEventHandler.cpp +#SOURCES += $$PWD/iris/IrisRegistProcess.cpp +#SOURCES += $$PWD/iris/IrisRecogProcess.cpp +#SOURCES += $$PWD/iris/CasicIrisRecState.cpp + diff --git a/images/bg_footer.png b/images/bg_footer.png new file mode 100644 index 0000000..a3a99ab --- /dev/null +++ b/images/bg_footer.png Binary files differ diff --git a/images/bg_statcked.png b/images/bg_statcked.png new file mode 100644 index 0000000..18b63e1 --- /dev/null +++ b/images/bg_statcked.png Binary files differ diff --git a/images/bg_title.png b/images/bg_title.png new file mode 100644 index 0000000..0316e2d --- /dev/null +++ b/images/bg_title.png Binary files differ diff --git a/main.cpp b/main.cpp index 16bc45b..9052ddb 100644 --- a/main.cpp +++ b/main.cpp @@ -1,11 +1,11 @@ -#include "IdentifyForm.h" +#include "MainWindowForm.h" #include int main(int argc, char *argv[]) { QApplication a(argc, argv); - IdentifyForm w; + MainWindowForm w; w.show(); return a.exec(); } diff --git a/resource.qrc b/resource.qrc new file mode 100644 index 0000000..474586a --- /dev/null +++ b/resource.qrc @@ -0,0 +1,35 @@ + + + images/setting.png + images/user.png + images/back.png + images/home.png + images/btnPageFirst.png + images/btnPageLast.png + images/btnPageNext.png + images/btnPagePre.png + images/regist.png + images/photoEyeLeft.png + images/photoEyeRight.png + images/photoFace.png + images/save.png + images/upArrow.png + images/downArrow.png + images/faceCaped.png + images/faceNotCap.png + images/irisCaped.png + images/irisNotCap.png + images/tipsFailure.png + images/tipsSuccess.png + images/tipsConfirm.png + images/bg_recognize_result.png + images/iconRetry.png + images/bg_title.png + images/bg_footer.png + images/bg_statcked.png + + + images/add_bottom.png + images/add_top.png + + diff --git a/utils/ImageUtil.cpp b/utils/ImageUtil.cpp new file mode 100644 index 0000000..7604572 --- /dev/null +++ b/utils/ImageUtil.cpp @@ -0,0 +1,97 @@ +#include "ImageUtil.h" + +ImageUtil::ImageUtil() +{ + +} + +QImage ImageUtil::MatImageToQImage(const cv::Mat &src) +{ + //CV_8UC1 8位无符号的单通道---灰度图片 + if(src.type() == CV_8UC1) + { + QImage qImage((const unsigned char *)(src.data), src.cols, src.rows, src.cols, QImage::Format_Grayscale8); + return qImage; + } + //为3通道的彩色图片 + else if(src.type() == CV_8UC3) + { + //得到图像的的首地址 + const uchar *pSrc = (const uchar*)src.data; + //以src构造图片 + QImage qImage(pSrc, src.cols, src.rows, src.step, QImage::Format_RGB888); + //在不改变实际图像数据的条件下, 交换红蓝通道 + return qImage.rgbSwapped(); + } + //四通道图片, 带Alpha通道的RGB彩色图像 + else if(src.type() == CV_8UC4) + { + const uchar *pSrc = (const uchar*)src.data; + QImage qImage(pSrc, src.cols, src.rows, src.step, QImage::Format_ARGB32); + //返回图像的子区域作为一个新图像 + return qImage.copy(); + } + else + { + return QImage(); + } +} +/* +QImage ImageUtil::UcharToQImage(unsigned char* data, int width, int height, QImage::Format format) +{ + QImage qImage(data, width, height, format); + //在不改变实际图像数据的条件下, 交换红蓝通道 + return qImage.rgbSwapped(); +} + +cv::Mat ImageUtil::QImageToMat(QImage image) +{ + cv::Mat mat; + switch(image.format()) + { + case QImage::Format_ARGB32: + case QImage::Format_RGB32: + case QImage::Format_ARGB32_Premultiplied: + mat = cv::Mat(image.height(), image.width(), CV_8UC4, (void*)image.constBits(), image.bytesPerLine()); + break; + case QImage::Format_RGB888: + mat = cv::Mat(image.height(), image.width(), CV_8UC3, (void*)image.constBits(), image.bytesPerLine()); + cv::cvtColor(mat, mat, cv::COLOR_BGR2RGB); + break; + case QImage::Format_Indexed8: + mat = cv::Mat(image.height(), image.width(), CV_8UC1, (void*)image.constBits(), image.bytesPerLine()); + break; + case QImage::Format_Grayscale8: + mat = cv::Mat(image.height(), image.width(), CV_8UC1, (void *)image.bits(), image.bytesPerLine()); + break; + } + + mat = mat.clone(); + + return mat; +} + +QString ImageUtil::QImageToBase64(QImage image) +{ + QByteArray ba; + QBuffer buf(&ba); + image.save(&buf, "bmp"); + QString base64String = ba.toBase64(); + return base64String; +} + +cv::Mat ImageUtil::MatImageRect(const cv::Mat &src, cv::Rect rect, int delta) +{ + cv::Mat matClone = src.clone(); + cv::Rect bigRect; + + bigRect.x = rect.x - delta < 0 ? 0 : rect.x - delta; + bigRect.y = rect.y - delta < 0 ? 0 : rect.y - delta; + bigRect.width = rect.x + rect.width + 2 * delta > src.cols ? src.cols - rect.x : rect.width + 2 * delta; + bigRect.height = rect.y + rect.height + 2 * delta > src.rows ? src.rows - rect.y : rect.height + 2 * delta; + + cv::Mat roi = matClone(bigRect); + + return roi; +} +*/ diff --git a/utils/ImageUtil.h b/utils/ImageUtil.h new file mode 100644 index 0000000..dbfdd48 --- /dev/null +++ b/utils/ImageUtil.h @@ -0,0 +1,22 @@ +#ifndef IMAGEUTIL_H +#define IMAGEUTIL_H + +#include +#include +#include "opencv2/opencv.hpp" + +class ImageUtil +{ +public: + ImageUtil(); + + static QImage MatImageToQImage(const cv::Mat &src); +// static QImage UcharToQImage(unsigned char* data, int width, int height, QImage::Format format); + +// static cv::Mat QImageToMat(QImage image); +// static QString QImageToBase64(QImage image); + +// static cv::Mat MatImageRect(const cv::Mat &src, cv::Rect rect, int delta); +}; + +#endif // IMAGEUTIL_H diff --git a/utils/SettingConfig.cpp b/utils/SettingConfig.cpp new file mode 100644 index 0000000..d420285 --- /dev/null +++ b/utils/SettingConfig.cpp @@ -0,0 +1,44 @@ +#include "SettingConfig.h" +#include + +SettingConfig::SettingConfig() +{ + filename = QApplication::applicationDirPath() + "/conf/config.ini"; + setting = new QSettings(this->filename, QSettings::IniFormat); + + WINDOW_WIDTH = getProperty("window", "width").toInt(); + WINDOW_HEIGHT = getProperty("window", "height").toInt(); + WINDOW_BACKGROUND_COLOR = getProperty("window", "backgroundColor").toString(); + WINDOW_TITLE = getProperty("window", "title").toString(); + WINDOW_RIGHTS = getProperty("window", "copyright").toString(); + WINDOW_VERSION = getProperty("window", "version").toString(); + + IRIS_FRAME_WIDTH = getProperty("camera", "irisFrameWidth").toInt(); + IRIS_FRAME_HEIGHT = getProperty("camera", "irisFrameHeight").toInt(); + IRIS_WIDTH = getProperty("camera", "irisWidth").toInt(); + IRIS_HEIGHT = getProperty("camera", "irisHeight").toInt(); + IRIS_FRAME_INTERVAL = getProperty("camera", "irisFrameInterval").toInt(); + IRIS_DISPLAY_WIDTH = getProperty("camera", "irisDisplayWidth").toInt(); + IRIS_DISPLAY_HEIGHT = getProperty("camera", "irisDisplayHeight").toInt(); + + MAX_MATCH_TIME = getProperty("recognize", "maxMatchTime").toInt(); + SUCCESS_TIPS_LAST = getProperty("recognize", "successTipsLast").toInt(); + FAILURE_TIPS_LAST = getProperty("recognize", "failureTipsLast").toInt(); + MAX_FACE_TRY_COUNT = getProperty("recognize", "maxFaceTryCount").toInt(); + MAX_FACE_NOT_FOUND_COUNT = getProperty("recognize", "maxFaceNotFoundCount").toInt(); + MAX_IRIS_TRY_COUNT = getProperty("recognize", "maxIrisTryCount").toInt(); + MAX_EYE_NOT_FOUND_COUNT = getProperty("recognize", "maxEyeNotFoundCount").toInt(); + + MAX_CAPTURE_STACK_SIZE = getProperty("stack", "capture").toInt(); + MAX_FOUND_STACK_SIZE = getProperty("stack", "found").toInt(); + MAX_QUALIFIED_STACK_SIZE = getProperty("stack", "qualified").toInt(); + + LOG_FILE = getProperty("log", "logFile").toString(); + LOG_LEVEL = getProperty("log", "logLevel").toString(); +} + + +QVariant SettingConfig::getProperty(QString nodeName, QString keyName) { + QVariant var = this->setting->value(QString("/%1/%2").arg(nodeName).arg(keyName)); + return var; +} diff --git a/utils/SettingConfig.h b/utils/SettingConfig.h new file mode 100644 index 0000000..30c3bec --- /dev/null +++ b/utils/SettingConfig.h @@ -0,0 +1,66 @@ +#ifndef SETTINGCONFIG_H +#define SETTINGCONFIG_H + +#include +#include + +class SettingConfig : public QObject +{ +public: + ~SettingConfig() {}; + SettingConfig(const SettingConfig&)=delete; + SettingConfig& operator=(const SettingConfig&)=delete; + + static SettingConfig& getInstance() { + static SettingConfig instance; + return instance; + } + + /** + * @brief get + * @param nodeName + * @param keyName + * @return QVariant + * @title + */ + QVariant getProperty(QString nodeName, QString keyName); + + /******** 以下为需要的各类参数 ********/ + int WINDOW_WIDTH; + int WINDOW_HEIGHT; + QString WINDOW_BACKGROUND_COLOR; + QString WINDOW_TITLE; + QString WINDOW_RIGHTS; + QString WINDOW_VERSION; + + int IRIS_FRAME_INTERVAL; + int IRIS_FRAME_WIDTH; + int IRIS_FRAME_HEIGHT; + int IRIS_WIDTH; + int IRIS_HEIGHT; + int IRIS_DISPLAY_WIDTH; + int IRIS_DISPLAY_HEIGHT; + + int MAX_MATCH_TIME; + int SUCCESS_TIPS_LAST; + int FAILURE_TIPS_LAST; + int MAX_FACE_TRY_COUNT; + int MAX_FACE_NOT_FOUND_COUNT; + int MAX_IRIS_TRY_COUNT; + int MAX_EYE_NOT_FOUND_COUNT; + + int MAX_CAPTURE_STACK_SIZE; + int MAX_FOUND_STACK_SIZE; + int MAX_QUALIFIED_STACK_SIZE; + + QString LOG_FILE; + QString LOG_LEVEL; + +private: + SettingConfig(); + + QString filename; + QSettings* setting; +}; + +#endif // SETTINGCONFIG_H diff --git a/utils/TimeCounterUtil.cpp b/utils/TimeCounterUtil.cpp new file mode 100644 index 0000000..275945f --- /dev/null +++ b/utils/TimeCounterUtil.cpp @@ -0,0 +1,8 @@ +#include "TimeCounterUtil.h" + +TimeCounterUtil::TimeCounterUtil() +{ + faceCapCounter = new QTimer(); + irisCapCounter = new QTimer(); + clockCounter = new QTimer(); +} diff --git a/utils/TimeCounterUtil.h b/utils/TimeCounterUtil.h new file mode 100644 index 0000000..28b29f1 --- /dev/null +++ b/utils/TimeCounterUtil.h @@ -0,0 +1,29 @@ +#ifndef TIMECOUNTERUTIL_H +#define TIMECOUNTERUTIL_H + +#include +#include + +class TimeCounterUtil : public QObject +{ +public: + + ~TimeCounterUtil() {}; + TimeCounterUtil(const TimeCounterUtil&)=delete; + TimeCounterUtil& operator=(const TimeCounterUtil&)=delete; + + static TimeCounterUtil& getInstance() { + static TimeCounterUtil instance; + return instance; + } + + QTimer * faceCapCounter; + QTimer * irisCapCounter; + QTimer * clockCounter; + +private: + TimeCounterUtil(); + +}; + +#endif // TIMECOUNTERUTIL_H diff --git a/utils/UtilInclude.h b/utils/UtilInclude.h new file mode 100644 index 0000000..e7b899a --- /dev/null +++ b/utils/UtilInclude.h @@ -0,0 +1,13 @@ +#ifndef UTILINCLUDE_H +#define UTILINCLUDE_H + +//#include "ByteUtil.h" +#include "ImageUtil.h" +//#include "LogUtil.h" +#include "SettingConfig.h" +//#include "SpeakerUtil.h" +#include "TimeCounterUtil.h" +//#include "UDPClientUtil.h" +//#include "HttpRequestUtil.h" + +#endif // UTILINCLUDE_H diff --git a/utils/id/IdWorker.h b/utils/id/IdWorker.h new file mode 100644 index 0000000..6c48aa9 --- /dev/null +++ b/utils/id/IdWorker.h @@ -0,0 +1,218 @@ +#ifndef _JW_CORE_ID_WORKER_H_ +#define _JW_CORE_ID_WORKER_H_ + +#include +#include +#include +#include +#include +#include "Noncopyable.h" +#include "Singleton.h" + +// 如果不使用 mutex, 则开启下面这个定义, 但是我发现, 还是开启 mutex 功能, 速度比较快 +// #define SNOWFLAKE_ID_WORKER_NO_LOCK + +namespace Jiawa { + + /** + * @brief 核心 + * 核心功能 + */ + namespace Core { + + /** + * @brief 分布式id生成类 + * https://segmentfault.com/a/1190000011282426 + * https://github.com/twitter/snowflake/blob/snowflake-2010/src/main/scala/com/twitter/service/snowflake/IdWorker.scala + * + * 64bit id: 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 + * || || || | | | + * |└---------------------------时间戳--------------------------┘└中心-┘└机器-┘ └----序列号----┘ + * | + * 不用 + * SnowFlake的优点: 整体上按照时间自增排序, 并且整个分布式系统内不会产生ID碰撞(由数据中心ID和机器ID作区分), 并且效率较高, 经测试, SnowFlake每秒能够产生26万ID左右. + */ + class SnowflakeIdWorker : private Noncopyable { + + // 实现单例 + friend class Singleton; + + public: + typedef unsigned int UInt; + typedef unsigned long long int UInt64; + +#ifdef SNOWFLAKE_ID_WORKER_NO_LOCK + typedef std::atomic AtomicUInt; + typedef std::atomic AtomicUInt64; +#else + typedef UInt AtomicUInt; + typedef UInt64 AtomicUInt64; +#endif + + void setWorkerId(UInt workerId) { + this->workerId = workerId; + } + + void setDatacenterId(UInt datacenterId) { + this->datacenterId = datacenterId; + } + + UInt64 getId() { + return nextId(); + } + + /** + * 获得下一个ID (该方法是线程安全的) + * + * @return SnowflakeId + */ + UInt64 nextId() { +#ifndef SNOWFLAKE_ID_WORKER_NO_LOCK + std::unique_lock lock{ mutex }; + AtomicUInt64 timestamp{ 0 }; +#else + static AtomicUInt64 timestamp{ 0 }; +#endif + timestamp = timeGen(); + + // 如果当前时间小于上一次ID生成的时间戳, 说明系统时钟回退过这个时候应当抛出异常 + if (timestamp < lastTimestamp) { + std::ostringstream s; + s << "clock moved backwards. Refusing to generate id for " << lastTimestamp - timestamp << " milliseconds"; + throw std::exception(std::runtime_error(s.str())); + } + + if (lastTimestamp == timestamp) { + // 如果是同一时间生成的, 则进行毫秒内序列 + sequence = (sequence + 1) & sequenceMask; + if (0 == sequence) { + // 毫秒内序列溢出, 阻塞到下一个毫秒,获得新的时间戳 + timestamp = tilNextMillis(lastTimestamp); + } + } else { + sequence = 0; + } + +#ifndef SNOWFLAKE_ID_WORKER_NO_LOCK + lastTimestamp = timestamp; +#else + lastTimestamp = timestamp.load(); +#endif + + // 移位并通过或运算拼到一起组成64位的ID + return ((timestamp - twepoch) << timestampLeftShift) + | (datacenterId << datacenterIdShift) + | (workerId << workerIdShift) + | sequence; + } + + protected: + SnowflakeIdWorker() : workerId(0), datacenterId(0), sequence(0), lastTimestamp(0) { } + + /** + * 返回以毫秒为单位的当前时间 + * + * @return 当前时间(毫秒) + */ + UInt64 timeGen() const { + auto t = std::chrono::time_point_cast(std::chrono::high_resolution_clock::now()); + return t.time_since_epoch().count(); + } + + /** + * 阻塞到下一个毫秒, 直到获得新的时间戳 + * + * @param lastTimestamp 上次生成ID的时间截 + * @return 当前时间戳 + */ + UInt64 tilNextMillis(UInt64 lastTimestamp) const { + UInt64 timestamp = timeGen(); + while (timestamp <= lastTimestamp) { + timestamp = timeGen(); + } + return timestamp; + } + + private: + +#ifndef SNOWFLAKE_ID_WORKER_NO_LOCK + std::mutex mutex; +#endif + + /** + * 开始时间截 (2018-01-01 00:00:00.000) + */ + const UInt64 twepoch = 1514736000000; + + /** + * 机器id所占的位数 + */ + const UInt workerIdBits = 5; + + /** + * 数据中心id所占的位数 + */ + const UInt datacenterIdBits = 5; + + /** + * 序列所占的位数 + */ + const UInt sequenceBits = 12; + + /** + * 机器ID向左移12位 + */ + const UInt workerIdShift = sequenceBits; + + /** + * 数据标识id向左移17位 + */ + const UInt datacenterIdShift = workerIdShift + workerIdBits; + + /** + * 时间截向左移22位 + */ + const UInt timestampLeftShift = datacenterIdShift + datacenterIdBits; + + /** + * 支持的最大机器id, 结果是31 + */ + const UInt maxWorkerId = -1 ^ (-1 << workerIdBits); + + /** + * 支持的最大数据中心id, 结果是31 + */ + const UInt maxDatacenterId = -1 ^ (-1 << datacenterIdBits); + + /** + * 生成序列的掩码, 这里为4095 + */ + const UInt sequenceMask = -1 ^ (-1 << sequenceBits); + + /** + * 工作机器id(0~31) + */ + UInt workerId; + + /** + * 数据中心id(0~31) + */ + UInt datacenterId; + + /** + * 毫秒内序列(0~4095) + */ + AtomicUInt sequence{ 0 }; + + /** + * 上次生成ID的时间截 + */ + AtomicUInt64 lastTimestamp{ 0 }; + + }; + + typedef SnowflakeIdWorker IdWorker; + } +} + +#endif // _JW_CORE_ID_WORKER_H_ diff --git a/AppConstants.h b/AppConstants.h new file mode 100644 index 0000000..296c53f --- /dev/null +++ b/AppConstants.h @@ -0,0 +1,28 @@ +#ifndef APPCONSTANTS_H +#define APPCONSTANTS_H + +class AppConstants +{ +public: + enum WidgeFrameName + { + MAIN_PAGE = 0, // 主页面 + PERSON_LIST_FORM = 1, // 人员列表页面 + ADD_PERSON_FORM = 2, // 添加人员页面 + ADD_PERSON_CAPTURE_FACE = 21, // 添加/编辑人员时进行人脸拍图 + ADD_PERSON_CAPTURE_IRIS = 22, // 添加/编辑人员时进行虹膜拍图 + SETTING_FORM = 3, // 设置页面 + RECOGNIZE_RESULT_FORM = 4, // 识别结果界面 + IDENTIFY_FORM = 5, // 识别界面 含识别中 和 识别结果 + LOCKSCREEN_FORM = 6 // 锁屏待机界面 + }; + + enum ApplicationState + { + STATE_WAIT = 0, // 待机 + STATE_WORKING = 1, // 工作状态 + STATE_IDENTIFYING = 2, // 识别中 + }; +}; + +#endif // APPCONSTANTS_H diff --git a/CasicIrisIdentify.pro b/CasicIrisIdentify.pro index 5d7fea6..575ce3d 100644 --- a/CasicIrisIdentify.pro +++ b/CasicIrisIdentify.pro @@ -1,4 +1,4 @@ -QT += core gui +QT += core gui sql network texttospeech greaterThan(QT_MAJOR_VERSION, 4): QT += widgets @@ -15,20 +15,46 @@ # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 -SOURCES += \ - main.cpp \ - IdentifyForm.cpp +include("dao/dao.pri") +include("device/device.pri") +include("utils/utils.pri") -HEADERS += \ - IdentifyForm.h +SOURCES += main.cpp +SOURCES += ProMemory.cpp +SOURCES += MainWindowForm.cpp +SOURCES += IdentifyForm.cpp +SOURCES += LockScreenForm.cpp -FORMS += \ - IdentifyForm.ui +HEADERS += AppConstants.h +HEADERS += ProMemory.h +HEADERS += MainWindowForm.h +HEADERS += IdentifyForm.h +HEADERS += LockScreenForm.h -TRANSLATIONS += \ - CasicIrisIdentify_zh_CN.ts +FORMS += MainWindowForm.ui +FORMS += IdentifyForm.ui +FORMS += LockScreenForm.ui + +RESOURCES += resource.qrc + +DISTFILES += conf/config.ini + +#TRANSLATIONS += CasicIrisIdentify_zh_CN.ts + +#INCLUDEPATH += include/spdlog +#DEPENDPATH += include/spdlog # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target + + +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lopencv_world420 +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lGxIAPICPPEx + +INCLUDEPATH += $$PWD/include/daheng +DEPENDPATH += $$PWD/include/daheng + +INCLUDEPATH += $$PWD/include +DEPENDPATH += $$PWD/include diff --git a/CasicIrisIdentify_zh_CN.ts b/CasicIrisIdentify_zh_CN.ts index 5526fe4..81900df 100644 --- a/CasicIrisIdentify_zh_CN.ts +++ b/CasicIrisIdentify_zh_CN.ts @@ -1,3 +1,12 @@ - + + + IdentifyForm + + + IdentifyForm + + + + diff --git a/IdentifyForm.cpp b/IdentifyForm.cpp index 348a897..ba1f251 100644 --- a/IdentifyForm.cpp +++ b/IdentifyForm.cpp @@ -1,4 +1,4 @@ -#include "IdentifyForm.h" +#include "IdentifyForm.h" #include "ui_IdentifyForm.h" IdentifyForm::IdentifyForm(QWidget *parent) @@ -6,6 +6,12 @@ , ui(new Ui::IdentifyForm) { ui->setupUi(this); + + // 初始化更新界面的定时器 + // 每秒执行一次 + connect(TimeCounterUtil::getInstance().clockCounter, &QTimer::timeout, this, &IdentifyForm::updateDateAndTime); + + TimeCounterUtil::getInstance().clockCounter->start(1000); } IdentifyForm::~IdentifyForm() @@ -13,3 +19,16 @@ delete ui; } +void IdentifyForm::drawIrisImageOnFrame(QImage image) +{ + // 只在识别界面才显示画面 + if (ui->wgtStacked->currentIndex() == 0) { + ui->labelVideo->setPixmap(QPixmap::fromImage(image)); + } +} + + +void IdentifyForm::updateDateAndTime() +{ + ui->labelTime->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd dddd HH:mm:ss")); +} diff --git a/IdentifyForm.h b/IdentifyForm.h index fc857a1..ae1cd22 100644 --- a/IdentifyForm.h +++ b/IdentifyForm.h @@ -1,7 +1,10 @@ -#ifndef IDENTIFYFORM_H +#ifndef IDENTIFYFORM_H #define IDENTIFYFORM_H #include +#include + +#include "utils/UtilInclude.h" QT_BEGIN_NAMESPACE namespace Ui { class IdentifyForm; } @@ -15,7 +18,14 @@ IdentifyForm(QWidget *parent = nullptr); ~IdentifyForm(); +public slots: + void drawIrisImageOnFrame(QImage image); + private: Ui::IdentifyForm *ui; + +private slots: + void updateDateAndTime(); + }; #endif // IDENTIFYFORM_H diff --git a/IdentifyForm.ui b/IdentifyForm.ui index c72a36f..879dc9a 100644 --- a/IdentifyForm.ui +++ b/IdentifyForm.ui @@ -6,13 +6,59 @@ 0 0 - 800 + 600 600 IdentifyForm + + + + 0 + 40 + 600 + 450 + + + + 0 + + + + + + 100 + 10 + 400 + 300 + + + + + + + + + + + + + + 0 + 0 + 600 + 40 + + + + TextLabel + + + Qt::AlignCenter + + diff --git a/LockScreenForm.cpp b/LockScreenForm.cpp new file mode 100644 index 0000000..58dc54b --- /dev/null +++ b/LockScreenForm.cpp @@ -0,0 +1,14 @@ +#include "LockScreenForm.h" +#include "ui_LockScreenForm.h" + +LockScreenForm::LockScreenForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::LockScreenForm) +{ + ui->setupUi(this); +} + +LockScreenForm::~LockScreenForm() +{ + delete ui; +} diff --git a/LockScreenForm.h b/LockScreenForm.h new file mode 100644 index 0000000..b5ded48 --- /dev/null +++ b/LockScreenForm.h @@ -0,0 +1,25 @@ +#ifndef LOCKSCREENFORM_H +#define LOCKSCREENFORM_H + +#include +#include + +#include "utils/UtilInclude.h" + +namespace Ui { +class LockScreenForm; +} + +class LockScreenForm : public QWidget +{ + Q_OBJECT + +public: + explicit LockScreenForm(QWidget *parent = nullptr); + ~LockScreenForm(); + +private: + Ui::LockScreenForm *ui; +}; + +#endif // LOCKSCREENFORM_H diff --git a/LockScreenForm.ui b/LockScreenForm.ui new file mode 100644 index 0000000..7f2a6db --- /dev/null +++ b/LockScreenForm.ui @@ -0,0 +1,45 @@ + + + LockScreenForm + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + 180 + 100 + 54 + 12 + + + + TextLabel + + + + + + 180 + 160 + 54 + 12 + + + + TextLabel + + + + + + diff --git a/MainWindowForm.cpp b/MainWindowForm.cpp new file mode 100644 index 0000000..84f8159 --- /dev/null +++ b/MainWindowForm.cpp @@ -0,0 +1,86 @@ +#include "MainWindowForm.h" +#include "ui_MainWindowForm.h" +#include + +MainWindowForm::MainWindowForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::MainWindowForm) +{ + ui->setupUi(this); + + // 设置窗口透明和大小、位置 + this->setWindowFlags(Qt::FramelessWindowHint); + this->move(1400, 15); + this->resize(SettingConfig::getInstance().WINDOW_WIDTH, SettingConfig::getInstance().WINDOW_HEIGHT); + + // 通过调色板的颜色来设置窗口的统一背景色 + qApp->setPalette(QPalette(QColor(SettingConfig::getInstance().WINDOW_BACKGROUND_COLOR))); + + // 加载css文件设置控件样式 + QFile file(QApplication::applicationDirPath() + "/qss/main.css"); + if (file.open(QFile::ReadOnly)) + { + QString qssStr = QLatin1String(file.readAll()); + this->setStyleSheet(qssStr); + file.close(); + } + + initFormsPtr(); + + // 设置标题文字 + ui->labelTitle->setText(SettingConfig::getInstance().WINDOW_TITLE); + ui->labelCopyright->setText(SettingConfig::getInstance().WINDOW_RIGHTS); + ui->labelVersion->setText(SettingConfig::getInstance().WINDOW_VERSION); + + // 初始化虹膜相机控制 + ProMemory::getInstance().irisCam = new IrisCameraController(this); + ProMemory::getInstance().irisCam->initIrisCamera(); + ProMemory::getInstance().irisCam->openIrisCamera(); + connect(ProMemory::getInstance().irisCam->irisCamHandler, &IrisCameraCapEventHandler::sendIrisFrameToDraw, identifyForm, &IdentifyForm::drawIrisImageOnFrame); + +// LOG_INFO(QString("应用程序启动成功[Application Startup Success]").toStdString()); + qDebug() << "应用程序启动成功[Application Startup Success]"; + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::IDENTIFY_FORM; + ui->wdgtStatced->setCurrentWidget(identifyForm); + + // 开始虹膜相机拍图 + ProMemory::getInstance().irisCam->startCapture(); +} + +MainWindowForm::~MainWindowForm() +{ + delete ui; +} + +void MainWindowForm::lockScreen() +{ + ui->wdgtStatced->setCurrentWidget(lockScreenForm); + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::LOCKSCREEN_FORM; + ProMemory::getInstance().appState = AppConstants::ApplicationState::STATE_WAIT; +} + +void MainWindowForm::keyPressEvent(QKeyEvent *event) +{ + switch (event->key()) { + case Qt::Key_Escape: + QTimer::singleShot(100, qApp, [=](){ + QApplication::quit(); + }); + + default: + QWidget::keyPressEvent(event); + } +} + +void MainWindowForm::initFormsPtr() +{ + // 初始化各个form + lockScreenForm = new LockScreenForm(this); + identifyForm = new IdentifyForm(this); + + // 将form添加到statcked widget中 + ui->wdgtStatced->addWidget(identifyForm); + ui->wdgtStatced->addWidget(lockScreenForm); + + // 绑定按钮函数 +} diff --git a/MainWindowForm.h b/MainWindowForm.h new file mode 100644 index 0000000..7fb2d89 --- /dev/null +++ b/MainWindowForm.h @@ -0,0 +1,38 @@ +#ifndef MAINWINDOWFORM_H +#define MAINWINDOWFORM_H + +#include +#include +#include + +#include "utils/UtilInclude.h" +#include "ProMemory.h" +#include "LockScreenForm.h" +#include "IdentifyForm.h" + +namespace Ui { +class MainWindowForm; +} + +class MainWindowForm : public QWidget +{ + Q_OBJECT + +public: + explicit MainWindowForm(QWidget *parent = nullptr); + ~MainWindowForm(); + +public slots: + void lockScreen(); + +private: + Ui::MainWindowForm *ui; + LockScreenForm * lockScreenForm; + IdentifyForm * identifyForm; + + void keyPressEvent(QKeyEvent *event); + + void initFormsPtr(); +}; + +#endif // MAINWINDOWFORM_H diff --git a/MainWindowForm.ui b/MainWindowForm.ui new file mode 100644 index 0000000..e793ebf --- /dev/null +++ b/MainWindowForm.ui @@ -0,0 +1,85 @@ + + + MainWindowForm + + + + 0 + 0 + 600 + 1024 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + 0 + 0 + 600 + 84 + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + + + + TextLabel + + + Qt::AlignBottom|Qt::AlignHCenter + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + diff --git a/ProMemory.cpp b/ProMemory.cpp new file mode 100644 index 0000000..19e7403 --- /dev/null +++ b/ProMemory.cpp @@ -0,0 +1,84 @@ +#include "ProMemory.h" + +ProMemory::ProMemory() +{ + +} + +ProMemory::~ProMemory() +{ + +} + +/* +void ProMemory::pushCasicIris(CasicIrisInfo irisInfo) +{ + QMutex mutex; + mutex.lock(); + if (this->irisQueue.size() > 30) + { + QStack empty; + std::swap(empty, irisQueue); + } + + irisQueue.push(irisInfo); + mutex.unlock(); +} +CasicIrisInfo ProMemory::popCasicIris() +{ + CasicIrisInfo result; + + QMutex mutex; + mutex.lock(); + if (this->irisQueue.size() > 0) + { + result = irisQueue.pop(); + } + + mutex.unlock(); + + return result; +} +*/ +int ProMemory::getIrisQueueSize() +{ + int size = 0; + + QMutex mutex; + mutex.lock(); + +// size = this->irisQueue.size(); + + mutex.unlock(); + + return size; +} +bool ProMemory::isIrisQueueEmpty() +{ + bool empty = true; + + QMutex mutex; + mutex.lock(); + +// empty = this->irisQueue.isEmpty(); + + mutex.unlock(); + + return empty; +} +void ProMemory::clearIrisQueue() +{ + QMutex mutex; + mutex.lock(); + +// QStack empty; +// std::swap(empty, irisQueue); + + mutex.unlock(); +} + + +void ProMemory::initIrisFeatures(QString personId) +{ +// irisRegistPro->sendDataToExract(QByteArray(QString("[-u]").append(personId).toLocal8Bit())); +} diff --git a/ProMemory.h b/ProMemory.h new file mode 100644 index 0000000..2ecd653 --- /dev/null +++ b/ProMemory.h @@ -0,0 +1,52 @@ +#ifndef PROMEMORY_H +#define PROMEMORY_H + +#include +#include + +#include "AppConstants.h" +//#include "casic/iris/CasicIrisInfo.h" +#include "dao/IrisDataDao.h" + +#include "device/IrisCameraController.h" +//#include "device/iris/IrisRegistProcess.h" +//#include "device/iris/IrisRecogProcess.h" + +class IrisCameraController; +class IrisRegistProcess; +class IrisRecogProcess; + +class ProMemory +{ +public: + ~ProMemory(); + ProMemory(const ProMemory&)=delete; + ProMemory& operator=(const ProMemory&)=delete; + + static ProMemory& getInstance() { + static ProMemory instance; + return instance; + } + +// void pushCasicIris(CasicIrisInfo irisInfo); +// CasicIrisInfo popCasicIris(); + int getIrisQueueSize(); + bool isIrisQueueEmpty(); + void clearIrisQueue(); + + volatile int widgeFrame = 0; // 当前显示的界面 + volatile int appState = 0; // 当前程序所处的状态 + + void initIrisFeatures(QString personId = ""); // 初始化虹膜特征值集合 + + IrisCameraController * irisCam; + IrisRecogProcess * irisRecogPro; + +private: + ProMemory(); + +// QStack irisQueue; // 虹膜信息队列 + QVector irisFeatures; // 虹膜特征值集合 +}; + +#endif // PROMEMORY_H diff --git a/conf/config.ini b/conf/config.ini new file mode 100644 index 0000000..66e46ad --- /dev/null +++ b/conf/config.ini @@ -0,0 +1,67 @@ +[recognize] +#最大允许识别时间(ms) +maxMatchTime=10000 +#识别成功界面停留时间(ms) +successTipsLast=5000 +#识别失败界面停留时间(ms) +failureTipsLast=3000 +#人脸识别最大尝试次数 +maxFaceTryCount=20 +#持续没找到人脸的最大次数 +maxFaceNotFoundCount=500 +#注册时最小人脸 +minFaceRegist=240 +#识别时最小人脸 +minFaceRecog=100 + +#虹膜识别最大尝试次数 +maxIrisTryCount=10 +#虹膜识别持续没有找到眼的最大次数 +maxEyeNotFoundCount=50 + +#识别方式[1=人脸;2=虹膜;3=双认证;4=任意] +recogType=4 + +[window] +#界面窗口宽(px) +width=600 +#界面窗口高(px) +height=1024 +#统一背景色 +backgroundColor="#FFFFFF" +#标题 +title="虹膜识别终端" + +[work] +#工作状态检测时最小人脸范围 +minFaceSize=160 +#人脸范围最小横坐标 +minFacePosX=320 +#人脸范围最大横坐标 +maxFacePosX=960 +#人脸范围最小纵坐标 +minFacePosY=180 +#人脸范围最大纵坐标 +maxFacePosY=540 +#人脸太近阈值 +faceCloseSize=360 +#人脸太远阈值 +faceFarSize=480 + +[camera] +#虹膜相机取一幅画面的时间间隔(ms) +irisFrameInterval=100 +#虹膜相机拍摄宽度 +irisFrameWidth=1440 +#虹膜相机拍摄高度 +irisFrameHeight=1080 +#虹膜图像高度 +irisWidth=640 +#虹膜图像高度 +irisHeight=480 + +[log] +#日志文件位置 +logFile="d://irisLogs//casic_log.txt" +#日志级别 +logLevel="trace" diff --git a/dao/BaseDao.cpp b/dao/BaseDao.cpp new file mode 100644 index 0000000..f51c144 --- /dev/null +++ b/dao/BaseDao.cpp @@ -0,0 +1,12 @@ +#include "BaseDao.h" +#include "dao/util/ConnectionManager.h" + +BaseDao::BaseDao(QObject *parent) : QObject(parent) +{ + +} + +BaseDao::~BaseDao() +{ + +} diff --git a/dao/BaseDao.h b/dao/BaseDao.h new file mode 100644 index 0000000..1693c88 --- /dev/null +++ b/dao/BaseDao.h @@ -0,0 +1,32 @@ +#ifndef BASEDAO_H +#define BASEDAO_H + +#include +#include +#include +#include + +#include "dao/util/ConnectionManager.h" +#include "utils/UtilInclude.h" + +class BaseDao : public QObject +{ + Q_OBJECT +public: + explicit BaseDao(QObject *parent = nullptr); + ~BaseDao(); + + virtual QVector findAllRecord() = 0; + virtual QVariantMap findRecordById(QString id) = 0; + + virtual QString save(QVariantMap object) = 0; + virtual bool edit(QVariantMap newObject, QString id) = 0; + virtual bool dele(QString id) = 0; + +private: + +signals: + +}; + +#endif // BASEDAO_H diff --git a/dao/IrisDataDao.cpp b/dao/IrisDataDao.cpp new file mode 100644 index 0000000..37a0ed6 --- /dev/null +++ b/dao/IrisDataDao.cpp @@ -0,0 +1,204 @@ +#include "IrisDataDao.h" + +IrisDataDao::IrisDataDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector IrisDataDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM IRIS_DATA"; + query.prepare(sql); + + // 执行查询 + query.exec(); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + item.insert("id", query.value("id").toString()); + item.insert("person_id", query.value("person_id").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("left_iris_code1", query.value("left_iris_code1")); + item.insert("left_iris_code2", query.value("left_iris_code2")); + item.insert("left_iris_code3", query.value("left_iris_code3")); + item.insert("right_iris_code1", query.value("right_iris_code1")); + item.insert("right_iris_code2", query.value("right_iris_code2")); + item.insert("right_iris_code3", query.value("right_iris_code3")); + + result.append(item); + } + +// LOG_DEBUG(QString("查询IRIS_DATA表的所有记录[结果数:%1]").arg(result.size()).toStdString()); + return result; +} + +QVariantMap IrisDataDao::findRecordById(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM IRIS_DATA WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + // 获取结果 + if (query.next()) + { + result.insert("id", query.value("id").toString()); + result.insert("person_id", query.value("person_id").toLongLong()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("left_iris_code1", query.value("left_iris_code1")); + result.insert("left_iris_code2", query.value("left_iris_code2")); + result.insert("left_iris_code3", query.value("left_iris_code3")); + result.insert("right_iris_code1", query.value("right_iris_code1")); + result.insert("right_iris_code2", query.value("right_iris_code2")); + result.insert("right_iris_code3", query.value("right_iris_code3")); + } + +// LOG_DEBUG(QString("根据id查询IRIS_DATA表的记录[id=%1]").arg(id).toStdString()); + return result; +} + +QVariantMap IrisDataDao::findRecordByPersonId(QString personId) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM IRIS_DATA WHERE PERSON_ID = :personId"); + query.prepare(sql); + query.bindValue(":personId", personId); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + if (query.next()) + { + result.insert("id", query.value("id").toString()); + result.insert("person_id", query.value("person_id").toLongLong()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("left_iris_code1", query.value("left_iris_code1")); + result.insert("left_iris_code2", query.value("left_iris_code2")); + result.insert("left_iris_code3", query.value("left_iris_code3")); + result.insert("right_iris_code1", query.value("right_iris_code1")); + result.insert("right_iris_code2", query.value("right_iris_code2")); + result.insert("right_iris_code3", query.value("right_iris_code3")); + } + +// LOG_DEBUG(QString("根据personId查询IRIS_DATA表的记录[personId=%1]").arg(personId).toStdString()); + return result; +} + + +QString IrisDataDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + + // INSERT语句 + QString sql = QString("INSERT INTO IRIS_DATA (ID, PERSON_ID, ID_CARD_NO, LEFT_IRIS_CODE1, RIGHT_IRIS_CODE1) VALUES (:id, :personId, :idCardNo, :left1, :right1)"); + + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":personId", object.value("person_id").toString()); + query.bindValue(":idCardNo", object.value("id_card_no").toString()); + query.bindValue(":left1", object.value("left_iris_code1")); + query.bindValue(":right1", object.value("right_iris_code1")); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(); + +// LOG_DEBUG(QString("保存虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool IrisDataDao::edit(QVariantMap newObject, QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // UPDATE语句 + if (!newObject.contains("left_iris_code1") || !newObject.contains("right_iris_code1")){ + return false; + } + QString sql = QString("UPDATE IRIS_DATA SET LEFT_IRIS_CODE1 = :left1, RIGHT_IRIS_CODE1 = :right1 WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":left1", newObject.value("left_iris_code1")); + query.bindValue(":right1", newObject.value("right_iris_code1")); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(); + +// LOG_DEBUG(QString("编辑虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; +} + + +bool IrisDataDao::dele(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + QString sql = QString("DELETE FROM IRIS_DATA WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(); + +// LOG_DEBUG(QString("删除虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; +} diff --git a/dao/IrisDataDao.h b/dao/IrisDataDao.h new file mode 100644 index 0000000..c74dbbd --- /dev/null +++ b/dao/IrisDataDao.h @@ -0,0 +1,25 @@ +#ifndef IRISDATADAO_H +#define IRISDATADAO_H + +#include +#include "BaseDao.h" + +class IrisDataDao : public BaseDao +{ + Q_OBJECT +public: + explicit IrisDataDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + QVariantMap findRecordByPersonId(QString personId); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +signals: + +}; + +#endif // IRISDATADAO_H diff --git a/dao/RecognitionRecordsDao.cpp b/dao/RecognitionRecordsDao.cpp new file mode 100644 index 0000000..40db453 --- /dev/null +++ b/dao/RecognitionRecordsDao.cpp @@ -0,0 +1,100 @@ +#include "RecognitionRecordsDao.h" + +RecognitionRecordsDao::RecognitionRecordsDao(QObject *parent) : BaseDao(parent) +{ + +} + + +QVector RecognitionRecordsDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM RECOGNITION_RECORDS"; + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + item.insert("id", query.value("id").toLongLong()); + result.append(item); + } + +// LOG_DEBUG(QString("查询RECOGNITION_RECORDS表的所有记录[记录数:%1]").arg(result.size()).toStdString()); + return result; +} + +QVariantMap RecognitionRecordsDao::findRecordById(QString id) +{ + QVariantMap item; + return item; +} + +QString RecognitionRecordsDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + + // INSERT语句 + QString sql = QString("INSERT INTO RECOGNITION_RECORDS (ID, PERSON_ID, DATETIME, REC_TYPE, DEV_CODE, DOOR_CODE, INOUT_TYPE) " + "VALUES (:id, :personId, :datetime, :recType, :devCode, :doorCode, :inoutType)"); + + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":personId", object.value("person_id").toString()); + query.bindValue(":datetime", object.value("date_time").toString()); + query.bindValue(":recType", object.value("rec_type").toString()); + query.bindValue(":devCode", object.value("dev_code").toString()); + query.bindValue(":doorCode", object.value("door_code").toString()); + query.bindValue(":inoutType", object.value("inout_type").toString()); + +// LOG_DEBUG(sql.toStdString()); + + // 插入识别的log日志 + QString logStr = QString("INSERT INTO RECOGNITION_LOGS (ID, LOG_INFO) VALUES (:id, :logInfo)"); + + QSqlQuery logQuery(ConnectionManager::getInstance()->getConnection()); + logQuery.prepare(logStr); + logQuery.bindValue(":id", id); + logQuery.bindValue(":logInfo", object.value("debug_info").toString()); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(); + logQuery.exec(); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool RecognitionRecordsDao::edit(QVariantMap newObject, QString id) +{ + return false; +} + +bool RecognitionRecordsDao::dele(QString id) +{ + return false; +} diff --git a/dao/RecognitionRecordsDao.h b/dao/RecognitionRecordsDao.h new file mode 100644 index 0000000..38de7c9 --- /dev/null +++ b/dao/RecognitionRecordsDao.h @@ -0,0 +1,23 @@ +#ifndef RECOGNITIONRECORDSDAO_H +#define RECOGNITIONRECORDSDAO_H + +#include +#include "BaseDao.h" +class RecognitionRecordsDao: public BaseDao +{ + Q_OBJECT +public: + explicit RecognitionRecordsDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +signals: + +}; + +#endif // RECOGNITIONRECORDSDAO_H diff --git a/dao/SysDeptDao.cpp b/dao/SysDeptDao.cpp new file mode 100644 index 0000000..22f9946 --- /dev/null +++ b/dao/SysDeptDao.cpp @@ -0,0 +1,88 @@ +#include "SysDeptDao.h" + +SysDeptDao::SysDeptDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector SysDeptDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_DEPT WHERE PID != '-1' ORDER BY PID, NUM"; + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + item.insert("id", query.value("id").toString()); + item.insert("pid", query.value("pid").toString()); + item.insert("pids", query.value("pids").toString()); + item.insert("simplename", query.value("simplename").toString()); + item.insert("fullname", query.value("fullname").toString()); + } + +// LOG_TRACE(QString("查询表[SYS_DEPT]的所有记录[%1][%2]").arg(result.size()).arg(sql).toStdString()); + + return result; +} + +QVariantMap SysDeptDao::findRecordById(QString id) +{ + QVariantMap item; + return item; + + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM SYS_DEPT WHERE SYS_DEPT.ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + // 获取结果集的大小 + query.last(); + int count = query.at() + 1; + + if (count >=1) + { + query.first(); + + result.insert("id", query.value("id").toString()); + result.insert("pid", query.value("pid").toString()); + result.insert("pids", query.value("pids").toString()); + result.insert("simplename", query.value("simplename").toString()); + result.insert("fullname", query.value("fullname").toString()); + } + +// LOG_TRACE(QString("根据id查询SYS_DEPT表的记录[ID=%1][%2]").arg(id).arg(sql).toStdString()); + + return result; +} + + +QString SysDeptDao::save(QVariantMap object) +{ + return "0"; +} +bool SysDeptDao::edit(QVariantMap newObject, QString id) +{ + return true; +} +bool SysDeptDao::dele(QString id) +{ + return true; +} diff --git a/dao/SysDeptDao.h b/dao/SysDeptDao.h new file mode 100644 index 0000000..e07a09f --- /dev/null +++ b/dao/SysDeptDao.h @@ -0,0 +1,24 @@ +#ifndef SYSDEPTDAO_H +#define SYSDEPTDAO_H + +#include +#include "BaseDao.h" + +class SysDeptDao : public BaseDao +{ + Q_OBJECT +public: + explicit SysDeptDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +private: + +}; + +#endif // SYSDEPTDAO_H diff --git a/dao/SysPersonDao.cpp b/dao/SysPersonDao.cpp new file mode 100644 index 0000000..dd9480f --- /dev/null +++ b/dao/SysPersonDao.cpp @@ -0,0 +1,371 @@ +#include "SysPersonDao.h" + + +SysPersonDao::SysPersonDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector SysPersonDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0'"; + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + count++; + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + result.append(item); + } + +// LOG(TRACE) << QString("查询SYS_PERSON表的所有记录[%1]").arg(count).toStdString(); +// LOG_TRACE(QString("查询SYS_PERSON表的所有记录[%1]").arg(count).toStdString()); + + return result; +} + +QVariantMap SysPersonDao::findRecordById(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0' AND SYS_PERSON.ID = '%1'").arg(id); + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVariantMap result; + + // 获取结果集的大小 + query.last(); + int count = query.at() + 1; + + if (count >=1) + { + query.first(); + + result.insert("id", query.value("id").toString()); + result.insert("delflag", query.value("delflag").toString()); + result.insert("createtime", query.value("createtime").toString()); + result.insert("updatetime", query.value("updatetime").toString()); + result.insert("name", query.value("name").toString()); + result.insert("gender", query.value("gender").toString()); + result.insert("deptid", query.value("deptid").toString()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("remarks", query.value("remarks").toString()); + result.insert("person_code", query.value("person_code").toString()); + result.insert("deptname", query.value("fullname").toString()); + result.insert("sync_id", query.value("sync_id").toString()); + result.insert("hasFace", query.value("face_valid").toString()); + result.insert("hasIris", query.value("iris_valid").toString()); + } + +// LOG(TRACE) << QString("根据id查询SYS_PERSON表的记录[id=%1][%2]").arg(id).arg(sql).toStdString(); +// LOG_TRACE(QString("根据id查询SYS_PERSON表的记录[id=%1][%2]").arg(id).arg(sql).toStdString()); + + return result; +} + +int SysPersonDao::findRecordCountByNameAndDept(QString name, QString dept) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT COUNT(P.ID) AS RECCT FROM SYS_PERSON P LEFT JOIN SYS_DEPT D ON P.DEPTID = D.ID WHERE P.DELFLAG = '0'"; + if (name.isEmpty() == false) + { + sql += " AND P.NAME LIKE '%" + name + "%'"; + } + if (dept.isEmpty() == false && dept.indexOf("-1") < 0) + { + sql += QString(" AND ((P.DEPTID = '%1') OR (D.PIDS LIKE '%,%1,%'))").arg(dept); + } + + // 执行查询 + query.exec(sql); + + // 返回结果 + int result; + + // 遍历查询结果 + if (query.next()) { + result = query.value("RECCT").toInt(); + } + +// LOG(TRACE) << QString("根据姓名和部门查询SYS_PERSON记录总数[%1][%2]").arg(result).arg(sql).toStdString(); +// LOG_TRACE(QString("根据姓名和部门查询SYS_PERSON记录总数[%1][%2]").arg(result).arg(sql).toStdString()); + + return result; +} + +QVector SysPersonDao::findRecordsByNameAndDept(QString name, QString dept, qint8 limit, qint16 offset) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON P LEFT JOIN SYS_DEPT D ON P.DEPTID = D.ID WHERE P.DELFLAG = '0'"; + if (name.isEmpty() == false) + { + sql += " AND P.NAME LIKE '%" + name + "%'"; + } + if (dept.isEmpty() == false && dept.indexOf("-1") < 0) + { + sql += QString(" AND ((P.DEPTID = '%1') OR (D.PIDS LIKE '%,%1,%'))").arg(dept); + } + + sql += QString(" LIMIT %1 OFFSET %2").arg(limit).arg(offset); + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + count++; + + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + + result.append(item); + } + +// LOG(TRACE) << QString("根据姓名和部门分页查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString(); +// LOG_TRACE(QString("根据姓名和部门分页查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString()); + + return result; +} + +QVector SysPersonDao::findRecordsByProperties(QVariantMap conditions) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0'"; + QVariantMap::iterator it; + for (it = conditions.begin(); it != conditions.end(); it++) + { + sql += QString(" AND SYS_PERSON.%1 = %2").arg(it.key()).arg(it.value().toString()); + } + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + count++; + + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + + result.append(item); + } + +// LOG(TRACE) << QString("根据属性值查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString(); +// LOG_TRACE(QString("根据属性值查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString()); + + return result; +} + +QString SysPersonDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + + // INSERT语句 + QString sql = QString("INSERT INTO SYS_PERSON " + "(ID, DELFLAG, CREATETIME, UPDATETIME, " + "NAME, GENDER, DEPTID, ID_CARD_NO, " + "REMARKS, PERSON_CODE, SYNC_ID, FACE_VALID, IRIS_VALID) " + "VALUES ('%1', '0', '%2', '%2', '%3', '%4', '%5', '%6', '%7', '%8', '%9', 0, 0)") + .arg(id).arg(tm) + .arg(object.value("name").toString()) + .arg(object.value("gender").toString()) + .arg(object.value("deptid").toString()) + .arg(object.value("id_card_no").toString()) + .arg(object.value("remarks").toString()) + .arg(object.value("person_code").toString()) + .arg(object.value("sync_id").toString()); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(sql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { +// LOG(DEBUG) << QString("保存SYS_PERSON记录成功[ID = %1][%2]").arg(id).arg(sql).toStdString(); +// LOG_DEBUG(QString("保存SYS_PERSON记录成功[ID = %1][%2]").arg(id).arg(sql).toStdString()); + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool SysPersonDao::edit(QVariantMap newObject, QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + + // UPDATE语句 + QString sql = QString("UPDATE SYS_PERSON SET UPDATETIME = '%1'").arg(tm); + if (newObject.contains("name")) + { + sql.append(QString(", NAME = '%1'").arg(newObject.value("name").toString())); + } + if (newObject.contains("gender")) + { + sql.append(QString(", GENDER = '%1'").arg(newObject.value("gender").toString())); + } + if (newObject.contains("deptid")) + { + sql.append(QString(", DEPTID = '%1'").arg(newObject.value("deptid").toString())); + } + if (newObject.contains("person_code")) + { + sql.append(QString(", PERSON_CODE = '%1'").arg(newObject.value("person_code").toString())); + } + if (newObject.contains("face_valid")) + { + sql.append(QString(", FACE_VALID = '%1'").arg(newObject.value("face_valid").toString())); + } + if (newObject.contains("iris_valid")) + { + sql.append(QString(", IRIS_VALID = '%1'").arg(newObject.value("iris_valid").toString())); + } + + sql.append(QString(" WHERE ID = '%1'").arg(id)); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(sql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + +// LOG(DEBUG) << QString("编辑人员[ID=%1][%2]").arg(id).arg(sql).toStdString(); +// LOG_DEBUG(QString("编辑人员[ID=%1][%2]").arg(id).arg(sql).toStdString()); + + // 返回结果 + return success; +} + +bool SysPersonDao::dele(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + QSqlQuery irisDel(ConnectionManager::getInstance()->getConnection()); + + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + qint64 tmms = QDateTime::currentDateTime().toMSecsSinceEpoch(); + + // UPDATE语句 + QString sql = QString("UPDATE SYS_PERSON SET UPDATETIME = :updateTime, DELFLAG = :flag WHERE ID = :id").arg(tm).arg(tmms).arg(id); + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":updateTime", tm); + query.bindValue(":flag", tmms); + + // 物理删除人员的人脸和虹膜数据 + QString delIrisSql = QString("DELETE FROM IRIS_DATA WHERE PERSON_ID = :personId"); + irisDel.prepare(delIrisSql); + irisDel.bindValue(":personId", id); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(sql); + query.exec(delIrisSql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + +// LOG_DEBUG(QString("删除人员SYS_PERSON[ID=%1][%2]").arg(id).arg(success).toStdString()); + + // 返回结果 + return success; +} diff --git a/dao/SysPersonDao.h b/dao/SysPersonDao.h new file mode 100644 index 0000000..e02e5ba --- /dev/null +++ b/dao/SysPersonDao.h @@ -0,0 +1,27 @@ +#ifndef SYSPERSONDAO_H +#define SYSPERSONDAO_H + +#include +#include "BaseDao.h" + +class SysPersonDao : public BaseDao +{ + Q_OBJECT +public: + explicit SysPersonDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + int findRecordCountByNameAndDept(QString name, QString dept); + QVector findRecordsByNameAndDept(QString name, QString dept, qint8 limit, qint16 offset); + QVector findRecordsByProperties(QVariantMap conditions); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); +signals: + +}; + +#endif // SYSPERSONDAO_H diff --git a/dao/dao.pri b/dao/dao.pri new file mode 100644 index 0000000..1e04ce4 --- /dev/null +++ b/dao/dao.pri @@ -0,0 +1,18 @@ + +HEADERS += $$PWD/BaseDao.h +HEADERS += $$PWD/IrisDataDao.h +HEADERS += $$PWD/RecognitionRecordsDao.h +HEADERS += $$PWD/SysPersonDao.h +HEADERS += $$PWD/SysDeptDao.h + +SOURCES += $$PWD/BaseDao.cpp +SOURCES += $$PWD/IrisDataDao.cpp +SOURCES += $$PWD/RecognitionRecordsDao.cpp +SOURCES += $$PWD/SysPersonDao.cpp +SOURCES += $$PWD/SysDeptDao.cpp + +HEADERS += $$PWD/util/ConnectionManager.h +SOURCES += $$PWD/util/ConnectionManager.cpp +#HEADERS += $$PWD/util/CacheManager.h +#SOURCES += $$PWD/util/CacheManager.cpp + diff --git a/dao/util/ConnectionManager.cpp b/dao/util/ConnectionManager.cpp new file mode 100644 index 0000000..84b17be --- /dev/null +++ b/dao/util/ConnectionManager.cpp @@ -0,0 +1,47 @@ +#include "ConnectionManager.h" +#include + +Q_GLOBAL_STATIC(ConnectionManager, cm) + +ConnectionManager::ConnectionManager(QObject *parent) : QObject(parent) +{ + // 初始化数据库连接 + if (QSqlDatabase::contains("qt_sql_dafault_connection")) + { + conn = QSqlDatabase::database("qt_sql_default_connection"); + } + else + { + conn = QSqlDatabase::addDatabase("QSQLITE"); + conn.setDatabaseName(QApplication::applicationDirPath() + "/data/casic.db"); + + bool succ = conn.open(); + if (succ == true) + { +// LOG_INFO(QString("打开数据库操作正常[Open Database Success]").toStdString()); + } else + { +// LOG_ERROR(QString("打开数据库操作失败[Open Database Failed]").toStdString()); + } + } +} + +ConnectionManager::~ConnectionManager() +{ + conn.close(); +} + +ConnectionManager* ConnectionManager::getInstance() +{ + return cm; +} + +QSqlDatabase ConnectionManager::getConnection() +{ + return this->conn; +} + +qint64 ConnectionManager::generateId() +{ + return this->idWorker.nextId(); +} diff --git a/dao/util/ConnectionManager.h b/dao/util/ConnectionManager.h new file mode 100644 index 0000000..84647e3 --- /dev/null +++ b/dao/util/ConnectionManager.h @@ -0,0 +1,34 @@ +#ifndef CONNECTIONMANAGER_H +#define CONNECTIONMANAGER_H + +#include +#include +#include "utils/id/IdWorker.h" +#include "utils/UtilInclude.h" + +using namespace Jiawa::Core; + +class ConnectionManager : public QObject +{ + Q_OBJECT +public: + explicit ConnectionManager(QObject *parent = nullptr); + ~ConnectionManager(); + + static ConnectionManager * getInstance(); + + QSqlDatabase getConnection(); + qint64 generateId(); + +private: + // 数据库连接 + QSqlDatabase conn; + + // 雪花id生成工具 + IdWorker &idWorker = Singleton::instance(); + +signals: + +}; + +#endif // CONNECTIONMANAGER_H diff --git a/device/IrisCameraCapEventHandler.cpp b/device/IrisCameraCapEventHandler.cpp new file mode 100644 index 0000000..45df089 --- /dev/null +++ b/device/IrisCameraCapEventHandler.cpp @@ -0,0 +1,103 @@ +#include "IrisCameraCapEventHandler.h" + +IrisCameraCapEventHandler::IrisCameraCapEventHandler(QObject *parent) : QObject(parent) +{ + +} + +void IrisCameraCapEventHandler::DoOnImageCaptured(CImageDataPointer &objImageDataPointer, void *pUserParam) +{ + if (objImageDataPointer.IsNull() == false) + { + CGXDevicePointer* cam = (CGXDevicePointer *) pUserParam; + + auto camName = cam->getPtr()->GetDeviceInfo().GetUserID(); + int width = objImageDataPointer->GetWidth(); + int height = objImageDataPointer->GetHeight(); + size_t leftKeyIndex = camName.find("left"); + size_t rightKeyIndex = camName.find("right"); + + uchar * pBuffer = (BYTE*)objImageDataPointer->GetBuffer(); + + // 相机拍摄下的图像1440*1080, 直接用于算法判断 + QImage img = QImage(pBuffer, width, height, QImage::Format_Grayscale8); // 用于展示 +// QImage imgAlgo = img.copy(0, 0, width, height); + + // 用于显示的图像需要缩小到400 * 300的尺寸 + img = img.scaled(SettingConfig::getInstance().IRIS_DISPLAY_HEIGHT, SettingConfig::getInstance().IRIS_DISPLAY_WIDTH); + img = img.transformed(QTransform().rotate(-90)); // 图像逆时针旋转90度 + + // 发送到界面进行显示 + emit sendIrisFrameToDraw(img); +// cv::Mat irisMat = ImageUtil::QImageToMat(imgAlgo); + +// irisInfo.data = imgAlgo; +// irisInfo.matData = irisMat; + +// // 将图像显示在注册页面的label上 +// // 并将虹膜信息对象存入队列中 +// ProMemory::getInstance().pushCasicIris(irisInfo); + +// if (leftKeyIndex >= 0 && leftKeyIndex < 32) +// { +// emit sendIrisFrameToDraw(img, 0); // 左眼画面 +// } else if (rightKeyIndex >= 0 && rightKeyIndex < 32) +// { +// emit sendIrisFrameToDraw(img, 1); // 右眼画面 +// } +/* + if (pBuffer != NULL) + { + // 创建虹膜信息对象 + CasicIrisInfo irisInfo; + irisInfo.hasEye = false; + if (leftKeyIndex >= 0 && leftKeyIndex < 32) + { + // 左眼相机拍摄的图像 + irisInfo.leftOrRight = "left"; + } else if (rightKeyIndex >= 0 && rightKeyIndex < 32) + { + // 右眼相机 + irisInfo.leftOrRight = "right"; + } + + if (ProMemory::getInstance().widgeFrame == CasicBioRecConst::RECOGNIZE_RESULT_FORM) + { + // 相机拍摄下的图像1280*960, 直接用于算法判断 + QImage imgDisp = QImage(pBuffer, width, height, QImage::Format_Grayscale8); + cv::Mat irisMat = ImageUtil::QImageToMat(imgDisp); + + irisInfo.data = imgDisp; + irisInfo.matData = irisMat; + + ProMemory::getInstance().pushCasicIris(irisInfo); + +// cv::imwrite(QString("D:\\irisLogs\\iristest-%1.bmp").arg(irisInfo.leftOrRight).toStdString(), irisMat); + } else if (ProMemory::getInstance().widgeFrame == CasicBioRecConst::ADD_PERSON_CAPTURE_IRIS) + { + // 相机拍摄下的图像1280*960, 直接用于算法判断 + QImage img = QImage(pBuffer, width, height, QImage::Format_Grayscale8); + QImage imgAlgo = img.copy(0, 0, width, height); + + // 用于显示的图像需要缩小到1/4的尺寸 + img = img.scaled(640, 480); + cv::Mat irisMat = ImageUtil::QImageToMat(imgAlgo); + + irisInfo.data = imgAlgo; + irisInfo.matData = irisMat; + + // 将图像显示在注册页面的label上 + // 并将虹膜信息对象存入队列中 + ProMemory::getInstance().pushCasicIris(irisInfo); + + if (leftKeyIndex >= 0 && leftKeyIndex < 32) + { + emit sendIrisFrameToDraw(img, 0); // 左眼画面 + } else if (rightKeyIndex >= 0 && rightKeyIndex < 32) + { + emit sendIrisFrameToDraw(img, 1); // 右眼画面 + } + } + }*/ + } +} diff --git a/device/IrisCameraCapEventHandler.h b/device/IrisCameraCapEventHandler.h new file mode 100644 index 0000000..ad75a97 --- /dev/null +++ b/device/IrisCameraCapEventHandler.h @@ -0,0 +1,30 @@ +#ifndef IRISCAMERACAPEVENTHANDLER_H +#define IRISCAMERACAPEVENTHANDLER_H + +#include +#include +#include "include/opencv2/opencv.hpp" +#include "include/daheng/GalaxyIncludes.h" + +//#include "casic/iris/CasicIrisInterface.h" +#include "ProMemory.h" + +#include "utils/UtilInclude.h" + +class IrisCameraCapEventHandler : public QObject, public ICaptureEventHandler +{ + Q_OBJECT +public: + explicit IrisCameraCapEventHandler(QObject *parent = nullptr); + + void DoOnImageCaptured(CImageDataPointer &objImageDataPointer, void *pUserParam); + +private: + unsigned char* pImageBuffer; + +signals: + void sendIrisFrameToDraw(QImage irisImage); + +}; + +#endif // IRISCAMERACAPEVENTHANDLER_H diff --git a/device/IrisCameraController.cpp b/device/IrisCameraController.cpp new file mode 100644 index 0000000..0928176 --- /dev/null +++ b/device/IrisCameraController.cpp @@ -0,0 +1,110 @@ +#include "IrisCameraController.h" + +IrisCameraController::IrisCameraController(QObject *parent) : QObject(parent) +{ + this->irisCamHandler = new IrisCameraCapEventHandler(this); +} +IrisCameraController::~IrisCameraController() +{ + this->closeIrisCamera(); +} + + +void IrisCameraController::initIrisCamera() +{ + IGXFactory::GetInstance().Init(); + + //枚举设备 + IGXFactory::GetInstance().UpdateDeviceList(1000, irisCamList); + + this->OpenDevice(); +} + +void IrisCameraController::openIrisCamera() +{ + //设置Buffer处理模式 + irisStreamFeaturePtr->GetEnumFeature("StreamBufferHandlingMode")->SetValue("OldestFirst"); + + //注册回调函数 + irisStreamPtr->RegisterCaptureCallback(irisCamHandler, &irisCamPtr); + + //开启流层通道 + irisStreamPtr->StartGrab(); + + //发送开采命令 + irisFeaturePtr->GetCommandFeature("AcquisitionStart")->Execute(); + + // 启动定时器 + TimeCounterUtil::getInstance().irisCapCounter->start(SettingConfig::getInstance().IRIS_FRAME_INTERVAL); // 50ms执行一次定时器 +} + +void IrisCameraController::closeIrisCamera() +{ + +} + +void IrisCameraController::startCapture() +{ + // 获取定时器, 绑定定时函数 + connect(TimeCounterUtil::getInstance().irisCapCounter, &QTimer::timeout, this, &IrisCameraController::getOneFaceFrm); +// LOG(DEBUG) << QString("[IrisCameraController][startCapture]虹膜相机拍图").toStdString(); +// LOG_DEBUG(QString("[IrisCameraController][startCapture]虹膜相机拍图").toStdString()); + +} +void IrisCameraController::stopCapture() +{ + // 获取定时器, 绑定定时函数 + disconnect(TimeCounterUtil::getInstance().irisCapCounter, &QTimer::timeout, this, &IrisCameraController::getOneFaceFrm); +// LOG(DEBUG) << QString("[IrisCameraController][stopCapture]虹膜相机停止拍图").toStdString(); +// LOG_DEBUG(QString("[IrisCameraController][stopCapture]虹膜相机停止拍图").toStdString()); + +} + +void IrisCameraController::getOneFaceFrm() +{ + // 发送软触发命令(在触发模式开启时有效) + irisFeaturePtr->GetCommandFeature("TriggerSoftware")->Execute(); +} + +void IrisCameraController::getLeftAndRightEyeFrame() +{ + irisFeaturePtr->GetCommandFeature("TriggerSoftware")->Execute(); +} + +void IrisCameraController::OpenDevice() +{ + auto device = irisCamList.at(0); + + irisCamPtr = IGXFactory::GetInstance().OpenDeviceByUserID(device.GetUserID(), GX_ACCESS_EXCLUSIVE); + irisFeaturePtr = irisCamPtr->GetRemoteFeatureControl(); + + // 判断设备流是否大于零, 如果大于零则打开流 + int nStreamCount = irisCamPtr->GetStreamCount(); + if (nStreamCount > 0) + { + irisStreamPtr = irisCamPtr->OpenStream(0); + irisStreamFeaturePtr = irisStreamPtr->GetFeatureControl(); + } + + // 建议用户在打开网络相机之后, 根据当前网络环境设置相机的流通道包长值, + // 以提高网络相机的采集性能, 设置方法参考以下代码。 + GX_DEVICE_CLASS_LIST objDeviceClass = irisCamPtr->GetDeviceInfo().GetDeviceClass(); + if(GX_DEVICE_CLASS_GEV == objDeviceClass) + { + // 判断设备是否支持流通道数据包功能 + if(true == irisFeaturePtr->IsImplemented("GevSCPSPacketSize")) + { + // 获取当前网络环境的最优包长值 + int nPacketSize = irisStreamPtr->GetOptimalPacketSize(); + // 将最优包长值设置为当前设备的流通道包长值 + irisFeaturePtr->GetIntFeature("GevSCPSPacketSize")->SetValue(nPacketSize); + } + } + + //设置采集模式为连续采集模式 + irisFeaturePtr->GetEnumFeature("AcquisitionMode")->SetValue("Continuous"); + + //设置触发模式关 + irisFeaturePtr->GetEnumFeature("TriggerMode")->SetValue("On"); + irisFeaturePtr->GetEnumFeature("TriggerSource")->SetValue("Software"); +} diff --git a/device/IrisCameraController.h b/device/IrisCameraController.h new file mode 100644 index 0000000..5d7e269 --- /dev/null +++ b/device/IrisCameraController.h @@ -0,0 +1,49 @@ +#ifndef IRISCAMERACONTROLLER_H +#define IRISCAMERACONTROLLER_H + +#include + +#include "IrisCameraCapEventHandler.h" + +class IrisCameraCapEventHandler; + +class IrisCameraController : public QObject +{ + Q_OBJECT +public: + explicit IrisCameraController(QObject *parent = nullptr); + ~IrisCameraController(); + + // 初始化并打开人脸相机 + void initIrisCamera(); + void openIrisCamera(); + void closeIrisCamera(); + + void startCapture(); + void stopCapture(); + + void getLeftAndRightEyeFrame(); + + IrisCameraCapEventHandler * irisCamHandler; + +private: + GxIAPICPP::gxdeviceinfo_vector irisCamList; + + CGXDevicePointer irisCamPtr; ///< 设备句柄 + + CGXStreamPointer irisStreamPtr; ///< 左眼设备流 + + CGXFeatureControlPointer irisFeaturePtr; ///< 左眼属性控制器 + + CGXFeatureControlPointer irisStreamFeaturePtr; ///< 左眼流层控制器对象 + + void OpenDevice(); + +signals: + +public slots: + void getOneFaceFrm(); + +}; + +#endif // IRISCAMERACONTROLLER_H diff --git a/device/device.pri b/device/device.pri new file mode 100644 index 0000000..a8417f2 --- /dev/null +++ b/device/device.pri @@ -0,0 +1,13 @@ + +HEADERS += $$PWD/IrisCameraController.h +HEADERS += $$PWD/IrisCameraCapEventHandler.h +#HEADERS += $$PWD/iris/IrisRegistProcess.h +#HEADERS += $$PWD/iris/IrisRecogProcess.h +#HEADERS += $$PWD/iris/CasicIrisRecState.h + +SOURCES += $$PWD/IrisCameraController.cpp +SOURCES += $$PWD/IrisCameraCapEventHandler.cpp +#SOURCES += $$PWD/iris/IrisRegistProcess.cpp +#SOURCES += $$PWD/iris/IrisRecogProcess.cpp +#SOURCES += $$PWD/iris/CasicIrisRecState.cpp + diff --git a/images/bg_footer.png b/images/bg_footer.png new file mode 100644 index 0000000..a3a99ab --- /dev/null +++ b/images/bg_footer.png Binary files differ diff --git a/images/bg_statcked.png b/images/bg_statcked.png new file mode 100644 index 0000000..18b63e1 --- /dev/null +++ b/images/bg_statcked.png Binary files differ diff --git a/images/bg_title.png b/images/bg_title.png new file mode 100644 index 0000000..0316e2d --- /dev/null +++ b/images/bg_title.png Binary files differ diff --git a/main.cpp b/main.cpp index 16bc45b..9052ddb 100644 --- a/main.cpp +++ b/main.cpp @@ -1,11 +1,11 @@ -#include "IdentifyForm.h" +#include "MainWindowForm.h" #include int main(int argc, char *argv[]) { QApplication a(argc, argv); - IdentifyForm w; + MainWindowForm w; w.show(); return a.exec(); } diff --git a/resource.qrc b/resource.qrc new file mode 100644 index 0000000..474586a --- /dev/null +++ b/resource.qrc @@ -0,0 +1,35 @@ + + + images/setting.png + images/user.png + images/back.png + images/home.png + images/btnPageFirst.png + images/btnPageLast.png + images/btnPageNext.png + images/btnPagePre.png + images/regist.png + images/photoEyeLeft.png + images/photoEyeRight.png + images/photoFace.png + images/save.png + images/upArrow.png + images/downArrow.png + images/faceCaped.png + images/faceNotCap.png + images/irisCaped.png + images/irisNotCap.png + images/tipsFailure.png + images/tipsSuccess.png + images/tipsConfirm.png + images/bg_recognize_result.png + images/iconRetry.png + images/bg_title.png + images/bg_footer.png + images/bg_statcked.png + + + images/add_bottom.png + images/add_top.png + + diff --git a/utils/ImageUtil.cpp b/utils/ImageUtil.cpp new file mode 100644 index 0000000..7604572 --- /dev/null +++ b/utils/ImageUtil.cpp @@ -0,0 +1,97 @@ +#include "ImageUtil.h" + +ImageUtil::ImageUtil() +{ + +} + +QImage ImageUtil::MatImageToQImage(const cv::Mat &src) +{ + //CV_8UC1 8位无符号的单通道---灰度图片 + if(src.type() == CV_8UC1) + { + QImage qImage((const unsigned char *)(src.data), src.cols, src.rows, src.cols, QImage::Format_Grayscale8); + return qImage; + } + //为3通道的彩色图片 + else if(src.type() == CV_8UC3) + { + //得到图像的的首地址 + const uchar *pSrc = (const uchar*)src.data; + //以src构造图片 + QImage qImage(pSrc, src.cols, src.rows, src.step, QImage::Format_RGB888); + //在不改变实际图像数据的条件下, 交换红蓝通道 + return qImage.rgbSwapped(); + } + //四通道图片, 带Alpha通道的RGB彩色图像 + else if(src.type() == CV_8UC4) + { + const uchar *pSrc = (const uchar*)src.data; + QImage qImage(pSrc, src.cols, src.rows, src.step, QImage::Format_ARGB32); + //返回图像的子区域作为一个新图像 + return qImage.copy(); + } + else + { + return QImage(); + } +} +/* +QImage ImageUtil::UcharToQImage(unsigned char* data, int width, int height, QImage::Format format) +{ + QImage qImage(data, width, height, format); + //在不改变实际图像数据的条件下, 交换红蓝通道 + return qImage.rgbSwapped(); +} + +cv::Mat ImageUtil::QImageToMat(QImage image) +{ + cv::Mat mat; + switch(image.format()) + { + case QImage::Format_ARGB32: + case QImage::Format_RGB32: + case QImage::Format_ARGB32_Premultiplied: + mat = cv::Mat(image.height(), image.width(), CV_8UC4, (void*)image.constBits(), image.bytesPerLine()); + break; + case QImage::Format_RGB888: + mat = cv::Mat(image.height(), image.width(), CV_8UC3, (void*)image.constBits(), image.bytesPerLine()); + cv::cvtColor(mat, mat, cv::COLOR_BGR2RGB); + break; + case QImage::Format_Indexed8: + mat = cv::Mat(image.height(), image.width(), CV_8UC1, (void*)image.constBits(), image.bytesPerLine()); + break; + case QImage::Format_Grayscale8: + mat = cv::Mat(image.height(), image.width(), CV_8UC1, (void *)image.bits(), image.bytesPerLine()); + break; + } + + mat = mat.clone(); + + return mat; +} + +QString ImageUtil::QImageToBase64(QImage image) +{ + QByteArray ba; + QBuffer buf(&ba); + image.save(&buf, "bmp"); + QString base64String = ba.toBase64(); + return base64String; +} + +cv::Mat ImageUtil::MatImageRect(const cv::Mat &src, cv::Rect rect, int delta) +{ + cv::Mat matClone = src.clone(); + cv::Rect bigRect; + + bigRect.x = rect.x - delta < 0 ? 0 : rect.x - delta; + bigRect.y = rect.y - delta < 0 ? 0 : rect.y - delta; + bigRect.width = rect.x + rect.width + 2 * delta > src.cols ? src.cols - rect.x : rect.width + 2 * delta; + bigRect.height = rect.y + rect.height + 2 * delta > src.rows ? src.rows - rect.y : rect.height + 2 * delta; + + cv::Mat roi = matClone(bigRect); + + return roi; +} +*/ diff --git a/utils/ImageUtil.h b/utils/ImageUtil.h new file mode 100644 index 0000000..dbfdd48 --- /dev/null +++ b/utils/ImageUtil.h @@ -0,0 +1,22 @@ +#ifndef IMAGEUTIL_H +#define IMAGEUTIL_H + +#include +#include +#include "opencv2/opencv.hpp" + +class ImageUtil +{ +public: + ImageUtil(); + + static QImage MatImageToQImage(const cv::Mat &src); +// static QImage UcharToQImage(unsigned char* data, int width, int height, QImage::Format format); + +// static cv::Mat QImageToMat(QImage image); +// static QString QImageToBase64(QImage image); + +// static cv::Mat MatImageRect(const cv::Mat &src, cv::Rect rect, int delta); +}; + +#endif // IMAGEUTIL_H diff --git a/utils/SettingConfig.cpp b/utils/SettingConfig.cpp new file mode 100644 index 0000000..d420285 --- /dev/null +++ b/utils/SettingConfig.cpp @@ -0,0 +1,44 @@ +#include "SettingConfig.h" +#include + +SettingConfig::SettingConfig() +{ + filename = QApplication::applicationDirPath() + "/conf/config.ini"; + setting = new QSettings(this->filename, QSettings::IniFormat); + + WINDOW_WIDTH = getProperty("window", "width").toInt(); + WINDOW_HEIGHT = getProperty("window", "height").toInt(); + WINDOW_BACKGROUND_COLOR = getProperty("window", "backgroundColor").toString(); + WINDOW_TITLE = getProperty("window", "title").toString(); + WINDOW_RIGHTS = getProperty("window", "copyright").toString(); + WINDOW_VERSION = getProperty("window", "version").toString(); + + IRIS_FRAME_WIDTH = getProperty("camera", "irisFrameWidth").toInt(); + IRIS_FRAME_HEIGHT = getProperty("camera", "irisFrameHeight").toInt(); + IRIS_WIDTH = getProperty("camera", "irisWidth").toInt(); + IRIS_HEIGHT = getProperty("camera", "irisHeight").toInt(); + IRIS_FRAME_INTERVAL = getProperty("camera", "irisFrameInterval").toInt(); + IRIS_DISPLAY_WIDTH = getProperty("camera", "irisDisplayWidth").toInt(); + IRIS_DISPLAY_HEIGHT = getProperty("camera", "irisDisplayHeight").toInt(); + + MAX_MATCH_TIME = getProperty("recognize", "maxMatchTime").toInt(); + SUCCESS_TIPS_LAST = getProperty("recognize", "successTipsLast").toInt(); + FAILURE_TIPS_LAST = getProperty("recognize", "failureTipsLast").toInt(); + MAX_FACE_TRY_COUNT = getProperty("recognize", "maxFaceTryCount").toInt(); + MAX_FACE_NOT_FOUND_COUNT = getProperty("recognize", "maxFaceNotFoundCount").toInt(); + MAX_IRIS_TRY_COUNT = getProperty("recognize", "maxIrisTryCount").toInt(); + MAX_EYE_NOT_FOUND_COUNT = getProperty("recognize", "maxEyeNotFoundCount").toInt(); + + MAX_CAPTURE_STACK_SIZE = getProperty("stack", "capture").toInt(); + MAX_FOUND_STACK_SIZE = getProperty("stack", "found").toInt(); + MAX_QUALIFIED_STACK_SIZE = getProperty("stack", "qualified").toInt(); + + LOG_FILE = getProperty("log", "logFile").toString(); + LOG_LEVEL = getProperty("log", "logLevel").toString(); +} + + +QVariant SettingConfig::getProperty(QString nodeName, QString keyName) { + QVariant var = this->setting->value(QString("/%1/%2").arg(nodeName).arg(keyName)); + return var; +} diff --git a/utils/SettingConfig.h b/utils/SettingConfig.h new file mode 100644 index 0000000..30c3bec --- /dev/null +++ b/utils/SettingConfig.h @@ -0,0 +1,66 @@ +#ifndef SETTINGCONFIG_H +#define SETTINGCONFIG_H + +#include +#include + +class SettingConfig : public QObject +{ +public: + ~SettingConfig() {}; + SettingConfig(const SettingConfig&)=delete; + SettingConfig& operator=(const SettingConfig&)=delete; + + static SettingConfig& getInstance() { + static SettingConfig instance; + return instance; + } + + /** + * @brief get + * @param nodeName + * @param keyName + * @return QVariant + * @title + */ + QVariant getProperty(QString nodeName, QString keyName); + + /******** 以下为需要的各类参数 ********/ + int WINDOW_WIDTH; + int WINDOW_HEIGHT; + QString WINDOW_BACKGROUND_COLOR; + QString WINDOW_TITLE; + QString WINDOW_RIGHTS; + QString WINDOW_VERSION; + + int IRIS_FRAME_INTERVAL; + int IRIS_FRAME_WIDTH; + int IRIS_FRAME_HEIGHT; + int IRIS_WIDTH; + int IRIS_HEIGHT; + int IRIS_DISPLAY_WIDTH; + int IRIS_DISPLAY_HEIGHT; + + int MAX_MATCH_TIME; + int SUCCESS_TIPS_LAST; + int FAILURE_TIPS_LAST; + int MAX_FACE_TRY_COUNT; + int MAX_FACE_NOT_FOUND_COUNT; + int MAX_IRIS_TRY_COUNT; + int MAX_EYE_NOT_FOUND_COUNT; + + int MAX_CAPTURE_STACK_SIZE; + int MAX_FOUND_STACK_SIZE; + int MAX_QUALIFIED_STACK_SIZE; + + QString LOG_FILE; + QString LOG_LEVEL; + +private: + SettingConfig(); + + QString filename; + QSettings* setting; +}; + +#endif // SETTINGCONFIG_H diff --git a/utils/TimeCounterUtil.cpp b/utils/TimeCounterUtil.cpp new file mode 100644 index 0000000..275945f --- /dev/null +++ b/utils/TimeCounterUtil.cpp @@ -0,0 +1,8 @@ +#include "TimeCounterUtil.h" + +TimeCounterUtil::TimeCounterUtil() +{ + faceCapCounter = new QTimer(); + irisCapCounter = new QTimer(); + clockCounter = new QTimer(); +} diff --git a/utils/TimeCounterUtil.h b/utils/TimeCounterUtil.h new file mode 100644 index 0000000..28b29f1 --- /dev/null +++ b/utils/TimeCounterUtil.h @@ -0,0 +1,29 @@ +#ifndef TIMECOUNTERUTIL_H +#define TIMECOUNTERUTIL_H + +#include +#include + +class TimeCounterUtil : public QObject +{ +public: + + ~TimeCounterUtil() {}; + TimeCounterUtil(const TimeCounterUtil&)=delete; + TimeCounterUtil& operator=(const TimeCounterUtil&)=delete; + + static TimeCounterUtil& getInstance() { + static TimeCounterUtil instance; + return instance; + } + + QTimer * faceCapCounter; + QTimer * irisCapCounter; + QTimer * clockCounter; + +private: + TimeCounterUtil(); + +}; + +#endif // TIMECOUNTERUTIL_H diff --git a/utils/UtilInclude.h b/utils/UtilInclude.h new file mode 100644 index 0000000..e7b899a --- /dev/null +++ b/utils/UtilInclude.h @@ -0,0 +1,13 @@ +#ifndef UTILINCLUDE_H +#define UTILINCLUDE_H + +//#include "ByteUtil.h" +#include "ImageUtil.h" +//#include "LogUtil.h" +#include "SettingConfig.h" +//#include "SpeakerUtil.h" +#include "TimeCounterUtil.h" +//#include "UDPClientUtil.h" +//#include "HttpRequestUtil.h" + +#endif // UTILINCLUDE_H diff --git a/utils/id/IdWorker.h b/utils/id/IdWorker.h new file mode 100644 index 0000000..6c48aa9 --- /dev/null +++ b/utils/id/IdWorker.h @@ -0,0 +1,218 @@ +#ifndef _JW_CORE_ID_WORKER_H_ +#define _JW_CORE_ID_WORKER_H_ + +#include +#include +#include +#include +#include +#include "Noncopyable.h" +#include "Singleton.h" + +// 如果不使用 mutex, 则开启下面这个定义, 但是我发现, 还是开启 mutex 功能, 速度比较快 +// #define SNOWFLAKE_ID_WORKER_NO_LOCK + +namespace Jiawa { + + /** + * @brief 核心 + * 核心功能 + */ + namespace Core { + + /** + * @brief 分布式id生成类 + * https://segmentfault.com/a/1190000011282426 + * https://github.com/twitter/snowflake/blob/snowflake-2010/src/main/scala/com/twitter/service/snowflake/IdWorker.scala + * + * 64bit id: 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 + * || || || | | | + * |└---------------------------时间戳--------------------------┘└中心-┘└机器-┘ └----序列号----┘ + * | + * 不用 + * SnowFlake的优点: 整体上按照时间自增排序, 并且整个分布式系统内不会产生ID碰撞(由数据中心ID和机器ID作区分), 并且效率较高, 经测试, SnowFlake每秒能够产生26万ID左右. + */ + class SnowflakeIdWorker : private Noncopyable { + + // 实现单例 + friend class Singleton; + + public: + typedef unsigned int UInt; + typedef unsigned long long int UInt64; + +#ifdef SNOWFLAKE_ID_WORKER_NO_LOCK + typedef std::atomic AtomicUInt; + typedef std::atomic AtomicUInt64; +#else + typedef UInt AtomicUInt; + typedef UInt64 AtomicUInt64; +#endif + + void setWorkerId(UInt workerId) { + this->workerId = workerId; + } + + void setDatacenterId(UInt datacenterId) { + this->datacenterId = datacenterId; + } + + UInt64 getId() { + return nextId(); + } + + /** + * 获得下一个ID (该方法是线程安全的) + * + * @return SnowflakeId + */ + UInt64 nextId() { +#ifndef SNOWFLAKE_ID_WORKER_NO_LOCK + std::unique_lock lock{ mutex }; + AtomicUInt64 timestamp{ 0 }; +#else + static AtomicUInt64 timestamp{ 0 }; +#endif + timestamp = timeGen(); + + // 如果当前时间小于上一次ID生成的时间戳, 说明系统时钟回退过这个时候应当抛出异常 + if (timestamp < lastTimestamp) { + std::ostringstream s; + s << "clock moved backwards. Refusing to generate id for " << lastTimestamp - timestamp << " milliseconds"; + throw std::exception(std::runtime_error(s.str())); + } + + if (lastTimestamp == timestamp) { + // 如果是同一时间生成的, 则进行毫秒内序列 + sequence = (sequence + 1) & sequenceMask; + if (0 == sequence) { + // 毫秒内序列溢出, 阻塞到下一个毫秒,获得新的时间戳 + timestamp = tilNextMillis(lastTimestamp); + } + } else { + sequence = 0; + } + +#ifndef SNOWFLAKE_ID_WORKER_NO_LOCK + lastTimestamp = timestamp; +#else + lastTimestamp = timestamp.load(); +#endif + + // 移位并通过或运算拼到一起组成64位的ID + return ((timestamp - twepoch) << timestampLeftShift) + | (datacenterId << datacenterIdShift) + | (workerId << workerIdShift) + | sequence; + } + + protected: + SnowflakeIdWorker() : workerId(0), datacenterId(0), sequence(0), lastTimestamp(0) { } + + /** + * 返回以毫秒为单位的当前时间 + * + * @return 当前时间(毫秒) + */ + UInt64 timeGen() const { + auto t = std::chrono::time_point_cast(std::chrono::high_resolution_clock::now()); + return t.time_since_epoch().count(); + } + + /** + * 阻塞到下一个毫秒, 直到获得新的时间戳 + * + * @param lastTimestamp 上次生成ID的时间截 + * @return 当前时间戳 + */ + UInt64 tilNextMillis(UInt64 lastTimestamp) const { + UInt64 timestamp = timeGen(); + while (timestamp <= lastTimestamp) { + timestamp = timeGen(); + } + return timestamp; + } + + private: + +#ifndef SNOWFLAKE_ID_WORKER_NO_LOCK + std::mutex mutex; +#endif + + /** + * 开始时间截 (2018-01-01 00:00:00.000) + */ + const UInt64 twepoch = 1514736000000; + + /** + * 机器id所占的位数 + */ + const UInt workerIdBits = 5; + + /** + * 数据中心id所占的位数 + */ + const UInt datacenterIdBits = 5; + + /** + * 序列所占的位数 + */ + const UInt sequenceBits = 12; + + /** + * 机器ID向左移12位 + */ + const UInt workerIdShift = sequenceBits; + + /** + * 数据标识id向左移17位 + */ + const UInt datacenterIdShift = workerIdShift + workerIdBits; + + /** + * 时间截向左移22位 + */ + const UInt timestampLeftShift = datacenterIdShift + datacenterIdBits; + + /** + * 支持的最大机器id, 结果是31 + */ + const UInt maxWorkerId = -1 ^ (-1 << workerIdBits); + + /** + * 支持的最大数据中心id, 结果是31 + */ + const UInt maxDatacenterId = -1 ^ (-1 << datacenterIdBits); + + /** + * 生成序列的掩码, 这里为4095 + */ + const UInt sequenceMask = -1 ^ (-1 << sequenceBits); + + /** + * 工作机器id(0~31) + */ + UInt workerId; + + /** + * 数据中心id(0~31) + */ + UInt datacenterId; + + /** + * 毫秒内序列(0~4095) + */ + AtomicUInt sequence{ 0 }; + + /** + * 上次生成ID的时间截 + */ + AtomicUInt64 lastTimestamp{ 0 }; + + }; + + typedef SnowflakeIdWorker IdWorker; + } +} + +#endif // _JW_CORE_ID_WORKER_H_ diff --git a/utils/id/Noncopyable.h b/utils/id/Noncopyable.h new file mode 100644 index 0000000..d87f58a --- /dev/null +++ b/utils/id/Noncopyable.h @@ -0,0 +1,31 @@ +#ifndef _JW_CORE_NONCOPYABLE_H_ +#define _JW_CORE_NONCOPYABLE_H_ + + +// Private copy constructor and copy assignment ensure classes derived from +// class noncopyable cannot be copied. + +namespace Jiawa { + namespace Core { + + // protection from unintended ADL(Argument Dependent Lookup) + namespace Noncopyable_ { + + class Noncopyable + { + protected: + Noncopyable() = default; + ~Noncopyable() = default; + + Noncopyable(const Noncopyable&) = delete; + Noncopyable(const Noncopyable&&) = delete; + Noncopyable& operator=(const Noncopyable&) = delete; + Noncopyable& operator=(const Noncopyable&&) = delete; + }; + } + + typedef Noncopyable_::Noncopyable Noncopyable; + } +} + +#endif // _JW_CORE_NONCOPYABLE_H_ diff --git a/AppConstants.h b/AppConstants.h new file mode 100644 index 0000000..296c53f --- /dev/null +++ b/AppConstants.h @@ -0,0 +1,28 @@ +#ifndef APPCONSTANTS_H +#define APPCONSTANTS_H + +class AppConstants +{ +public: + enum WidgeFrameName + { + MAIN_PAGE = 0, // 主页面 + PERSON_LIST_FORM = 1, // 人员列表页面 + ADD_PERSON_FORM = 2, // 添加人员页面 + ADD_PERSON_CAPTURE_FACE = 21, // 添加/编辑人员时进行人脸拍图 + ADD_PERSON_CAPTURE_IRIS = 22, // 添加/编辑人员时进行虹膜拍图 + SETTING_FORM = 3, // 设置页面 + RECOGNIZE_RESULT_FORM = 4, // 识别结果界面 + IDENTIFY_FORM = 5, // 识别界面 含识别中 和 识别结果 + LOCKSCREEN_FORM = 6 // 锁屏待机界面 + }; + + enum ApplicationState + { + STATE_WAIT = 0, // 待机 + STATE_WORKING = 1, // 工作状态 + STATE_IDENTIFYING = 2, // 识别中 + }; +}; + +#endif // APPCONSTANTS_H diff --git a/CasicIrisIdentify.pro b/CasicIrisIdentify.pro index 5d7fea6..575ce3d 100644 --- a/CasicIrisIdentify.pro +++ b/CasicIrisIdentify.pro @@ -1,4 +1,4 @@ -QT += core gui +QT += core gui sql network texttospeech greaterThan(QT_MAJOR_VERSION, 4): QT += widgets @@ -15,20 +15,46 @@ # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 -SOURCES += \ - main.cpp \ - IdentifyForm.cpp +include("dao/dao.pri") +include("device/device.pri") +include("utils/utils.pri") -HEADERS += \ - IdentifyForm.h +SOURCES += main.cpp +SOURCES += ProMemory.cpp +SOURCES += MainWindowForm.cpp +SOURCES += IdentifyForm.cpp +SOURCES += LockScreenForm.cpp -FORMS += \ - IdentifyForm.ui +HEADERS += AppConstants.h +HEADERS += ProMemory.h +HEADERS += MainWindowForm.h +HEADERS += IdentifyForm.h +HEADERS += LockScreenForm.h -TRANSLATIONS += \ - CasicIrisIdentify_zh_CN.ts +FORMS += MainWindowForm.ui +FORMS += IdentifyForm.ui +FORMS += LockScreenForm.ui + +RESOURCES += resource.qrc + +DISTFILES += conf/config.ini + +#TRANSLATIONS += CasicIrisIdentify_zh_CN.ts + +#INCLUDEPATH += include/spdlog +#DEPENDPATH += include/spdlog # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target + + +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lopencv_world420 +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lGxIAPICPPEx + +INCLUDEPATH += $$PWD/include/daheng +DEPENDPATH += $$PWD/include/daheng + +INCLUDEPATH += $$PWD/include +DEPENDPATH += $$PWD/include diff --git a/CasicIrisIdentify_zh_CN.ts b/CasicIrisIdentify_zh_CN.ts index 5526fe4..81900df 100644 --- a/CasicIrisIdentify_zh_CN.ts +++ b/CasicIrisIdentify_zh_CN.ts @@ -1,3 +1,12 @@ - + + + IdentifyForm + + + IdentifyForm + + + + diff --git a/IdentifyForm.cpp b/IdentifyForm.cpp index 348a897..ba1f251 100644 --- a/IdentifyForm.cpp +++ b/IdentifyForm.cpp @@ -1,4 +1,4 @@ -#include "IdentifyForm.h" +#include "IdentifyForm.h" #include "ui_IdentifyForm.h" IdentifyForm::IdentifyForm(QWidget *parent) @@ -6,6 +6,12 @@ , ui(new Ui::IdentifyForm) { ui->setupUi(this); + + // 初始化更新界面的定时器 + // 每秒执行一次 + connect(TimeCounterUtil::getInstance().clockCounter, &QTimer::timeout, this, &IdentifyForm::updateDateAndTime); + + TimeCounterUtil::getInstance().clockCounter->start(1000); } IdentifyForm::~IdentifyForm() @@ -13,3 +19,16 @@ delete ui; } +void IdentifyForm::drawIrisImageOnFrame(QImage image) +{ + // 只在识别界面才显示画面 + if (ui->wgtStacked->currentIndex() == 0) { + ui->labelVideo->setPixmap(QPixmap::fromImage(image)); + } +} + + +void IdentifyForm::updateDateAndTime() +{ + ui->labelTime->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd dddd HH:mm:ss")); +} diff --git a/IdentifyForm.h b/IdentifyForm.h index fc857a1..ae1cd22 100644 --- a/IdentifyForm.h +++ b/IdentifyForm.h @@ -1,7 +1,10 @@ -#ifndef IDENTIFYFORM_H +#ifndef IDENTIFYFORM_H #define IDENTIFYFORM_H #include +#include + +#include "utils/UtilInclude.h" QT_BEGIN_NAMESPACE namespace Ui { class IdentifyForm; } @@ -15,7 +18,14 @@ IdentifyForm(QWidget *parent = nullptr); ~IdentifyForm(); +public slots: + void drawIrisImageOnFrame(QImage image); + private: Ui::IdentifyForm *ui; + +private slots: + void updateDateAndTime(); + }; #endif // IDENTIFYFORM_H diff --git a/IdentifyForm.ui b/IdentifyForm.ui index c72a36f..879dc9a 100644 --- a/IdentifyForm.ui +++ b/IdentifyForm.ui @@ -6,13 +6,59 @@ 0 0 - 800 + 600 600 IdentifyForm + + + + 0 + 40 + 600 + 450 + + + + 0 + + + + + + 100 + 10 + 400 + 300 + + + + + + + + + + + + + + 0 + 0 + 600 + 40 + + + + TextLabel + + + Qt::AlignCenter + + diff --git a/LockScreenForm.cpp b/LockScreenForm.cpp new file mode 100644 index 0000000..58dc54b --- /dev/null +++ b/LockScreenForm.cpp @@ -0,0 +1,14 @@ +#include "LockScreenForm.h" +#include "ui_LockScreenForm.h" + +LockScreenForm::LockScreenForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::LockScreenForm) +{ + ui->setupUi(this); +} + +LockScreenForm::~LockScreenForm() +{ + delete ui; +} diff --git a/LockScreenForm.h b/LockScreenForm.h new file mode 100644 index 0000000..b5ded48 --- /dev/null +++ b/LockScreenForm.h @@ -0,0 +1,25 @@ +#ifndef LOCKSCREENFORM_H +#define LOCKSCREENFORM_H + +#include +#include + +#include "utils/UtilInclude.h" + +namespace Ui { +class LockScreenForm; +} + +class LockScreenForm : public QWidget +{ + Q_OBJECT + +public: + explicit LockScreenForm(QWidget *parent = nullptr); + ~LockScreenForm(); + +private: + Ui::LockScreenForm *ui; +}; + +#endif // LOCKSCREENFORM_H diff --git a/LockScreenForm.ui b/LockScreenForm.ui new file mode 100644 index 0000000..7f2a6db --- /dev/null +++ b/LockScreenForm.ui @@ -0,0 +1,45 @@ + + + LockScreenForm + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + 180 + 100 + 54 + 12 + + + + TextLabel + + + + + + 180 + 160 + 54 + 12 + + + + TextLabel + + + + + + diff --git a/MainWindowForm.cpp b/MainWindowForm.cpp new file mode 100644 index 0000000..84f8159 --- /dev/null +++ b/MainWindowForm.cpp @@ -0,0 +1,86 @@ +#include "MainWindowForm.h" +#include "ui_MainWindowForm.h" +#include + +MainWindowForm::MainWindowForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::MainWindowForm) +{ + ui->setupUi(this); + + // 设置窗口透明和大小、位置 + this->setWindowFlags(Qt::FramelessWindowHint); + this->move(1400, 15); + this->resize(SettingConfig::getInstance().WINDOW_WIDTH, SettingConfig::getInstance().WINDOW_HEIGHT); + + // 通过调色板的颜色来设置窗口的统一背景色 + qApp->setPalette(QPalette(QColor(SettingConfig::getInstance().WINDOW_BACKGROUND_COLOR))); + + // 加载css文件设置控件样式 + QFile file(QApplication::applicationDirPath() + "/qss/main.css"); + if (file.open(QFile::ReadOnly)) + { + QString qssStr = QLatin1String(file.readAll()); + this->setStyleSheet(qssStr); + file.close(); + } + + initFormsPtr(); + + // 设置标题文字 + ui->labelTitle->setText(SettingConfig::getInstance().WINDOW_TITLE); + ui->labelCopyright->setText(SettingConfig::getInstance().WINDOW_RIGHTS); + ui->labelVersion->setText(SettingConfig::getInstance().WINDOW_VERSION); + + // 初始化虹膜相机控制 + ProMemory::getInstance().irisCam = new IrisCameraController(this); + ProMemory::getInstance().irisCam->initIrisCamera(); + ProMemory::getInstance().irisCam->openIrisCamera(); + connect(ProMemory::getInstance().irisCam->irisCamHandler, &IrisCameraCapEventHandler::sendIrisFrameToDraw, identifyForm, &IdentifyForm::drawIrisImageOnFrame); + +// LOG_INFO(QString("应用程序启动成功[Application Startup Success]").toStdString()); + qDebug() << "应用程序启动成功[Application Startup Success]"; + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::IDENTIFY_FORM; + ui->wdgtStatced->setCurrentWidget(identifyForm); + + // 开始虹膜相机拍图 + ProMemory::getInstance().irisCam->startCapture(); +} + +MainWindowForm::~MainWindowForm() +{ + delete ui; +} + +void MainWindowForm::lockScreen() +{ + ui->wdgtStatced->setCurrentWidget(lockScreenForm); + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::LOCKSCREEN_FORM; + ProMemory::getInstance().appState = AppConstants::ApplicationState::STATE_WAIT; +} + +void MainWindowForm::keyPressEvent(QKeyEvent *event) +{ + switch (event->key()) { + case Qt::Key_Escape: + QTimer::singleShot(100, qApp, [=](){ + QApplication::quit(); + }); + + default: + QWidget::keyPressEvent(event); + } +} + +void MainWindowForm::initFormsPtr() +{ + // 初始化各个form + lockScreenForm = new LockScreenForm(this); + identifyForm = new IdentifyForm(this); + + // 将form添加到statcked widget中 + ui->wdgtStatced->addWidget(identifyForm); + ui->wdgtStatced->addWidget(lockScreenForm); + + // 绑定按钮函数 +} diff --git a/MainWindowForm.h b/MainWindowForm.h new file mode 100644 index 0000000..7fb2d89 --- /dev/null +++ b/MainWindowForm.h @@ -0,0 +1,38 @@ +#ifndef MAINWINDOWFORM_H +#define MAINWINDOWFORM_H + +#include +#include +#include + +#include "utils/UtilInclude.h" +#include "ProMemory.h" +#include "LockScreenForm.h" +#include "IdentifyForm.h" + +namespace Ui { +class MainWindowForm; +} + +class MainWindowForm : public QWidget +{ + Q_OBJECT + +public: + explicit MainWindowForm(QWidget *parent = nullptr); + ~MainWindowForm(); + +public slots: + void lockScreen(); + +private: + Ui::MainWindowForm *ui; + LockScreenForm * lockScreenForm; + IdentifyForm * identifyForm; + + void keyPressEvent(QKeyEvent *event); + + void initFormsPtr(); +}; + +#endif // MAINWINDOWFORM_H diff --git a/MainWindowForm.ui b/MainWindowForm.ui new file mode 100644 index 0000000..e793ebf --- /dev/null +++ b/MainWindowForm.ui @@ -0,0 +1,85 @@ + + + MainWindowForm + + + + 0 + 0 + 600 + 1024 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + 0 + 0 + 600 + 84 + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + + + + TextLabel + + + Qt::AlignBottom|Qt::AlignHCenter + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + diff --git a/ProMemory.cpp b/ProMemory.cpp new file mode 100644 index 0000000..19e7403 --- /dev/null +++ b/ProMemory.cpp @@ -0,0 +1,84 @@ +#include "ProMemory.h" + +ProMemory::ProMemory() +{ + +} + +ProMemory::~ProMemory() +{ + +} + +/* +void ProMemory::pushCasicIris(CasicIrisInfo irisInfo) +{ + QMutex mutex; + mutex.lock(); + if (this->irisQueue.size() > 30) + { + QStack empty; + std::swap(empty, irisQueue); + } + + irisQueue.push(irisInfo); + mutex.unlock(); +} +CasicIrisInfo ProMemory::popCasicIris() +{ + CasicIrisInfo result; + + QMutex mutex; + mutex.lock(); + if (this->irisQueue.size() > 0) + { + result = irisQueue.pop(); + } + + mutex.unlock(); + + return result; +} +*/ +int ProMemory::getIrisQueueSize() +{ + int size = 0; + + QMutex mutex; + mutex.lock(); + +// size = this->irisQueue.size(); + + mutex.unlock(); + + return size; +} +bool ProMemory::isIrisQueueEmpty() +{ + bool empty = true; + + QMutex mutex; + mutex.lock(); + +// empty = this->irisQueue.isEmpty(); + + mutex.unlock(); + + return empty; +} +void ProMemory::clearIrisQueue() +{ + QMutex mutex; + mutex.lock(); + +// QStack empty; +// std::swap(empty, irisQueue); + + mutex.unlock(); +} + + +void ProMemory::initIrisFeatures(QString personId) +{ +// irisRegistPro->sendDataToExract(QByteArray(QString("[-u]").append(personId).toLocal8Bit())); +} diff --git a/ProMemory.h b/ProMemory.h new file mode 100644 index 0000000..2ecd653 --- /dev/null +++ b/ProMemory.h @@ -0,0 +1,52 @@ +#ifndef PROMEMORY_H +#define PROMEMORY_H + +#include +#include + +#include "AppConstants.h" +//#include "casic/iris/CasicIrisInfo.h" +#include "dao/IrisDataDao.h" + +#include "device/IrisCameraController.h" +//#include "device/iris/IrisRegistProcess.h" +//#include "device/iris/IrisRecogProcess.h" + +class IrisCameraController; +class IrisRegistProcess; +class IrisRecogProcess; + +class ProMemory +{ +public: + ~ProMemory(); + ProMemory(const ProMemory&)=delete; + ProMemory& operator=(const ProMemory&)=delete; + + static ProMemory& getInstance() { + static ProMemory instance; + return instance; + } + +// void pushCasicIris(CasicIrisInfo irisInfo); +// CasicIrisInfo popCasicIris(); + int getIrisQueueSize(); + bool isIrisQueueEmpty(); + void clearIrisQueue(); + + volatile int widgeFrame = 0; // 当前显示的界面 + volatile int appState = 0; // 当前程序所处的状态 + + void initIrisFeatures(QString personId = ""); // 初始化虹膜特征值集合 + + IrisCameraController * irisCam; + IrisRecogProcess * irisRecogPro; + +private: + ProMemory(); + +// QStack irisQueue; // 虹膜信息队列 + QVector irisFeatures; // 虹膜特征值集合 +}; + +#endif // PROMEMORY_H diff --git a/conf/config.ini b/conf/config.ini new file mode 100644 index 0000000..66e46ad --- /dev/null +++ b/conf/config.ini @@ -0,0 +1,67 @@ +[recognize] +#最大允许识别时间(ms) +maxMatchTime=10000 +#识别成功界面停留时间(ms) +successTipsLast=5000 +#识别失败界面停留时间(ms) +failureTipsLast=3000 +#人脸识别最大尝试次数 +maxFaceTryCount=20 +#持续没找到人脸的最大次数 +maxFaceNotFoundCount=500 +#注册时最小人脸 +minFaceRegist=240 +#识别时最小人脸 +minFaceRecog=100 + +#虹膜识别最大尝试次数 +maxIrisTryCount=10 +#虹膜识别持续没有找到眼的最大次数 +maxEyeNotFoundCount=50 + +#识别方式[1=人脸;2=虹膜;3=双认证;4=任意] +recogType=4 + +[window] +#界面窗口宽(px) +width=600 +#界面窗口高(px) +height=1024 +#统一背景色 +backgroundColor="#FFFFFF" +#标题 +title="虹膜识别终端" + +[work] +#工作状态检测时最小人脸范围 +minFaceSize=160 +#人脸范围最小横坐标 +minFacePosX=320 +#人脸范围最大横坐标 +maxFacePosX=960 +#人脸范围最小纵坐标 +minFacePosY=180 +#人脸范围最大纵坐标 +maxFacePosY=540 +#人脸太近阈值 +faceCloseSize=360 +#人脸太远阈值 +faceFarSize=480 + +[camera] +#虹膜相机取一幅画面的时间间隔(ms) +irisFrameInterval=100 +#虹膜相机拍摄宽度 +irisFrameWidth=1440 +#虹膜相机拍摄高度 +irisFrameHeight=1080 +#虹膜图像高度 +irisWidth=640 +#虹膜图像高度 +irisHeight=480 + +[log] +#日志文件位置 +logFile="d://irisLogs//casic_log.txt" +#日志级别 +logLevel="trace" diff --git a/dao/BaseDao.cpp b/dao/BaseDao.cpp new file mode 100644 index 0000000..f51c144 --- /dev/null +++ b/dao/BaseDao.cpp @@ -0,0 +1,12 @@ +#include "BaseDao.h" +#include "dao/util/ConnectionManager.h" + +BaseDao::BaseDao(QObject *parent) : QObject(parent) +{ + +} + +BaseDao::~BaseDao() +{ + +} diff --git a/dao/BaseDao.h b/dao/BaseDao.h new file mode 100644 index 0000000..1693c88 --- /dev/null +++ b/dao/BaseDao.h @@ -0,0 +1,32 @@ +#ifndef BASEDAO_H +#define BASEDAO_H + +#include +#include +#include +#include + +#include "dao/util/ConnectionManager.h" +#include "utils/UtilInclude.h" + +class BaseDao : public QObject +{ + Q_OBJECT +public: + explicit BaseDao(QObject *parent = nullptr); + ~BaseDao(); + + virtual QVector findAllRecord() = 0; + virtual QVariantMap findRecordById(QString id) = 0; + + virtual QString save(QVariantMap object) = 0; + virtual bool edit(QVariantMap newObject, QString id) = 0; + virtual bool dele(QString id) = 0; + +private: + +signals: + +}; + +#endif // BASEDAO_H diff --git a/dao/IrisDataDao.cpp b/dao/IrisDataDao.cpp new file mode 100644 index 0000000..37a0ed6 --- /dev/null +++ b/dao/IrisDataDao.cpp @@ -0,0 +1,204 @@ +#include "IrisDataDao.h" + +IrisDataDao::IrisDataDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector IrisDataDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM IRIS_DATA"; + query.prepare(sql); + + // 执行查询 + query.exec(); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + item.insert("id", query.value("id").toString()); + item.insert("person_id", query.value("person_id").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("left_iris_code1", query.value("left_iris_code1")); + item.insert("left_iris_code2", query.value("left_iris_code2")); + item.insert("left_iris_code3", query.value("left_iris_code3")); + item.insert("right_iris_code1", query.value("right_iris_code1")); + item.insert("right_iris_code2", query.value("right_iris_code2")); + item.insert("right_iris_code3", query.value("right_iris_code3")); + + result.append(item); + } + +// LOG_DEBUG(QString("查询IRIS_DATA表的所有记录[结果数:%1]").arg(result.size()).toStdString()); + return result; +} + +QVariantMap IrisDataDao::findRecordById(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM IRIS_DATA WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + // 获取结果 + if (query.next()) + { + result.insert("id", query.value("id").toString()); + result.insert("person_id", query.value("person_id").toLongLong()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("left_iris_code1", query.value("left_iris_code1")); + result.insert("left_iris_code2", query.value("left_iris_code2")); + result.insert("left_iris_code3", query.value("left_iris_code3")); + result.insert("right_iris_code1", query.value("right_iris_code1")); + result.insert("right_iris_code2", query.value("right_iris_code2")); + result.insert("right_iris_code3", query.value("right_iris_code3")); + } + +// LOG_DEBUG(QString("根据id查询IRIS_DATA表的记录[id=%1]").arg(id).toStdString()); + return result; +} + +QVariantMap IrisDataDao::findRecordByPersonId(QString personId) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM IRIS_DATA WHERE PERSON_ID = :personId"); + query.prepare(sql); + query.bindValue(":personId", personId); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + if (query.next()) + { + result.insert("id", query.value("id").toString()); + result.insert("person_id", query.value("person_id").toLongLong()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("left_iris_code1", query.value("left_iris_code1")); + result.insert("left_iris_code2", query.value("left_iris_code2")); + result.insert("left_iris_code3", query.value("left_iris_code3")); + result.insert("right_iris_code1", query.value("right_iris_code1")); + result.insert("right_iris_code2", query.value("right_iris_code2")); + result.insert("right_iris_code3", query.value("right_iris_code3")); + } + +// LOG_DEBUG(QString("根据personId查询IRIS_DATA表的记录[personId=%1]").arg(personId).toStdString()); + return result; +} + + +QString IrisDataDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + + // INSERT语句 + QString sql = QString("INSERT INTO IRIS_DATA (ID, PERSON_ID, ID_CARD_NO, LEFT_IRIS_CODE1, RIGHT_IRIS_CODE1) VALUES (:id, :personId, :idCardNo, :left1, :right1)"); + + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":personId", object.value("person_id").toString()); + query.bindValue(":idCardNo", object.value("id_card_no").toString()); + query.bindValue(":left1", object.value("left_iris_code1")); + query.bindValue(":right1", object.value("right_iris_code1")); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(); + +// LOG_DEBUG(QString("保存虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool IrisDataDao::edit(QVariantMap newObject, QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // UPDATE语句 + if (!newObject.contains("left_iris_code1") || !newObject.contains("right_iris_code1")){ + return false; + } + QString sql = QString("UPDATE IRIS_DATA SET LEFT_IRIS_CODE1 = :left1, RIGHT_IRIS_CODE1 = :right1 WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":left1", newObject.value("left_iris_code1")); + query.bindValue(":right1", newObject.value("right_iris_code1")); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(); + +// LOG_DEBUG(QString("编辑虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; +} + + +bool IrisDataDao::dele(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + QString sql = QString("DELETE FROM IRIS_DATA WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(); + +// LOG_DEBUG(QString("删除虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; +} diff --git a/dao/IrisDataDao.h b/dao/IrisDataDao.h new file mode 100644 index 0000000..c74dbbd --- /dev/null +++ b/dao/IrisDataDao.h @@ -0,0 +1,25 @@ +#ifndef IRISDATADAO_H +#define IRISDATADAO_H + +#include +#include "BaseDao.h" + +class IrisDataDao : public BaseDao +{ + Q_OBJECT +public: + explicit IrisDataDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + QVariantMap findRecordByPersonId(QString personId); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +signals: + +}; + +#endif // IRISDATADAO_H diff --git a/dao/RecognitionRecordsDao.cpp b/dao/RecognitionRecordsDao.cpp new file mode 100644 index 0000000..40db453 --- /dev/null +++ b/dao/RecognitionRecordsDao.cpp @@ -0,0 +1,100 @@ +#include "RecognitionRecordsDao.h" + +RecognitionRecordsDao::RecognitionRecordsDao(QObject *parent) : BaseDao(parent) +{ + +} + + +QVector RecognitionRecordsDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM RECOGNITION_RECORDS"; + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + item.insert("id", query.value("id").toLongLong()); + result.append(item); + } + +// LOG_DEBUG(QString("查询RECOGNITION_RECORDS表的所有记录[记录数:%1]").arg(result.size()).toStdString()); + return result; +} + +QVariantMap RecognitionRecordsDao::findRecordById(QString id) +{ + QVariantMap item; + return item; +} + +QString RecognitionRecordsDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + + // INSERT语句 + QString sql = QString("INSERT INTO RECOGNITION_RECORDS (ID, PERSON_ID, DATETIME, REC_TYPE, DEV_CODE, DOOR_CODE, INOUT_TYPE) " + "VALUES (:id, :personId, :datetime, :recType, :devCode, :doorCode, :inoutType)"); + + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":personId", object.value("person_id").toString()); + query.bindValue(":datetime", object.value("date_time").toString()); + query.bindValue(":recType", object.value("rec_type").toString()); + query.bindValue(":devCode", object.value("dev_code").toString()); + query.bindValue(":doorCode", object.value("door_code").toString()); + query.bindValue(":inoutType", object.value("inout_type").toString()); + +// LOG_DEBUG(sql.toStdString()); + + // 插入识别的log日志 + QString logStr = QString("INSERT INTO RECOGNITION_LOGS (ID, LOG_INFO) VALUES (:id, :logInfo)"); + + QSqlQuery logQuery(ConnectionManager::getInstance()->getConnection()); + logQuery.prepare(logStr); + logQuery.bindValue(":id", id); + logQuery.bindValue(":logInfo", object.value("debug_info").toString()); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(); + logQuery.exec(); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool RecognitionRecordsDao::edit(QVariantMap newObject, QString id) +{ + return false; +} + +bool RecognitionRecordsDao::dele(QString id) +{ + return false; +} diff --git a/dao/RecognitionRecordsDao.h b/dao/RecognitionRecordsDao.h new file mode 100644 index 0000000..38de7c9 --- /dev/null +++ b/dao/RecognitionRecordsDao.h @@ -0,0 +1,23 @@ +#ifndef RECOGNITIONRECORDSDAO_H +#define RECOGNITIONRECORDSDAO_H + +#include +#include "BaseDao.h" +class RecognitionRecordsDao: public BaseDao +{ + Q_OBJECT +public: + explicit RecognitionRecordsDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +signals: + +}; + +#endif // RECOGNITIONRECORDSDAO_H diff --git a/dao/SysDeptDao.cpp b/dao/SysDeptDao.cpp new file mode 100644 index 0000000..22f9946 --- /dev/null +++ b/dao/SysDeptDao.cpp @@ -0,0 +1,88 @@ +#include "SysDeptDao.h" + +SysDeptDao::SysDeptDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector SysDeptDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_DEPT WHERE PID != '-1' ORDER BY PID, NUM"; + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + item.insert("id", query.value("id").toString()); + item.insert("pid", query.value("pid").toString()); + item.insert("pids", query.value("pids").toString()); + item.insert("simplename", query.value("simplename").toString()); + item.insert("fullname", query.value("fullname").toString()); + } + +// LOG_TRACE(QString("查询表[SYS_DEPT]的所有记录[%1][%2]").arg(result.size()).arg(sql).toStdString()); + + return result; +} + +QVariantMap SysDeptDao::findRecordById(QString id) +{ + QVariantMap item; + return item; + + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM SYS_DEPT WHERE SYS_DEPT.ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + // 获取结果集的大小 + query.last(); + int count = query.at() + 1; + + if (count >=1) + { + query.first(); + + result.insert("id", query.value("id").toString()); + result.insert("pid", query.value("pid").toString()); + result.insert("pids", query.value("pids").toString()); + result.insert("simplename", query.value("simplename").toString()); + result.insert("fullname", query.value("fullname").toString()); + } + +// LOG_TRACE(QString("根据id查询SYS_DEPT表的记录[ID=%1][%2]").arg(id).arg(sql).toStdString()); + + return result; +} + + +QString SysDeptDao::save(QVariantMap object) +{ + return "0"; +} +bool SysDeptDao::edit(QVariantMap newObject, QString id) +{ + return true; +} +bool SysDeptDao::dele(QString id) +{ + return true; +} diff --git a/dao/SysDeptDao.h b/dao/SysDeptDao.h new file mode 100644 index 0000000..e07a09f --- /dev/null +++ b/dao/SysDeptDao.h @@ -0,0 +1,24 @@ +#ifndef SYSDEPTDAO_H +#define SYSDEPTDAO_H + +#include +#include "BaseDao.h" + +class SysDeptDao : public BaseDao +{ + Q_OBJECT +public: + explicit SysDeptDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +private: + +}; + +#endif // SYSDEPTDAO_H diff --git a/dao/SysPersonDao.cpp b/dao/SysPersonDao.cpp new file mode 100644 index 0000000..dd9480f --- /dev/null +++ b/dao/SysPersonDao.cpp @@ -0,0 +1,371 @@ +#include "SysPersonDao.h" + + +SysPersonDao::SysPersonDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector SysPersonDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0'"; + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + count++; + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + result.append(item); + } + +// LOG(TRACE) << QString("查询SYS_PERSON表的所有记录[%1]").arg(count).toStdString(); +// LOG_TRACE(QString("查询SYS_PERSON表的所有记录[%1]").arg(count).toStdString()); + + return result; +} + +QVariantMap SysPersonDao::findRecordById(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0' AND SYS_PERSON.ID = '%1'").arg(id); + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVariantMap result; + + // 获取结果集的大小 + query.last(); + int count = query.at() + 1; + + if (count >=1) + { + query.first(); + + result.insert("id", query.value("id").toString()); + result.insert("delflag", query.value("delflag").toString()); + result.insert("createtime", query.value("createtime").toString()); + result.insert("updatetime", query.value("updatetime").toString()); + result.insert("name", query.value("name").toString()); + result.insert("gender", query.value("gender").toString()); + result.insert("deptid", query.value("deptid").toString()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("remarks", query.value("remarks").toString()); + result.insert("person_code", query.value("person_code").toString()); + result.insert("deptname", query.value("fullname").toString()); + result.insert("sync_id", query.value("sync_id").toString()); + result.insert("hasFace", query.value("face_valid").toString()); + result.insert("hasIris", query.value("iris_valid").toString()); + } + +// LOG(TRACE) << QString("根据id查询SYS_PERSON表的记录[id=%1][%2]").arg(id).arg(sql).toStdString(); +// LOG_TRACE(QString("根据id查询SYS_PERSON表的记录[id=%1][%2]").arg(id).arg(sql).toStdString()); + + return result; +} + +int SysPersonDao::findRecordCountByNameAndDept(QString name, QString dept) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT COUNT(P.ID) AS RECCT FROM SYS_PERSON P LEFT JOIN SYS_DEPT D ON P.DEPTID = D.ID WHERE P.DELFLAG = '0'"; + if (name.isEmpty() == false) + { + sql += " AND P.NAME LIKE '%" + name + "%'"; + } + if (dept.isEmpty() == false && dept.indexOf("-1") < 0) + { + sql += QString(" AND ((P.DEPTID = '%1') OR (D.PIDS LIKE '%,%1,%'))").arg(dept); + } + + // 执行查询 + query.exec(sql); + + // 返回结果 + int result; + + // 遍历查询结果 + if (query.next()) { + result = query.value("RECCT").toInt(); + } + +// LOG(TRACE) << QString("根据姓名和部门查询SYS_PERSON记录总数[%1][%2]").arg(result).arg(sql).toStdString(); +// LOG_TRACE(QString("根据姓名和部门查询SYS_PERSON记录总数[%1][%2]").arg(result).arg(sql).toStdString()); + + return result; +} + +QVector SysPersonDao::findRecordsByNameAndDept(QString name, QString dept, qint8 limit, qint16 offset) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON P LEFT JOIN SYS_DEPT D ON P.DEPTID = D.ID WHERE P.DELFLAG = '0'"; + if (name.isEmpty() == false) + { + sql += " AND P.NAME LIKE '%" + name + "%'"; + } + if (dept.isEmpty() == false && dept.indexOf("-1") < 0) + { + sql += QString(" AND ((P.DEPTID = '%1') OR (D.PIDS LIKE '%,%1,%'))").arg(dept); + } + + sql += QString(" LIMIT %1 OFFSET %2").arg(limit).arg(offset); + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + count++; + + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + + result.append(item); + } + +// LOG(TRACE) << QString("根据姓名和部门分页查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString(); +// LOG_TRACE(QString("根据姓名和部门分页查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString()); + + return result; +} + +QVector SysPersonDao::findRecordsByProperties(QVariantMap conditions) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0'"; + QVariantMap::iterator it; + for (it = conditions.begin(); it != conditions.end(); it++) + { + sql += QString(" AND SYS_PERSON.%1 = %2").arg(it.key()).arg(it.value().toString()); + } + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + count++; + + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + + result.append(item); + } + +// LOG(TRACE) << QString("根据属性值查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString(); +// LOG_TRACE(QString("根据属性值查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString()); + + return result; +} + +QString SysPersonDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + + // INSERT语句 + QString sql = QString("INSERT INTO SYS_PERSON " + "(ID, DELFLAG, CREATETIME, UPDATETIME, " + "NAME, GENDER, DEPTID, ID_CARD_NO, " + "REMARKS, PERSON_CODE, SYNC_ID, FACE_VALID, IRIS_VALID) " + "VALUES ('%1', '0', '%2', '%2', '%3', '%4', '%5', '%6', '%7', '%8', '%9', 0, 0)") + .arg(id).arg(tm) + .arg(object.value("name").toString()) + .arg(object.value("gender").toString()) + .arg(object.value("deptid").toString()) + .arg(object.value("id_card_no").toString()) + .arg(object.value("remarks").toString()) + .arg(object.value("person_code").toString()) + .arg(object.value("sync_id").toString()); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(sql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { +// LOG(DEBUG) << QString("保存SYS_PERSON记录成功[ID = %1][%2]").arg(id).arg(sql).toStdString(); +// LOG_DEBUG(QString("保存SYS_PERSON记录成功[ID = %1][%2]").arg(id).arg(sql).toStdString()); + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool SysPersonDao::edit(QVariantMap newObject, QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + + // UPDATE语句 + QString sql = QString("UPDATE SYS_PERSON SET UPDATETIME = '%1'").arg(tm); + if (newObject.contains("name")) + { + sql.append(QString(", NAME = '%1'").arg(newObject.value("name").toString())); + } + if (newObject.contains("gender")) + { + sql.append(QString(", GENDER = '%1'").arg(newObject.value("gender").toString())); + } + if (newObject.contains("deptid")) + { + sql.append(QString(", DEPTID = '%1'").arg(newObject.value("deptid").toString())); + } + if (newObject.contains("person_code")) + { + sql.append(QString(", PERSON_CODE = '%1'").arg(newObject.value("person_code").toString())); + } + if (newObject.contains("face_valid")) + { + sql.append(QString(", FACE_VALID = '%1'").arg(newObject.value("face_valid").toString())); + } + if (newObject.contains("iris_valid")) + { + sql.append(QString(", IRIS_VALID = '%1'").arg(newObject.value("iris_valid").toString())); + } + + sql.append(QString(" WHERE ID = '%1'").arg(id)); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(sql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + +// LOG(DEBUG) << QString("编辑人员[ID=%1][%2]").arg(id).arg(sql).toStdString(); +// LOG_DEBUG(QString("编辑人员[ID=%1][%2]").arg(id).arg(sql).toStdString()); + + // 返回结果 + return success; +} + +bool SysPersonDao::dele(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + QSqlQuery irisDel(ConnectionManager::getInstance()->getConnection()); + + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + qint64 tmms = QDateTime::currentDateTime().toMSecsSinceEpoch(); + + // UPDATE语句 + QString sql = QString("UPDATE SYS_PERSON SET UPDATETIME = :updateTime, DELFLAG = :flag WHERE ID = :id").arg(tm).arg(tmms).arg(id); + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":updateTime", tm); + query.bindValue(":flag", tmms); + + // 物理删除人员的人脸和虹膜数据 + QString delIrisSql = QString("DELETE FROM IRIS_DATA WHERE PERSON_ID = :personId"); + irisDel.prepare(delIrisSql); + irisDel.bindValue(":personId", id); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(sql); + query.exec(delIrisSql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + +// LOG_DEBUG(QString("删除人员SYS_PERSON[ID=%1][%2]").arg(id).arg(success).toStdString()); + + // 返回结果 + return success; +} diff --git a/dao/SysPersonDao.h b/dao/SysPersonDao.h new file mode 100644 index 0000000..e02e5ba --- /dev/null +++ b/dao/SysPersonDao.h @@ -0,0 +1,27 @@ +#ifndef SYSPERSONDAO_H +#define SYSPERSONDAO_H + +#include +#include "BaseDao.h" + +class SysPersonDao : public BaseDao +{ + Q_OBJECT +public: + explicit SysPersonDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + int findRecordCountByNameAndDept(QString name, QString dept); + QVector findRecordsByNameAndDept(QString name, QString dept, qint8 limit, qint16 offset); + QVector findRecordsByProperties(QVariantMap conditions); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); +signals: + +}; + +#endif // SYSPERSONDAO_H diff --git a/dao/dao.pri b/dao/dao.pri new file mode 100644 index 0000000..1e04ce4 --- /dev/null +++ b/dao/dao.pri @@ -0,0 +1,18 @@ + +HEADERS += $$PWD/BaseDao.h +HEADERS += $$PWD/IrisDataDao.h +HEADERS += $$PWD/RecognitionRecordsDao.h +HEADERS += $$PWD/SysPersonDao.h +HEADERS += $$PWD/SysDeptDao.h + +SOURCES += $$PWD/BaseDao.cpp +SOURCES += $$PWD/IrisDataDao.cpp +SOURCES += $$PWD/RecognitionRecordsDao.cpp +SOURCES += $$PWD/SysPersonDao.cpp +SOURCES += $$PWD/SysDeptDao.cpp + +HEADERS += $$PWD/util/ConnectionManager.h +SOURCES += $$PWD/util/ConnectionManager.cpp +#HEADERS += $$PWD/util/CacheManager.h +#SOURCES += $$PWD/util/CacheManager.cpp + diff --git a/dao/util/ConnectionManager.cpp b/dao/util/ConnectionManager.cpp new file mode 100644 index 0000000..84b17be --- /dev/null +++ b/dao/util/ConnectionManager.cpp @@ -0,0 +1,47 @@ +#include "ConnectionManager.h" +#include + +Q_GLOBAL_STATIC(ConnectionManager, cm) + +ConnectionManager::ConnectionManager(QObject *parent) : QObject(parent) +{ + // 初始化数据库连接 + if (QSqlDatabase::contains("qt_sql_dafault_connection")) + { + conn = QSqlDatabase::database("qt_sql_default_connection"); + } + else + { + conn = QSqlDatabase::addDatabase("QSQLITE"); + conn.setDatabaseName(QApplication::applicationDirPath() + "/data/casic.db"); + + bool succ = conn.open(); + if (succ == true) + { +// LOG_INFO(QString("打开数据库操作正常[Open Database Success]").toStdString()); + } else + { +// LOG_ERROR(QString("打开数据库操作失败[Open Database Failed]").toStdString()); + } + } +} + +ConnectionManager::~ConnectionManager() +{ + conn.close(); +} + +ConnectionManager* ConnectionManager::getInstance() +{ + return cm; +} + +QSqlDatabase ConnectionManager::getConnection() +{ + return this->conn; +} + +qint64 ConnectionManager::generateId() +{ + return this->idWorker.nextId(); +} diff --git a/dao/util/ConnectionManager.h b/dao/util/ConnectionManager.h new file mode 100644 index 0000000..84647e3 --- /dev/null +++ b/dao/util/ConnectionManager.h @@ -0,0 +1,34 @@ +#ifndef CONNECTIONMANAGER_H +#define CONNECTIONMANAGER_H + +#include +#include +#include "utils/id/IdWorker.h" +#include "utils/UtilInclude.h" + +using namespace Jiawa::Core; + +class ConnectionManager : public QObject +{ + Q_OBJECT +public: + explicit ConnectionManager(QObject *parent = nullptr); + ~ConnectionManager(); + + static ConnectionManager * getInstance(); + + QSqlDatabase getConnection(); + qint64 generateId(); + +private: + // 数据库连接 + QSqlDatabase conn; + + // 雪花id生成工具 + IdWorker &idWorker = Singleton::instance(); + +signals: + +}; + +#endif // CONNECTIONMANAGER_H diff --git a/device/IrisCameraCapEventHandler.cpp b/device/IrisCameraCapEventHandler.cpp new file mode 100644 index 0000000..45df089 --- /dev/null +++ b/device/IrisCameraCapEventHandler.cpp @@ -0,0 +1,103 @@ +#include "IrisCameraCapEventHandler.h" + +IrisCameraCapEventHandler::IrisCameraCapEventHandler(QObject *parent) : QObject(parent) +{ + +} + +void IrisCameraCapEventHandler::DoOnImageCaptured(CImageDataPointer &objImageDataPointer, void *pUserParam) +{ + if (objImageDataPointer.IsNull() == false) + { + CGXDevicePointer* cam = (CGXDevicePointer *) pUserParam; + + auto camName = cam->getPtr()->GetDeviceInfo().GetUserID(); + int width = objImageDataPointer->GetWidth(); + int height = objImageDataPointer->GetHeight(); + size_t leftKeyIndex = camName.find("left"); + size_t rightKeyIndex = camName.find("right"); + + uchar * pBuffer = (BYTE*)objImageDataPointer->GetBuffer(); + + // 相机拍摄下的图像1440*1080, 直接用于算法判断 + QImage img = QImage(pBuffer, width, height, QImage::Format_Grayscale8); // 用于展示 +// QImage imgAlgo = img.copy(0, 0, width, height); + + // 用于显示的图像需要缩小到400 * 300的尺寸 + img = img.scaled(SettingConfig::getInstance().IRIS_DISPLAY_HEIGHT, SettingConfig::getInstance().IRIS_DISPLAY_WIDTH); + img = img.transformed(QTransform().rotate(-90)); // 图像逆时针旋转90度 + + // 发送到界面进行显示 + emit sendIrisFrameToDraw(img); +// cv::Mat irisMat = ImageUtil::QImageToMat(imgAlgo); + +// irisInfo.data = imgAlgo; +// irisInfo.matData = irisMat; + +// // 将图像显示在注册页面的label上 +// // 并将虹膜信息对象存入队列中 +// ProMemory::getInstance().pushCasicIris(irisInfo); + +// if (leftKeyIndex >= 0 && leftKeyIndex < 32) +// { +// emit sendIrisFrameToDraw(img, 0); // 左眼画面 +// } else if (rightKeyIndex >= 0 && rightKeyIndex < 32) +// { +// emit sendIrisFrameToDraw(img, 1); // 右眼画面 +// } +/* + if (pBuffer != NULL) + { + // 创建虹膜信息对象 + CasicIrisInfo irisInfo; + irisInfo.hasEye = false; + if (leftKeyIndex >= 0 && leftKeyIndex < 32) + { + // 左眼相机拍摄的图像 + irisInfo.leftOrRight = "left"; + } else if (rightKeyIndex >= 0 && rightKeyIndex < 32) + { + // 右眼相机 + irisInfo.leftOrRight = "right"; + } + + if (ProMemory::getInstance().widgeFrame == CasicBioRecConst::RECOGNIZE_RESULT_FORM) + { + // 相机拍摄下的图像1280*960, 直接用于算法判断 + QImage imgDisp = QImage(pBuffer, width, height, QImage::Format_Grayscale8); + cv::Mat irisMat = ImageUtil::QImageToMat(imgDisp); + + irisInfo.data = imgDisp; + irisInfo.matData = irisMat; + + ProMemory::getInstance().pushCasicIris(irisInfo); + +// cv::imwrite(QString("D:\\irisLogs\\iristest-%1.bmp").arg(irisInfo.leftOrRight).toStdString(), irisMat); + } else if (ProMemory::getInstance().widgeFrame == CasicBioRecConst::ADD_PERSON_CAPTURE_IRIS) + { + // 相机拍摄下的图像1280*960, 直接用于算法判断 + QImage img = QImage(pBuffer, width, height, QImage::Format_Grayscale8); + QImage imgAlgo = img.copy(0, 0, width, height); + + // 用于显示的图像需要缩小到1/4的尺寸 + img = img.scaled(640, 480); + cv::Mat irisMat = ImageUtil::QImageToMat(imgAlgo); + + irisInfo.data = imgAlgo; + irisInfo.matData = irisMat; + + // 将图像显示在注册页面的label上 + // 并将虹膜信息对象存入队列中 + ProMemory::getInstance().pushCasicIris(irisInfo); + + if (leftKeyIndex >= 0 && leftKeyIndex < 32) + { + emit sendIrisFrameToDraw(img, 0); // 左眼画面 + } else if (rightKeyIndex >= 0 && rightKeyIndex < 32) + { + emit sendIrisFrameToDraw(img, 1); // 右眼画面 + } + } + }*/ + } +} diff --git a/device/IrisCameraCapEventHandler.h b/device/IrisCameraCapEventHandler.h new file mode 100644 index 0000000..ad75a97 --- /dev/null +++ b/device/IrisCameraCapEventHandler.h @@ -0,0 +1,30 @@ +#ifndef IRISCAMERACAPEVENTHANDLER_H +#define IRISCAMERACAPEVENTHANDLER_H + +#include +#include +#include "include/opencv2/opencv.hpp" +#include "include/daheng/GalaxyIncludes.h" + +//#include "casic/iris/CasicIrisInterface.h" +#include "ProMemory.h" + +#include "utils/UtilInclude.h" + +class IrisCameraCapEventHandler : public QObject, public ICaptureEventHandler +{ + Q_OBJECT +public: + explicit IrisCameraCapEventHandler(QObject *parent = nullptr); + + void DoOnImageCaptured(CImageDataPointer &objImageDataPointer, void *pUserParam); + +private: + unsigned char* pImageBuffer; + +signals: + void sendIrisFrameToDraw(QImage irisImage); + +}; + +#endif // IRISCAMERACAPEVENTHANDLER_H diff --git a/device/IrisCameraController.cpp b/device/IrisCameraController.cpp new file mode 100644 index 0000000..0928176 --- /dev/null +++ b/device/IrisCameraController.cpp @@ -0,0 +1,110 @@ +#include "IrisCameraController.h" + +IrisCameraController::IrisCameraController(QObject *parent) : QObject(parent) +{ + this->irisCamHandler = new IrisCameraCapEventHandler(this); +} +IrisCameraController::~IrisCameraController() +{ + this->closeIrisCamera(); +} + + +void IrisCameraController::initIrisCamera() +{ + IGXFactory::GetInstance().Init(); + + //枚举设备 + IGXFactory::GetInstance().UpdateDeviceList(1000, irisCamList); + + this->OpenDevice(); +} + +void IrisCameraController::openIrisCamera() +{ + //设置Buffer处理模式 + irisStreamFeaturePtr->GetEnumFeature("StreamBufferHandlingMode")->SetValue("OldestFirst"); + + //注册回调函数 + irisStreamPtr->RegisterCaptureCallback(irisCamHandler, &irisCamPtr); + + //开启流层通道 + irisStreamPtr->StartGrab(); + + //发送开采命令 + irisFeaturePtr->GetCommandFeature("AcquisitionStart")->Execute(); + + // 启动定时器 + TimeCounterUtil::getInstance().irisCapCounter->start(SettingConfig::getInstance().IRIS_FRAME_INTERVAL); // 50ms执行一次定时器 +} + +void IrisCameraController::closeIrisCamera() +{ + +} + +void IrisCameraController::startCapture() +{ + // 获取定时器, 绑定定时函数 + connect(TimeCounterUtil::getInstance().irisCapCounter, &QTimer::timeout, this, &IrisCameraController::getOneFaceFrm); +// LOG(DEBUG) << QString("[IrisCameraController][startCapture]虹膜相机拍图").toStdString(); +// LOG_DEBUG(QString("[IrisCameraController][startCapture]虹膜相机拍图").toStdString()); + +} +void IrisCameraController::stopCapture() +{ + // 获取定时器, 绑定定时函数 + disconnect(TimeCounterUtil::getInstance().irisCapCounter, &QTimer::timeout, this, &IrisCameraController::getOneFaceFrm); +// LOG(DEBUG) << QString("[IrisCameraController][stopCapture]虹膜相机停止拍图").toStdString(); +// LOG_DEBUG(QString("[IrisCameraController][stopCapture]虹膜相机停止拍图").toStdString()); + +} + +void IrisCameraController::getOneFaceFrm() +{ + // 发送软触发命令(在触发模式开启时有效) + irisFeaturePtr->GetCommandFeature("TriggerSoftware")->Execute(); +} + +void IrisCameraController::getLeftAndRightEyeFrame() +{ + irisFeaturePtr->GetCommandFeature("TriggerSoftware")->Execute(); +} + +void IrisCameraController::OpenDevice() +{ + auto device = irisCamList.at(0); + + irisCamPtr = IGXFactory::GetInstance().OpenDeviceByUserID(device.GetUserID(), GX_ACCESS_EXCLUSIVE); + irisFeaturePtr = irisCamPtr->GetRemoteFeatureControl(); + + // 判断设备流是否大于零, 如果大于零则打开流 + int nStreamCount = irisCamPtr->GetStreamCount(); + if (nStreamCount > 0) + { + irisStreamPtr = irisCamPtr->OpenStream(0); + irisStreamFeaturePtr = irisStreamPtr->GetFeatureControl(); + } + + // 建议用户在打开网络相机之后, 根据当前网络环境设置相机的流通道包长值, + // 以提高网络相机的采集性能, 设置方法参考以下代码。 + GX_DEVICE_CLASS_LIST objDeviceClass = irisCamPtr->GetDeviceInfo().GetDeviceClass(); + if(GX_DEVICE_CLASS_GEV == objDeviceClass) + { + // 判断设备是否支持流通道数据包功能 + if(true == irisFeaturePtr->IsImplemented("GevSCPSPacketSize")) + { + // 获取当前网络环境的最优包长值 + int nPacketSize = irisStreamPtr->GetOptimalPacketSize(); + // 将最优包长值设置为当前设备的流通道包长值 + irisFeaturePtr->GetIntFeature("GevSCPSPacketSize")->SetValue(nPacketSize); + } + } + + //设置采集模式为连续采集模式 + irisFeaturePtr->GetEnumFeature("AcquisitionMode")->SetValue("Continuous"); + + //设置触发模式关 + irisFeaturePtr->GetEnumFeature("TriggerMode")->SetValue("On"); + irisFeaturePtr->GetEnumFeature("TriggerSource")->SetValue("Software"); +} diff --git a/device/IrisCameraController.h b/device/IrisCameraController.h new file mode 100644 index 0000000..5d7e269 --- /dev/null +++ b/device/IrisCameraController.h @@ -0,0 +1,49 @@ +#ifndef IRISCAMERACONTROLLER_H +#define IRISCAMERACONTROLLER_H + +#include + +#include "IrisCameraCapEventHandler.h" + +class IrisCameraCapEventHandler; + +class IrisCameraController : public QObject +{ + Q_OBJECT +public: + explicit IrisCameraController(QObject *parent = nullptr); + ~IrisCameraController(); + + // 初始化并打开人脸相机 + void initIrisCamera(); + void openIrisCamera(); + void closeIrisCamera(); + + void startCapture(); + void stopCapture(); + + void getLeftAndRightEyeFrame(); + + IrisCameraCapEventHandler * irisCamHandler; + +private: + GxIAPICPP::gxdeviceinfo_vector irisCamList; + + CGXDevicePointer irisCamPtr; ///< 设备句柄 + + CGXStreamPointer irisStreamPtr; ///< 左眼设备流 + + CGXFeatureControlPointer irisFeaturePtr; ///< 左眼属性控制器 + + CGXFeatureControlPointer irisStreamFeaturePtr; ///< 左眼流层控制器对象 + + void OpenDevice(); + +signals: + +public slots: + void getOneFaceFrm(); + +}; + +#endif // IRISCAMERACONTROLLER_H diff --git a/device/device.pri b/device/device.pri new file mode 100644 index 0000000..a8417f2 --- /dev/null +++ b/device/device.pri @@ -0,0 +1,13 @@ + +HEADERS += $$PWD/IrisCameraController.h +HEADERS += $$PWD/IrisCameraCapEventHandler.h +#HEADERS += $$PWD/iris/IrisRegistProcess.h +#HEADERS += $$PWD/iris/IrisRecogProcess.h +#HEADERS += $$PWD/iris/CasicIrisRecState.h + +SOURCES += $$PWD/IrisCameraController.cpp +SOURCES += $$PWD/IrisCameraCapEventHandler.cpp +#SOURCES += $$PWD/iris/IrisRegistProcess.cpp +#SOURCES += $$PWD/iris/IrisRecogProcess.cpp +#SOURCES += $$PWD/iris/CasicIrisRecState.cpp + diff --git a/images/bg_footer.png b/images/bg_footer.png new file mode 100644 index 0000000..a3a99ab --- /dev/null +++ b/images/bg_footer.png Binary files differ diff --git a/images/bg_statcked.png b/images/bg_statcked.png new file mode 100644 index 0000000..18b63e1 --- /dev/null +++ b/images/bg_statcked.png Binary files differ diff --git a/images/bg_title.png b/images/bg_title.png new file mode 100644 index 0000000..0316e2d --- /dev/null +++ b/images/bg_title.png Binary files differ diff --git a/main.cpp b/main.cpp index 16bc45b..9052ddb 100644 --- a/main.cpp +++ b/main.cpp @@ -1,11 +1,11 @@ -#include "IdentifyForm.h" +#include "MainWindowForm.h" #include int main(int argc, char *argv[]) { QApplication a(argc, argv); - IdentifyForm w; + MainWindowForm w; w.show(); return a.exec(); } diff --git a/resource.qrc b/resource.qrc new file mode 100644 index 0000000..474586a --- /dev/null +++ b/resource.qrc @@ -0,0 +1,35 @@ + + + images/setting.png + images/user.png + images/back.png + images/home.png + images/btnPageFirst.png + images/btnPageLast.png + images/btnPageNext.png + images/btnPagePre.png + images/regist.png + images/photoEyeLeft.png + images/photoEyeRight.png + images/photoFace.png + images/save.png + images/upArrow.png + images/downArrow.png + images/faceCaped.png + images/faceNotCap.png + images/irisCaped.png + images/irisNotCap.png + images/tipsFailure.png + images/tipsSuccess.png + images/tipsConfirm.png + images/bg_recognize_result.png + images/iconRetry.png + images/bg_title.png + images/bg_footer.png + images/bg_statcked.png + + + images/add_bottom.png + images/add_top.png + + diff --git a/utils/ImageUtil.cpp b/utils/ImageUtil.cpp new file mode 100644 index 0000000..7604572 --- /dev/null +++ b/utils/ImageUtil.cpp @@ -0,0 +1,97 @@ +#include "ImageUtil.h" + +ImageUtil::ImageUtil() +{ + +} + +QImage ImageUtil::MatImageToQImage(const cv::Mat &src) +{ + //CV_8UC1 8位无符号的单通道---灰度图片 + if(src.type() == CV_8UC1) + { + QImage qImage((const unsigned char *)(src.data), src.cols, src.rows, src.cols, QImage::Format_Grayscale8); + return qImage; + } + //为3通道的彩色图片 + else if(src.type() == CV_8UC3) + { + //得到图像的的首地址 + const uchar *pSrc = (const uchar*)src.data; + //以src构造图片 + QImage qImage(pSrc, src.cols, src.rows, src.step, QImage::Format_RGB888); + //在不改变实际图像数据的条件下, 交换红蓝通道 + return qImage.rgbSwapped(); + } + //四通道图片, 带Alpha通道的RGB彩色图像 + else if(src.type() == CV_8UC4) + { + const uchar *pSrc = (const uchar*)src.data; + QImage qImage(pSrc, src.cols, src.rows, src.step, QImage::Format_ARGB32); + //返回图像的子区域作为一个新图像 + return qImage.copy(); + } + else + { + return QImage(); + } +} +/* +QImage ImageUtil::UcharToQImage(unsigned char* data, int width, int height, QImage::Format format) +{ + QImage qImage(data, width, height, format); + //在不改变实际图像数据的条件下, 交换红蓝通道 + return qImage.rgbSwapped(); +} + +cv::Mat ImageUtil::QImageToMat(QImage image) +{ + cv::Mat mat; + switch(image.format()) + { + case QImage::Format_ARGB32: + case QImage::Format_RGB32: + case QImage::Format_ARGB32_Premultiplied: + mat = cv::Mat(image.height(), image.width(), CV_8UC4, (void*)image.constBits(), image.bytesPerLine()); + break; + case QImage::Format_RGB888: + mat = cv::Mat(image.height(), image.width(), CV_8UC3, (void*)image.constBits(), image.bytesPerLine()); + cv::cvtColor(mat, mat, cv::COLOR_BGR2RGB); + break; + case QImage::Format_Indexed8: + mat = cv::Mat(image.height(), image.width(), CV_8UC1, (void*)image.constBits(), image.bytesPerLine()); + break; + case QImage::Format_Grayscale8: + mat = cv::Mat(image.height(), image.width(), CV_8UC1, (void *)image.bits(), image.bytesPerLine()); + break; + } + + mat = mat.clone(); + + return mat; +} + +QString ImageUtil::QImageToBase64(QImage image) +{ + QByteArray ba; + QBuffer buf(&ba); + image.save(&buf, "bmp"); + QString base64String = ba.toBase64(); + return base64String; +} + +cv::Mat ImageUtil::MatImageRect(const cv::Mat &src, cv::Rect rect, int delta) +{ + cv::Mat matClone = src.clone(); + cv::Rect bigRect; + + bigRect.x = rect.x - delta < 0 ? 0 : rect.x - delta; + bigRect.y = rect.y - delta < 0 ? 0 : rect.y - delta; + bigRect.width = rect.x + rect.width + 2 * delta > src.cols ? src.cols - rect.x : rect.width + 2 * delta; + bigRect.height = rect.y + rect.height + 2 * delta > src.rows ? src.rows - rect.y : rect.height + 2 * delta; + + cv::Mat roi = matClone(bigRect); + + return roi; +} +*/ diff --git a/utils/ImageUtil.h b/utils/ImageUtil.h new file mode 100644 index 0000000..dbfdd48 --- /dev/null +++ b/utils/ImageUtil.h @@ -0,0 +1,22 @@ +#ifndef IMAGEUTIL_H +#define IMAGEUTIL_H + +#include +#include +#include "opencv2/opencv.hpp" + +class ImageUtil +{ +public: + ImageUtil(); + + static QImage MatImageToQImage(const cv::Mat &src); +// static QImage UcharToQImage(unsigned char* data, int width, int height, QImage::Format format); + +// static cv::Mat QImageToMat(QImage image); +// static QString QImageToBase64(QImage image); + +// static cv::Mat MatImageRect(const cv::Mat &src, cv::Rect rect, int delta); +}; + +#endif // IMAGEUTIL_H diff --git a/utils/SettingConfig.cpp b/utils/SettingConfig.cpp new file mode 100644 index 0000000..d420285 --- /dev/null +++ b/utils/SettingConfig.cpp @@ -0,0 +1,44 @@ +#include "SettingConfig.h" +#include + +SettingConfig::SettingConfig() +{ + filename = QApplication::applicationDirPath() + "/conf/config.ini"; + setting = new QSettings(this->filename, QSettings::IniFormat); + + WINDOW_WIDTH = getProperty("window", "width").toInt(); + WINDOW_HEIGHT = getProperty("window", "height").toInt(); + WINDOW_BACKGROUND_COLOR = getProperty("window", "backgroundColor").toString(); + WINDOW_TITLE = getProperty("window", "title").toString(); + WINDOW_RIGHTS = getProperty("window", "copyright").toString(); + WINDOW_VERSION = getProperty("window", "version").toString(); + + IRIS_FRAME_WIDTH = getProperty("camera", "irisFrameWidth").toInt(); + IRIS_FRAME_HEIGHT = getProperty("camera", "irisFrameHeight").toInt(); + IRIS_WIDTH = getProperty("camera", "irisWidth").toInt(); + IRIS_HEIGHT = getProperty("camera", "irisHeight").toInt(); + IRIS_FRAME_INTERVAL = getProperty("camera", "irisFrameInterval").toInt(); + IRIS_DISPLAY_WIDTH = getProperty("camera", "irisDisplayWidth").toInt(); + IRIS_DISPLAY_HEIGHT = getProperty("camera", "irisDisplayHeight").toInt(); + + MAX_MATCH_TIME = getProperty("recognize", "maxMatchTime").toInt(); + SUCCESS_TIPS_LAST = getProperty("recognize", "successTipsLast").toInt(); + FAILURE_TIPS_LAST = getProperty("recognize", "failureTipsLast").toInt(); + MAX_FACE_TRY_COUNT = getProperty("recognize", "maxFaceTryCount").toInt(); + MAX_FACE_NOT_FOUND_COUNT = getProperty("recognize", "maxFaceNotFoundCount").toInt(); + MAX_IRIS_TRY_COUNT = getProperty("recognize", "maxIrisTryCount").toInt(); + MAX_EYE_NOT_FOUND_COUNT = getProperty("recognize", "maxEyeNotFoundCount").toInt(); + + MAX_CAPTURE_STACK_SIZE = getProperty("stack", "capture").toInt(); + MAX_FOUND_STACK_SIZE = getProperty("stack", "found").toInt(); + MAX_QUALIFIED_STACK_SIZE = getProperty("stack", "qualified").toInt(); + + LOG_FILE = getProperty("log", "logFile").toString(); + LOG_LEVEL = getProperty("log", "logLevel").toString(); +} + + +QVariant SettingConfig::getProperty(QString nodeName, QString keyName) { + QVariant var = this->setting->value(QString("/%1/%2").arg(nodeName).arg(keyName)); + return var; +} diff --git a/utils/SettingConfig.h b/utils/SettingConfig.h new file mode 100644 index 0000000..30c3bec --- /dev/null +++ b/utils/SettingConfig.h @@ -0,0 +1,66 @@ +#ifndef SETTINGCONFIG_H +#define SETTINGCONFIG_H + +#include +#include + +class SettingConfig : public QObject +{ +public: + ~SettingConfig() {}; + SettingConfig(const SettingConfig&)=delete; + SettingConfig& operator=(const SettingConfig&)=delete; + + static SettingConfig& getInstance() { + static SettingConfig instance; + return instance; + } + + /** + * @brief get + * @param nodeName + * @param keyName + * @return QVariant + * @title + */ + QVariant getProperty(QString nodeName, QString keyName); + + /******** 以下为需要的各类参数 ********/ + int WINDOW_WIDTH; + int WINDOW_HEIGHT; + QString WINDOW_BACKGROUND_COLOR; + QString WINDOW_TITLE; + QString WINDOW_RIGHTS; + QString WINDOW_VERSION; + + int IRIS_FRAME_INTERVAL; + int IRIS_FRAME_WIDTH; + int IRIS_FRAME_HEIGHT; + int IRIS_WIDTH; + int IRIS_HEIGHT; + int IRIS_DISPLAY_WIDTH; + int IRIS_DISPLAY_HEIGHT; + + int MAX_MATCH_TIME; + int SUCCESS_TIPS_LAST; + int FAILURE_TIPS_LAST; + int MAX_FACE_TRY_COUNT; + int MAX_FACE_NOT_FOUND_COUNT; + int MAX_IRIS_TRY_COUNT; + int MAX_EYE_NOT_FOUND_COUNT; + + int MAX_CAPTURE_STACK_SIZE; + int MAX_FOUND_STACK_SIZE; + int MAX_QUALIFIED_STACK_SIZE; + + QString LOG_FILE; + QString LOG_LEVEL; + +private: + SettingConfig(); + + QString filename; + QSettings* setting; +}; + +#endif // SETTINGCONFIG_H diff --git a/utils/TimeCounterUtil.cpp b/utils/TimeCounterUtil.cpp new file mode 100644 index 0000000..275945f --- /dev/null +++ b/utils/TimeCounterUtil.cpp @@ -0,0 +1,8 @@ +#include "TimeCounterUtil.h" + +TimeCounterUtil::TimeCounterUtil() +{ + faceCapCounter = new QTimer(); + irisCapCounter = new QTimer(); + clockCounter = new QTimer(); +} diff --git a/utils/TimeCounterUtil.h b/utils/TimeCounterUtil.h new file mode 100644 index 0000000..28b29f1 --- /dev/null +++ b/utils/TimeCounterUtil.h @@ -0,0 +1,29 @@ +#ifndef TIMECOUNTERUTIL_H +#define TIMECOUNTERUTIL_H + +#include +#include + +class TimeCounterUtil : public QObject +{ +public: + + ~TimeCounterUtil() {}; + TimeCounterUtil(const TimeCounterUtil&)=delete; + TimeCounterUtil& operator=(const TimeCounterUtil&)=delete; + + static TimeCounterUtil& getInstance() { + static TimeCounterUtil instance; + return instance; + } + + QTimer * faceCapCounter; + QTimer * irisCapCounter; + QTimer * clockCounter; + +private: + TimeCounterUtil(); + +}; + +#endif // TIMECOUNTERUTIL_H diff --git a/utils/UtilInclude.h b/utils/UtilInclude.h new file mode 100644 index 0000000..e7b899a --- /dev/null +++ b/utils/UtilInclude.h @@ -0,0 +1,13 @@ +#ifndef UTILINCLUDE_H +#define UTILINCLUDE_H + +//#include "ByteUtil.h" +#include "ImageUtil.h" +//#include "LogUtil.h" +#include "SettingConfig.h" +//#include "SpeakerUtil.h" +#include "TimeCounterUtil.h" +//#include "UDPClientUtil.h" +//#include "HttpRequestUtil.h" + +#endif // UTILINCLUDE_H diff --git a/utils/id/IdWorker.h b/utils/id/IdWorker.h new file mode 100644 index 0000000..6c48aa9 --- /dev/null +++ b/utils/id/IdWorker.h @@ -0,0 +1,218 @@ +#ifndef _JW_CORE_ID_WORKER_H_ +#define _JW_CORE_ID_WORKER_H_ + +#include +#include +#include +#include +#include +#include "Noncopyable.h" +#include "Singleton.h" + +// 如果不使用 mutex, 则开启下面这个定义, 但是我发现, 还是开启 mutex 功能, 速度比较快 +// #define SNOWFLAKE_ID_WORKER_NO_LOCK + +namespace Jiawa { + + /** + * @brief 核心 + * 核心功能 + */ + namespace Core { + + /** + * @brief 分布式id生成类 + * https://segmentfault.com/a/1190000011282426 + * https://github.com/twitter/snowflake/blob/snowflake-2010/src/main/scala/com/twitter/service/snowflake/IdWorker.scala + * + * 64bit id: 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 + * || || || | | | + * |└---------------------------时间戳--------------------------┘└中心-┘└机器-┘ └----序列号----┘ + * | + * 不用 + * SnowFlake的优点: 整体上按照时间自增排序, 并且整个分布式系统内不会产生ID碰撞(由数据中心ID和机器ID作区分), 并且效率较高, 经测试, SnowFlake每秒能够产生26万ID左右. + */ + class SnowflakeIdWorker : private Noncopyable { + + // 实现单例 + friend class Singleton; + + public: + typedef unsigned int UInt; + typedef unsigned long long int UInt64; + +#ifdef SNOWFLAKE_ID_WORKER_NO_LOCK + typedef std::atomic AtomicUInt; + typedef std::atomic AtomicUInt64; +#else + typedef UInt AtomicUInt; + typedef UInt64 AtomicUInt64; +#endif + + void setWorkerId(UInt workerId) { + this->workerId = workerId; + } + + void setDatacenterId(UInt datacenterId) { + this->datacenterId = datacenterId; + } + + UInt64 getId() { + return nextId(); + } + + /** + * 获得下一个ID (该方法是线程安全的) + * + * @return SnowflakeId + */ + UInt64 nextId() { +#ifndef SNOWFLAKE_ID_WORKER_NO_LOCK + std::unique_lock lock{ mutex }; + AtomicUInt64 timestamp{ 0 }; +#else + static AtomicUInt64 timestamp{ 0 }; +#endif + timestamp = timeGen(); + + // 如果当前时间小于上一次ID生成的时间戳, 说明系统时钟回退过这个时候应当抛出异常 + if (timestamp < lastTimestamp) { + std::ostringstream s; + s << "clock moved backwards. Refusing to generate id for " << lastTimestamp - timestamp << " milliseconds"; + throw std::exception(std::runtime_error(s.str())); + } + + if (lastTimestamp == timestamp) { + // 如果是同一时间生成的, 则进行毫秒内序列 + sequence = (sequence + 1) & sequenceMask; + if (0 == sequence) { + // 毫秒内序列溢出, 阻塞到下一个毫秒,获得新的时间戳 + timestamp = tilNextMillis(lastTimestamp); + } + } else { + sequence = 0; + } + +#ifndef SNOWFLAKE_ID_WORKER_NO_LOCK + lastTimestamp = timestamp; +#else + lastTimestamp = timestamp.load(); +#endif + + // 移位并通过或运算拼到一起组成64位的ID + return ((timestamp - twepoch) << timestampLeftShift) + | (datacenterId << datacenterIdShift) + | (workerId << workerIdShift) + | sequence; + } + + protected: + SnowflakeIdWorker() : workerId(0), datacenterId(0), sequence(0), lastTimestamp(0) { } + + /** + * 返回以毫秒为单位的当前时间 + * + * @return 当前时间(毫秒) + */ + UInt64 timeGen() const { + auto t = std::chrono::time_point_cast(std::chrono::high_resolution_clock::now()); + return t.time_since_epoch().count(); + } + + /** + * 阻塞到下一个毫秒, 直到获得新的时间戳 + * + * @param lastTimestamp 上次生成ID的时间截 + * @return 当前时间戳 + */ + UInt64 tilNextMillis(UInt64 lastTimestamp) const { + UInt64 timestamp = timeGen(); + while (timestamp <= lastTimestamp) { + timestamp = timeGen(); + } + return timestamp; + } + + private: + +#ifndef SNOWFLAKE_ID_WORKER_NO_LOCK + std::mutex mutex; +#endif + + /** + * 开始时间截 (2018-01-01 00:00:00.000) + */ + const UInt64 twepoch = 1514736000000; + + /** + * 机器id所占的位数 + */ + const UInt workerIdBits = 5; + + /** + * 数据中心id所占的位数 + */ + const UInt datacenterIdBits = 5; + + /** + * 序列所占的位数 + */ + const UInt sequenceBits = 12; + + /** + * 机器ID向左移12位 + */ + const UInt workerIdShift = sequenceBits; + + /** + * 数据标识id向左移17位 + */ + const UInt datacenterIdShift = workerIdShift + workerIdBits; + + /** + * 时间截向左移22位 + */ + const UInt timestampLeftShift = datacenterIdShift + datacenterIdBits; + + /** + * 支持的最大机器id, 结果是31 + */ + const UInt maxWorkerId = -1 ^ (-1 << workerIdBits); + + /** + * 支持的最大数据中心id, 结果是31 + */ + const UInt maxDatacenterId = -1 ^ (-1 << datacenterIdBits); + + /** + * 生成序列的掩码, 这里为4095 + */ + const UInt sequenceMask = -1 ^ (-1 << sequenceBits); + + /** + * 工作机器id(0~31) + */ + UInt workerId; + + /** + * 数据中心id(0~31) + */ + UInt datacenterId; + + /** + * 毫秒内序列(0~4095) + */ + AtomicUInt sequence{ 0 }; + + /** + * 上次生成ID的时间截 + */ + AtomicUInt64 lastTimestamp{ 0 }; + + }; + + typedef SnowflakeIdWorker IdWorker; + } +} + +#endif // _JW_CORE_ID_WORKER_H_ diff --git a/utils/id/Noncopyable.h b/utils/id/Noncopyable.h new file mode 100644 index 0000000..d87f58a --- /dev/null +++ b/utils/id/Noncopyable.h @@ -0,0 +1,31 @@ +#ifndef _JW_CORE_NONCOPYABLE_H_ +#define _JW_CORE_NONCOPYABLE_H_ + + +// Private copy constructor and copy assignment ensure classes derived from +// class noncopyable cannot be copied. + +namespace Jiawa { + namespace Core { + + // protection from unintended ADL(Argument Dependent Lookup) + namespace Noncopyable_ { + + class Noncopyable + { + protected: + Noncopyable() = default; + ~Noncopyable() = default; + + Noncopyable(const Noncopyable&) = delete; + Noncopyable(const Noncopyable&&) = delete; + Noncopyable& operator=(const Noncopyable&) = delete; + Noncopyable& operator=(const Noncopyable&&) = delete; + }; + } + + typedef Noncopyable_::Noncopyable Noncopyable; + } +} + +#endif // _JW_CORE_NONCOPYABLE_H_ diff --git a/utils/id/Singleton.h b/utils/id/Singleton.h new file mode 100644 index 0000000..d1c0553 --- /dev/null +++ b/utils/id/Singleton.h @@ -0,0 +1,60 @@ +#ifndef _JW_CORE_SINGLETON_H_ +#define _JW_CORE_SINGLETON_H_ + +namespace Jiawa { + namespace Core { + + // boost/container/detail/singleton.hpp + // http://blog.csdn.net/fullsail/article/details/8483106 + // T must be: no-throw default constructible and no-throw destructible + template + class Singleton { + private: + Singleton() = default; + ~Singleton() = default; + + private: + struct object_creator + { + // This constructor does nothing more than ensure that instance() + // is called before main() begins, thus creating the static + // T object before multithreading race issues can come up. + object_creator() { Singleton::instance(); } + inline void do_nothing() const { } + }; + static object_creator create_object; + + private: + Singleton(const Singleton&) = delete; + Singleton(const Singleton&&) = delete; + Singleton& operator=(const Singleton&) = delete; + Singleton& operator=(const Singleton&&) = delete; + + public: + typedef T object_type; + + // If, at any point (in user code), Singleton::instance() + // is called, then the following function is instantiated. + static object_type& instance() + { + // This is the object that we return a reference to. + // It is guaranteed to be created before main() begins because of + // the next line. + static object_type obj; + + // The following line does nothing else than force the instantiation + // of Singleton::create_object, whose constructor is + // called before main() begins. + create_object.do_nothing(); + + return obj; + } + }; + + template + typename Singleton::object_creator Singleton::create_object; + } +} + +#endif // _JW_CORE_SINGLETON_H_ + diff --git a/AppConstants.h b/AppConstants.h new file mode 100644 index 0000000..296c53f --- /dev/null +++ b/AppConstants.h @@ -0,0 +1,28 @@ +#ifndef APPCONSTANTS_H +#define APPCONSTANTS_H + +class AppConstants +{ +public: + enum WidgeFrameName + { + MAIN_PAGE = 0, // 主页面 + PERSON_LIST_FORM = 1, // 人员列表页面 + ADD_PERSON_FORM = 2, // 添加人员页面 + ADD_PERSON_CAPTURE_FACE = 21, // 添加/编辑人员时进行人脸拍图 + ADD_PERSON_CAPTURE_IRIS = 22, // 添加/编辑人员时进行虹膜拍图 + SETTING_FORM = 3, // 设置页面 + RECOGNIZE_RESULT_FORM = 4, // 识别结果界面 + IDENTIFY_FORM = 5, // 识别界面 含识别中 和 识别结果 + LOCKSCREEN_FORM = 6 // 锁屏待机界面 + }; + + enum ApplicationState + { + STATE_WAIT = 0, // 待机 + STATE_WORKING = 1, // 工作状态 + STATE_IDENTIFYING = 2, // 识别中 + }; +}; + +#endif // APPCONSTANTS_H diff --git a/CasicIrisIdentify.pro b/CasicIrisIdentify.pro index 5d7fea6..575ce3d 100644 --- a/CasicIrisIdentify.pro +++ b/CasicIrisIdentify.pro @@ -1,4 +1,4 @@ -QT += core gui +QT += core gui sql network texttospeech greaterThan(QT_MAJOR_VERSION, 4): QT += widgets @@ -15,20 +15,46 @@ # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 -SOURCES += \ - main.cpp \ - IdentifyForm.cpp +include("dao/dao.pri") +include("device/device.pri") +include("utils/utils.pri") -HEADERS += \ - IdentifyForm.h +SOURCES += main.cpp +SOURCES += ProMemory.cpp +SOURCES += MainWindowForm.cpp +SOURCES += IdentifyForm.cpp +SOURCES += LockScreenForm.cpp -FORMS += \ - IdentifyForm.ui +HEADERS += AppConstants.h +HEADERS += ProMemory.h +HEADERS += MainWindowForm.h +HEADERS += IdentifyForm.h +HEADERS += LockScreenForm.h -TRANSLATIONS += \ - CasicIrisIdentify_zh_CN.ts +FORMS += MainWindowForm.ui +FORMS += IdentifyForm.ui +FORMS += LockScreenForm.ui + +RESOURCES += resource.qrc + +DISTFILES += conf/config.ini + +#TRANSLATIONS += CasicIrisIdentify_zh_CN.ts + +#INCLUDEPATH += include/spdlog +#DEPENDPATH += include/spdlog # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target + + +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lopencv_world420 +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lGxIAPICPPEx + +INCLUDEPATH += $$PWD/include/daheng +DEPENDPATH += $$PWD/include/daheng + +INCLUDEPATH += $$PWD/include +DEPENDPATH += $$PWD/include diff --git a/CasicIrisIdentify_zh_CN.ts b/CasicIrisIdentify_zh_CN.ts index 5526fe4..81900df 100644 --- a/CasicIrisIdentify_zh_CN.ts +++ b/CasicIrisIdentify_zh_CN.ts @@ -1,3 +1,12 @@ - + + + IdentifyForm + + + IdentifyForm + + + + diff --git a/IdentifyForm.cpp b/IdentifyForm.cpp index 348a897..ba1f251 100644 --- a/IdentifyForm.cpp +++ b/IdentifyForm.cpp @@ -1,4 +1,4 @@ -#include "IdentifyForm.h" +#include "IdentifyForm.h" #include "ui_IdentifyForm.h" IdentifyForm::IdentifyForm(QWidget *parent) @@ -6,6 +6,12 @@ , ui(new Ui::IdentifyForm) { ui->setupUi(this); + + // 初始化更新界面的定时器 + // 每秒执行一次 + connect(TimeCounterUtil::getInstance().clockCounter, &QTimer::timeout, this, &IdentifyForm::updateDateAndTime); + + TimeCounterUtil::getInstance().clockCounter->start(1000); } IdentifyForm::~IdentifyForm() @@ -13,3 +19,16 @@ delete ui; } +void IdentifyForm::drawIrisImageOnFrame(QImage image) +{ + // 只在识别界面才显示画面 + if (ui->wgtStacked->currentIndex() == 0) { + ui->labelVideo->setPixmap(QPixmap::fromImage(image)); + } +} + + +void IdentifyForm::updateDateAndTime() +{ + ui->labelTime->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd dddd HH:mm:ss")); +} diff --git a/IdentifyForm.h b/IdentifyForm.h index fc857a1..ae1cd22 100644 --- a/IdentifyForm.h +++ b/IdentifyForm.h @@ -1,7 +1,10 @@ -#ifndef IDENTIFYFORM_H +#ifndef IDENTIFYFORM_H #define IDENTIFYFORM_H #include +#include + +#include "utils/UtilInclude.h" QT_BEGIN_NAMESPACE namespace Ui { class IdentifyForm; } @@ -15,7 +18,14 @@ IdentifyForm(QWidget *parent = nullptr); ~IdentifyForm(); +public slots: + void drawIrisImageOnFrame(QImage image); + private: Ui::IdentifyForm *ui; + +private slots: + void updateDateAndTime(); + }; #endif // IDENTIFYFORM_H diff --git a/IdentifyForm.ui b/IdentifyForm.ui index c72a36f..879dc9a 100644 --- a/IdentifyForm.ui +++ b/IdentifyForm.ui @@ -6,13 +6,59 @@ 0 0 - 800 + 600 600 IdentifyForm + + + + 0 + 40 + 600 + 450 + + + + 0 + + + + + + 100 + 10 + 400 + 300 + + + + + + + + + + + + + + 0 + 0 + 600 + 40 + + + + TextLabel + + + Qt::AlignCenter + + diff --git a/LockScreenForm.cpp b/LockScreenForm.cpp new file mode 100644 index 0000000..58dc54b --- /dev/null +++ b/LockScreenForm.cpp @@ -0,0 +1,14 @@ +#include "LockScreenForm.h" +#include "ui_LockScreenForm.h" + +LockScreenForm::LockScreenForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::LockScreenForm) +{ + ui->setupUi(this); +} + +LockScreenForm::~LockScreenForm() +{ + delete ui; +} diff --git a/LockScreenForm.h b/LockScreenForm.h new file mode 100644 index 0000000..b5ded48 --- /dev/null +++ b/LockScreenForm.h @@ -0,0 +1,25 @@ +#ifndef LOCKSCREENFORM_H +#define LOCKSCREENFORM_H + +#include +#include + +#include "utils/UtilInclude.h" + +namespace Ui { +class LockScreenForm; +} + +class LockScreenForm : public QWidget +{ + Q_OBJECT + +public: + explicit LockScreenForm(QWidget *parent = nullptr); + ~LockScreenForm(); + +private: + Ui::LockScreenForm *ui; +}; + +#endif // LOCKSCREENFORM_H diff --git a/LockScreenForm.ui b/LockScreenForm.ui new file mode 100644 index 0000000..7f2a6db --- /dev/null +++ b/LockScreenForm.ui @@ -0,0 +1,45 @@ + + + LockScreenForm + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + 180 + 100 + 54 + 12 + + + + TextLabel + + + + + + 180 + 160 + 54 + 12 + + + + TextLabel + + + + + + diff --git a/MainWindowForm.cpp b/MainWindowForm.cpp new file mode 100644 index 0000000..84f8159 --- /dev/null +++ b/MainWindowForm.cpp @@ -0,0 +1,86 @@ +#include "MainWindowForm.h" +#include "ui_MainWindowForm.h" +#include + +MainWindowForm::MainWindowForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::MainWindowForm) +{ + ui->setupUi(this); + + // 设置窗口透明和大小、位置 + this->setWindowFlags(Qt::FramelessWindowHint); + this->move(1400, 15); + this->resize(SettingConfig::getInstance().WINDOW_WIDTH, SettingConfig::getInstance().WINDOW_HEIGHT); + + // 通过调色板的颜色来设置窗口的统一背景色 + qApp->setPalette(QPalette(QColor(SettingConfig::getInstance().WINDOW_BACKGROUND_COLOR))); + + // 加载css文件设置控件样式 + QFile file(QApplication::applicationDirPath() + "/qss/main.css"); + if (file.open(QFile::ReadOnly)) + { + QString qssStr = QLatin1String(file.readAll()); + this->setStyleSheet(qssStr); + file.close(); + } + + initFormsPtr(); + + // 设置标题文字 + ui->labelTitle->setText(SettingConfig::getInstance().WINDOW_TITLE); + ui->labelCopyright->setText(SettingConfig::getInstance().WINDOW_RIGHTS); + ui->labelVersion->setText(SettingConfig::getInstance().WINDOW_VERSION); + + // 初始化虹膜相机控制 + ProMemory::getInstance().irisCam = new IrisCameraController(this); + ProMemory::getInstance().irisCam->initIrisCamera(); + ProMemory::getInstance().irisCam->openIrisCamera(); + connect(ProMemory::getInstance().irisCam->irisCamHandler, &IrisCameraCapEventHandler::sendIrisFrameToDraw, identifyForm, &IdentifyForm::drawIrisImageOnFrame); + +// LOG_INFO(QString("应用程序启动成功[Application Startup Success]").toStdString()); + qDebug() << "应用程序启动成功[Application Startup Success]"; + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::IDENTIFY_FORM; + ui->wdgtStatced->setCurrentWidget(identifyForm); + + // 开始虹膜相机拍图 + ProMemory::getInstance().irisCam->startCapture(); +} + +MainWindowForm::~MainWindowForm() +{ + delete ui; +} + +void MainWindowForm::lockScreen() +{ + ui->wdgtStatced->setCurrentWidget(lockScreenForm); + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::LOCKSCREEN_FORM; + ProMemory::getInstance().appState = AppConstants::ApplicationState::STATE_WAIT; +} + +void MainWindowForm::keyPressEvent(QKeyEvent *event) +{ + switch (event->key()) { + case Qt::Key_Escape: + QTimer::singleShot(100, qApp, [=](){ + QApplication::quit(); + }); + + default: + QWidget::keyPressEvent(event); + } +} + +void MainWindowForm::initFormsPtr() +{ + // 初始化各个form + lockScreenForm = new LockScreenForm(this); + identifyForm = new IdentifyForm(this); + + // 将form添加到statcked widget中 + ui->wdgtStatced->addWidget(identifyForm); + ui->wdgtStatced->addWidget(lockScreenForm); + + // 绑定按钮函数 +} diff --git a/MainWindowForm.h b/MainWindowForm.h new file mode 100644 index 0000000..7fb2d89 --- /dev/null +++ b/MainWindowForm.h @@ -0,0 +1,38 @@ +#ifndef MAINWINDOWFORM_H +#define MAINWINDOWFORM_H + +#include +#include +#include + +#include "utils/UtilInclude.h" +#include "ProMemory.h" +#include "LockScreenForm.h" +#include "IdentifyForm.h" + +namespace Ui { +class MainWindowForm; +} + +class MainWindowForm : public QWidget +{ + Q_OBJECT + +public: + explicit MainWindowForm(QWidget *parent = nullptr); + ~MainWindowForm(); + +public slots: + void lockScreen(); + +private: + Ui::MainWindowForm *ui; + LockScreenForm * lockScreenForm; + IdentifyForm * identifyForm; + + void keyPressEvent(QKeyEvent *event); + + void initFormsPtr(); +}; + +#endif // MAINWINDOWFORM_H diff --git a/MainWindowForm.ui b/MainWindowForm.ui new file mode 100644 index 0000000..e793ebf --- /dev/null +++ b/MainWindowForm.ui @@ -0,0 +1,85 @@ + + + MainWindowForm + + + + 0 + 0 + 600 + 1024 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + 0 + 0 + 600 + 84 + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + + + + TextLabel + + + Qt::AlignBottom|Qt::AlignHCenter + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + diff --git a/ProMemory.cpp b/ProMemory.cpp new file mode 100644 index 0000000..19e7403 --- /dev/null +++ b/ProMemory.cpp @@ -0,0 +1,84 @@ +#include "ProMemory.h" + +ProMemory::ProMemory() +{ + +} + +ProMemory::~ProMemory() +{ + +} + +/* +void ProMemory::pushCasicIris(CasicIrisInfo irisInfo) +{ + QMutex mutex; + mutex.lock(); + if (this->irisQueue.size() > 30) + { + QStack empty; + std::swap(empty, irisQueue); + } + + irisQueue.push(irisInfo); + mutex.unlock(); +} +CasicIrisInfo ProMemory::popCasicIris() +{ + CasicIrisInfo result; + + QMutex mutex; + mutex.lock(); + if (this->irisQueue.size() > 0) + { + result = irisQueue.pop(); + } + + mutex.unlock(); + + return result; +} +*/ +int ProMemory::getIrisQueueSize() +{ + int size = 0; + + QMutex mutex; + mutex.lock(); + +// size = this->irisQueue.size(); + + mutex.unlock(); + + return size; +} +bool ProMemory::isIrisQueueEmpty() +{ + bool empty = true; + + QMutex mutex; + mutex.lock(); + +// empty = this->irisQueue.isEmpty(); + + mutex.unlock(); + + return empty; +} +void ProMemory::clearIrisQueue() +{ + QMutex mutex; + mutex.lock(); + +// QStack empty; +// std::swap(empty, irisQueue); + + mutex.unlock(); +} + + +void ProMemory::initIrisFeatures(QString personId) +{ +// irisRegistPro->sendDataToExract(QByteArray(QString("[-u]").append(personId).toLocal8Bit())); +} diff --git a/ProMemory.h b/ProMemory.h new file mode 100644 index 0000000..2ecd653 --- /dev/null +++ b/ProMemory.h @@ -0,0 +1,52 @@ +#ifndef PROMEMORY_H +#define PROMEMORY_H + +#include +#include + +#include "AppConstants.h" +//#include "casic/iris/CasicIrisInfo.h" +#include "dao/IrisDataDao.h" + +#include "device/IrisCameraController.h" +//#include "device/iris/IrisRegistProcess.h" +//#include "device/iris/IrisRecogProcess.h" + +class IrisCameraController; +class IrisRegistProcess; +class IrisRecogProcess; + +class ProMemory +{ +public: + ~ProMemory(); + ProMemory(const ProMemory&)=delete; + ProMemory& operator=(const ProMemory&)=delete; + + static ProMemory& getInstance() { + static ProMemory instance; + return instance; + } + +// void pushCasicIris(CasicIrisInfo irisInfo); +// CasicIrisInfo popCasicIris(); + int getIrisQueueSize(); + bool isIrisQueueEmpty(); + void clearIrisQueue(); + + volatile int widgeFrame = 0; // 当前显示的界面 + volatile int appState = 0; // 当前程序所处的状态 + + void initIrisFeatures(QString personId = ""); // 初始化虹膜特征值集合 + + IrisCameraController * irisCam; + IrisRecogProcess * irisRecogPro; + +private: + ProMemory(); + +// QStack irisQueue; // 虹膜信息队列 + QVector irisFeatures; // 虹膜特征值集合 +}; + +#endif // PROMEMORY_H diff --git a/conf/config.ini b/conf/config.ini new file mode 100644 index 0000000..66e46ad --- /dev/null +++ b/conf/config.ini @@ -0,0 +1,67 @@ +[recognize] +#最大允许识别时间(ms) +maxMatchTime=10000 +#识别成功界面停留时间(ms) +successTipsLast=5000 +#识别失败界面停留时间(ms) +failureTipsLast=3000 +#人脸识别最大尝试次数 +maxFaceTryCount=20 +#持续没找到人脸的最大次数 +maxFaceNotFoundCount=500 +#注册时最小人脸 +minFaceRegist=240 +#识别时最小人脸 +minFaceRecog=100 + +#虹膜识别最大尝试次数 +maxIrisTryCount=10 +#虹膜识别持续没有找到眼的最大次数 +maxEyeNotFoundCount=50 + +#识别方式[1=人脸;2=虹膜;3=双认证;4=任意] +recogType=4 + +[window] +#界面窗口宽(px) +width=600 +#界面窗口高(px) +height=1024 +#统一背景色 +backgroundColor="#FFFFFF" +#标题 +title="虹膜识别终端" + +[work] +#工作状态检测时最小人脸范围 +minFaceSize=160 +#人脸范围最小横坐标 +minFacePosX=320 +#人脸范围最大横坐标 +maxFacePosX=960 +#人脸范围最小纵坐标 +minFacePosY=180 +#人脸范围最大纵坐标 +maxFacePosY=540 +#人脸太近阈值 +faceCloseSize=360 +#人脸太远阈值 +faceFarSize=480 + +[camera] +#虹膜相机取一幅画面的时间间隔(ms) +irisFrameInterval=100 +#虹膜相机拍摄宽度 +irisFrameWidth=1440 +#虹膜相机拍摄高度 +irisFrameHeight=1080 +#虹膜图像高度 +irisWidth=640 +#虹膜图像高度 +irisHeight=480 + +[log] +#日志文件位置 +logFile="d://irisLogs//casic_log.txt" +#日志级别 +logLevel="trace" diff --git a/dao/BaseDao.cpp b/dao/BaseDao.cpp new file mode 100644 index 0000000..f51c144 --- /dev/null +++ b/dao/BaseDao.cpp @@ -0,0 +1,12 @@ +#include "BaseDao.h" +#include "dao/util/ConnectionManager.h" + +BaseDao::BaseDao(QObject *parent) : QObject(parent) +{ + +} + +BaseDao::~BaseDao() +{ + +} diff --git a/dao/BaseDao.h b/dao/BaseDao.h new file mode 100644 index 0000000..1693c88 --- /dev/null +++ b/dao/BaseDao.h @@ -0,0 +1,32 @@ +#ifndef BASEDAO_H +#define BASEDAO_H + +#include +#include +#include +#include + +#include "dao/util/ConnectionManager.h" +#include "utils/UtilInclude.h" + +class BaseDao : public QObject +{ + Q_OBJECT +public: + explicit BaseDao(QObject *parent = nullptr); + ~BaseDao(); + + virtual QVector findAllRecord() = 0; + virtual QVariantMap findRecordById(QString id) = 0; + + virtual QString save(QVariantMap object) = 0; + virtual bool edit(QVariantMap newObject, QString id) = 0; + virtual bool dele(QString id) = 0; + +private: + +signals: + +}; + +#endif // BASEDAO_H diff --git a/dao/IrisDataDao.cpp b/dao/IrisDataDao.cpp new file mode 100644 index 0000000..37a0ed6 --- /dev/null +++ b/dao/IrisDataDao.cpp @@ -0,0 +1,204 @@ +#include "IrisDataDao.h" + +IrisDataDao::IrisDataDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector IrisDataDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM IRIS_DATA"; + query.prepare(sql); + + // 执行查询 + query.exec(); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + item.insert("id", query.value("id").toString()); + item.insert("person_id", query.value("person_id").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("left_iris_code1", query.value("left_iris_code1")); + item.insert("left_iris_code2", query.value("left_iris_code2")); + item.insert("left_iris_code3", query.value("left_iris_code3")); + item.insert("right_iris_code1", query.value("right_iris_code1")); + item.insert("right_iris_code2", query.value("right_iris_code2")); + item.insert("right_iris_code3", query.value("right_iris_code3")); + + result.append(item); + } + +// LOG_DEBUG(QString("查询IRIS_DATA表的所有记录[结果数:%1]").arg(result.size()).toStdString()); + return result; +} + +QVariantMap IrisDataDao::findRecordById(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM IRIS_DATA WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + // 获取结果 + if (query.next()) + { + result.insert("id", query.value("id").toString()); + result.insert("person_id", query.value("person_id").toLongLong()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("left_iris_code1", query.value("left_iris_code1")); + result.insert("left_iris_code2", query.value("left_iris_code2")); + result.insert("left_iris_code3", query.value("left_iris_code3")); + result.insert("right_iris_code1", query.value("right_iris_code1")); + result.insert("right_iris_code2", query.value("right_iris_code2")); + result.insert("right_iris_code3", query.value("right_iris_code3")); + } + +// LOG_DEBUG(QString("根据id查询IRIS_DATA表的记录[id=%1]").arg(id).toStdString()); + return result; +} + +QVariantMap IrisDataDao::findRecordByPersonId(QString personId) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM IRIS_DATA WHERE PERSON_ID = :personId"); + query.prepare(sql); + query.bindValue(":personId", personId); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + if (query.next()) + { + result.insert("id", query.value("id").toString()); + result.insert("person_id", query.value("person_id").toLongLong()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("left_iris_code1", query.value("left_iris_code1")); + result.insert("left_iris_code2", query.value("left_iris_code2")); + result.insert("left_iris_code3", query.value("left_iris_code3")); + result.insert("right_iris_code1", query.value("right_iris_code1")); + result.insert("right_iris_code2", query.value("right_iris_code2")); + result.insert("right_iris_code3", query.value("right_iris_code3")); + } + +// LOG_DEBUG(QString("根据personId查询IRIS_DATA表的记录[personId=%1]").arg(personId).toStdString()); + return result; +} + + +QString IrisDataDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + + // INSERT语句 + QString sql = QString("INSERT INTO IRIS_DATA (ID, PERSON_ID, ID_CARD_NO, LEFT_IRIS_CODE1, RIGHT_IRIS_CODE1) VALUES (:id, :personId, :idCardNo, :left1, :right1)"); + + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":personId", object.value("person_id").toString()); + query.bindValue(":idCardNo", object.value("id_card_no").toString()); + query.bindValue(":left1", object.value("left_iris_code1")); + query.bindValue(":right1", object.value("right_iris_code1")); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(); + +// LOG_DEBUG(QString("保存虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool IrisDataDao::edit(QVariantMap newObject, QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // UPDATE语句 + if (!newObject.contains("left_iris_code1") || !newObject.contains("right_iris_code1")){ + return false; + } + QString sql = QString("UPDATE IRIS_DATA SET LEFT_IRIS_CODE1 = :left1, RIGHT_IRIS_CODE1 = :right1 WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":left1", newObject.value("left_iris_code1")); + query.bindValue(":right1", newObject.value("right_iris_code1")); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(); + +// LOG_DEBUG(QString("编辑虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; +} + + +bool IrisDataDao::dele(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + QString sql = QString("DELETE FROM IRIS_DATA WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(); + +// LOG_DEBUG(QString("删除虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; +} diff --git a/dao/IrisDataDao.h b/dao/IrisDataDao.h new file mode 100644 index 0000000..c74dbbd --- /dev/null +++ b/dao/IrisDataDao.h @@ -0,0 +1,25 @@ +#ifndef IRISDATADAO_H +#define IRISDATADAO_H + +#include +#include "BaseDao.h" + +class IrisDataDao : public BaseDao +{ + Q_OBJECT +public: + explicit IrisDataDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + QVariantMap findRecordByPersonId(QString personId); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +signals: + +}; + +#endif // IRISDATADAO_H diff --git a/dao/RecognitionRecordsDao.cpp b/dao/RecognitionRecordsDao.cpp new file mode 100644 index 0000000..40db453 --- /dev/null +++ b/dao/RecognitionRecordsDao.cpp @@ -0,0 +1,100 @@ +#include "RecognitionRecordsDao.h" + +RecognitionRecordsDao::RecognitionRecordsDao(QObject *parent) : BaseDao(parent) +{ + +} + + +QVector RecognitionRecordsDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM RECOGNITION_RECORDS"; + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + item.insert("id", query.value("id").toLongLong()); + result.append(item); + } + +// LOG_DEBUG(QString("查询RECOGNITION_RECORDS表的所有记录[记录数:%1]").arg(result.size()).toStdString()); + return result; +} + +QVariantMap RecognitionRecordsDao::findRecordById(QString id) +{ + QVariantMap item; + return item; +} + +QString RecognitionRecordsDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + + // INSERT语句 + QString sql = QString("INSERT INTO RECOGNITION_RECORDS (ID, PERSON_ID, DATETIME, REC_TYPE, DEV_CODE, DOOR_CODE, INOUT_TYPE) " + "VALUES (:id, :personId, :datetime, :recType, :devCode, :doorCode, :inoutType)"); + + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":personId", object.value("person_id").toString()); + query.bindValue(":datetime", object.value("date_time").toString()); + query.bindValue(":recType", object.value("rec_type").toString()); + query.bindValue(":devCode", object.value("dev_code").toString()); + query.bindValue(":doorCode", object.value("door_code").toString()); + query.bindValue(":inoutType", object.value("inout_type").toString()); + +// LOG_DEBUG(sql.toStdString()); + + // 插入识别的log日志 + QString logStr = QString("INSERT INTO RECOGNITION_LOGS (ID, LOG_INFO) VALUES (:id, :logInfo)"); + + QSqlQuery logQuery(ConnectionManager::getInstance()->getConnection()); + logQuery.prepare(logStr); + logQuery.bindValue(":id", id); + logQuery.bindValue(":logInfo", object.value("debug_info").toString()); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(); + logQuery.exec(); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool RecognitionRecordsDao::edit(QVariantMap newObject, QString id) +{ + return false; +} + +bool RecognitionRecordsDao::dele(QString id) +{ + return false; +} diff --git a/dao/RecognitionRecordsDao.h b/dao/RecognitionRecordsDao.h new file mode 100644 index 0000000..38de7c9 --- /dev/null +++ b/dao/RecognitionRecordsDao.h @@ -0,0 +1,23 @@ +#ifndef RECOGNITIONRECORDSDAO_H +#define RECOGNITIONRECORDSDAO_H + +#include +#include "BaseDao.h" +class RecognitionRecordsDao: public BaseDao +{ + Q_OBJECT +public: + explicit RecognitionRecordsDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +signals: + +}; + +#endif // RECOGNITIONRECORDSDAO_H diff --git a/dao/SysDeptDao.cpp b/dao/SysDeptDao.cpp new file mode 100644 index 0000000..22f9946 --- /dev/null +++ b/dao/SysDeptDao.cpp @@ -0,0 +1,88 @@ +#include "SysDeptDao.h" + +SysDeptDao::SysDeptDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector SysDeptDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_DEPT WHERE PID != '-1' ORDER BY PID, NUM"; + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + item.insert("id", query.value("id").toString()); + item.insert("pid", query.value("pid").toString()); + item.insert("pids", query.value("pids").toString()); + item.insert("simplename", query.value("simplename").toString()); + item.insert("fullname", query.value("fullname").toString()); + } + +// LOG_TRACE(QString("查询表[SYS_DEPT]的所有记录[%1][%2]").arg(result.size()).arg(sql).toStdString()); + + return result; +} + +QVariantMap SysDeptDao::findRecordById(QString id) +{ + QVariantMap item; + return item; + + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM SYS_DEPT WHERE SYS_DEPT.ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + // 获取结果集的大小 + query.last(); + int count = query.at() + 1; + + if (count >=1) + { + query.first(); + + result.insert("id", query.value("id").toString()); + result.insert("pid", query.value("pid").toString()); + result.insert("pids", query.value("pids").toString()); + result.insert("simplename", query.value("simplename").toString()); + result.insert("fullname", query.value("fullname").toString()); + } + +// LOG_TRACE(QString("根据id查询SYS_DEPT表的记录[ID=%1][%2]").arg(id).arg(sql).toStdString()); + + return result; +} + + +QString SysDeptDao::save(QVariantMap object) +{ + return "0"; +} +bool SysDeptDao::edit(QVariantMap newObject, QString id) +{ + return true; +} +bool SysDeptDao::dele(QString id) +{ + return true; +} diff --git a/dao/SysDeptDao.h b/dao/SysDeptDao.h new file mode 100644 index 0000000..e07a09f --- /dev/null +++ b/dao/SysDeptDao.h @@ -0,0 +1,24 @@ +#ifndef SYSDEPTDAO_H +#define SYSDEPTDAO_H + +#include +#include "BaseDao.h" + +class SysDeptDao : public BaseDao +{ + Q_OBJECT +public: + explicit SysDeptDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +private: + +}; + +#endif // SYSDEPTDAO_H diff --git a/dao/SysPersonDao.cpp b/dao/SysPersonDao.cpp new file mode 100644 index 0000000..dd9480f --- /dev/null +++ b/dao/SysPersonDao.cpp @@ -0,0 +1,371 @@ +#include "SysPersonDao.h" + + +SysPersonDao::SysPersonDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector SysPersonDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0'"; + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + count++; + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + result.append(item); + } + +// LOG(TRACE) << QString("查询SYS_PERSON表的所有记录[%1]").arg(count).toStdString(); +// LOG_TRACE(QString("查询SYS_PERSON表的所有记录[%1]").arg(count).toStdString()); + + return result; +} + +QVariantMap SysPersonDao::findRecordById(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0' AND SYS_PERSON.ID = '%1'").arg(id); + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVariantMap result; + + // 获取结果集的大小 + query.last(); + int count = query.at() + 1; + + if (count >=1) + { + query.first(); + + result.insert("id", query.value("id").toString()); + result.insert("delflag", query.value("delflag").toString()); + result.insert("createtime", query.value("createtime").toString()); + result.insert("updatetime", query.value("updatetime").toString()); + result.insert("name", query.value("name").toString()); + result.insert("gender", query.value("gender").toString()); + result.insert("deptid", query.value("deptid").toString()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("remarks", query.value("remarks").toString()); + result.insert("person_code", query.value("person_code").toString()); + result.insert("deptname", query.value("fullname").toString()); + result.insert("sync_id", query.value("sync_id").toString()); + result.insert("hasFace", query.value("face_valid").toString()); + result.insert("hasIris", query.value("iris_valid").toString()); + } + +// LOG(TRACE) << QString("根据id查询SYS_PERSON表的记录[id=%1][%2]").arg(id).arg(sql).toStdString(); +// LOG_TRACE(QString("根据id查询SYS_PERSON表的记录[id=%1][%2]").arg(id).arg(sql).toStdString()); + + return result; +} + +int SysPersonDao::findRecordCountByNameAndDept(QString name, QString dept) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT COUNT(P.ID) AS RECCT FROM SYS_PERSON P LEFT JOIN SYS_DEPT D ON P.DEPTID = D.ID WHERE P.DELFLAG = '0'"; + if (name.isEmpty() == false) + { + sql += " AND P.NAME LIKE '%" + name + "%'"; + } + if (dept.isEmpty() == false && dept.indexOf("-1") < 0) + { + sql += QString(" AND ((P.DEPTID = '%1') OR (D.PIDS LIKE '%,%1,%'))").arg(dept); + } + + // 执行查询 + query.exec(sql); + + // 返回结果 + int result; + + // 遍历查询结果 + if (query.next()) { + result = query.value("RECCT").toInt(); + } + +// LOG(TRACE) << QString("根据姓名和部门查询SYS_PERSON记录总数[%1][%2]").arg(result).arg(sql).toStdString(); +// LOG_TRACE(QString("根据姓名和部门查询SYS_PERSON记录总数[%1][%2]").arg(result).arg(sql).toStdString()); + + return result; +} + +QVector SysPersonDao::findRecordsByNameAndDept(QString name, QString dept, qint8 limit, qint16 offset) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON P LEFT JOIN SYS_DEPT D ON P.DEPTID = D.ID WHERE P.DELFLAG = '0'"; + if (name.isEmpty() == false) + { + sql += " AND P.NAME LIKE '%" + name + "%'"; + } + if (dept.isEmpty() == false && dept.indexOf("-1") < 0) + { + sql += QString(" AND ((P.DEPTID = '%1') OR (D.PIDS LIKE '%,%1,%'))").arg(dept); + } + + sql += QString(" LIMIT %1 OFFSET %2").arg(limit).arg(offset); + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + count++; + + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + + result.append(item); + } + +// LOG(TRACE) << QString("根据姓名和部门分页查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString(); +// LOG_TRACE(QString("根据姓名和部门分页查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString()); + + return result; +} + +QVector SysPersonDao::findRecordsByProperties(QVariantMap conditions) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0'"; + QVariantMap::iterator it; + for (it = conditions.begin(); it != conditions.end(); it++) + { + sql += QString(" AND SYS_PERSON.%1 = %2").arg(it.key()).arg(it.value().toString()); + } + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + count++; + + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + + result.append(item); + } + +// LOG(TRACE) << QString("根据属性值查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString(); +// LOG_TRACE(QString("根据属性值查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString()); + + return result; +} + +QString SysPersonDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + + // INSERT语句 + QString sql = QString("INSERT INTO SYS_PERSON " + "(ID, DELFLAG, CREATETIME, UPDATETIME, " + "NAME, GENDER, DEPTID, ID_CARD_NO, " + "REMARKS, PERSON_CODE, SYNC_ID, FACE_VALID, IRIS_VALID) " + "VALUES ('%1', '0', '%2', '%2', '%3', '%4', '%5', '%6', '%7', '%8', '%9', 0, 0)") + .arg(id).arg(tm) + .arg(object.value("name").toString()) + .arg(object.value("gender").toString()) + .arg(object.value("deptid").toString()) + .arg(object.value("id_card_no").toString()) + .arg(object.value("remarks").toString()) + .arg(object.value("person_code").toString()) + .arg(object.value("sync_id").toString()); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(sql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { +// LOG(DEBUG) << QString("保存SYS_PERSON记录成功[ID = %1][%2]").arg(id).arg(sql).toStdString(); +// LOG_DEBUG(QString("保存SYS_PERSON记录成功[ID = %1][%2]").arg(id).arg(sql).toStdString()); + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool SysPersonDao::edit(QVariantMap newObject, QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + + // UPDATE语句 + QString sql = QString("UPDATE SYS_PERSON SET UPDATETIME = '%1'").arg(tm); + if (newObject.contains("name")) + { + sql.append(QString(", NAME = '%1'").arg(newObject.value("name").toString())); + } + if (newObject.contains("gender")) + { + sql.append(QString(", GENDER = '%1'").arg(newObject.value("gender").toString())); + } + if (newObject.contains("deptid")) + { + sql.append(QString(", DEPTID = '%1'").arg(newObject.value("deptid").toString())); + } + if (newObject.contains("person_code")) + { + sql.append(QString(", PERSON_CODE = '%1'").arg(newObject.value("person_code").toString())); + } + if (newObject.contains("face_valid")) + { + sql.append(QString(", FACE_VALID = '%1'").arg(newObject.value("face_valid").toString())); + } + if (newObject.contains("iris_valid")) + { + sql.append(QString(", IRIS_VALID = '%1'").arg(newObject.value("iris_valid").toString())); + } + + sql.append(QString(" WHERE ID = '%1'").arg(id)); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(sql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + +// LOG(DEBUG) << QString("编辑人员[ID=%1][%2]").arg(id).arg(sql).toStdString(); +// LOG_DEBUG(QString("编辑人员[ID=%1][%2]").arg(id).arg(sql).toStdString()); + + // 返回结果 + return success; +} + +bool SysPersonDao::dele(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + QSqlQuery irisDel(ConnectionManager::getInstance()->getConnection()); + + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + qint64 tmms = QDateTime::currentDateTime().toMSecsSinceEpoch(); + + // UPDATE语句 + QString sql = QString("UPDATE SYS_PERSON SET UPDATETIME = :updateTime, DELFLAG = :flag WHERE ID = :id").arg(tm).arg(tmms).arg(id); + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":updateTime", tm); + query.bindValue(":flag", tmms); + + // 物理删除人员的人脸和虹膜数据 + QString delIrisSql = QString("DELETE FROM IRIS_DATA WHERE PERSON_ID = :personId"); + irisDel.prepare(delIrisSql); + irisDel.bindValue(":personId", id); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(sql); + query.exec(delIrisSql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + +// LOG_DEBUG(QString("删除人员SYS_PERSON[ID=%1][%2]").arg(id).arg(success).toStdString()); + + // 返回结果 + return success; +} diff --git a/dao/SysPersonDao.h b/dao/SysPersonDao.h new file mode 100644 index 0000000..e02e5ba --- /dev/null +++ b/dao/SysPersonDao.h @@ -0,0 +1,27 @@ +#ifndef SYSPERSONDAO_H +#define SYSPERSONDAO_H + +#include +#include "BaseDao.h" + +class SysPersonDao : public BaseDao +{ + Q_OBJECT +public: + explicit SysPersonDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + int findRecordCountByNameAndDept(QString name, QString dept); + QVector findRecordsByNameAndDept(QString name, QString dept, qint8 limit, qint16 offset); + QVector findRecordsByProperties(QVariantMap conditions); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); +signals: + +}; + +#endif // SYSPERSONDAO_H diff --git a/dao/dao.pri b/dao/dao.pri new file mode 100644 index 0000000..1e04ce4 --- /dev/null +++ b/dao/dao.pri @@ -0,0 +1,18 @@ + +HEADERS += $$PWD/BaseDao.h +HEADERS += $$PWD/IrisDataDao.h +HEADERS += $$PWD/RecognitionRecordsDao.h +HEADERS += $$PWD/SysPersonDao.h +HEADERS += $$PWD/SysDeptDao.h + +SOURCES += $$PWD/BaseDao.cpp +SOURCES += $$PWD/IrisDataDao.cpp +SOURCES += $$PWD/RecognitionRecordsDao.cpp +SOURCES += $$PWD/SysPersonDao.cpp +SOURCES += $$PWD/SysDeptDao.cpp + +HEADERS += $$PWD/util/ConnectionManager.h +SOURCES += $$PWD/util/ConnectionManager.cpp +#HEADERS += $$PWD/util/CacheManager.h +#SOURCES += $$PWD/util/CacheManager.cpp + diff --git a/dao/util/ConnectionManager.cpp b/dao/util/ConnectionManager.cpp new file mode 100644 index 0000000..84b17be --- /dev/null +++ b/dao/util/ConnectionManager.cpp @@ -0,0 +1,47 @@ +#include "ConnectionManager.h" +#include + +Q_GLOBAL_STATIC(ConnectionManager, cm) + +ConnectionManager::ConnectionManager(QObject *parent) : QObject(parent) +{ + // 初始化数据库连接 + if (QSqlDatabase::contains("qt_sql_dafault_connection")) + { + conn = QSqlDatabase::database("qt_sql_default_connection"); + } + else + { + conn = QSqlDatabase::addDatabase("QSQLITE"); + conn.setDatabaseName(QApplication::applicationDirPath() + "/data/casic.db"); + + bool succ = conn.open(); + if (succ == true) + { +// LOG_INFO(QString("打开数据库操作正常[Open Database Success]").toStdString()); + } else + { +// LOG_ERROR(QString("打开数据库操作失败[Open Database Failed]").toStdString()); + } + } +} + +ConnectionManager::~ConnectionManager() +{ + conn.close(); +} + +ConnectionManager* ConnectionManager::getInstance() +{ + return cm; +} + +QSqlDatabase ConnectionManager::getConnection() +{ + return this->conn; +} + +qint64 ConnectionManager::generateId() +{ + return this->idWorker.nextId(); +} diff --git a/dao/util/ConnectionManager.h b/dao/util/ConnectionManager.h new file mode 100644 index 0000000..84647e3 --- /dev/null +++ b/dao/util/ConnectionManager.h @@ -0,0 +1,34 @@ +#ifndef CONNECTIONMANAGER_H +#define CONNECTIONMANAGER_H + +#include +#include +#include "utils/id/IdWorker.h" +#include "utils/UtilInclude.h" + +using namespace Jiawa::Core; + +class ConnectionManager : public QObject +{ + Q_OBJECT +public: + explicit ConnectionManager(QObject *parent = nullptr); + ~ConnectionManager(); + + static ConnectionManager * getInstance(); + + QSqlDatabase getConnection(); + qint64 generateId(); + +private: + // 数据库连接 + QSqlDatabase conn; + + // 雪花id生成工具 + IdWorker &idWorker = Singleton::instance(); + +signals: + +}; + +#endif // CONNECTIONMANAGER_H diff --git a/device/IrisCameraCapEventHandler.cpp b/device/IrisCameraCapEventHandler.cpp new file mode 100644 index 0000000..45df089 --- /dev/null +++ b/device/IrisCameraCapEventHandler.cpp @@ -0,0 +1,103 @@ +#include "IrisCameraCapEventHandler.h" + +IrisCameraCapEventHandler::IrisCameraCapEventHandler(QObject *parent) : QObject(parent) +{ + +} + +void IrisCameraCapEventHandler::DoOnImageCaptured(CImageDataPointer &objImageDataPointer, void *pUserParam) +{ + if (objImageDataPointer.IsNull() == false) + { + CGXDevicePointer* cam = (CGXDevicePointer *) pUserParam; + + auto camName = cam->getPtr()->GetDeviceInfo().GetUserID(); + int width = objImageDataPointer->GetWidth(); + int height = objImageDataPointer->GetHeight(); + size_t leftKeyIndex = camName.find("left"); + size_t rightKeyIndex = camName.find("right"); + + uchar * pBuffer = (BYTE*)objImageDataPointer->GetBuffer(); + + // 相机拍摄下的图像1440*1080, 直接用于算法判断 + QImage img = QImage(pBuffer, width, height, QImage::Format_Grayscale8); // 用于展示 +// QImage imgAlgo = img.copy(0, 0, width, height); + + // 用于显示的图像需要缩小到400 * 300的尺寸 + img = img.scaled(SettingConfig::getInstance().IRIS_DISPLAY_HEIGHT, SettingConfig::getInstance().IRIS_DISPLAY_WIDTH); + img = img.transformed(QTransform().rotate(-90)); // 图像逆时针旋转90度 + + // 发送到界面进行显示 + emit sendIrisFrameToDraw(img); +// cv::Mat irisMat = ImageUtil::QImageToMat(imgAlgo); + +// irisInfo.data = imgAlgo; +// irisInfo.matData = irisMat; + +// // 将图像显示在注册页面的label上 +// // 并将虹膜信息对象存入队列中 +// ProMemory::getInstance().pushCasicIris(irisInfo); + +// if (leftKeyIndex >= 0 && leftKeyIndex < 32) +// { +// emit sendIrisFrameToDraw(img, 0); // 左眼画面 +// } else if (rightKeyIndex >= 0 && rightKeyIndex < 32) +// { +// emit sendIrisFrameToDraw(img, 1); // 右眼画面 +// } +/* + if (pBuffer != NULL) + { + // 创建虹膜信息对象 + CasicIrisInfo irisInfo; + irisInfo.hasEye = false; + if (leftKeyIndex >= 0 && leftKeyIndex < 32) + { + // 左眼相机拍摄的图像 + irisInfo.leftOrRight = "left"; + } else if (rightKeyIndex >= 0 && rightKeyIndex < 32) + { + // 右眼相机 + irisInfo.leftOrRight = "right"; + } + + if (ProMemory::getInstance().widgeFrame == CasicBioRecConst::RECOGNIZE_RESULT_FORM) + { + // 相机拍摄下的图像1280*960, 直接用于算法判断 + QImage imgDisp = QImage(pBuffer, width, height, QImage::Format_Grayscale8); + cv::Mat irisMat = ImageUtil::QImageToMat(imgDisp); + + irisInfo.data = imgDisp; + irisInfo.matData = irisMat; + + ProMemory::getInstance().pushCasicIris(irisInfo); + +// cv::imwrite(QString("D:\\irisLogs\\iristest-%1.bmp").arg(irisInfo.leftOrRight).toStdString(), irisMat); + } else if (ProMemory::getInstance().widgeFrame == CasicBioRecConst::ADD_PERSON_CAPTURE_IRIS) + { + // 相机拍摄下的图像1280*960, 直接用于算法判断 + QImage img = QImage(pBuffer, width, height, QImage::Format_Grayscale8); + QImage imgAlgo = img.copy(0, 0, width, height); + + // 用于显示的图像需要缩小到1/4的尺寸 + img = img.scaled(640, 480); + cv::Mat irisMat = ImageUtil::QImageToMat(imgAlgo); + + irisInfo.data = imgAlgo; + irisInfo.matData = irisMat; + + // 将图像显示在注册页面的label上 + // 并将虹膜信息对象存入队列中 + ProMemory::getInstance().pushCasicIris(irisInfo); + + if (leftKeyIndex >= 0 && leftKeyIndex < 32) + { + emit sendIrisFrameToDraw(img, 0); // 左眼画面 + } else if (rightKeyIndex >= 0 && rightKeyIndex < 32) + { + emit sendIrisFrameToDraw(img, 1); // 右眼画面 + } + } + }*/ + } +} diff --git a/device/IrisCameraCapEventHandler.h b/device/IrisCameraCapEventHandler.h new file mode 100644 index 0000000..ad75a97 --- /dev/null +++ b/device/IrisCameraCapEventHandler.h @@ -0,0 +1,30 @@ +#ifndef IRISCAMERACAPEVENTHANDLER_H +#define IRISCAMERACAPEVENTHANDLER_H + +#include +#include +#include "include/opencv2/opencv.hpp" +#include "include/daheng/GalaxyIncludes.h" + +//#include "casic/iris/CasicIrisInterface.h" +#include "ProMemory.h" + +#include "utils/UtilInclude.h" + +class IrisCameraCapEventHandler : public QObject, public ICaptureEventHandler +{ + Q_OBJECT +public: + explicit IrisCameraCapEventHandler(QObject *parent = nullptr); + + void DoOnImageCaptured(CImageDataPointer &objImageDataPointer, void *pUserParam); + +private: + unsigned char* pImageBuffer; + +signals: + void sendIrisFrameToDraw(QImage irisImage); + +}; + +#endif // IRISCAMERACAPEVENTHANDLER_H diff --git a/device/IrisCameraController.cpp b/device/IrisCameraController.cpp new file mode 100644 index 0000000..0928176 --- /dev/null +++ b/device/IrisCameraController.cpp @@ -0,0 +1,110 @@ +#include "IrisCameraController.h" + +IrisCameraController::IrisCameraController(QObject *parent) : QObject(parent) +{ + this->irisCamHandler = new IrisCameraCapEventHandler(this); +} +IrisCameraController::~IrisCameraController() +{ + this->closeIrisCamera(); +} + + +void IrisCameraController::initIrisCamera() +{ + IGXFactory::GetInstance().Init(); + + //枚举设备 + IGXFactory::GetInstance().UpdateDeviceList(1000, irisCamList); + + this->OpenDevice(); +} + +void IrisCameraController::openIrisCamera() +{ + //设置Buffer处理模式 + irisStreamFeaturePtr->GetEnumFeature("StreamBufferHandlingMode")->SetValue("OldestFirst"); + + //注册回调函数 + irisStreamPtr->RegisterCaptureCallback(irisCamHandler, &irisCamPtr); + + //开启流层通道 + irisStreamPtr->StartGrab(); + + //发送开采命令 + irisFeaturePtr->GetCommandFeature("AcquisitionStart")->Execute(); + + // 启动定时器 + TimeCounterUtil::getInstance().irisCapCounter->start(SettingConfig::getInstance().IRIS_FRAME_INTERVAL); // 50ms执行一次定时器 +} + +void IrisCameraController::closeIrisCamera() +{ + +} + +void IrisCameraController::startCapture() +{ + // 获取定时器, 绑定定时函数 + connect(TimeCounterUtil::getInstance().irisCapCounter, &QTimer::timeout, this, &IrisCameraController::getOneFaceFrm); +// LOG(DEBUG) << QString("[IrisCameraController][startCapture]虹膜相机拍图").toStdString(); +// LOG_DEBUG(QString("[IrisCameraController][startCapture]虹膜相机拍图").toStdString()); + +} +void IrisCameraController::stopCapture() +{ + // 获取定时器, 绑定定时函数 + disconnect(TimeCounterUtil::getInstance().irisCapCounter, &QTimer::timeout, this, &IrisCameraController::getOneFaceFrm); +// LOG(DEBUG) << QString("[IrisCameraController][stopCapture]虹膜相机停止拍图").toStdString(); +// LOG_DEBUG(QString("[IrisCameraController][stopCapture]虹膜相机停止拍图").toStdString()); + +} + +void IrisCameraController::getOneFaceFrm() +{ + // 发送软触发命令(在触发模式开启时有效) + irisFeaturePtr->GetCommandFeature("TriggerSoftware")->Execute(); +} + +void IrisCameraController::getLeftAndRightEyeFrame() +{ + irisFeaturePtr->GetCommandFeature("TriggerSoftware")->Execute(); +} + +void IrisCameraController::OpenDevice() +{ + auto device = irisCamList.at(0); + + irisCamPtr = IGXFactory::GetInstance().OpenDeviceByUserID(device.GetUserID(), GX_ACCESS_EXCLUSIVE); + irisFeaturePtr = irisCamPtr->GetRemoteFeatureControl(); + + // 判断设备流是否大于零, 如果大于零则打开流 + int nStreamCount = irisCamPtr->GetStreamCount(); + if (nStreamCount > 0) + { + irisStreamPtr = irisCamPtr->OpenStream(0); + irisStreamFeaturePtr = irisStreamPtr->GetFeatureControl(); + } + + // 建议用户在打开网络相机之后, 根据当前网络环境设置相机的流通道包长值, + // 以提高网络相机的采集性能, 设置方法参考以下代码。 + GX_DEVICE_CLASS_LIST objDeviceClass = irisCamPtr->GetDeviceInfo().GetDeviceClass(); + if(GX_DEVICE_CLASS_GEV == objDeviceClass) + { + // 判断设备是否支持流通道数据包功能 + if(true == irisFeaturePtr->IsImplemented("GevSCPSPacketSize")) + { + // 获取当前网络环境的最优包长值 + int nPacketSize = irisStreamPtr->GetOptimalPacketSize(); + // 将最优包长值设置为当前设备的流通道包长值 + irisFeaturePtr->GetIntFeature("GevSCPSPacketSize")->SetValue(nPacketSize); + } + } + + //设置采集模式为连续采集模式 + irisFeaturePtr->GetEnumFeature("AcquisitionMode")->SetValue("Continuous"); + + //设置触发模式关 + irisFeaturePtr->GetEnumFeature("TriggerMode")->SetValue("On"); + irisFeaturePtr->GetEnumFeature("TriggerSource")->SetValue("Software"); +} diff --git a/device/IrisCameraController.h b/device/IrisCameraController.h new file mode 100644 index 0000000..5d7e269 --- /dev/null +++ b/device/IrisCameraController.h @@ -0,0 +1,49 @@ +#ifndef IRISCAMERACONTROLLER_H +#define IRISCAMERACONTROLLER_H + +#include + +#include "IrisCameraCapEventHandler.h" + +class IrisCameraCapEventHandler; + +class IrisCameraController : public QObject +{ + Q_OBJECT +public: + explicit IrisCameraController(QObject *parent = nullptr); + ~IrisCameraController(); + + // 初始化并打开人脸相机 + void initIrisCamera(); + void openIrisCamera(); + void closeIrisCamera(); + + void startCapture(); + void stopCapture(); + + void getLeftAndRightEyeFrame(); + + IrisCameraCapEventHandler * irisCamHandler; + +private: + GxIAPICPP::gxdeviceinfo_vector irisCamList; + + CGXDevicePointer irisCamPtr; ///< 设备句柄 + + CGXStreamPointer irisStreamPtr; ///< 左眼设备流 + + CGXFeatureControlPointer irisFeaturePtr; ///< 左眼属性控制器 + + CGXFeatureControlPointer irisStreamFeaturePtr; ///< 左眼流层控制器对象 + + void OpenDevice(); + +signals: + +public slots: + void getOneFaceFrm(); + +}; + +#endif // IRISCAMERACONTROLLER_H diff --git a/device/device.pri b/device/device.pri new file mode 100644 index 0000000..a8417f2 --- /dev/null +++ b/device/device.pri @@ -0,0 +1,13 @@ + +HEADERS += $$PWD/IrisCameraController.h +HEADERS += $$PWD/IrisCameraCapEventHandler.h +#HEADERS += $$PWD/iris/IrisRegistProcess.h +#HEADERS += $$PWD/iris/IrisRecogProcess.h +#HEADERS += $$PWD/iris/CasicIrisRecState.h + +SOURCES += $$PWD/IrisCameraController.cpp +SOURCES += $$PWD/IrisCameraCapEventHandler.cpp +#SOURCES += $$PWD/iris/IrisRegistProcess.cpp +#SOURCES += $$PWD/iris/IrisRecogProcess.cpp +#SOURCES += $$PWD/iris/CasicIrisRecState.cpp + diff --git a/images/bg_footer.png b/images/bg_footer.png new file mode 100644 index 0000000..a3a99ab --- /dev/null +++ b/images/bg_footer.png Binary files differ diff --git a/images/bg_statcked.png b/images/bg_statcked.png new file mode 100644 index 0000000..18b63e1 --- /dev/null +++ b/images/bg_statcked.png Binary files differ diff --git a/images/bg_title.png b/images/bg_title.png new file mode 100644 index 0000000..0316e2d --- /dev/null +++ b/images/bg_title.png Binary files differ diff --git a/main.cpp b/main.cpp index 16bc45b..9052ddb 100644 --- a/main.cpp +++ b/main.cpp @@ -1,11 +1,11 @@ -#include "IdentifyForm.h" +#include "MainWindowForm.h" #include int main(int argc, char *argv[]) { QApplication a(argc, argv); - IdentifyForm w; + MainWindowForm w; w.show(); return a.exec(); } diff --git a/resource.qrc b/resource.qrc new file mode 100644 index 0000000..474586a --- /dev/null +++ b/resource.qrc @@ -0,0 +1,35 @@ + + + images/setting.png + images/user.png + images/back.png + images/home.png + images/btnPageFirst.png + images/btnPageLast.png + images/btnPageNext.png + images/btnPagePre.png + images/regist.png + images/photoEyeLeft.png + images/photoEyeRight.png + images/photoFace.png + images/save.png + images/upArrow.png + images/downArrow.png + images/faceCaped.png + images/faceNotCap.png + images/irisCaped.png + images/irisNotCap.png + images/tipsFailure.png + images/tipsSuccess.png + images/tipsConfirm.png + images/bg_recognize_result.png + images/iconRetry.png + images/bg_title.png + images/bg_footer.png + images/bg_statcked.png + + + images/add_bottom.png + images/add_top.png + + diff --git a/utils/ImageUtil.cpp b/utils/ImageUtil.cpp new file mode 100644 index 0000000..7604572 --- /dev/null +++ b/utils/ImageUtil.cpp @@ -0,0 +1,97 @@ +#include "ImageUtil.h" + +ImageUtil::ImageUtil() +{ + +} + +QImage ImageUtil::MatImageToQImage(const cv::Mat &src) +{ + //CV_8UC1 8位无符号的单通道---灰度图片 + if(src.type() == CV_8UC1) + { + QImage qImage((const unsigned char *)(src.data), src.cols, src.rows, src.cols, QImage::Format_Grayscale8); + return qImage; + } + //为3通道的彩色图片 + else if(src.type() == CV_8UC3) + { + //得到图像的的首地址 + const uchar *pSrc = (const uchar*)src.data; + //以src构造图片 + QImage qImage(pSrc, src.cols, src.rows, src.step, QImage::Format_RGB888); + //在不改变实际图像数据的条件下, 交换红蓝通道 + return qImage.rgbSwapped(); + } + //四通道图片, 带Alpha通道的RGB彩色图像 + else if(src.type() == CV_8UC4) + { + const uchar *pSrc = (const uchar*)src.data; + QImage qImage(pSrc, src.cols, src.rows, src.step, QImage::Format_ARGB32); + //返回图像的子区域作为一个新图像 + return qImage.copy(); + } + else + { + return QImage(); + } +} +/* +QImage ImageUtil::UcharToQImage(unsigned char* data, int width, int height, QImage::Format format) +{ + QImage qImage(data, width, height, format); + //在不改变实际图像数据的条件下, 交换红蓝通道 + return qImage.rgbSwapped(); +} + +cv::Mat ImageUtil::QImageToMat(QImage image) +{ + cv::Mat mat; + switch(image.format()) + { + case QImage::Format_ARGB32: + case QImage::Format_RGB32: + case QImage::Format_ARGB32_Premultiplied: + mat = cv::Mat(image.height(), image.width(), CV_8UC4, (void*)image.constBits(), image.bytesPerLine()); + break; + case QImage::Format_RGB888: + mat = cv::Mat(image.height(), image.width(), CV_8UC3, (void*)image.constBits(), image.bytesPerLine()); + cv::cvtColor(mat, mat, cv::COLOR_BGR2RGB); + break; + case QImage::Format_Indexed8: + mat = cv::Mat(image.height(), image.width(), CV_8UC1, (void*)image.constBits(), image.bytesPerLine()); + break; + case QImage::Format_Grayscale8: + mat = cv::Mat(image.height(), image.width(), CV_8UC1, (void *)image.bits(), image.bytesPerLine()); + break; + } + + mat = mat.clone(); + + return mat; +} + +QString ImageUtil::QImageToBase64(QImage image) +{ + QByteArray ba; + QBuffer buf(&ba); + image.save(&buf, "bmp"); + QString base64String = ba.toBase64(); + return base64String; +} + +cv::Mat ImageUtil::MatImageRect(const cv::Mat &src, cv::Rect rect, int delta) +{ + cv::Mat matClone = src.clone(); + cv::Rect bigRect; + + bigRect.x = rect.x - delta < 0 ? 0 : rect.x - delta; + bigRect.y = rect.y - delta < 0 ? 0 : rect.y - delta; + bigRect.width = rect.x + rect.width + 2 * delta > src.cols ? src.cols - rect.x : rect.width + 2 * delta; + bigRect.height = rect.y + rect.height + 2 * delta > src.rows ? src.rows - rect.y : rect.height + 2 * delta; + + cv::Mat roi = matClone(bigRect); + + return roi; +} +*/ diff --git a/utils/ImageUtil.h b/utils/ImageUtil.h new file mode 100644 index 0000000..dbfdd48 --- /dev/null +++ b/utils/ImageUtil.h @@ -0,0 +1,22 @@ +#ifndef IMAGEUTIL_H +#define IMAGEUTIL_H + +#include +#include +#include "opencv2/opencv.hpp" + +class ImageUtil +{ +public: + ImageUtil(); + + static QImage MatImageToQImage(const cv::Mat &src); +// static QImage UcharToQImage(unsigned char* data, int width, int height, QImage::Format format); + +// static cv::Mat QImageToMat(QImage image); +// static QString QImageToBase64(QImage image); + +// static cv::Mat MatImageRect(const cv::Mat &src, cv::Rect rect, int delta); +}; + +#endif // IMAGEUTIL_H diff --git a/utils/SettingConfig.cpp b/utils/SettingConfig.cpp new file mode 100644 index 0000000..d420285 --- /dev/null +++ b/utils/SettingConfig.cpp @@ -0,0 +1,44 @@ +#include "SettingConfig.h" +#include + +SettingConfig::SettingConfig() +{ + filename = QApplication::applicationDirPath() + "/conf/config.ini"; + setting = new QSettings(this->filename, QSettings::IniFormat); + + WINDOW_WIDTH = getProperty("window", "width").toInt(); + WINDOW_HEIGHT = getProperty("window", "height").toInt(); + WINDOW_BACKGROUND_COLOR = getProperty("window", "backgroundColor").toString(); + WINDOW_TITLE = getProperty("window", "title").toString(); + WINDOW_RIGHTS = getProperty("window", "copyright").toString(); + WINDOW_VERSION = getProperty("window", "version").toString(); + + IRIS_FRAME_WIDTH = getProperty("camera", "irisFrameWidth").toInt(); + IRIS_FRAME_HEIGHT = getProperty("camera", "irisFrameHeight").toInt(); + IRIS_WIDTH = getProperty("camera", "irisWidth").toInt(); + IRIS_HEIGHT = getProperty("camera", "irisHeight").toInt(); + IRIS_FRAME_INTERVAL = getProperty("camera", "irisFrameInterval").toInt(); + IRIS_DISPLAY_WIDTH = getProperty("camera", "irisDisplayWidth").toInt(); + IRIS_DISPLAY_HEIGHT = getProperty("camera", "irisDisplayHeight").toInt(); + + MAX_MATCH_TIME = getProperty("recognize", "maxMatchTime").toInt(); + SUCCESS_TIPS_LAST = getProperty("recognize", "successTipsLast").toInt(); + FAILURE_TIPS_LAST = getProperty("recognize", "failureTipsLast").toInt(); + MAX_FACE_TRY_COUNT = getProperty("recognize", "maxFaceTryCount").toInt(); + MAX_FACE_NOT_FOUND_COUNT = getProperty("recognize", "maxFaceNotFoundCount").toInt(); + MAX_IRIS_TRY_COUNT = getProperty("recognize", "maxIrisTryCount").toInt(); + MAX_EYE_NOT_FOUND_COUNT = getProperty("recognize", "maxEyeNotFoundCount").toInt(); + + MAX_CAPTURE_STACK_SIZE = getProperty("stack", "capture").toInt(); + MAX_FOUND_STACK_SIZE = getProperty("stack", "found").toInt(); + MAX_QUALIFIED_STACK_SIZE = getProperty("stack", "qualified").toInt(); + + LOG_FILE = getProperty("log", "logFile").toString(); + LOG_LEVEL = getProperty("log", "logLevel").toString(); +} + + +QVariant SettingConfig::getProperty(QString nodeName, QString keyName) { + QVariant var = this->setting->value(QString("/%1/%2").arg(nodeName).arg(keyName)); + return var; +} diff --git a/utils/SettingConfig.h b/utils/SettingConfig.h new file mode 100644 index 0000000..30c3bec --- /dev/null +++ b/utils/SettingConfig.h @@ -0,0 +1,66 @@ +#ifndef SETTINGCONFIG_H +#define SETTINGCONFIG_H + +#include +#include + +class SettingConfig : public QObject +{ +public: + ~SettingConfig() {}; + SettingConfig(const SettingConfig&)=delete; + SettingConfig& operator=(const SettingConfig&)=delete; + + static SettingConfig& getInstance() { + static SettingConfig instance; + return instance; + } + + /** + * @brief get + * @param nodeName + * @param keyName + * @return QVariant + * @title + */ + QVariant getProperty(QString nodeName, QString keyName); + + /******** 以下为需要的各类参数 ********/ + int WINDOW_WIDTH; + int WINDOW_HEIGHT; + QString WINDOW_BACKGROUND_COLOR; + QString WINDOW_TITLE; + QString WINDOW_RIGHTS; + QString WINDOW_VERSION; + + int IRIS_FRAME_INTERVAL; + int IRIS_FRAME_WIDTH; + int IRIS_FRAME_HEIGHT; + int IRIS_WIDTH; + int IRIS_HEIGHT; + int IRIS_DISPLAY_WIDTH; + int IRIS_DISPLAY_HEIGHT; + + int MAX_MATCH_TIME; + int SUCCESS_TIPS_LAST; + int FAILURE_TIPS_LAST; + int MAX_FACE_TRY_COUNT; + int MAX_FACE_NOT_FOUND_COUNT; + int MAX_IRIS_TRY_COUNT; + int MAX_EYE_NOT_FOUND_COUNT; + + int MAX_CAPTURE_STACK_SIZE; + int MAX_FOUND_STACK_SIZE; + int MAX_QUALIFIED_STACK_SIZE; + + QString LOG_FILE; + QString LOG_LEVEL; + +private: + SettingConfig(); + + QString filename; + QSettings* setting; +}; + +#endif // SETTINGCONFIG_H diff --git a/utils/TimeCounterUtil.cpp b/utils/TimeCounterUtil.cpp new file mode 100644 index 0000000..275945f --- /dev/null +++ b/utils/TimeCounterUtil.cpp @@ -0,0 +1,8 @@ +#include "TimeCounterUtil.h" + +TimeCounterUtil::TimeCounterUtil() +{ + faceCapCounter = new QTimer(); + irisCapCounter = new QTimer(); + clockCounter = new QTimer(); +} diff --git a/utils/TimeCounterUtil.h b/utils/TimeCounterUtil.h new file mode 100644 index 0000000..28b29f1 --- /dev/null +++ b/utils/TimeCounterUtil.h @@ -0,0 +1,29 @@ +#ifndef TIMECOUNTERUTIL_H +#define TIMECOUNTERUTIL_H + +#include +#include + +class TimeCounterUtil : public QObject +{ +public: + + ~TimeCounterUtil() {}; + TimeCounterUtil(const TimeCounterUtil&)=delete; + TimeCounterUtil& operator=(const TimeCounterUtil&)=delete; + + static TimeCounterUtil& getInstance() { + static TimeCounterUtil instance; + return instance; + } + + QTimer * faceCapCounter; + QTimer * irisCapCounter; + QTimer * clockCounter; + +private: + TimeCounterUtil(); + +}; + +#endif // TIMECOUNTERUTIL_H diff --git a/utils/UtilInclude.h b/utils/UtilInclude.h new file mode 100644 index 0000000..e7b899a --- /dev/null +++ b/utils/UtilInclude.h @@ -0,0 +1,13 @@ +#ifndef UTILINCLUDE_H +#define UTILINCLUDE_H + +//#include "ByteUtil.h" +#include "ImageUtil.h" +//#include "LogUtil.h" +#include "SettingConfig.h" +//#include "SpeakerUtil.h" +#include "TimeCounterUtil.h" +//#include "UDPClientUtil.h" +//#include "HttpRequestUtil.h" + +#endif // UTILINCLUDE_H diff --git a/utils/id/IdWorker.h b/utils/id/IdWorker.h new file mode 100644 index 0000000..6c48aa9 --- /dev/null +++ b/utils/id/IdWorker.h @@ -0,0 +1,218 @@ +#ifndef _JW_CORE_ID_WORKER_H_ +#define _JW_CORE_ID_WORKER_H_ + +#include +#include +#include +#include +#include +#include "Noncopyable.h" +#include "Singleton.h" + +// 如果不使用 mutex, 则开启下面这个定义, 但是我发现, 还是开启 mutex 功能, 速度比较快 +// #define SNOWFLAKE_ID_WORKER_NO_LOCK + +namespace Jiawa { + + /** + * @brief 核心 + * 核心功能 + */ + namespace Core { + + /** + * @brief 分布式id生成类 + * https://segmentfault.com/a/1190000011282426 + * https://github.com/twitter/snowflake/blob/snowflake-2010/src/main/scala/com/twitter/service/snowflake/IdWorker.scala + * + * 64bit id: 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 + * || || || | | | + * |└---------------------------时间戳--------------------------┘└中心-┘└机器-┘ └----序列号----┘ + * | + * 不用 + * SnowFlake的优点: 整体上按照时间自增排序, 并且整个分布式系统内不会产生ID碰撞(由数据中心ID和机器ID作区分), 并且效率较高, 经测试, SnowFlake每秒能够产生26万ID左右. + */ + class SnowflakeIdWorker : private Noncopyable { + + // 实现单例 + friend class Singleton; + + public: + typedef unsigned int UInt; + typedef unsigned long long int UInt64; + +#ifdef SNOWFLAKE_ID_WORKER_NO_LOCK + typedef std::atomic AtomicUInt; + typedef std::atomic AtomicUInt64; +#else + typedef UInt AtomicUInt; + typedef UInt64 AtomicUInt64; +#endif + + void setWorkerId(UInt workerId) { + this->workerId = workerId; + } + + void setDatacenterId(UInt datacenterId) { + this->datacenterId = datacenterId; + } + + UInt64 getId() { + return nextId(); + } + + /** + * 获得下一个ID (该方法是线程安全的) + * + * @return SnowflakeId + */ + UInt64 nextId() { +#ifndef SNOWFLAKE_ID_WORKER_NO_LOCK + std::unique_lock lock{ mutex }; + AtomicUInt64 timestamp{ 0 }; +#else + static AtomicUInt64 timestamp{ 0 }; +#endif + timestamp = timeGen(); + + // 如果当前时间小于上一次ID生成的时间戳, 说明系统时钟回退过这个时候应当抛出异常 + if (timestamp < lastTimestamp) { + std::ostringstream s; + s << "clock moved backwards. Refusing to generate id for " << lastTimestamp - timestamp << " milliseconds"; + throw std::exception(std::runtime_error(s.str())); + } + + if (lastTimestamp == timestamp) { + // 如果是同一时间生成的, 则进行毫秒内序列 + sequence = (sequence + 1) & sequenceMask; + if (0 == sequence) { + // 毫秒内序列溢出, 阻塞到下一个毫秒,获得新的时间戳 + timestamp = tilNextMillis(lastTimestamp); + } + } else { + sequence = 0; + } + +#ifndef SNOWFLAKE_ID_WORKER_NO_LOCK + lastTimestamp = timestamp; +#else + lastTimestamp = timestamp.load(); +#endif + + // 移位并通过或运算拼到一起组成64位的ID + return ((timestamp - twepoch) << timestampLeftShift) + | (datacenterId << datacenterIdShift) + | (workerId << workerIdShift) + | sequence; + } + + protected: + SnowflakeIdWorker() : workerId(0), datacenterId(0), sequence(0), lastTimestamp(0) { } + + /** + * 返回以毫秒为单位的当前时间 + * + * @return 当前时间(毫秒) + */ + UInt64 timeGen() const { + auto t = std::chrono::time_point_cast(std::chrono::high_resolution_clock::now()); + return t.time_since_epoch().count(); + } + + /** + * 阻塞到下一个毫秒, 直到获得新的时间戳 + * + * @param lastTimestamp 上次生成ID的时间截 + * @return 当前时间戳 + */ + UInt64 tilNextMillis(UInt64 lastTimestamp) const { + UInt64 timestamp = timeGen(); + while (timestamp <= lastTimestamp) { + timestamp = timeGen(); + } + return timestamp; + } + + private: + +#ifndef SNOWFLAKE_ID_WORKER_NO_LOCK + std::mutex mutex; +#endif + + /** + * 开始时间截 (2018-01-01 00:00:00.000) + */ + const UInt64 twepoch = 1514736000000; + + /** + * 机器id所占的位数 + */ + const UInt workerIdBits = 5; + + /** + * 数据中心id所占的位数 + */ + const UInt datacenterIdBits = 5; + + /** + * 序列所占的位数 + */ + const UInt sequenceBits = 12; + + /** + * 机器ID向左移12位 + */ + const UInt workerIdShift = sequenceBits; + + /** + * 数据标识id向左移17位 + */ + const UInt datacenterIdShift = workerIdShift + workerIdBits; + + /** + * 时间截向左移22位 + */ + const UInt timestampLeftShift = datacenterIdShift + datacenterIdBits; + + /** + * 支持的最大机器id, 结果是31 + */ + const UInt maxWorkerId = -1 ^ (-1 << workerIdBits); + + /** + * 支持的最大数据中心id, 结果是31 + */ + const UInt maxDatacenterId = -1 ^ (-1 << datacenterIdBits); + + /** + * 生成序列的掩码, 这里为4095 + */ + const UInt sequenceMask = -1 ^ (-1 << sequenceBits); + + /** + * 工作机器id(0~31) + */ + UInt workerId; + + /** + * 数据中心id(0~31) + */ + UInt datacenterId; + + /** + * 毫秒内序列(0~4095) + */ + AtomicUInt sequence{ 0 }; + + /** + * 上次生成ID的时间截 + */ + AtomicUInt64 lastTimestamp{ 0 }; + + }; + + typedef SnowflakeIdWorker IdWorker; + } +} + +#endif // _JW_CORE_ID_WORKER_H_ diff --git a/utils/id/Noncopyable.h b/utils/id/Noncopyable.h new file mode 100644 index 0000000..d87f58a --- /dev/null +++ b/utils/id/Noncopyable.h @@ -0,0 +1,31 @@ +#ifndef _JW_CORE_NONCOPYABLE_H_ +#define _JW_CORE_NONCOPYABLE_H_ + + +// Private copy constructor and copy assignment ensure classes derived from +// class noncopyable cannot be copied. + +namespace Jiawa { + namespace Core { + + // protection from unintended ADL(Argument Dependent Lookup) + namespace Noncopyable_ { + + class Noncopyable + { + protected: + Noncopyable() = default; + ~Noncopyable() = default; + + Noncopyable(const Noncopyable&) = delete; + Noncopyable(const Noncopyable&&) = delete; + Noncopyable& operator=(const Noncopyable&) = delete; + Noncopyable& operator=(const Noncopyable&&) = delete; + }; + } + + typedef Noncopyable_::Noncopyable Noncopyable; + } +} + +#endif // _JW_CORE_NONCOPYABLE_H_ diff --git a/utils/id/Singleton.h b/utils/id/Singleton.h new file mode 100644 index 0000000..d1c0553 --- /dev/null +++ b/utils/id/Singleton.h @@ -0,0 +1,60 @@ +#ifndef _JW_CORE_SINGLETON_H_ +#define _JW_CORE_SINGLETON_H_ + +namespace Jiawa { + namespace Core { + + // boost/container/detail/singleton.hpp + // http://blog.csdn.net/fullsail/article/details/8483106 + // T must be: no-throw default constructible and no-throw destructible + template + class Singleton { + private: + Singleton() = default; + ~Singleton() = default; + + private: + struct object_creator + { + // This constructor does nothing more than ensure that instance() + // is called before main() begins, thus creating the static + // T object before multithreading race issues can come up. + object_creator() { Singleton::instance(); } + inline void do_nothing() const { } + }; + static object_creator create_object; + + private: + Singleton(const Singleton&) = delete; + Singleton(const Singleton&&) = delete; + Singleton& operator=(const Singleton&) = delete; + Singleton& operator=(const Singleton&&) = delete; + + public: + typedef T object_type; + + // If, at any point (in user code), Singleton::instance() + // is called, then the following function is instantiated. + static object_type& instance() + { + // This is the object that we return a reference to. + // It is guaranteed to be created before main() begins because of + // the next line. + static object_type obj; + + // The following line does nothing else than force the instantiation + // of Singleton::create_object, whose constructor is + // called before main() begins. + create_object.do_nothing(); + + return obj; + } + }; + + template + typename Singleton::object_creator Singleton::create_object; + } +} + +#endif // _JW_CORE_SINGLETON_H_ + diff --git a/utils/id/Timer.h b/utils/id/Timer.h new file mode 100644 index 0000000..0f1ff1b --- /dev/null +++ b/utils/id/Timer.h @@ -0,0 +1,57 @@ +#ifndef _JW_CORE_TIMER_H_ +#define _JW_CORE_TIMER_H_ + +#include + +namespace Jiawa { + + /** + * @brief 核心 + * 核心功能 + */ + namespace Core { + + /** + * @brief 计时器类 + * 计时 + */ + template + class Timer { + public: + + typedef CLOCK clock; + typedef typename CLOCK::rep rep; + typedef typename CLOCK::duration duration; + typedef typename CLOCK::time_point time_point; + + Timer() : m_start(CLOCK::now()) { + } + + /** + * @brief 重置计时器 + * + * @return 开始的时间点 + */ + time_point reset() { + m_start = CLOCK::now(); + return m_start; + } + + /** + * @brief 得到流逝的时间 + * @param UNIT 返回时间的类型 + * + * @return 返回流逝的时间 + */ + template + typename UNIT::duration::rep elapsed() const { + return std::chrono::duration_cast(CLOCK::now() - m_start).count(); + } + + private: + time_point m_start; + }; + } +} + +#endif // _JW_CORE_TIMER_H_ \ No newline at end of file diff --git a/AppConstants.h b/AppConstants.h new file mode 100644 index 0000000..296c53f --- /dev/null +++ b/AppConstants.h @@ -0,0 +1,28 @@ +#ifndef APPCONSTANTS_H +#define APPCONSTANTS_H + +class AppConstants +{ +public: + enum WidgeFrameName + { + MAIN_PAGE = 0, // 主页面 + PERSON_LIST_FORM = 1, // 人员列表页面 + ADD_PERSON_FORM = 2, // 添加人员页面 + ADD_PERSON_CAPTURE_FACE = 21, // 添加/编辑人员时进行人脸拍图 + ADD_PERSON_CAPTURE_IRIS = 22, // 添加/编辑人员时进行虹膜拍图 + SETTING_FORM = 3, // 设置页面 + RECOGNIZE_RESULT_FORM = 4, // 识别结果界面 + IDENTIFY_FORM = 5, // 识别界面 含识别中 和 识别结果 + LOCKSCREEN_FORM = 6 // 锁屏待机界面 + }; + + enum ApplicationState + { + STATE_WAIT = 0, // 待机 + STATE_WORKING = 1, // 工作状态 + STATE_IDENTIFYING = 2, // 识别中 + }; +}; + +#endif // APPCONSTANTS_H diff --git a/CasicIrisIdentify.pro b/CasicIrisIdentify.pro index 5d7fea6..575ce3d 100644 --- a/CasicIrisIdentify.pro +++ b/CasicIrisIdentify.pro @@ -1,4 +1,4 @@ -QT += core gui +QT += core gui sql network texttospeech greaterThan(QT_MAJOR_VERSION, 4): QT += widgets @@ -15,20 +15,46 @@ # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 -SOURCES += \ - main.cpp \ - IdentifyForm.cpp +include("dao/dao.pri") +include("device/device.pri") +include("utils/utils.pri") -HEADERS += \ - IdentifyForm.h +SOURCES += main.cpp +SOURCES += ProMemory.cpp +SOURCES += MainWindowForm.cpp +SOURCES += IdentifyForm.cpp +SOURCES += LockScreenForm.cpp -FORMS += \ - IdentifyForm.ui +HEADERS += AppConstants.h +HEADERS += ProMemory.h +HEADERS += MainWindowForm.h +HEADERS += IdentifyForm.h +HEADERS += LockScreenForm.h -TRANSLATIONS += \ - CasicIrisIdentify_zh_CN.ts +FORMS += MainWindowForm.ui +FORMS += IdentifyForm.ui +FORMS += LockScreenForm.ui + +RESOURCES += resource.qrc + +DISTFILES += conf/config.ini + +#TRANSLATIONS += CasicIrisIdentify_zh_CN.ts + +#INCLUDEPATH += include/spdlog +#DEPENDPATH += include/spdlog # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target + + +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lopencv_world420 +unix:!macx|win32: LIBS += -L$$PWD/lib/ -lGxIAPICPPEx + +INCLUDEPATH += $$PWD/include/daheng +DEPENDPATH += $$PWD/include/daheng + +INCLUDEPATH += $$PWD/include +DEPENDPATH += $$PWD/include diff --git a/CasicIrisIdentify_zh_CN.ts b/CasicIrisIdentify_zh_CN.ts index 5526fe4..81900df 100644 --- a/CasicIrisIdentify_zh_CN.ts +++ b/CasicIrisIdentify_zh_CN.ts @@ -1,3 +1,12 @@ - + + + IdentifyForm + + + IdentifyForm + + + + diff --git a/IdentifyForm.cpp b/IdentifyForm.cpp index 348a897..ba1f251 100644 --- a/IdentifyForm.cpp +++ b/IdentifyForm.cpp @@ -1,4 +1,4 @@ -#include "IdentifyForm.h" +#include "IdentifyForm.h" #include "ui_IdentifyForm.h" IdentifyForm::IdentifyForm(QWidget *parent) @@ -6,6 +6,12 @@ , ui(new Ui::IdentifyForm) { ui->setupUi(this); + + // 初始化更新界面的定时器 + // 每秒执行一次 + connect(TimeCounterUtil::getInstance().clockCounter, &QTimer::timeout, this, &IdentifyForm::updateDateAndTime); + + TimeCounterUtil::getInstance().clockCounter->start(1000); } IdentifyForm::~IdentifyForm() @@ -13,3 +19,16 @@ delete ui; } +void IdentifyForm::drawIrisImageOnFrame(QImage image) +{ + // 只在识别界面才显示画面 + if (ui->wgtStacked->currentIndex() == 0) { + ui->labelVideo->setPixmap(QPixmap::fromImage(image)); + } +} + + +void IdentifyForm::updateDateAndTime() +{ + ui->labelTime->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd dddd HH:mm:ss")); +} diff --git a/IdentifyForm.h b/IdentifyForm.h index fc857a1..ae1cd22 100644 --- a/IdentifyForm.h +++ b/IdentifyForm.h @@ -1,7 +1,10 @@ -#ifndef IDENTIFYFORM_H +#ifndef IDENTIFYFORM_H #define IDENTIFYFORM_H #include +#include + +#include "utils/UtilInclude.h" QT_BEGIN_NAMESPACE namespace Ui { class IdentifyForm; } @@ -15,7 +18,14 @@ IdentifyForm(QWidget *parent = nullptr); ~IdentifyForm(); +public slots: + void drawIrisImageOnFrame(QImage image); + private: Ui::IdentifyForm *ui; + +private slots: + void updateDateAndTime(); + }; #endif // IDENTIFYFORM_H diff --git a/IdentifyForm.ui b/IdentifyForm.ui index c72a36f..879dc9a 100644 --- a/IdentifyForm.ui +++ b/IdentifyForm.ui @@ -6,13 +6,59 @@ 0 0 - 800 + 600 600 IdentifyForm + + + + 0 + 40 + 600 + 450 + + + + 0 + + + + + + 100 + 10 + 400 + 300 + + + + + + + + + + + + + + 0 + 0 + 600 + 40 + + + + TextLabel + + + Qt::AlignCenter + + diff --git a/LockScreenForm.cpp b/LockScreenForm.cpp new file mode 100644 index 0000000..58dc54b --- /dev/null +++ b/LockScreenForm.cpp @@ -0,0 +1,14 @@ +#include "LockScreenForm.h" +#include "ui_LockScreenForm.h" + +LockScreenForm::LockScreenForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::LockScreenForm) +{ + ui->setupUi(this); +} + +LockScreenForm::~LockScreenForm() +{ + delete ui; +} diff --git a/LockScreenForm.h b/LockScreenForm.h new file mode 100644 index 0000000..b5ded48 --- /dev/null +++ b/LockScreenForm.h @@ -0,0 +1,25 @@ +#ifndef LOCKSCREENFORM_H +#define LOCKSCREENFORM_H + +#include +#include + +#include "utils/UtilInclude.h" + +namespace Ui { +class LockScreenForm; +} + +class LockScreenForm : public QWidget +{ + Q_OBJECT + +public: + explicit LockScreenForm(QWidget *parent = nullptr); + ~LockScreenForm(); + +private: + Ui::LockScreenForm *ui; +}; + +#endif // LOCKSCREENFORM_H diff --git a/LockScreenForm.ui b/LockScreenForm.ui new file mode 100644 index 0000000..7f2a6db --- /dev/null +++ b/LockScreenForm.ui @@ -0,0 +1,45 @@ + + + LockScreenForm + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + 180 + 100 + 54 + 12 + + + + TextLabel + + + + + + 180 + 160 + 54 + 12 + + + + TextLabel + + + + + + diff --git a/MainWindowForm.cpp b/MainWindowForm.cpp new file mode 100644 index 0000000..84f8159 --- /dev/null +++ b/MainWindowForm.cpp @@ -0,0 +1,86 @@ +#include "MainWindowForm.h" +#include "ui_MainWindowForm.h" +#include + +MainWindowForm::MainWindowForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::MainWindowForm) +{ + ui->setupUi(this); + + // 设置窗口透明和大小、位置 + this->setWindowFlags(Qt::FramelessWindowHint); + this->move(1400, 15); + this->resize(SettingConfig::getInstance().WINDOW_WIDTH, SettingConfig::getInstance().WINDOW_HEIGHT); + + // 通过调色板的颜色来设置窗口的统一背景色 + qApp->setPalette(QPalette(QColor(SettingConfig::getInstance().WINDOW_BACKGROUND_COLOR))); + + // 加载css文件设置控件样式 + QFile file(QApplication::applicationDirPath() + "/qss/main.css"); + if (file.open(QFile::ReadOnly)) + { + QString qssStr = QLatin1String(file.readAll()); + this->setStyleSheet(qssStr); + file.close(); + } + + initFormsPtr(); + + // 设置标题文字 + ui->labelTitle->setText(SettingConfig::getInstance().WINDOW_TITLE); + ui->labelCopyright->setText(SettingConfig::getInstance().WINDOW_RIGHTS); + ui->labelVersion->setText(SettingConfig::getInstance().WINDOW_VERSION); + + // 初始化虹膜相机控制 + ProMemory::getInstance().irisCam = new IrisCameraController(this); + ProMemory::getInstance().irisCam->initIrisCamera(); + ProMemory::getInstance().irisCam->openIrisCamera(); + connect(ProMemory::getInstance().irisCam->irisCamHandler, &IrisCameraCapEventHandler::sendIrisFrameToDraw, identifyForm, &IdentifyForm::drawIrisImageOnFrame); + +// LOG_INFO(QString("应用程序启动成功[Application Startup Success]").toStdString()); + qDebug() << "应用程序启动成功[Application Startup Success]"; + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::IDENTIFY_FORM; + ui->wdgtStatced->setCurrentWidget(identifyForm); + + // 开始虹膜相机拍图 + ProMemory::getInstance().irisCam->startCapture(); +} + +MainWindowForm::~MainWindowForm() +{ + delete ui; +} + +void MainWindowForm::lockScreen() +{ + ui->wdgtStatced->setCurrentWidget(lockScreenForm); + ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::LOCKSCREEN_FORM; + ProMemory::getInstance().appState = AppConstants::ApplicationState::STATE_WAIT; +} + +void MainWindowForm::keyPressEvent(QKeyEvent *event) +{ + switch (event->key()) { + case Qt::Key_Escape: + QTimer::singleShot(100, qApp, [=](){ + QApplication::quit(); + }); + + default: + QWidget::keyPressEvent(event); + } +} + +void MainWindowForm::initFormsPtr() +{ + // 初始化各个form + lockScreenForm = new LockScreenForm(this); + identifyForm = new IdentifyForm(this); + + // 将form添加到statcked widget中 + ui->wdgtStatced->addWidget(identifyForm); + ui->wdgtStatced->addWidget(lockScreenForm); + + // 绑定按钮函数 +} diff --git a/MainWindowForm.h b/MainWindowForm.h new file mode 100644 index 0000000..7fb2d89 --- /dev/null +++ b/MainWindowForm.h @@ -0,0 +1,38 @@ +#ifndef MAINWINDOWFORM_H +#define MAINWINDOWFORM_H + +#include +#include +#include + +#include "utils/UtilInclude.h" +#include "ProMemory.h" +#include "LockScreenForm.h" +#include "IdentifyForm.h" + +namespace Ui { +class MainWindowForm; +} + +class MainWindowForm : public QWidget +{ + Q_OBJECT + +public: + explicit MainWindowForm(QWidget *parent = nullptr); + ~MainWindowForm(); + +public slots: + void lockScreen(); + +private: + Ui::MainWindowForm *ui; + LockScreenForm * lockScreenForm; + IdentifyForm * identifyForm; + + void keyPressEvent(QKeyEvent *event); + + void initFormsPtr(); +}; + +#endif // MAINWINDOWFORM_H diff --git a/MainWindowForm.ui b/MainWindowForm.ui new file mode 100644 index 0000000..e793ebf --- /dev/null +++ b/MainWindowForm.ui @@ -0,0 +1,85 @@ + + + MainWindowForm + + + + 0 + 0 + 600 + 1024 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + 0 + 0 + 600 + 84 + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + + + + TextLabel + + + Qt::AlignBottom|Qt::AlignHCenter + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + diff --git a/ProMemory.cpp b/ProMemory.cpp new file mode 100644 index 0000000..19e7403 --- /dev/null +++ b/ProMemory.cpp @@ -0,0 +1,84 @@ +#include "ProMemory.h" + +ProMemory::ProMemory() +{ + +} + +ProMemory::~ProMemory() +{ + +} + +/* +void ProMemory::pushCasicIris(CasicIrisInfo irisInfo) +{ + QMutex mutex; + mutex.lock(); + if (this->irisQueue.size() > 30) + { + QStack empty; + std::swap(empty, irisQueue); + } + + irisQueue.push(irisInfo); + mutex.unlock(); +} +CasicIrisInfo ProMemory::popCasicIris() +{ + CasicIrisInfo result; + + QMutex mutex; + mutex.lock(); + if (this->irisQueue.size() > 0) + { + result = irisQueue.pop(); + } + + mutex.unlock(); + + return result; +} +*/ +int ProMemory::getIrisQueueSize() +{ + int size = 0; + + QMutex mutex; + mutex.lock(); + +// size = this->irisQueue.size(); + + mutex.unlock(); + + return size; +} +bool ProMemory::isIrisQueueEmpty() +{ + bool empty = true; + + QMutex mutex; + mutex.lock(); + +// empty = this->irisQueue.isEmpty(); + + mutex.unlock(); + + return empty; +} +void ProMemory::clearIrisQueue() +{ + QMutex mutex; + mutex.lock(); + +// QStack empty; +// std::swap(empty, irisQueue); + + mutex.unlock(); +} + + +void ProMemory::initIrisFeatures(QString personId) +{ +// irisRegistPro->sendDataToExract(QByteArray(QString("[-u]").append(personId).toLocal8Bit())); +} diff --git a/ProMemory.h b/ProMemory.h new file mode 100644 index 0000000..2ecd653 --- /dev/null +++ b/ProMemory.h @@ -0,0 +1,52 @@ +#ifndef PROMEMORY_H +#define PROMEMORY_H + +#include +#include + +#include "AppConstants.h" +//#include "casic/iris/CasicIrisInfo.h" +#include "dao/IrisDataDao.h" + +#include "device/IrisCameraController.h" +//#include "device/iris/IrisRegistProcess.h" +//#include "device/iris/IrisRecogProcess.h" + +class IrisCameraController; +class IrisRegistProcess; +class IrisRecogProcess; + +class ProMemory +{ +public: + ~ProMemory(); + ProMemory(const ProMemory&)=delete; + ProMemory& operator=(const ProMemory&)=delete; + + static ProMemory& getInstance() { + static ProMemory instance; + return instance; + } + +// void pushCasicIris(CasicIrisInfo irisInfo); +// CasicIrisInfo popCasicIris(); + int getIrisQueueSize(); + bool isIrisQueueEmpty(); + void clearIrisQueue(); + + volatile int widgeFrame = 0; // 当前显示的界面 + volatile int appState = 0; // 当前程序所处的状态 + + void initIrisFeatures(QString personId = ""); // 初始化虹膜特征值集合 + + IrisCameraController * irisCam; + IrisRecogProcess * irisRecogPro; + +private: + ProMemory(); + +// QStack irisQueue; // 虹膜信息队列 + QVector irisFeatures; // 虹膜特征值集合 +}; + +#endif // PROMEMORY_H diff --git a/conf/config.ini b/conf/config.ini new file mode 100644 index 0000000..66e46ad --- /dev/null +++ b/conf/config.ini @@ -0,0 +1,67 @@ +[recognize] +#最大允许识别时间(ms) +maxMatchTime=10000 +#识别成功界面停留时间(ms) +successTipsLast=5000 +#识别失败界面停留时间(ms) +failureTipsLast=3000 +#人脸识别最大尝试次数 +maxFaceTryCount=20 +#持续没找到人脸的最大次数 +maxFaceNotFoundCount=500 +#注册时最小人脸 +minFaceRegist=240 +#识别时最小人脸 +minFaceRecog=100 + +#虹膜识别最大尝试次数 +maxIrisTryCount=10 +#虹膜识别持续没有找到眼的最大次数 +maxEyeNotFoundCount=50 + +#识别方式[1=人脸;2=虹膜;3=双认证;4=任意] +recogType=4 + +[window] +#界面窗口宽(px) +width=600 +#界面窗口高(px) +height=1024 +#统一背景色 +backgroundColor="#FFFFFF" +#标题 +title="虹膜识别终端" + +[work] +#工作状态检测时最小人脸范围 +minFaceSize=160 +#人脸范围最小横坐标 +minFacePosX=320 +#人脸范围最大横坐标 +maxFacePosX=960 +#人脸范围最小纵坐标 +minFacePosY=180 +#人脸范围最大纵坐标 +maxFacePosY=540 +#人脸太近阈值 +faceCloseSize=360 +#人脸太远阈值 +faceFarSize=480 + +[camera] +#虹膜相机取一幅画面的时间间隔(ms) +irisFrameInterval=100 +#虹膜相机拍摄宽度 +irisFrameWidth=1440 +#虹膜相机拍摄高度 +irisFrameHeight=1080 +#虹膜图像高度 +irisWidth=640 +#虹膜图像高度 +irisHeight=480 + +[log] +#日志文件位置 +logFile="d://irisLogs//casic_log.txt" +#日志级别 +logLevel="trace" diff --git a/dao/BaseDao.cpp b/dao/BaseDao.cpp new file mode 100644 index 0000000..f51c144 --- /dev/null +++ b/dao/BaseDao.cpp @@ -0,0 +1,12 @@ +#include "BaseDao.h" +#include "dao/util/ConnectionManager.h" + +BaseDao::BaseDao(QObject *parent) : QObject(parent) +{ + +} + +BaseDao::~BaseDao() +{ + +} diff --git a/dao/BaseDao.h b/dao/BaseDao.h new file mode 100644 index 0000000..1693c88 --- /dev/null +++ b/dao/BaseDao.h @@ -0,0 +1,32 @@ +#ifndef BASEDAO_H +#define BASEDAO_H + +#include +#include +#include +#include + +#include "dao/util/ConnectionManager.h" +#include "utils/UtilInclude.h" + +class BaseDao : public QObject +{ + Q_OBJECT +public: + explicit BaseDao(QObject *parent = nullptr); + ~BaseDao(); + + virtual QVector findAllRecord() = 0; + virtual QVariantMap findRecordById(QString id) = 0; + + virtual QString save(QVariantMap object) = 0; + virtual bool edit(QVariantMap newObject, QString id) = 0; + virtual bool dele(QString id) = 0; + +private: + +signals: + +}; + +#endif // BASEDAO_H diff --git a/dao/IrisDataDao.cpp b/dao/IrisDataDao.cpp new file mode 100644 index 0000000..37a0ed6 --- /dev/null +++ b/dao/IrisDataDao.cpp @@ -0,0 +1,204 @@ +#include "IrisDataDao.h" + +IrisDataDao::IrisDataDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector IrisDataDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM IRIS_DATA"; + query.prepare(sql); + + // 执行查询 + query.exec(); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + item.insert("id", query.value("id").toString()); + item.insert("person_id", query.value("person_id").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("left_iris_code1", query.value("left_iris_code1")); + item.insert("left_iris_code2", query.value("left_iris_code2")); + item.insert("left_iris_code3", query.value("left_iris_code3")); + item.insert("right_iris_code1", query.value("right_iris_code1")); + item.insert("right_iris_code2", query.value("right_iris_code2")); + item.insert("right_iris_code3", query.value("right_iris_code3")); + + result.append(item); + } + +// LOG_DEBUG(QString("查询IRIS_DATA表的所有记录[结果数:%1]").arg(result.size()).toStdString()); + return result; +} + +QVariantMap IrisDataDao::findRecordById(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM IRIS_DATA WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + // 获取结果 + if (query.next()) + { + result.insert("id", query.value("id").toString()); + result.insert("person_id", query.value("person_id").toLongLong()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("left_iris_code1", query.value("left_iris_code1")); + result.insert("left_iris_code2", query.value("left_iris_code2")); + result.insert("left_iris_code3", query.value("left_iris_code3")); + result.insert("right_iris_code1", query.value("right_iris_code1")); + result.insert("right_iris_code2", query.value("right_iris_code2")); + result.insert("right_iris_code3", query.value("right_iris_code3")); + } + +// LOG_DEBUG(QString("根据id查询IRIS_DATA表的记录[id=%1]").arg(id).toStdString()); + return result; +} + +QVariantMap IrisDataDao::findRecordByPersonId(QString personId) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM IRIS_DATA WHERE PERSON_ID = :personId"); + query.prepare(sql); + query.bindValue(":personId", personId); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + if (query.next()) + { + result.insert("id", query.value("id").toString()); + result.insert("person_id", query.value("person_id").toLongLong()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("left_iris_code1", query.value("left_iris_code1")); + result.insert("left_iris_code2", query.value("left_iris_code2")); + result.insert("left_iris_code3", query.value("left_iris_code3")); + result.insert("right_iris_code1", query.value("right_iris_code1")); + result.insert("right_iris_code2", query.value("right_iris_code2")); + result.insert("right_iris_code3", query.value("right_iris_code3")); + } + +// LOG_DEBUG(QString("根据personId查询IRIS_DATA表的记录[personId=%1]").arg(personId).toStdString()); + return result; +} + + +QString IrisDataDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + + // INSERT语句 + QString sql = QString("INSERT INTO IRIS_DATA (ID, PERSON_ID, ID_CARD_NO, LEFT_IRIS_CODE1, RIGHT_IRIS_CODE1) VALUES (:id, :personId, :idCardNo, :left1, :right1)"); + + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":personId", object.value("person_id").toString()); + query.bindValue(":idCardNo", object.value("id_card_no").toString()); + query.bindValue(":left1", object.value("left_iris_code1")); + query.bindValue(":right1", object.value("right_iris_code1")); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(); + +// LOG_DEBUG(QString("保存虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool IrisDataDao::edit(QVariantMap newObject, QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // UPDATE语句 + if (!newObject.contains("left_iris_code1") || !newObject.contains("right_iris_code1")){ + return false; + } + QString sql = QString("UPDATE IRIS_DATA SET LEFT_IRIS_CODE1 = :left1, RIGHT_IRIS_CODE1 = :right1 WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":left1", newObject.value("left_iris_code1")); + query.bindValue(":right1", newObject.value("right_iris_code1")); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(); + +// LOG_DEBUG(QString("编辑虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; +} + + +bool IrisDataDao::dele(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + QString sql = QString("DELETE FROM IRIS_DATA WHERE ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(); + +// LOG_DEBUG(QString("删除虹膜特征值[%1][id=%2]").arg(success).arg(id).toStdString()); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; +} diff --git a/dao/IrisDataDao.h b/dao/IrisDataDao.h new file mode 100644 index 0000000..c74dbbd --- /dev/null +++ b/dao/IrisDataDao.h @@ -0,0 +1,25 @@ +#ifndef IRISDATADAO_H +#define IRISDATADAO_H + +#include +#include "BaseDao.h" + +class IrisDataDao : public BaseDao +{ + Q_OBJECT +public: + explicit IrisDataDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + QVariantMap findRecordByPersonId(QString personId); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +signals: + +}; + +#endif // IRISDATADAO_H diff --git a/dao/RecognitionRecordsDao.cpp b/dao/RecognitionRecordsDao.cpp new file mode 100644 index 0000000..40db453 --- /dev/null +++ b/dao/RecognitionRecordsDao.cpp @@ -0,0 +1,100 @@ +#include "RecognitionRecordsDao.h" + +RecognitionRecordsDao::RecognitionRecordsDao(QObject *parent) : BaseDao(parent) +{ + +} + + +QVector RecognitionRecordsDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM RECOGNITION_RECORDS"; + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + item.insert("id", query.value("id").toLongLong()); + result.append(item); + } + +// LOG_DEBUG(QString("查询RECOGNITION_RECORDS表的所有记录[记录数:%1]").arg(result.size()).toStdString()); + return result; +} + +QVariantMap RecognitionRecordsDao::findRecordById(QString id) +{ + QVariantMap item; + return item; +} + +QString RecognitionRecordsDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + + // INSERT语句 + QString sql = QString("INSERT INTO RECOGNITION_RECORDS (ID, PERSON_ID, DATETIME, REC_TYPE, DEV_CODE, DOOR_CODE, INOUT_TYPE) " + "VALUES (:id, :personId, :datetime, :recType, :devCode, :doorCode, :inoutType)"); + + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":personId", object.value("person_id").toString()); + query.bindValue(":datetime", object.value("date_time").toString()); + query.bindValue(":recType", object.value("rec_type").toString()); + query.bindValue(":devCode", object.value("dev_code").toString()); + query.bindValue(":doorCode", object.value("door_code").toString()); + query.bindValue(":inoutType", object.value("inout_type").toString()); + +// LOG_DEBUG(sql.toStdString()); + + // 插入识别的log日志 + QString logStr = QString("INSERT INTO RECOGNITION_LOGS (ID, LOG_INFO) VALUES (:id, :logInfo)"); + + QSqlQuery logQuery(ConnectionManager::getInstance()->getConnection()); + logQuery.prepare(logStr); + logQuery.bindValue(":id", id); + logQuery.bindValue(":logInfo", object.value("debug_info").toString()); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(); + logQuery.exec(); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool RecognitionRecordsDao::edit(QVariantMap newObject, QString id) +{ + return false; +} + +bool RecognitionRecordsDao::dele(QString id) +{ + return false; +} diff --git a/dao/RecognitionRecordsDao.h b/dao/RecognitionRecordsDao.h new file mode 100644 index 0000000..38de7c9 --- /dev/null +++ b/dao/RecognitionRecordsDao.h @@ -0,0 +1,23 @@ +#ifndef RECOGNITIONRECORDSDAO_H +#define RECOGNITIONRECORDSDAO_H + +#include +#include "BaseDao.h" +class RecognitionRecordsDao: public BaseDao +{ + Q_OBJECT +public: + explicit RecognitionRecordsDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +signals: + +}; + +#endif // RECOGNITIONRECORDSDAO_H diff --git a/dao/SysDeptDao.cpp b/dao/SysDeptDao.cpp new file mode 100644 index 0000000..22f9946 --- /dev/null +++ b/dao/SysDeptDao.cpp @@ -0,0 +1,88 @@ +#include "SysDeptDao.h" + +SysDeptDao::SysDeptDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector SysDeptDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_DEPT WHERE PID != '-1' ORDER BY PID, NUM"; + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + item.insert("id", query.value("id").toString()); + item.insert("pid", query.value("pid").toString()); + item.insert("pids", query.value("pids").toString()); + item.insert("simplename", query.value("simplename").toString()); + item.insert("fullname", query.value("fullname").toString()); + } + +// LOG_TRACE(QString("查询表[SYS_DEPT]的所有记录[%1][%2]").arg(result.size()).arg(sql).toStdString()); + + return result; +} + +QVariantMap SysDeptDao::findRecordById(QString id) +{ + QVariantMap item; + return item; + + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM SYS_DEPT WHERE SYS_DEPT.ID = :id"); + query.prepare(sql); + query.bindValue(":id", id); + + // 执行查询 + query.exec(); + + // 返回结果 + QVariantMap result; + + // 获取结果集的大小 + query.last(); + int count = query.at() + 1; + + if (count >=1) + { + query.first(); + + result.insert("id", query.value("id").toString()); + result.insert("pid", query.value("pid").toString()); + result.insert("pids", query.value("pids").toString()); + result.insert("simplename", query.value("simplename").toString()); + result.insert("fullname", query.value("fullname").toString()); + } + +// LOG_TRACE(QString("根据id查询SYS_DEPT表的记录[ID=%1][%2]").arg(id).arg(sql).toStdString()); + + return result; +} + + +QString SysDeptDao::save(QVariantMap object) +{ + return "0"; +} +bool SysDeptDao::edit(QVariantMap newObject, QString id) +{ + return true; +} +bool SysDeptDao::dele(QString id) +{ + return true; +} diff --git a/dao/SysDeptDao.h b/dao/SysDeptDao.h new file mode 100644 index 0000000..e07a09f --- /dev/null +++ b/dao/SysDeptDao.h @@ -0,0 +1,24 @@ +#ifndef SYSDEPTDAO_H +#define SYSDEPTDAO_H + +#include +#include "BaseDao.h" + +class SysDeptDao : public BaseDao +{ + Q_OBJECT +public: + explicit SysDeptDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); + +private: + +}; + +#endif // SYSDEPTDAO_H diff --git a/dao/SysPersonDao.cpp b/dao/SysPersonDao.cpp new file mode 100644 index 0000000..dd9480f --- /dev/null +++ b/dao/SysPersonDao.cpp @@ -0,0 +1,371 @@ +#include "SysPersonDao.h" + + +SysPersonDao::SysPersonDao(QObject *parent) : BaseDao(parent) +{ + +} + +QVector SysPersonDao::findAllRecord() +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0'"; + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + count++; + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + result.append(item); + } + +// LOG(TRACE) << QString("查询SYS_PERSON表的所有记录[%1]").arg(count).toStdString(); +// LOG_TRACE(QString("查询SYS_PERSON表的所有记录[%1]").arg(count).toStdString()); + + return result; +} + +QVariantMap SysPersonDao::findRecordById(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0' AND SYS_PERSON.ID = '%1'").arg(id); + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVariantMap result; + + // 获取结果集的大小 + query.last(); + int count = query.at() + 1; + + if (count >=1) + { + query.first(); + + result.insert("id", query.value("id").toString()); + result.insert("delflag", query.value("delflag").toString()); + result.insert("createtime", query.value("createtime").toString()); + result.insert("updatetime", query.value("updatetime").toString()); + result.insert("name", query.value("name").toString()); + result.insert("gender", query.value("gender").toString()); + result.insert("deptid", query.value("deptid").toString()); + result.insert("id_card_no", query.value("id_card_no").toString()); + result.insert("remarks", query.value("remarks").toString()); + result.insert("person_code", query.value("person_code").toString()); + result.insert("deptname", query.value("fullname").toString()); + result.insert("sync_id", query.value("sync_id").toString()); + result.insert("hasFace", query.value("face_valid").toString()); + result.insert("hasIris", query.value("iris_valid").toString()); + } + +// LOG(TRACE) << QString("根据id查询SYS_PERSON表的记录[id=%1][%2]").arg(id).arg(sql).toStdString(); +// LOG_TRACE(QString("根据id查询SYS_PERSON表的记录[id=%1][%2]").arg(id).arg(sql).toStdString()); + + return result; +} + +int SysPersonDao::findRecordCountByNameAndDept(QString name, QString dept) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT COUNT(P.ID) AS RECCT FROM SYS_PERSON P LEFT JOIN SYS_DEPT D ON P.DEPTID = D.ID WHERE P.DELFLAG = '0'"; + if (name.isEmpty() == false) + { + sql += " AND P.NAME LIKE '%" + name + "%'"; + } + if (dept.isEmpty() == false && dept.indexOf("-1") < 0) + { + sql += QString(" AND ((P.DEPTID = '%1') OR (D.PIDS LIKE '%,%1,%'))").arg(dept); + } + + // 执行查询 + query.exec(sql); + + // 返回结果 + int result; + + // 遍历查询结果 + if (query.next()) { + result = query.value("RECCT").toInt(); + } + +// LOG(TRACE) << QString("根据姓名和部门查询SYS_PERSON记录总数[%1][%2]").arg(result).arg(sql).toStdString(); +// LOG_TRACE(QString("根据姓名和部门查询SYS_PERSON记录总数[%1][%2]").arg(result).arg(sql).toStdString()); + + return result; +} + +QVector SysPersonDao::findRecordsByNameAndDept(QString name, QString dept, qint8 limit, qint16 offset) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON P LEFT JOIN SYS_DEPT D ON P.DEPTID = D.ID WHERE P.DELFLAG = '0'"; + if (name.isEmpty() == false) + { + sql += " AND P.NAME LIKE '%" + name + "%'"; + } + if (dept.isEmpty() == false && dept.indexOf("-1") < 0) + { + sql += QString(" AND ((P.DEPTID = '%1') OR (D.PIDS LIKE '%,%1,%'))").arg(dept); + } + + sql += QString(" LIMIT %1 OFFSET %2").arg(limit).arg(offset); + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + count++; + + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + + result.append(item); + } + +// LOG(TRACE) << QString("根据姓名和部门分页查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString(); +// LOG_TRACE(QString("根据姓名和部门分页查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString()); + + return result; +} + +QVector SysPersonDao::findRecordsByProperties(QVariantMap conditions) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM SYS_PERSON LEFT JOIN SYS_DEPT ON SYS_PERSON.DEPTID = SYS_DEPT.ID WHERE SYS_PERSON.DELFLAG = '0'"; + QVariantMap::iterator it; + for (it = conditions.begin(); it != conditions.end(); it++) + { + sql += QString(" AND SYS_PERSON.%1 = %2").arg(it.key()).arg(it.value().toString()); + } + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 + QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + count++; + + item.insert("id", query.value("id").toString()); + item.insert("delflag", query.value("delflag").toString()); + item.insert("createtime", query.value("createtime").toString()); + item.insert("updatetime", query.value("updatetime").toString()); + item.insert("name", query.value("name").toString()); + item.insert("gender", query.value("gender").toString()); + item.insert("deptid", query.value("deptid").toString()); + item.insert("id_card_no", query.value("id_card_no").toString()); + item.insert("remarks", query.value("remarks").toString()); + item.insert("person_code", query.value("person_code").toString()); + item.insert("sync_id", query.value("sync_id").toString()); + item.insert("deptname", query.value("fullname").toString()); + item.insert("hasFace", query.value("face_valid").toString()); + item.insert("hasIris", query.value("iris_valid").toString()); + + result.append(item); + } + +// LOG(TRACE) << QString("根据属性值查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString(); +// LOG_TRACE(QString("根据属性值查询SYS_PERSON表的记录[%1][%2]").arg(count).arg(sql).toStdString()); + + return result; +} + +QString SysPersonDao::save(QVariantMap object) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + qulonglong id = ConnectionManager::getInstance()->generateId(); + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + + // INSERT语句 + QString sql = QString("INSERT INTO SYS_PERSON " + "(ID, DELFLAG, CREATETIME, UPDATETIME, " + "NAME, GENDER, DEPTID, ID_CARD_NO, " + "REMARKS, PERSON_CODE, SYNC_ID, FACE_VALID, IRIS_VALID) " + "VALUES ('%1', '0', '%2', '%2', '%3', '%4', '%5', '%6', '%7', '%8', '%9', 0, 0)") + .arg(id).arg(tm) + .arg(object.value("name").toString()) + .arg(object.value("gender").toString()) + .arg(object.value("deptid").toString()) + .arg(object.value("id_card_no").toString()) + .arg(object.value("remarks").toString()) + .arg(object.value("person_code").toString()) + .arg(object.value("sync_id").toString()); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行插入 + bool success = query.exec(sql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + if (success == true) + { +// LOG(DEBUG) << QString("保存SYS_PERSON记录成功[ID = %1][%2]").arg(id).arg(sql).toStdString(); +// LOG_DEBUG(QString("保存SYS_PERSON记录成功[ID = %1][%2]").arg(id).arg(sql).toStdString()); + return QString("%1").arg(id); + } + else + { + return "-1"; + } +} + +bool SysPersonDao::edit(QVariantMap newObject, QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + + // UPDATE语句 + QString sql = QString("UPDATE SYS_PERSON SET UPDATETIME = '%1'").arg(tm); + if (newObject.contains("name")) + { + sql.append(QString(", NAME = '%1'").arg(newObject.value("name").toString())); + } + if (newObject.contains("gender")) + { + sql.append(QString(", GENDER = '%1'").arg(newObject.value("gender").toString())); + } + if (newObject.contains("deptid")) + { + sql.append(QString(", DEPTID = '%1'").arg(newObject.value("deptid").toString())); + } + if (newObject.contains("person_code")) + { + sql.append(QString(", PERSON_CODE = '%1'").arg(newObject.value("person_code").toString())); + } + if (newObject.contains("face_valid")) + { + sql.append(QString(", FACE_VALID = '%1'").arg(newObject.value("face_valid").toString())); + } + if (newObject.contains("iris_valid")) + { + sql.append(QString(", IRIS_VALID = '%1'").arg(newObject.value("iris_valid").toString())); + } + + sql.append(QString(" WHERE ID = '%1'").arg(id)); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(sql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + +// LOG(DEBUG) << QString("编辑人员[ID=%1][%2]").arg(id).arg(sql).toStdString(); +// LOG_DEBUG(QString("编辑人员[ID=%1][%2]").arg(id).arg(sql).toStdString()); + + // 返回结果 + return success; +} + +bool SysPersonDao::dele(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + QSqlQuery irisDel(ConnectionManager::getInstance()->getConnection()); + + QString tm = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + qint64 tmms = QDateTime::currentDateTime().toMSecsSinceEpoch(); + + // UPDATE语句 + QString sql = QString("UPDATE SYS_PERSON SET UPDATETIME = :updateTime, DELFLAG = :flag WHERE ID = :id").arg(tm).arg(tmms).arg(id); + query.prepare(sql); + query.bindValue(":id", id); + query.bindValue(":updateTime", tm); + query.bindValue(":flag", tmms); + + // 物理删除人员的人脸和虹膜数据 + QString delIrisSql = QString("DELETE FROM IRIS_DATA WHERE PERSON_ID = :personId"); + irisDel.prepare(delIrisSql); + irisDel.bindValue(":personId", id); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(sql); + query.exec(delIrisSql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + +// LOG_DEBUG(QString("删除人员SYS_PERSON[ID=%1][%2]").arg(id).arg(success).toStdString()); + + // 返回结果 + return success; +} diff --git a/dao/SysPersonDao.h b/dao/SysPersonDao.h new file mode 100644 index 0000000..e02e5ba --- /dev/null +++ b/dao/SysPersonDao.h @@ -0,0 +1,27 @@ +#ifndef SYSPERSONDAO_H +#define SYSPERSONDAO_H + +#include +#include "BaseDao.h" + +class SysPersonDao : public BaseDao +{ + Q_OBJECT +public: + explicit SysPersonDao(QObject *parent = nullptr); + + QVector findAllRecord(); + QVariantMap findRecordById(QString id); + + int findRecordCountByNameAndDept(QString name, QString dept); + QVector findRecordsByNameAndDept(QString name, QString dept, qint8 limit, qint16 offset); + QVector findRecordsByProperties(QVariantMap conditions); + + QString save(QVariantMap object); + bool edit(QVariantMap newObject, QString id); + bool dele(QString id); +signals: + +}; + +#endif // SYSPERSONDAO_H diff --git a/dao/dao.pri b/dao/dao.pri new file mode 100644 index 0000000..1e04ce4 --- /dev/null +++ b/dao/dao.pri @@ -0,0 +1,18 @@ + +HEADERS += $$PWD/BaseDao.h +HEADERS += $$PWD/IrisDataDao.h +HEADERS += $$PWD/RecognitionRecordsDao.h +HEADERS += $$PWD/SysPersonDao.h +HEADERS += $$PWD/SysDeptDao.h + +SOURCES += $$PWD/BaseDao.cpp +SOURCES += $$PWD/IrisDataDao.cpp +SOURCES += $$PWD/RecognitionRecordsDao.cpp +SOURCES += $$PWD/SysPersonDao.cpp +SOURCES += $$PWD/SysDeptDao.cpp + +HEADERS += $$PWD/util/ConnectionManager.h +SOURCES += $$PWD/util/ConnectionManager.cpp +#HEADERS += $$PWD/util/CacheManager.h +#SOURCES += $$PWD/util/CacheManager.cpp + diff --git a/dao/util/ConnectionManager.cpp b/dao/util/ConnectionManager.cpp new file mode 100644 index 0000000..84b17be --- /dev/null +++ b/dao/util/ConnectionManager.cpp @@ -0,0 +1,47 @@ +#include "ConnectionManager.h" +#include + +Q_GLOBAL_STATIC(ConnectionManager, cm) + +ConnectionManager::ConnectionManager(QObject *parent) : QObject(parent) +{ + // 初始化数据库连接 + if (QSqlDatabase::contains("qt_sql_dafault_connection")) + { + conn = QSqlDatabase::database("qt_sql_default_connection"); + } + else + { + conn = QSqlDatabase::addDatabase("QSQLITE"); + conn.setDatabaseName(QApplication::applicationDirPath() + "/data/casic.db"); + + bool succ = conn.open(); + if (succ == true) + { +// LOG_INFO(QString("打开数据库操作正常[Open Database Success]").toStdString()); + } else + { +// LOG_ERROR(QString("打开数据库操作失败[Open Database Failed]").toStdString()); + } + } +} + +ConnectionManager::~ConnectionManager() +{ + conn.close(); +} + +ConnectionManager* ConnectionManager::getInstance() +{ + return cm; +} + +QSqlDatabase ConnectionManager::getConnection() +{ + return this->conn; +} + +qint64 ConnectionManager::generateId() +{ + return this->idWorker.nextId(); +} diff --git a/dao/util/ConnectionManager.h b/dao/util/ConnectionManager.h new file mode 100644 index 0000000..84647e3 --- /dev/null +++ b/dao/util/ConnectionManager.h @@ -0,0 +1,34 @@ +#ifndef CONNECTIONMANAGER_H +#define CONNECTIONMANAGER_H + +#include +#include +#include "utils/id/IdWorker.h" +#include "utils/UtilInclude.h" + +using namespace Jiawa::Core; + +class ConnectionManager : public QObject +{ + Q_OBJECT +public: + explicit ConnectionManager(QObject *parent = nullptr); + ~ConnectionManager(); + + static ConnectionManager * getInstance(); + + QSqlDatabase getConnection(); + qint64 generateId(); + +private: + // 数据库连接 + QSqlDatabase conn; + + // 雪花id生成工具 + IdWorker &idWorker = Singleton::instance(); + +signals: + +}; + +#endif // CONNECTIONMANAGER_H diff --git a/device/IrisCameraCapEventHandler.cpp b/device/IrisCameraCapEventHandler.cpp new file mode 100644 index 0000000..45df089 --- /dev/null +++ b/device/IrisCameraCapEventHandler.cpp @@ -0,0 +1,103 @@ +#include "IrisCameraCapEventHandler.h" + +IrisCameraCapEventHandler::IrisCameraCapEventHandler(QObject *parent) : QObject(parent) +{ + +} + +void IrisCameraCapEventHandler::DoOnImageCaptured(CImageDataPointer &objImageDataPointer, void *pUserParam) +{ + if (objImageDataPointer.IsNull() == false) + { + CGXDevicePointer* cam = (CGXDevicePointer *) pUserParam; + + auto camName = cam->getPtr()->GetDeviceInfo().GetUserID(); + int width = objImageDataPointer->GetWidth(); + int height = objImageDataPointer->GetHeight(); + size_t leftKeyIndex = camName.find("left"); + size_t rightKeyIndex = camName.find("right"); + + uchar * pBuffer = (BYTE*)objImageDataPointer->GetBuffer(); + + // 相机拍摄下的图像1440*1080, 直接用于算法判断 + QImage img = QImage(pBuffer, width, height, QImage::Format_Grayscale8); // 用于展示 +// QImage imgAlgo = img.copy(0, 0, width, height); + + // 用于显示的图像需要缩小到400 * 300的尺寸 + img = img.scaled(SettingConfig::getInstance().IRIS_DISPLAY_HEIGHT, SettingConfig::getInstance().IRIS_DISPLAY_WIDTH); + img = img.transformed(QTransform().rotate(-90)); // 图像逆时针旋转90度 + + // 发送到界面进行显示 + emit sendIrisFrameToDraw(img); +// cv::Mat irisMat = ImageUtil::QImageToMat(imgAlgo); + +// irisInfo.data = imgAlgo; +// irisInfo.matData = irisMat; + +// // 将图像显示在注册页面的label上 +// // 并将虹膜信息对象存入队列中 +// ProMemory::getInstance().pushCasicIris(irisInfo); + +// if (leftKeyIndex >= 0 && leftKeyIndex < 32) +// { +// emit sendIrisFrameToDraw(img, 0); // 左眼画面 +// } else if (rightKeyIndex >= 0 && rightKeyIndex < 32) +// { +// emit sendIrisFrameToDraw(img, 1); // 右眼画面 +// } +/* + if (pBuffer != NULL) + { + // 创建虹膜信息对象 + CasicIrisInfo irisInfo; + irisInfo.hasEye = false; + if (leftKeyIndex >= 0 && leftKeyIndex < 32) + { + // 左眼相机拍摄的图像 + irisInfo.leftOrRight = "left"; + } else if (rightKeyIndex >= 0 && rightKeyIndex < 32) + { + // 右眼相机 + irisInfo.leftOrRight = "right"; + } + + if (ProMemory::getInstance().widgeFrame == CasicBioRecConst::RECOGNIZE_RESULT_FORM) + { + // 相机拍摄下的图像1280*960, 直接用于算法判断 + QImage imgDisp = QImage(pBuffer, width, height, QImage::Format_Grayscale8); + cv::Mat irisMat = ImageUtil::QImageToMat(imgDisp); + + irisInfo.data = imgDisp; + irisInfo.matData = irisMat; + + ProMemory::getInstance().pushCasicIris(irisInfo); + +// cv::imwrite(QString("D:\\irisLogs\\iristest-%1.bmp").arg(irisInfo.leftOrRight).toStdString(), irisMat); + } else if (ProMemory::getInstance().widgeFrame == CasicBioRecConst::ADD_PERSON_CAPTURE_IRIS) + { + // 相机拍摄下的图像1280*960, 直接用于算法判断 + QImage img = QImage(pBuffer, width, height, QImage::Format_Grayscale8); + QImage imgAlgo = img.copy(0, 0, width, height); + + // 用于显示的图像需要缩小到1/4的尺寸 + img = img.scaled(640, 480); + cv::Mat irisMat = ImageUtil::QImageToMat(imgAlgo); + + irisInfo.data = imgAlgo; + irisInfo.matData = irisMat; + + // 将图像显示在注册页面的label上 + // 并将虹膜信息对象存入队列中 + ProMemory::getInstance().pushCasicIris(irisInfo); + + if (leftKeyIndex >= 0 && leftKeyIndex < 32) + { + emit sendIrisFrameToDraw(img, 0); // 左眼画面 + } else if (rightKeyIndex >= 0 && rightKeyIndex < 32) + { + emit sendIrisFrameToDraw(img, 1); // 右眼画面 + } + } + }*/ + } +} diff --git a/device/IrisCameraCapEventHandler.h b/device/IrisCameraCapEventHandler.h new file mode 100644 index 0000000..ad75a97 --- /dev/null +++ b/device/IrisCameraCapEventHandler.h @@ -0,0 +1,30 @@ +#ifndef IRISCAMERACAPEVENTHANDLER_H +#define IRISCAMERACAPEVENTHANDLER_H + +#include +#include +#include "include/opencv2/opencv.hpp" +#include "include/daheng/GalaxyIncludes.h" + +//#include "casic/iris/CasicIrisInterface.h" +#include "ProMemory.h" + +#include "utils/UtilInclude.h" + +class IrisCameraCapEventHandler : public QObject, public ICaptureEventHandler +{ + Q_OBJECT +public: + explicit IrisCameraCapEventHandler(QObject *parent = nullptr); + + void DoOnImageCaptured(CImageDataPointer &objImageDataPointer, void *pUserParam); + +private: + unsigned char* pImageBuffer; + +signals: + void sendIrisFrameToDraw(QImage irisImage); + +}; + +#endif // IRISCAMERACAPEVENTHANDLER_H diff --git a/device/IrisCameraController.cpp b/device/IrisCameraController.cpp new file mode 100644 index 0000000..0928176 --- /dev/null +++ b/device/IrisCameraController.cpp @@ -0,0 +1,110 @@ +#include "IrisCameraController.h" + +IrisCameraController::IrisCameraController(QObject *parent) : QObject(parent) +{ + this->irisCamHandler = new IrisCameraCapEventHandler(this); +} +IrisCameraController::~IrisCameraController() +{ + this->closeIrisCamera(); +} + + +void IrisCameraController::initIrisCamera() +{ + IGXFactory::GetInstance().Init(); + + //枚举设备 + IGXFactory::GetInstance().UpdateDeviceList(1000, irisCamList); + + this->OpenDevice(); +} + +void IrisCameraController::openIrisCamera() +{ + //设置Buffer处理模式 + irisStreamFeaturePtr->GetEnumFeature("StreamBufferHandlingMode")->SetValue("OldestFirst"); + + //注册回调函数 + irisStreamPtr->RegisterCaptureCallback(irisCamHandler, &irisCamPtr); + + //开启流层通道 + irisStreamPtr->StartGrab(); + + //发送开采命令 + irisFeaturePtr->GetCommandFeature("AcquisitionStart")->Execute(); + + // 启动定时器 + TimeCounterUtil::getInstance().irisCapCounter->start(SettingConfig::getInstance().IRIS_FRAME_INTERVAL); // 50ms执行一次定时器 +} + +void IrisCameraController::closeIrisCamera() +{ + +} + +void IrisCameraController::startCapture() +{ + // 获取定时器, 绑定定时函数 + connect(TimeCounterUtil::getInstance().irisCapCounter, &QTimer::timeout, this, &IrisCameraController::getOneFaceFrm); +// LOG(DEBUG) << QString("[IrisCameraController][startCapture]虹膜相机拍图").toStdString(); +// LOG_DEBUG(QString("[IrisCameraController][startCapture]虹膜相机拍图").toStdString()); + +} +void IrisCameraController::stopCapture() +{ + // 获取定时器, 绑定定时函数 + disconnect(TimeCounterUtil::getInstance().irisCapCounter, &QTimer::timeout, this, &IrisCameraController::getOneFaceFrm); +// LOG(DEBUG) << QString("[IrisCameraController][stopCapture]虹膜相机停止拍图").toStdString(); +// LOG_DEBUG(QString("[IrisCameraController][stopCapture]虹膜相机停止拍图").toStdString()); + +} + +void IrisCameraController::getOneFaceFrm() +{ + // 发送软触发命令(在触发模式开启时有效) + irisFeaturePtr->GetCommandFeature("TriggerSoftware")->Execute(); +} + +void IrisCameraController::getLeftAndRightEyeFrame() +{ + irisFeaturePtr->GetCommandFeature("TriggerSoftware")->Execute(); +} + +void IrisCameraController::OpenDevice() +{ + auto device = irisCamList.at(0); + + irisCamPtr = IGXFactory::GetInstance().OpenDeviceByUserID(device.GetUserID(), GX_ACCESS_EXCLUSIVE); + irisFeaturePtr = irisCamPtr->GetRemoteFeatureControl(); + + // 判断设备流是否大于零, 如果大于零则打开流 + int nStreamCount = irisCamPtr->GetStreamCount(); + if (nStreamCount > 0) + { + irisStreamPtr = irisCamPtr->OpenStream(0); + irisStreamFeaturePtr = irisStreamPtr->GetFeatureControl(); + } + + // 建议用户在打开网络相机之后, 根据当前网络环境设置相机的流通道包长值, + // 以提高网络相机的采集性能, 设置方法参考以下代码。 + GX_DEVICE_CLASS_LIST objDeviceClass = irisCamPtr->GetDeviceInfo().GetDeviceClass(); + if(GX_DEVICE_CLASS_GEV == objDeviceClass) + { + // 判断设备是否支持流通道数据包功能 + if(true == irisFeaturePtr->IsImplemented("GevSCPSPacketSize")) + { + // 获取当前网络环境的最优包长值 + int nPacketSize = irisStreamPtr->GetOptimalPacketSize(); + // 将最优包长值设置为当前设备的流通道包长值 + irisFeaturePtr->GetIntFeature("GevSCPSPacketSize")->SetValue(nPacketSize); + } + } + + //设置采集模式为连续采集模式 + irisFeaturePtr->GetEnumFeature("AcquisitionMode")->SetValue("Continuous"); + + //设置触发模式关 + irisFeaturePtr->GetEnumFeature("TriggerMode")->SetValue("On"); + irisFeaturePtr->GetEnumFeature("TriggerSource")->SetValue("Software"); +} diff --git a/device/IrisCameraController.h b/device/IrisCameraController.h new file mode 100644 index 0000000..5d7e269 --- /dev/null +++ b/device/IrisCameraController.h @@ -0,0 +1,49 @@ +#ifndef IRISCAMERACONTROLLER_H +#define IRISCAMERACONTROLLER_H + +#include + +#include "IrisCameraCapEventHandler.h" + +class IrisCameraCapEventHandler; + +class IrisCameraController : public QObject +{ + Q_OBJECT +public: + explicit IrisCameraController(QObject *parent = nullptr); + ~IrisCameraController(); + + // 初始化并打开人脸相机 + void initIrisCamera(); + void openIrisCamera(); + void closeIrisCamera(); + + void startCapture(); + void stopCapture(); + + void getLeftAndRightEyeFrame(); + + IrisCameraCapEventHandler * irisCamHandler; + +private: + GxIAPICPP::gxdeviceinfo_vector irisCamList; + + CGXDevicePointer irisCamPtr; ///< 设备句柄 + + CGXStreamPointer irisStreamPtr; ///< 左眼设备流 + + CGXFeatureControlPointer irisFeaturePtr; ///< 左眼属性控制器 + + CGXFeatureControlPointer irisStreamFeaturePtr; ///< 左眼流层控制器对象 + + void OpenDevice(); + +signals: + +public slots: + void getOneFaceFrm(); + +}; + +#endif // IRISCAMERACONTROLLER_H diff --git a/device/device.pri b/device/device.pri new file mode 100644 index 0000000..a8417f2 --- /dev/null +++ b/device/device.pri @@ -0,0 +1,13 @@ + +HEADERS += $$PWD/IrisCameraController.h +HEADERS += $$PWD/IrisCameraCapEventHandler.h +#HEADERS += $$PWD/iris/IrisRegistProcess.h +#HEADERS += $$PWD/iris/IrisRecogProcess.h +#HEADERS += $$PWD/iris/CasicIrisRecState.h + +SOURCES += $$PWD/IrisCameraController.cpp +SOURCES += $$PWD/IrisCameraCapEventHandler.cpp +#SOURCES += $$PWD/iris/IrisRegistProcess.cpp +#SOURCES += $$PWD/iris/IrisRecogProcess.cpp +#SOURCES += $$PWD/iris/CasicIrisRecState.cpp + diff --git a/images/bg_footer.png b/images/bg_footer.png new file mode 100644 index 0000000..a3a99ab --- /dev/null +++ b/images/bg_footer.png Binary files differ diff --git a/images/bg_statcked.png b/images/bg_statcked.png new file mode 100644 index 0000000..18b63e1 --- /dev/null +++ b/images/bg_statcked.png Binary files differ diff --git a/images/bg_title.png b/images/bg_title.png new file mode 100644 index 0000000..0316e2d --- /dev/null +++ b/images/bg_title.png Binary files differ diff --git a/main.cpp b/main.cpp index 16bc45b..9052ddb 100644 --- a/main.cpp +++ b/main.cpp @@ -1,11 +1,11 @@ -#include "IdentifyForm.h" +#include "MainWindowForm.h" #include int main(int argc, char *argv[]) { QApplication a(argc, argv); - IdentifyForm w; + MainWindowForm w; w.show(); return a.exec(); } diff --git a/resource.qrc b/resource.qrc new file mode 100644 index 0000000..474586a --- /dev/null +++ b/resource.qrc @@ -0,0 +1,35 @@ + + + images/setting.png + images/user.png + images/back.png + images/home.png + images/btnPageFirst.png + images/btnPageLast.png + images/btnPageNext.png + images/btnPagePre.png + images/regist.png + images/photoEyeLeft.png + images/photoEyeRight.png + images/photoFace.png + images/save.png + images/upArrow.png + images/downArrow.png + images/faceCaped.png + images/faceNotCap.png + images/irisCaped.png + images/irisNotCap.png + images/tipsFailure.png + images/tipsSuccess.png + images/tipsConfirm.png + images/bg_recognize_result.png + images/iconRetry.png + images/bg_title.png + images/bg_footer.png + images/bg_statcked.png + + + images/add_bottom.png + images/add_top.png + + diff --git a/utils/ImageUtil.cpp b/utils/ImageUtil.cpp new file mode 100644 index 0000000..7604572 --- /dev/null +++ b/utils/ImageUtil.cpp @@ -0,0 +1,97 @@ +#include "ImageUtil.h" + +ImageUtil::ImageUtil() +{ + +} + +QImage ImageUtil::MatImageToQImage(const cv::Mat &src) +{ + //CV_8UC1 8位无符号的单通道---灰度图片 + if(src.type() == CV_8UC1) + { + QImage qImage((const unsigned char *)(src.data), src.cols, src.rows, src.cols, QImage::Format_Grayscale8); + return qImage; + } + //为3通道的彩色图片 + else if(src.type() == CV_8UC3) + { + //得到图像的的首地址 + const uchar *pSrc = (const uchar*)src.data; + //以src构造图片 + QImage qImage(pSrc, src.cols, src.rows, src.step, QImage::Format_RGB888); + //在不改变实际图像数据的条件下, 交换红蓝通道 + return qImage.rgbSwapped(); + } + //四通道图片, 带Alpha通道的RGB彩色图像 + else if(src.type() == CV_8UC4) + { + const uchar *pSrc = (const uchar*)src.data; + QImage qImage(pSrc, src.cols, src.rows, src.step, QImage::Format_ARGB32); + //返回图像的子区域作为一个新图像 + return qImage.copy(); + } + else + { + return QImage(); + } +} +/* +QImage ImageUtil::UcharToQImage(unsigned char* data, int width, int height, QImage::Format format) +{ + QImage qImage(data, width, height, format); + //在不改变实际图像数据的条件下, 交换红蓝通道 + return qImage.rgbSwapped(); +} + +cv::Mat ImageUtil::QImageToMat(QImage image) +{ + cv::Mat mat; + switch(image.format()) + { + case QImage::Format_ARGB32: + case QImage::Format_RGB32: + case QImage::Format_ARGB32_Premultiplied: + mat = cv::Mat(image.height(), image.width(), CV_8UC4, (void*)image.constBits(), image.bytesPerLine()); + break; + case QImage::Format_RGB888: + mat = cv::Mat(image.height(), image.width(), CV_8UC3, (void*)image.constBits(), image.bytesPerLine()); + cv::cvtColor(mat, mat, cv::COLOR_BGR2RGB); + break; + case QImage::Format_Indexed8: + mat = cv::Mat(image.height(), image.width(), CV_8UC1, (void*)image.constBits(), image.bytesPerLine()); + break; + case QImage::Format_Grayscale8: + mat = cv::Mat(image.height(), image.width(), CV_8UC1, (void *)image.bits(), image.bytesPerLine()); + break; + } + + mat = mat.clone(); + + return mat; +} + +QString ImageUtil::QImageToBase64(QImage image) +{ + QByteArray ba; + QBuffer buf(&ba); + image.save(&buf, "bmp"); + QString base64String = ba.toBase64(); + return base64String; +} + +cv::Mat ImageUtil::MatImageRect(const cv::Mat &src, cv::Rect rect, int delta) +{ + cv::Mat matClone = src.clone(); + cv::Rect bigRect; + + bigRect.x = rect.x - delta < 0 ? 0 : rect.x - delta; + bigRect.y = rect.y - delta < 0 ? 0 : rect.y - delta; + bigRect.width = rect.x + rect.width + 2 * delta > src.cols ? src.cols - rect.x : rect.width + 2 * delta; + bigRect.height = rect.y + rect.height + 2 * delta > src.rows ? src.rows - rect.y : rect.height + 2 * delta; + + cv::Mat roi = matClone(bigRect); + + return roi; +} +*/ diff --git a/utils/ImageUtil.h b/utils/ImageUtil.h new file mode 100644 index 0000000..dbfdd48 --- /dev/null +++ b/utils/ImageUtil.h @@ -0,0 +1,22 @@ +#ifndef IMAGEUTIL_H +#define IMAGEUTIL_H + +#include +#include +#include "opencv2/opencv.hpp" + +class ImageUtil +{ +public: + ImageUtil(); + + static QImage MatImageToQImage(const cv::Mat &src); +// static QImage UcharToQImage(unsigned char* data, int width, int height, QImage::Format format); + +// static cv::Mat QImageToMat(QImage image); +// static QString QImageToBase64(QImage image); + +// static cv::Mat MatImageRect(const cv::Mat &src, cv::Rect rect, int delta); +}; + +#endif // IMAGEUTIL_H diff --git a/utils/SettingConfig.cpp b/utils/SettingConfig.cpp new file mode 100644 index 0000000..d420285 --- /dev/null +++ b/utils/SettingConfig.cpp @@ -0,0 +1,44 @@ +#include "SettingConfig.h" +#include + +SettingConfig::SettingConfig() +{ + filename = QApplication::applicationDirPath() + "/conf/config.ini"; + setting = new QSettings(this->filename, QSettings::IniFormat); + + WINDOW_WIDTH = getProperty("window", "width").toInt(); + WINDOW_HEIGHT = getProperty("window", "height").toInt(); + WINDOW_BACKGROUND_COLOR = getProperty("window", "backgroundColor").toString(); + WINDOW_TITLE = getProperty("window", "title").toString(); + WINDOW_RIGHTS = getProperty("window", "copyright").toString(); + WINDOW_VERSION = getProperty("window", "version").toString(); + + IRIS_FRAME_WIDTH = getProperty("camera", "irisFrameWidth").toInt(); + IRIS_FRAME_HEIGHT = getProperty("camera", "irisFrameHeight").toInt(); + IRIS_WIDTH = getProperty("camera", "irisWidth").toInt(); + IRIS_HEIGHT = getProperty("camera", "irisHeight").toInt(); + IRIS_FRAME_INTERVAL = getProperty("camera", "irisFrameInterval").toInt(); + IRIS_DISPLAY_WIDTH = getProperty("camera", "irisDisplayWidth").toInt(); + IRIS_DISPLAY_HEIGHT = getProperty("camera", "irisDisplayHeight").toInt(); + + MAX_MATCH_TIME = getProperty("recognize", "maxMatchTime").toInt(); + SUCCESS_TIPS_LAST = getProperty("recognize", "successTipsLast").toInt(); + FAILURE_TIPS_LAST = getProperty("recognize", "failureTipsLast").toInt(); + MAX_FACE_TRY_COUNT = getProperty("recognize", "maxFaceTryCount").toInt(); + MAX_FACE_NOT_FOUND_COUNT = getProperty("recognize", "maxFaceNotFoundCount").toInt(); + MAX_IRIS_TRY_COUNT = getProperty("recognize", "maxIrisTryCount").toInt(); + MAX_EYE_NOT_FOUND_COUNT = getProperty("recognize", "maxEyeNotFoundCount").toInt(); + + MAX_CAPTURE_STACK_SIZE = getProperty("stack", "capture").toInt(); + MAX_FOUND_STACK_SIZE = getProperty("stack", "found").toInt(); + MAX_QUALIFIED_STACK_SIZE = getProperty("stack", "qualified").toInt(); + + LOG_FILE = getProperty("log", "logFile").toString(); + LOG_LEVEL = getProperty("log", "logLevel").toString(); +} + + +QVariant SettingConfig::getProperty(QString nodeName, QString keyName) { + QVariant var = this->setting->value(QString("/%1/%2").arg(nodeName).arg(keyName)); + return var; +} diff --git a/utils/SettingConfig.h b/utils/SettingConfig.h new file mode 100644 index 0000000..30c3bec --- /dev/null +++ b/utils/SettingConfig.h @@ -0,0 +1,66 @@ +#ifndef SETTINGCONFIG_H +#define SETTINGCONFIG_H + +#include +#include + +class SettingConfig : public QObject +{ +public: + ~SettingConfig() {}; + SettingConfig(const SettingConfig&)=delete; + SettingConfig& operator=(const SettingConfig&)=delete; + + static SettingConfig& getInstance() { + static SettingConfig instance; + return instance; + } + + /** + * @brief get + * @param nodeName + * @param keyName + * @return QVariant + * @title + */ + QVariant getProperty(QString nodeName, QString keyName); + + /******** 以下为需要的各类参数 ********/ + int WINDOW_WIDTH; + int WINDOW_HEIGHT; + QString WINDOW_BACKGROUND_COLOR; + QString WINDOW_TITLE; + QString WINDOW_RIGHTS; + QString WINDOW_VERSION; + + int IRIS_FRAME_INTERVAL; + int IRIS_FRAME_WIDTH; + int IRIS_FRAME_HEIGHT; + int IRIS_WIDTH; + int IRIS_HEIGHT; + int IRIS_DISPLAY_WIDTH; + int IRIS_DISPLAY_HEIGHT; + + int MAX_MATCH_TIME; + int SUCCESS_TIPS_LAST; + int FAILURE_TIPS_LAST; + int MAX_FACE_TRY_COUNT; + int MAX_FACE_NOT_FOUND_COUNT; + int MAX_IRIS_TRY_COUNT; + int MAX_EYE_NOT_FOUND_COUNT; + + int MAX_CAPTURE_STACK_SIZE; + int MAX_FOUND_STACK_SIZE; + int MAX_QUALIFIED_STACK_SIZE; + + QString LOG_FILE; + QString LOG_LEVEL; + +private: + SettingConfig(); + + QString filename; + QSettings* setting; +}; + +#endif // SETTINGCONFIG_H diff --git a/utils/TimeCounterUtil.cpp b/utils/TimeCounterUtil.cpp new file mode 100644 index 0000000..275945f --- /dev/null +++ b/utils/TimeCounterUtil.cpp @@ -0,0 +1,8 @@ +#include "TimeCounterUtil.h" + +TimeCounterUtil::TimeCounterUtil() +{ + faceCapCounter = new QTimer(); + irisCapCounter = new QTimer(); + clockCounter = new QTimer(); +} diff --git a/utils/TimeCounterUtil.h b/utils/TimeCounterUtil.h new file mode 100644 index 0000000..28b29f1 --- /dev/null +++ b/utils/TimeCounterUtil.h @@ -0,0 +1,29 @@ +#ifndef TIMECOUNTERUTIL_H +#define TIMECOUNTERUTIL_H + +#include +#include + +class TimeCounterUtil : public QObject +{ +public: + + ~TimeCounterUtil() {}; + TimeCounterUtil(const TimeCounterUtil&)=delete; + TimeCounterUtil& operator=(const TimeCounterUtil&)=delete; + + static TimeCounterUtil& getInstance() { + static TimeCounterUtil instance; + return instance; + } + + QTimer * faceCapCounter; + QTimer * irisCapCounter; + QTimer * clockCounter; + +private: + TimeCounterUtil(); + +}; + +#endif // TIMECOUNTERUTIL_H diff --git a/utils/UtilInclude.h b/utils/UtilInclude.h new file mode 100644 index 0000000..e7b899a --- /dev/null +++ b/utils/UtilInclude.h @@ -0,0 +1,13 @@ +#ifndef UTILINCLUDE_H +#define UTILINCLUDE_H + +//#include "ByteUtil.h" +#include "ImageUtil.h" +//#include "LogUtil.h" +#include "SettingConfig.h" +//#include "SpeakerUtil.h" +#include "TimeCounterUtil.h" +//#include "UDPClientUtil.h" +//#include "HttpRequestUtil.h" + +#endif // UTILINCLUDE_H diff --git a/utils/id/IdWorker.h b/utils/id/IdWorker.h new file mode 100644 index 0000000..6c48aa9 --- /dev/null +++ b/utils/id/IdWorker.h @@ -0,0 +1,218 @@ +#ifndef _JW_CORE_ID_WORKER_H_ +#define _JW_CORE_ID_WORKER_H_ + +#include +#include +#include +#include +#include +#include "Noncopyable.h" +#include "Singleton.h" + +// 如果不使用 mutex, 则开启下面这个定义, 但是我发现, 还是开启 mutex 功能, 速度比较快 +// #define SNOWFLAKE_ID_WORKER_NO_LOCK + +namespace Jiawa { + + /** + * @brief 核心 + * 核心功能 + */ + namespace Core { + + /** + * @brief 分布式id生成类 + * https://segmentfault.com/a/1190000011282426 + * https://github.com/twitter/snowflake/blob/snowflake-2010/src/main/scala/com/twitter/service/snowflake/IdWorker.scala + * + * 64bit id: 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 + * || || || | | | + * |└---------------------------时间戳--------------------------┘└中心-┘└机器-┘ └----序列号----┘ + * | + * 不用 + * SnowFlake的优点: 整体上按照时间自增排序, 并且整个分布式系统内不会产生ID碰撞(由数据中心ID和机器ID作区分), 并且效率较高, 经测试, SnowFlake每秒能够产生26万ID左右. + */ + class SnowflakeIdWorker : private Noncopyable { + + // 实现单例 + friend class Singleton; + + public: + typedef unsigned int UInt; + typedef unsigned long long int UInt64; + +#ifdef SNOWFLAKE_ID_WORKER_NO_LOCK + typedef std::atomic AtomicUInt; + typedef std::atomic AtomicUInt64; +#else + typedef UInt AtomicUInt; + typedef UInt64 AtomicUInt64; +#endif + + void setWorkerId(UInt workerId) { + this->workerId = workerId; + } + + void setDatacenterId(UInt datacenterId) { + this->datacenterId = datacenterId; + } + + UInt64 getId() { + return nextId(); + } + + /** + * 获得下一个ID (该方法是线程安全的) + * + * @return SnowflakeId + */ + UInt64 nextId() { +#ifndef SNOWFLAKE_ID_WORKER_NO_LOCK + std::unique_lock lock{ mutex }; + AtomicUInt64 timestamp{ 0 }; +#else + static AtomicUInt64 timestamp{ 0 }; +#endif + timestamp = timeGen(); + + // 如果当前时间小于上一次ID生成的时间戳, 说明系统时钟回退过这个时候应当抛出异常 + if (timestamp < lastTimestamp) { + std::ostringstream s; + s << "clock moved backwards. Refusing to generate id for " << lastTimestamp - timestamp << " milliseconds"; + throw std::exception(std::runtime_error(s.str())); + } + + if (lastTimestamp == timestamp) { + // 如果是同一时间生成的, 则进行毫秒内序列 + sequence = (sequence + 1) & sequenceMask; + if (0 == sequence) { + // 毫秒内序列溢出, 阻塞到下一个毫秒,获得新的时间戳 + timestamp = tilNextMillis(lastTimestamp); + } + } else { + sequence = 0; + } + +#ifndef SNOWFLAKE_ID_WORKER_NO_LOCK + lastTimestamp = timestamp; +#else + lastTimestamp = timestamp.load(); +#endif + + // 移位并通过或运算拼到一起组成64位的ID + return ((timestamp - twepoch) << timestampLeftShift) + | (datacenterId << datacenterIdShift) + | (workerId << workerIdShift) + | sequence; + } + + protected: + SnowflakeIdWorker() : workerId(0), datacenterId(0), sequence(0), lastTimestamp(0) { } + + /** + * 返回以毫秒为单位的当前时间 + * + * @return 当前时间(毫秒) + */ + UInt64 timeGen() const { + auto t = std::chrono::time_point_cast(std::chrono::high_resolution_clock::now()); + return t.time_since_epoch().count(); + } + + /** + * 阻塞到下一个毫秒, 直到获得新的时间戳 + * + * @param lastTimestamp 上次生成ID的时间截 + * @return 当前时间戳 + */ + UInt64 tilNextMillis(UInt64 lastTimestamp) const { + UInt64 timestamp = timeGen(); + while (timestamp <= lastTimestamp) { + timestamp = timeGen(); + } + return timestamp; + } + + private: + +#ifndef SNOWFLAKE_ID_WORKER_NO_LOCK + std::mutex mutex; +#endif + + /** + * 开始时间截 (2018-01-01 00:00:00.000) + */ + const UInt64 twepoch = 1514736000000; + + /** + * 机器id所占的位数 + */ + const UInt workerIdBits = 5; + + /** + * 数据中心id所占的位数 + */ + const UInt datacenterIdBits = 5; + + /** + * 序列所占的位数 + */ + const UInt sequenceBits = 12; + + /** + * 机器ID向左移12位 + */ + const UInt workerIdShift = sequenceBits; + + /** + * 数据标识id向左移17位 + */ + const UInt datacenterIdShift = workerIdShift + workerIdBits; + + /** + * 时间截向左移22位 + */ + const UInt timestampLeftShift = datacenterIdShift + datacenterIdBits; + + /** + * 支持的最大机器id, 结果是31 + */ + const UInt maxWorkerId = -1 ^ (-1 << workerIdBits); + + /** + * 支持的最大数据中心id, 结果是31 + */ + const UInt maxDatacenterId = -1 ^ (-1 << datacenterIdBits); + + /** + * 生成序列的掩码, 这里为4095 + */ + const UInt sequenceMask = -1 ^ (-1 << sequenceBits); + + /** + * 工作机器id(0~31) + */ + UInt workerId; + + /** + * 数据中心id(0~31) + */ + UInt datacenterId; + + /** + * 毫秒内序列(0~4095) + */ + AtomicUInt sequence{ 0 }; + + /** + * 上次生成ID的时间截 + */ + AtomicUInt64 lastTimestamp{ 0 }; + + }; + + typedef SnowflakeIdWorker IdWorker; + } +} + +#endif // _JW_CORE_ID_WORKER_H_ diff --git a/utils/id/Noncopyable.h b/utils/id/Noncopyable.h new file mode 100644 index 0000000..d87f58a --- /dev/null +++ b/utils/id/Noncopyable.h @@ -0,0 +1,31 @@ +#ifndef _JW_CORE_NONCOPYABLE_H_ +#define _JW_CORE_NONCOPYABLE_H_ + + +// Private copy constructor and copy assignment ensure classes derived from +// class noncopyable cannot be copied. + +namespace Jiawa { + namespace Core { + + // protection from unintended ADL(Argument Dependent Lookup) + namespace Noncopyable_ { + + class Noncopyable + { + protected: + Noncopyable() = default; + ~Noncopyable() = default; + + Noncopyable(const Noncopyable&) = delete; + Noncopyable(const Noncopyable&&) = delete; + Noncopyable& operator=(const Noncopyable&) = delete; + Noncopyable& operator=(const Noncopyable&&) = delete; + }; + } + + typedef Noncopyable_::Noncopyable Noncopyable; + } +} + +#endif // _JW_CORE_NONCOPYABLE_H_ diff --git a/utils/id/Singleton.h b/utils/id/Singleton.h new file mode 100644 index 0000000..d1c0553 --- /dev/null +++ b/utils/id/Singleton.h @@ -0,0 +1,60 @@ +#ifndef _JW_CORE_SINGLETON_H_ +#define _JW_CORE_SINGLETON_H_ + +namespace Jiawa { + namespace Core { + + // boost/container/detail/singleton.hpp + // http://blog.csdn.net/fullsail/article/details/8483106 + // T must be: no-throw default constructible and no-throw destructible + template + class Singleton { + private: + Singleton() = default; + ~Singleton() = default; + + private: + struct object_creator + { + // This constructor does nothing more than ensure that instance() + // is called before main() begins, thus creating the static + // T object before multithreading race issues can come up. + object_creator() { Singleton::instance(); } + inline void do_nothing() const { } + }; + static object_creator create_object; + + private: + Singleton(const Singleton&) = delete; + Singleton(const Singleton&&) = delete; + Singleton& operator=(const Singleton&) = delete; + Singleton& operator=(const Singleton&&) = delete; + + public: + typedef T object_type; + + // If, at any point (in user code), Singleton::instance() + // is called, then the following function is instantiated. + static object_type& instance() + { + // This is the object that we return a reference to. + // It is guaranteed to be created before main() begins because of + // the next line. + static object_type obj; + + // The following line does nothing else than force the instantiation + // of Singleton::create_object, whose constructor is + // called before main() begins. + create_object.do_nothing(); + + return obj; + } + }; + + template + typename Singleton::object_creator Singleton::create_object; + } +} + +#endif // _JW_CORE_SINGLETON_H_ + diff --git a/utils/id/Timer.h b/utils/id/Timer.h new file mode 100644 index 0000000..0f1ff1b --- /dev/null +++ b/utils/id/Timer.h @@ -0,0 +1,57 @@ +#ifndef _JW_CORE_TIMER_H_ +#define _JW_CORE_TIMER_H_ + +#include + +namespace Jiawa { + + /** + * @brief 核心 + * 核心功能 + */ + namespace Core { + + /** + * @brief 计时器类 + * 计时 + */ + template + class Timer { + public: + + typedef CLOCK clock; + typedef typename CLOCK::rep rep; + typedef typename CLOCK::duration duration; + typedef typename CLOCK::time_point time_point; + + Timer() : m_start(CLOCK::now()) { + } + + /** + * @brief 重置计时器 + * + * @return 开始的时间点 + */ + time_point reset() { + m_start = CLOCK::now(); + return m_start; + } + + /** + * @brief 得到流逝的时间 + * @param UNIT 返回时间的类型 + * + * @return 返回流逝的时间 + */ + template + typename UNIT::duration::rep elapsed() const { + return std::chrono::duration_cast(CLOCK::now() - m_start).count(); + } + + private: + time_point m_start; + }; + } +} + +#endif // _JW_CORE_TIMER_H_ \ No newline at end of file diff --git a/utils/utils.pri b/utils/utils.pri new file mode 100644 index 0000000..83096b2 --- /dev/null +++ b/utils/utils.pri @@ -0,0 +1,33 @@ + +HEADERS += $$PWD/UtilInclude.h + +HEADERS += $$PWD/id/IdWorker.h +HEADERS += $$PWD/id/Noncopyable.h +HEADERS += $$PWD/id/Singleton.h +HEADERS += $$PWD/id/Timer.h + +HEADERS += $$PWD/ImageUtil.h +SOURCES += $$PWD/ImageUtil.cpp + +#HEADERS += $$PWD/LogUtil.h + +HEADERS += $$PWD/SettingConfig.h +SOURCES += $$PWD/SettingConfig.cpp + +HEADERS += $$PWD/TimeCounterUtil.h +SOURCES += $$PWD/TimeCounterUtil.cpp + + +#HEADERS += $$PWD/SelectDeptUtil.h +#SOURCES += $$PWD/SelectDeptUtil.cpp + +#HEADERS += $$PWD/QByteUtil.h +#HEADERS += $$PWD/QSocketClientUtil.h +#HEADERS += $$PWD/TimerCounter.h +#HEADERS += $$PWD/SpeakerUtil.h + + +#SOURCES += $$PWD/QByteUtil.cpp +#SOURCES += $$PWD/QSocketClientUtil.cpp +#SOURCES += $$PWD/TimerCounter.cpp +#SOURCES += $$PWD/SpeakerUtil.cpp