Ver código fonte

初始化项目

lichanglin 3 anos atrás
pai
commit
78ceb02198
100 arquivos alterados com 6261 adições e 0 exclusões
  1. 34 0
      AutoGenetateModelServiceUI/AutoGenetateModelServiceUI.pro
  2. 11 0
      AutoGenetateModelServiceUI/main.cpp
  3. 168 0
      AutoGenetateModelServiceUI/mainwindow.cpp
  4. 30 0
      AutoGenetateModelServiceUI/mainwindow.h
  5. 298 0
      AutoGenetateModelServiceUI/mainwindow.ui
  6. 29 0
      AutoGenetateModelServiceUI/template/Model.cpp.template
  7. 14 0
      AutoGenetateModelServiceUI/template/Model.h.template
  8. 182 0
      AutoGenetateModelServiceUI/template/MultipleWidget.cpp.template
  9. 44 0
      AutoGenetateModelServiceUI/template/MultipleWidget.h.template
  10. 253 0
      AutoGenetateModelServiceUI/template/MultipleWidget.ui.template
  11. 10 0
      AutoGenetateModelServiceUI/template/Service.cpp.template
  12. 11 0
      AutoGenetateModelServiceUI/template/Service.h.template
  13. 176 0
      AutoGenetateModelServiceUI/template/Widget.cpp.template
  14. 44 0
      AutoGenetateModelServiceUI/template/Widget.h.template
  15. 246 0
      AutoGenetateModelServiceUI/template/Widget.ui.template
  16. 5 0
      DataManage.pro
  17. 156 0
      DataManage/DataManage.pro
  18. 21 0
      DataManage/MainWindow.qrc
  19. BIN
      DataManage/Resources/App.ico
  20. BIN
      DataManage/Resources/arrow_down.png
  21. BIN
      DataManage/Resources/arrow_left.png
  22. BIN
      DataManage/Resources/arrow_right.png
  23. BIN
      DataManage/Resources/arrow_up.png
  24. BIN
      DataManage/Resources/bgLogin.jpg
  25. BIN
      DataManage/Resources/btn_hidepanel.png
  26. BIN
      DataManage/Resources/btn_hidepanel_hover.png
  27. BIN
      DataManage/Resources/close.png
  28. BIN
      DataManage/Resources/close_small.png
  29. BIN
      DataManage/Resources/ico_checked.png
  30. BIN
      DataManage/Resources/loading.gif
  31. BIN
      DataManage/Resources/logo.png
  32. BIN
      DataManage/Resources/max.png
  33. BIN
      DataManage/Resources/min.png
  34. BIN
      DataManage/Resources/restore.png
  35. 296 0
      DataManage/Resources/style.qss
  36. 115 0
      DataManage/entity/Airport.cpp
  37. 74 0
      DataManage/entity/Airport.h
  38. 188 0
      DataManage/forms/AirportWidget.cpp
  39. 45 0
      DataManage/forms/AirportWidget.h
  40. 246 0
      DataManage/forms/AirportWidget.ui
  41. 46 0
      DataManage/main.cpp
  42. 31 0
      DataManage/mainwindow.cpp
  43. 21 0
      DataManage/mainwindow.h
  44. 31 0
      DataManage/mainwindow.ui
  45. 32 0
      DataManage/models/AirportModel.cpp
  46. 14 0
      DataManage/models/AirportModel.h
  47. 93 0
      DataManage/models/ModelBase.cpp
  48. 44 0
      DataManage/models/ModelBase.h
  49. 82 0
      DataManage/models/OrmModelBase.cpp
  50. 46 0
      DataManage/models/OrmModelBase.h
  51. 86 0
      DataManage/models/QxModelBase.h
  52. 10 0
      DataManage/services/AirportService.cpp
  53. 11 0
      DataManage/services/AirportService.h
  54. 122 0
      DataManage/services/Application.cpp
  55. 51 0
      DataManage/services/Application.h
  56. 59 0
      DataManage/services/ApplicationConfigurator.cpp
  57. 91 0
      DataManage/services/ApplicationConfigurator.h
  58. 84 0
      DataManage/services/DatabaseConnector.cpp
  59. 29 0
      DataManage/services/DatabaseConnector.h
  60. 14 0
      DataManage/services/Dict.cpp
  61. 14 0
      DataManage/services/Dict.h
  62. 10 0
      DataManage/services/ServiceBase.cpp
  63. 59 0
      DataManage/services/ServiceBase.h
  64. 11 0
      DataManage/utils/DebugUtil.h
  65. 38 0
      DataManage/utils/DoubleValidator.cpp
  66. 17 0
      DataManage/utils/DoubleValidator.h
  67. 64 0
      DataManage/utils/FormBuilder.cpp
  68. 178 0
      DataManage/utils/FormBuilder.h
  69. 15 0
      DataManage/utils/IxWidgetUtil.cpp
  70. 12 0
      DataManage/utils/IxWidgetUtil.h
  71. 23 0
      DataManage/utils/MessageException.h
  72. 41 0
      DataManage/utils/SqlGenerator_Oracle.cpp
  73. 22 0
      DataManage/utils/SqlGenerator_Oracle.h
  74. 3 0
      DataManage/utils/charcode.h
  75. 85 0
      DataManage/utils/excelinport.cpp
  76. 34 0
      DataManage/utils/excelinport.h
  77. 11 0
      DataManage/utils/regExp.h
  78. 30 0
      DataManage/utils/utils.h
  79. 333 0
      DataManage/widgets/AdvancedTableView.cpp
  80. 60 0
      DataManage/widgets/AdvancedTableView.h
  81. 39 0
      DataManage/widgets/CustomDelegate.cpp
  82. 31 0
      DataManage/widgets/CustomDelegate.h
  83. 37 0
      DataManage/widgets/DialogTemplate.cpp
  84. 17 0
      DataManage/widgets/DialogTemplate.h
  85. 647 0
      DataManage/widgets/FramelessHelper.cpp
  86. 48 0
      DataManage/widgets/FramelessHelper.h
  87. 33 0
      DataManage/widgets/IxWidgets/AutoCompleteComBoxWidget.cpp
  88. 22 0
      DataManage/widgets/IxWidgets/AutoCompleteComBoxWidget.h
  89. 151 0
      DataManage/widgets/IxWidgets/AutoCompleteTagEditWidget.cpp
  90. 45 0
      DataManage/widgets/IxWidgets/AutoCompleteTagEditWidget.h
  91. 86 0
      DataManage/widgets/IxWidgets/CheckComboBoxWidget.cpp
  92. 47 0
      DataManage/widgets/IxWidgets/CheckComboBoxWidget.h
  93. 67 0
      DataManage/widgets/IxWidgets/ComboBoxWidget.cpp
  94. 35 0
      DataManage/widgets/IxWidgets/ComboBoxWidget.h
  95. 38 0
      DataManage/widgets/IxWidgets/DateTimeWidget.cpp
  96. 28 0
      DataManage/widgets/IxWidgets/DateTimeWidget.h
  97. 31 0
      DataManage/widgets/IxWidgets/IxWidget.h
  98. 44 0
      DataManage/widgets/IxWidgets/LineEditWidget.cpp
  99. 28 0
      DataManage/widgets/IxWidgets/LineEditWidget.h
  100. 34 0
      DataManage/widgets/IxWidgets/PathSelectorWidget.cpp

+ 34 - 0
AutoGenetateModelServiceUI/AutoGenetateModelServiceUI.pro

@@ -0,0 +1,34 @@
+QT       += core gui
+
+greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
+
+CONFIG += c++11
+
+# You can make your code fail to compile if it uses deprecated APIs.
+# In order to do so, uncomment the following line.
+#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0
+
+SOURCES += \
+    main.cpp \
+    mainwindow.cpp
+
+HEADERS += \
+    mainwindow.h \
+    template/Model.cpp.template \
+    template/Model.h.template \
+    template/MultipleWidget.cpp.template \
+    template/MultipleWidget.h.template \
+    template/Service.cpp.template \
+    template/Service.h.template \
+    template/Widget.cpp.template \
+    template/Widget.h.template
+
+FORMS += \
+    mainwindow.ui \
+    template/MultipleWidget.ui.template \
+    template/Widget.ui.template
+
+# Default rules for deployment.
+qnx: target.path = /tmp/$${TARGET}/bin
+else: unix:!android: target.path = /opt/$${TARGET}/bin
+!isEmpty(target.path): INSTALLS += target

+ 11 - 0
AutoGenetateModelServiceUI/main.cpp

@@ -0,0 +1,11 @@
+#include "mainwindow.h"
+
+#include <QApplication>
+
+int main(int argc, char *argv[])
+{
+    QApplication a(argc, argv);
+    MainWindow w;
+    w.show();
+    return a.exec();
+}

+ 168 - 0
AutoGenetateModelServiceUI/mainwindow.cpp

@@ -0,0 +1,168 @@
+#include "MainWindow.h"
+#include <qfiledialog.h>
+#include <qsettings.h>
+#include <qdatastream.h>
+#include <qfile.h>
+#include <qtextstream.h>
+#include <qmessagebox.h>
+
+MainWindow::MainWindow(QWidget *parent)
+	: QMainWindow(parent)
+{
+	ui.setupUi(this);
+
+	QSettings setting("config.ini", QSettings::IniFormat);
+	ui.modelPath->setText(setting.value("modelPath").toString());
+	ui.servicePath->setText(setting.value("servicePath").toString());
+	ui.widgetPath->setText(setting.value("widgetPath").toString());
+}
+
+void MainWindow::onModelPath()
+{
+	QString path = QFileDialog::getExistingDirectory(this);
+	ui.modelPath->setText(path);
+	QSettings setting("config.ini", QSettings::IniFormat);
+	setting.setValue("modelPath", path);
+}
+
+void MainWindow::onServicePath()
+{
+	QString path = QFileDialog::getExistingDirectory(this);
+	ui.servicePath->setText(path);
+	QSettings setting("config.ini", QSettings::IniFormat);
+	setting.setValue("servicePath", path);
+}
+
+void MainWindow::onWidgetPath()
+{
+	QString path = QFileDialog::getExistingDirectory(this);
+	ui.widgetPath->setText(path);
+	QSettings setting("config.ini", QSettings::IniFormat);
+	setting.setValue("widgetPath", path);
+}
+
+void MainWindow::onGenerate()
+{
+	QString entityName = ui.entityName->text();
+    if(entityName.isEmpty()){
+        ui.entityName->setFocus();
+        return;
+    }
+	QString modelName = ui.modelName->text();
+	QString serviceName = ui.serviceName->text();
+	QString widgetName = ui.widgetName->text();
+	if (modelName.isEmpty())
+		 modelName = entityName + "Model";
+	if (serviceName.isEmpty())
+		 serviceName = entityName + "Service";
+	if (widgetName.isEmpty())
+		widgetName = entityName + "Widget";
+
+	createModel(modelName, entityName);
+	createService(serviceName, entityName);
+	if (ui.MultipleSelect->isChecked())
+		createMultipleWidget(widgetName, modelName, serviceName, entityName,ui.name->text().trimmed());
+	else
+		createWidget(widgetName, modelName, serviceName, entityName, ui.name->text().trimmed());
+	QMessageBox::information(this, "", "success");
+}
+
+QString MainWindow::readAll(const QString &filename)
+{
+	QFile file(filename);
+	if (!file.open(QIODevice::ReadOnly))
+		return "";
+	QTextStream in(&file);
+    in.setCodec("UTF-8");
+	QString txt = in.readAll();
+	file.close();
+	return txt;
+}
+
+void MainWindow::write(const QString &filename, const QString &content)
+{
+	QFile file(filename);
+	if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate))
+		return ;
+	QTextStream out(&file);
+    out.setCodec("UTF-8");
+	out << content;
+	file.close();
+}
+
+void MainWindow::createModel(const QString &modelName, const QString &entityName)
+{
+	QString modelH = readAll("template/model.h.template");
+	modelH = modelH.arg(modelName).arg(entityName);
+
+	QString modelCpp = readAll("template/model.cpp.template");
+	modelCpp = modelCpp.arg(modelName).arg(entityName);
+
+	QString path = ui.modelPath->text().trimmed();
+	QString modelHFilename = QString("%1/%2.h").arg(path).arg(modelName);
+	write(modelHFilename, modelH);
+
+	QString modelCppFilename = QString("%1/%2.cpp").arg(path).arg(modelName);
+	write(modelCppFilename, modelCpp);
+}
+
+void MainWindow::createService(const QString &serviceName, const QString &entityName)
+{
+	QString serviceH = readAll("template/service.h.template");
+	serviceH = serviceH.arg(serviceName);
+
+	QString serviceCpp = readAll("template/service.cpp.template");
+	serviceCpp = serviceCpp.arg(serviceName).arg(entityName);
+
+	QString path = ui.servicePath->text().trimmed();
+	QString modelHFilename = QString("%1/%2.h").arg(path).arg(serviceName);
+	write(modelHFilename, serviceH);
+
+	QString modelCppFilename = QString("%1/%2.cpp").arg(path).arg(serviceName);
+	write(modelCppFilename, serviceCpp);
+}
+
+void MainWindow::createWidget(const QString &widgetName, const QString &modelName, const QString &serviceName, const QString &entityName, const QString &name)
+{
+	QString widgetH = readAll("template/widget.h.template");
+	widgetH = widgetH.arg(widgetName).arg(modelName).arg(serviceName);
+
+	QString widgetCpp = readAll("template/widget.cpp.template");
+	widgetCpp = widgetCpp.arg(widgetName).arg(entityName).arg(modelName).arg(serviceName).arg(name);
+
+	QString widgetUi = readAll("template/widget.ui.template");
+	widgetUi = widgetUi.arg(widgetName);
+
+	QString path = ui.widgetPath->text().trimmed();
+	QString widgetHFilename = QString("%1/%2.h").arg(path).arg(widgetName);
+	write(widgetHFilename, widgetH);
+
+	QString widgetCppFilename = QString("%1/%2.cpp").arg(path).arg(widgetName);
+	write(widgetCppFilename, widgetCpp);
+
+	QString widgetUiFilename = QString("%1/%2.ui").arg(path).arg(widgetName);
+	write(widgetUiFilename, widgetUi);
+}
+
+void MainWindow::createMultipleWidget(const QString &widgetName, const QString &modelName, const QString &serviceName, const QString &entityName,const QString &name)
+{
+	QString widgetH = readAll("template/MultipleWidget.h.template");
+	widgetH = widgetH.arg(widgetName).arg(modelName).arg(serviceName).arg(entityName);
+
+	QString widgetCpp = readAll("template/MultipleWidget.cpp.template");
+	widgetCpp = widgetCpp.arg(widgetName).arg(entityName).arg(modelName).arg(serviceName).arg(name);
+
+	QString widgetUi = readAll("template/MultipleWidget.ui.template");
+	widgetUi = widgetUi.arg(widgetName);
+
+	QString path = ui.widgetPath->text().trimmed();
+	QString widgetHFilename = QString("%1/%2.h").arg(path).arg(widgetName);
+	write(widgetHFilename, widgetH);
+
+	QString widgetCppFilename = QString("%1/%2.cpp").arg(path).arg(widgetName);
+	write(widgetCppFilename, widgetCpp);
+
+	QString widgetUiFilename = QString("%1/%2.ui").arg(path).arg(widgetName);
+	write(widgetUiFilename, widgetUi);
+}
+

+ 30 - 0
AutoGenetateModelServiceUI/mainwindow.h

@@ -0,0 +1,30 @@
+#pragma once
+
+#include <QtWidgets/QMainWindow>
+#include "ui_MainWindow.h"
+
+class MainWindow : public QMainWindow
+{
+	Q_OBJECT
+
+public:
+	MainWindow(QWidget *parent = Q_NULLPTR);
+
+private slots:
+	void onModelPath();
+	void onServicePath();
+	void onWidgetPath();
+	void onGenerate();
+
+private:
+	void createModel(const QString &modelName, const QString &entityName);
+	void createService(const QString &serviceName, const QString &entityName);
+	void createWidget(const QString &widgetName, const QString &modelName, const QString &serviceName, const QString &entityName, const QString &name);
+	void createMultipleWidget(const QString &widgetName, const QString &modelName, const QString &serviceName, const QString &entityName, const QString &name);
+
+	QString readAll(const QString &filename);
+	void write(const QString &filename, const QString &content);
+
+private:
+	Ui::MainWindowClass ui;
+};

+ 298 - 0
AutoGenetateModelServiceUI/mainwindow.ui

@@ -0,0 +1,298 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MainWindowClass</class>
+ <widget class="QMainWindow" name="MainWindowClass">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>600</width>
+    <height>400</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>自动生成</string>
+  </property>
+  <widget class="QWidget" name="centralWidget">
+   <layout class="QVBoxLayout" name="verticalLayout">
+    <item>
+     <layout class="QHBoxLayout" name="horizontalLayout_3">
+      <item>
+       <widget class="QLabel" name="label_2">
+        <property name="text">
+         <string>实体类中文名</string>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <widget class="QLineEdit" name="name"/>
+      </item>
+     </layout>
+    </item>
+    <item>
+     <layout class="QGridLayout" name="gridLayout_2">
+      <item row="0" column="0">
+       <widget class="QLabel" name="label">
+        <property name="text">
+         <string>entity名称</string>
+        </property>
+       </widget>
+      </item>
+      <item row="0" column="1">
+       <widget class="QLineEdit" name="entityName"/>
+      </item>
+      <item row="1" column="0">
+       <widget class="QLabel" name="label_3">
+        <property name="text">
+         <string>model名称</string>
+        </property>
+       </widget>
+      </item>
+      <item row="1" column="1">
+       <widget class="QLineEdit" name="modelName">
+        <property name="placeholderText">
+         <string>默认实体类名称后+Model</string>
+        </property>
+       </widget>
+      </item>
+      <item row="2" column="0">
+       <widget class="QLabel" name="label_4">
+        <property name="text">
+         <string>service名称</string>
+        </property>
+       </widget>
+      </item>
+      <item row="2" column="1">
+       <widget class="QLineEdit" name="serviceName">
+        <property name="placeholderText">
+         <string>默认实体类名称后+Service</string>
+        </property>
+       </widget>
+      </item>
+      <item row="3" column="0">
+       <widget class="QLabel" name="label_5">
+        <property name="text">
+         <string>Widget名称</string>
+        </property>
+       </widget>
+      </item>
+      <item row="3" column="1">
+       <layout class="QHBoxLayout" name="horizontalLayout_2">
+        <item>
+         <widget class="QLineEdit" name="widgetName">
+          <property name="placeholderText">
+           <string>默认实体类名称后+Widget</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QCheckBox" name="MultipleSelect">
+          <property name="text">
+           <string>多选</string>
+          </property>
+         </widget>
+        </item>
+       </layout>
+      </item>
+     </layout>
+    </item>
+    <item>
+     <layout class="QGridLayout" name="gridLayout">
+      <item row="0" column="0">
+       <widget class="QLabel" name="label_6">
+        <property name="text">
+         <string>model路径</string>
+        </property>
+       </widget>
+      </item>
+      <item row="0" column="1">
+       <widget class="QLineEdit" name="modelPath">
+        <property name="text">
+         <string/>
+        </property>
+       </widget>
+      </item>
+      <item row="0" column="2">
+       <widget class="QPushButton" name="pbModelPath">
+        <property name="text">
+         <string>选择</string>
+        </property>
+       </widget>
+      </item>
+      <item row="1" column="0">
+       <widget class="QLabel" name="label_8">
+        <property name="text">
+         <string>service路径</string>
+        </property>
+       </widget>
+      </item>
+      <item row="1" column="1">
+       <widget class="QLineEdit" name="servicePath">
+        <property name="text">
+         <string/>
+        </property>
+       </widget>
+      </item>
+      <item row="1" column="2">
+       <widget class="QPushButton" name="pbServicelPath">
+        <property name="text">
+         <string>选择</string>
+        </property>
+       </widget>
+      </item>
+      <item row="2" column="0">
+       <widget class="QLabel" name="label_7">
+        <property name="text">
+         <string>Widget路径</string>
+        </property>
+       </widget>
+      </item>
+      <item row="2" column="1">
+       <widget class="QLineEdit" name="widgetPath">
+        <property name="text">
+         <string/>
+        </property>
+       </widget>
+      </item>
+      <item row="2" column="2">
+       <widget class="QPushButton" name="pbWidgetPath">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="text">
+         <string>选择</string>
+        </property>
+       </widget>
+      </item>
+     </layout>
+    </item>
+    <item>
+     <layout class="QHBoxLayout" name="horizontalLayout">
+      <item>
+       <spacer name="horizontalSpacer">
+        <property name="orientation">
+         <enum>Qt::Horizontal</enum>
+        </property>
+        <property name="sizeHint" stdset="0">
+         <size>
+          <width>40</width>
+          <height>20</height>
+         </size>
+        </property>
+       </spacer>
+      </item>
+      <item>
+       <widget class="QPushButton" name="pbGenerate">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="text">
+         <string>生成</string>
+        </property>
+       </widget>
+      </item>
+     </layout>
+    </item>
+   </layout>
+  </widget>
+  <widget class="QMenuBar" name="menuBar">
+   <property name="geometry">
+    <rect>
+     <x>0</x>
+     <y>0</y>
+     <width>600</width>
+     <height>23</height>
+    </rect>
+   </property>
+  </widget>
+  <widget class="QToolBar" name="mainToolBar">
+   <attribute name="toolBarArea">
+    <enum>TopToolBarArea</enum>
+   </attribute>
+   <attribute name="toolBarBreak">
+    <bool>false</bool>
+   </attribute>
+  </widget>
+  <widget class="QStatusBar" name="statusBar"/>
+ </widget>
+ <layoutdefault spacing="6" margin="11"/>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>pbModelPath</sender>
+   <signal>clicked()</signal>
+   <receiver>MainWindowClass</receiver>
+   <slot>onModelPath()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>589</x>
+     <y>182</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>601</x>
+     <y>292</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>pbServicelPath</sender>
+   <signal>clicked()</signal>
+   <receiver>MainWindowClass</receiver>
+   <slot>onServicePath()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>589</x>
+     <y>216</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>598</x>
+     <y>335</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>pbWidgetPath</sender>
+   <signal>clicked()</signal>
+   <receiver>MainWindowClass</receiver>
+   <slot>onWidgetPath()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>589</x>
+     <y>250</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>600</x>
+     <y>395</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>pbGenerate</sender>
+   <signal>clicked()</signal>
+   <receiver>MainWindowClass</receiver>
+   <slot>onGenerate()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>530</x>
+     <y>315</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>508</x>
+     <y>406</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+ <slots>
+  <slot>onModelPath()</slot>
+  <slot>onServicePath()</slot>
+  <slot>onWidgetPath()</slot>
+  <slot>onGenerate()</slot>
+ </slots>
+</ui>

+ 29 - 0
AutoGenetateModelServiceUI/template/Model.cpp.template

@@ -0,0 +1,29 @@
+#include "%1.h"
+#include "MessageException.h"
+
+%1::%1(QObject *parent)
+: QxModelBase<%2>(parent)
+{
+}
+
+%1::~%1()
+{
+}
+
+
+void %1::fetchByName(const QString &name, int pageIndex)
+{
+	qx::QxSqlQuery query;
+	if (!name.isEmpty())
+		query.where("t." + %2::column_NAME()).containsString(name).orderAsc("t." + %2::column_ID());
+
+    query.orderAsc("t." + %2::column_ID());
+	QStringList relations;
+	relations << "<t>";
+
+	this->countWithRelation(query, relations);
+	this->limit(query, pageIndex);
+	QSqlError error = this->qxFetchByQuery(query, relations);
+	if (error.isValid())
+		throw MessageException(error.text());
+}

+ 14 - 0
AutoGenetateModelServiceUI/template/Model.h.template

@@ -0,0 +1,14 @@
+#pragma once
+#include "QxModelBase.h"
+#include "%2.h"
+
+class %1 : public QxModelBase<%2>
+{
+	Q_OBJECT
+
+public:
+	%1(QObject *parent);
+	~%1();
+
+	void fetchByName(const QString &name, int pageIndex = 0);
+};

+ 182 - 0
AutoGenetateModelServiceUI/template/MultipleWidget.cpp.template

@@ -0,0 +1,182 @@
+#include "%1.h"
+#include "MessageException.h"
+#include "%2.h"
+#include "Application.h"
+
+#include <QMessageBox>
+
+#if _MSC_VER >= 1600
+#pragma execution_character_set("utf-8")
+#endif
+
+%1::%1(QWidget *parent)
+	: QWidget(parent)
+	, m_PageIndex(0)
+{
+	ui = new Ui::%1();
+	ui->setupUi(this);
+
+	init();
+	doQuery();
+}
+
+%1::~%1()
+{
+	delete ui;
+}
+
+void %1::init()
+{
+	initTableView();
+	initModel();
+	initService();
+	initPagination();
+    initFormBuilder();
+}
+
+void %1::initTableView()
+{
+	ui->tvData->setMultipleSelect(true);
+}
+
+void %1::initModel()
+{
+	m_Model = new %3(this);
+	m_Model->setMultiSelect(true);
+	ui->tvData->setModel(m_Model);
+}
+
+void %1::initService()
+{
+	m_Service = new %4(this);
+}
+
+void %1::initFormBuilder()
+{
+    m_FormBuilder = new FormBuilder(this);
+}
+
+void %1::initPagination()
+{
+	ui->pagination->setPageCount(0);
+	ui->pagination->setRecordCount(0);
+
+	connect(ui->pagination, &Pagination::selectPage, [=](int value) {
+		doQuery(value);
+	});
+}
+
+QList<%2_ptr> %1::convertToList(qx::IxCollection *collection)
+{
+	QList<%2_ptr> objs;
+	for (size_t i = 0; i < collection->_count(); i++)
+	{
+		objs << collection->_get<%2_ptr>(i);
+	}
+	return objs;
+}
+
+void %1::doQuery(int pageIndex /*= 0*/)
+{
+	QString name = ui->leQName->text();
+	try
+	{
+		m_Model->fetchByName(name, pageIndex);
+		ui->pagination->setRecordCount(m_Model->getTotalCount());
+		ui->pagination->setPageCount(m_Model->getPageCount());
+	}
+	catch (MessageException &e)
+	{
+		QMessageBox::critical(this, "错误", e.getMessage());
+	}
+}
+
+void %1::onQuery()
+{
+	doQuery();
+}
+
+void %1::onReset()
+{
+	ui->leQName->clear();
+	doQuery();
+}
+
+void %1::onAdd()
+{
+    QWidget *widget = m_FormBuilder->build<%2>("添加%5");
+    m_FormBuilder->clear();
+	int result = Application::instance()->showModalDialog(widget, this);
+
+	if (result == QDialog::Accepted)
+	{
+        %2_ptr obj = m_FormBuilder->getValue<%2>();
+		try
+		{
+			m_Service->add(obj);
+		}
+		catch (MessageException &e)
+		{
+			QMessageBox::critical(this, "错误", e.getMessage());
+			return;
+		}
+		doQuery();
+	}
+}
+
+void %1::onEdit()
+{
+	QModelIndex index = ui->tvData->currentIndex();
+	if (!index.isValid())
+	{
+		QMessageBox::information(this, "提示", "请选中要修改的数据!");
+		return;
+	}
+	%2_ptr oldObj = m_Model->getByRow(index.row());
+	
+    QWidget *widget = m_FormBuilder->build<%2>("修改%5");
+    m_FormBuilder->clear();
+    m_FormBuilder->fill(oldObj);
+
+	int result = Application::instance()->showModalDialog(widget, this);
+
+	if (result == QDialog::Accepted)
+	{
+		try{
+            %2_ptr newObj = m_FormBuilder->getValue<%2>();
+			newObj->setID(oldObj->getID());
+			m_Service->updateById(newObj);
+		}
+		catch (MessageException &e){
+			QMessageBox::critical(this, "错误", e.getMessage());
+			return;
+		}
+		doQuery();
+	}
+}
+
+void %1::onRemove()
+{
+	qx::IxCollection * collection = ui->tvData->getSelectedRecord();
+	if (collection->_count() <= 0)
+	{
+		QMessageBox::information(this, "提示", "请选中要删除的数据!");
+		return;
+	}
+	QMessageBox::StandardButton msgBox;
+	msgBox = QMessageBox::question(this, "提示", "确定删除选中的数据吗?", QMessageBox::Yes | QMessageBox::No);
+	if (msgBox == QMessageBox::No)
+		return;
+	try
+	{
+		m_Service->deleteById(convertToList(collection));
+		m_Model->clear();
+		doQuery();
+	}
+	catch (MessageException &e)
+	{
+		QMessageBox::critical(this, "错误", e.getMessage());
+	}
+}
+
+

+ 44 - 0
AutoGenetateModelServiceUI/template/MultipleWidget.h.template

@@ -0,0 +1,44 @@
+#pragma once
+
+#include <QWidget>
+
+#include "%2.h"
+#include "FormBuilder.h"
+#include "%3.h"
+#include "ui_%1.h"
+
+namespace Ui { class %1; };
+
+class %1 : public QWidget
+{
+	Q_OBJECT
+
+public:
+	%1(QWidget *parent = Q_NULLPTR);
+	~%1();
+
+private:
+	void init();
+	void initTableView();
+	void initModel();
+	void initService();
+	void initPagination();
+    void initFormBuilder();
+
+	void doQuery(int pageIndex = 0);
+	QList<%4_ptr> convertToList(qx::IxCollection *collection);
+
+private slots:
+	void onQuery();
+	void onReset();
+	void onAdd();
+	void onEdit();
+	void onRemove();
+
+private:
+	Ui::%1 *ui;
+	%2 *m_Model;
+    FormBuilder *m_FormBuilder;
+	%3 *m_Service;
+	int m_PageIndex;
+};

+ 253 - 0
AutoGenetateModelServiceUI/template/MultipleWidget.ui.template

@@ -0,0 +1,253 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+  <class>%1</class>
+  <widget class="QWidget" name="%1">
+    <property name="geometry">
+      <rect>
+        <x>0</x>
+        <y>0</y>
+        <width>745</width>
+        <height>559</height>
+      </rect>
+    </property>
+    <property name="windowTitle">
+      <string>%1</string>
+    </property>
+    <layout class="QVBoxLayout" name="verticalLayout">
+      <property name="leftMargin">
+        <number>0</number>
+      </property>
+      <property name="topMargin">
+        <number>0</number>
+      </property>
+      <property name="rightMargin">
+        <number>0</number>
+      </property>
+      <property name="bottomMargin">
+        <number>0</number>
+      </property>
+      <item>
+        <widget class="QFrame" name="frame">
+          <property name="styleSheet">
+            <string notr="true">
+              QFrame{
+              border:1px solid #cccccc;
+              border-radius: 2px;
+              background-color: white;
+              }
+              QPushButton{
+              min-width:45px;
+              min-height:20px;
+              }
+            </string>
+          </property>
+          <property name="frameShape">
+            <enum>QFrame::StyledPanel</enum>
+          </property>
+          <property name="frameShadow">
+            <enum>QFrame::Raised</enum>
+          </property>
+          <layout class="QHBoxLayout" name="horizontalLayout">
+            <item>
+              <widget class="QLineEdit" name="leQName">
+                <property name="placeholderText">
+                  <string>按名称关键字查询</string>
+                </property>
+              </widget>
+            </item>
+            <item>
+              <widget class="QPushButton" name="pbQuery">
+                <property name="text">
+                  <string>查询</string>
+                </property>
+                <property name="shortcut">
+                  <string>Enter</string>
+                </property>
+                <property name="default">
+                  <bool>true</bool>
+                </property>
+              </widget>
+            </item>
+            <item>
+              <widget class="QPushButton" name="pbSet">
+                <property name="text">
+                  <string>重置</string>
+                </property>
+              </widget>
+            </item>
+            <item>
+              <widget class="QPushButton" name="pbImport">
+                <property name="text">
+                  <string>导入</string>
+                </property>
+              </widget>
+            </item>
+            <item>
+              <spacer name="horizontalSpacer_2">
+                <property name="orientation">
+                  <enum>Qt::Horizontal</enum>
+                </property>
+                <property name="sizeHint" stdset="0">
+                  <size>
+                    <width>40</width>
+                    <height>20</height>
+                  </size>
+                </property>
+              </spacer>
+            </item>
+          </layout>
+        </widget>
+      </item>
+      <item>
+        <widget class="MultipleTableView" name="tvData"/>
+      </item>
+      <item>
+        <widget class="Pagination" name="pagination"/>
+      </item>
+      <item>
+        <layout class="QHBoxLayout" name="horizontalLayout_2">
+          <property name="topMargin">
+            <number>0</number>
+          </property>
+          <item>
+            <widget class="QPushButton" name="pbAdd">
+              <property name="text">
+                <string>添加</string>
+              </property>
+            </widget>
+          </item>
+          <item>
+            <widget class="QPushButton" name="pbEdit">
+              <property name="text">
+                <string>修改</string>
+              </property>
+            </widget>
+          </item>
+          <item>
+            <widget class="QPushButton" name="pbRemove">
+              <property name="text">
+                <string>删除</string>
+              </property>
+            </widget>
+          </item>
+          <item>
+            <spacer name="horizontalSpacer">
+              <property name="orientation">
+                <enum>Qt::Horizontal</enum>
+              </property>
+              <property name="sizeHint" stdset="0">
+                <size>
+                  <width>40</width>
+                  <height>20</height>
+                </size>
+              </property>
+            </spacer>
+          </item>
+        </layout>
+      </item>
+    </layout>
+  </widget>
+  <layoutdefault spacing="6" margin="11"/>
+  <customwidgets>
+    <customwidget>
+      <class>Pagination</class>
+      <extends>QWidget</extends>
+      <header>Pagination.h</header>
+    </customwidget>
+    <customwidget>
+      <class>MultipleTableView</class>
+      <extends>QTableView</extends>
+      <header location="global">MultipleTableView.h</header>
+    </customwidget>
+  </customwidgets>
+  <resources/>
+  <connections>
+    <connection>
+      <sender>pbQuery</sender>
+      <signal>clicked()</signal>
+      <receiver>%1</receiver>
+      <slot>onQuery()</slot>
+      <hints>
+        <hint type="sourcelabel">
+          <x>338</x>
+          <y>31</y>
+        </hint>
+        <hint type="destinationlabel">
+          <x>328</x>
+          <y>-22</y>
+        </hint>
+      </hints>
+    </connection>
+    <connection>
+      <sender>pbSet</sender>
+      <signal>clicked()</signal>
+      <receiver>%1</receiver>
+      <slot>onReset()</slot>
+      <hints>
+        <hint type="sourcelabel">
+          <x>409</x>
+          <y>38</y>
+        </hint>
+        <hint type="destinationlabel">
+          <x>420</x>
+          <y>-20</y>
+        </hint>
+      </hints>
+    </connection>
+    <connection>
+      <sender>pbAdd</sender>
+      <signal>clicked()</signal>
+      <receiver>%1</receiver>
+      <slot>onAdd()</slot>
+      <hints>
+        <hint type="sourcelabel">
+          <x>38</x>
+          <y>594</y>
+        </hint>
+        <hint type="destinationlabel">
+          <x>4</x>
+          <y>590</y>
+        </hint>
+      </hints>
+    </connection>
+    <connection>
+      <sender>pbEdit</sender>
+      <signal>clicked()</signal>
+      <receiver>%1</receiver>
+      <slot>onEdit()</slot>
+      <hints>
+        <hint type="sourcelabel">
+          <x>123</x>
+          <y>596</y>
+        </hint>
+        <hint type="destinationlabel">
+          <x>130</x>
+          <y>608</y>
+        </hint>
+      </hints>
+    </connection>
+    <connection>
+      <sender>pbRemove</sender>
+      <signal>clicked()</signal>
+      <receiver>%1</receiver>
+      <slot>onRemove()</slot>
+      <hints>
+        <hint type="sourcelabel">
+          <x>222</x>
+          <y>590</y>
+        </hint>
+        <hint type="destinationlabel">
+          <x>284</x>
+          <y>614</y>
+        </hint>
+      </hints>
+    </connection>
+  </connections>
+  <slots>
+    <slot>onQuery()</slot>
+    <slot>onReset()</slot>
+    <slot>onAdd()</slot>
+    <slot>onEdit()</slot>
+    <slot>onRemove()</slot>
+  </slots>
+</ui>

+ 10 - 0
AutoGenetateModelServiceUI/template/Service.cpp.template

@@ -0,0 +1,10 @@
+#include "%1.h"
+
+%1::%1(QObject *parent)
+: ServiceBase(parent)
+{
+}
+
+%1::~%1()
+{
+}

+ 11 - 0
AutoGenetateModelServiceUI/template/Service.h.template

@@ -0,0 +1,11 @@
+#pragma once
+#include "ServiceBase.h"
+
+class %1 : public ServiceBase
+{
+	Q_OBJECT
+
+public:
+	%1(QObject *parent = nullptr);
+	~%1();
+};

+ 176 - 0
AutoGenetateModelServiceUI/template/Widget.cpp.template

@@ -0,0 +1,176 @@
+#include "%1.h"
+#include "MessageException.h"
+#include "%2.h"
+#include "Application.h"
+
+#include <QMessageBox>
+
+#if _MSC_VER >= 1600
+#pragma execution_character_set("utf-8")
+#endif
+
+%1::%1(QWidget *parent)
+	: QWidget(parent)
+	, m_PageIndex(0)
+{
+	ui = new Ui::%1();
+	ui->setupUi(this);
+
+	init();
+	doQuery();
+}
+
+%1::~%1()
+{
+	delete ui;
+}
+
+void %1::init()
+{
+	initTableView();
+	initModel();
+	initService();
+	initPagination();
+	initFormBuild();
+}
+
+void %1::initTableView()
+{
+	ui->tvData->setEditTriggers(QAbstractItemView::NoEditTriggers);
+	ui->tvData->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
+	ui->tvData->setSelectionBehavior(QAbstractItemView::SelectRows);
+	ui->tvData->setAlternatingRowColors(true);
+	ui->tvData->verticalHeader()->hide();
+    ui->tvData->setAlternatingRowColors(true);
+}
+
+void %1::initModel()
+{
+	m_Model = new %3(this);
+	ui->tvData->setModel(m_Model);
+    ui->tvData->hideColumns<%2>();
+}
+
+void %1::initService()
+{
+	m_Service = new %4(this);
+}
+
+void %1::initFormBuild()
+{
+    m_FormBuilder = new FormBuilder(this);
+}
+
+void %1::initPagination()
+{
+	ui->pagination->setPageCount(0);
+	ui->pagination->setRecordCount(0);
+
+	connect(ui->pagination, &Pagination::selectPage, [=](int value) {
+		doQuery(value);
+	});
+}
+
+void %1::doQuery(int pageIndex /*= 0*/)
+{
+	QString name = ui->leQName->text();
+	try
+	{
+		m_Model->fetchByName(name, pageIndex);
+		ui->pagination->setRecordCount(m_Model->getTotalCount());
+		ui->pagination->setPageCount(m_Model->getPageCount());
+	}
+	catch (MessageException &e)
+	{
+		QMessageBox::critical(this, "错误", e.getMessage());
+	}
+}
+
+void %1::onQuery()
+{
+	doQuery();
+}
+
+void %1::onReset()
+{
+	ui->leQName->clear();
+	doQuery();
+}
+
+void %1::onAdd()
+{
+    QWidget *widget = m_FormBuilder->build<%2>("添加%5");
+    m_FormBuilder->clear();
+	int result = Application::instance()->showModalDialog(widget, this);
+
+	if (result == QDialog::Accepted)
+	{
+        %2_ptr obj = m_FormBuilder->getValue<%2>();
+		try
+		{
+			m_Service->add(obj);
+		}
+		catch (MessageException &e)
+		{
+			QMessageBox::critical(this, "错误", e.getMessage());
+			return;
+		}
+		doQuery();
+	}
+}
+
+void %1::onEdit()
+{
+	QModelIndex index = ui->tvData->currentIndex();
+	if (!index.isValid())
+	{
+        QMessageBox::information(this, "提示", "请选中要修改的数据!");
+		return;
+	}
+	%2_ptr oldObj = m_Model->getCollection()->_get<%2_ptr>(index.row());
+	
+    QWidget *widget = m_FormBuilder->build<%2>("修改%5");
+    m_FormBuilder->clear();
+    m_FormBuilder->fill(oldObj);
+
+	int result = Application::instance()->showModalDialog(widget, this);
+
+	if (result == QDialog::Accepted)
+	{
+		try{
+            %2_ptr newObj = m_FormBuilder->getValue<%2>();
+			newObj->setID(oldObj->getID());
+			m_Service->updateById(newObj);
+		}
+		catch (MessageException &e){
+			QMessageBox::critical(this, "错误", e.getMessage());
+			return;
+		}
+		doQuery();
+	}
+}
+
+void %1::onRemove()
+{
+	QModelIndex index = ui->tvData->currentIndex();
+	if (!index.isValid())
+	{
+        QMessageBox::information(this, "提示", "请选中要删除的数据!");
+		return;
+	}
+	QMessageBox::StandardButton msgBox;
+	msgBox = QMessageBox::question(this, "提示", "确定删除选中的数据吗?", QMessageBox::Yes | QMessageBox::No);
+
+	if (msgBox == QMessageBox::No)
+		return;
+
+	QSqlError error = m_Model->qxDeleteRow(index.row());
+	if (error.isValid())
+	{
+		QMessageBox::critical(this, "错误", error.text()); 
+		return;
+	}
+	m_Model->removeRow(index.row());
+}
+
+

+ 44 - 0
AutoGenetateModelServiceUI/template/Widget.h.template

@@ -0,0 +1,44 @@
+#pragma once
+
+#include <QWidget>
+
+#include "%2.h"
+#include "FormBuilder.h"
+#include "%3.h"
+#include "ui_%1.h"
+
+namespace Ui { class %1; };
+
+class %1 : public QWidget
+{
+	Q_OBJECT
+
+public:
+	%1(QWidget *parent = Q_NULLPTR);
+	~%1();
+
+private:
+	void init();
+	void initTableView();
+	void initModel();
+	void initService();
+	void initPagination();
+	void initFormBuild();
+
+	void doQuery(int pageIndex = 0);
+
+
+private slots:
+	void onQuery();
+	void onReset();
+	void onAdd();
+	void onEdit();
+	void onRemove();
+
+private:
+	Ui::%1 *ui;
+	%2 *m_Model;
+    FormBuilder *m_FormBuilder;
+	%3 *m_Service;
+	int m_PageIndex;
+};

+ 246 - 0
AutoGenetateModelServiceUI/template/Widget.ui.template

@@ -0,0 +1,246 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>%1</class>
+ <widget class="QWidget" name="%1">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>745</width>
+    <height>559</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>%1</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <property name="leftMargin">
+    <number>0</number>
+   </property>
+   <property name="topMargin">
+    <number>0</number>
+   </property>
+   <property name="rightMargin">
+    <number>0</number>
+   </property>
+   <property name="bottomMargin">
+    <number>0</number>
+   </property>
+   <item>
+    <widget class="QFrame" name="frame">
+     <property name="styleSheet">
+      <string notr="true">
+              QFrame{
+              border:1px solid #cccccc;
+              border-radius: 2px;
+              background-color: white;
+              }
+              QPushButton{
+              min-width:45px;
+              min-height:20px;
+              }
+            </string>
+     </property>
+     <property name="frameShape">
+      <enum>QFrame::StyledPanel</enum>
+     </property>
+     <property name="frameShadow">
+      <enum>QFrame::Raised</enum>
+     </property>
+     <layout class="QHBoxLayout" name="horizontalLayout">
+      <item>
+       <widget class="QLineEdit" name="leQName">
+        <property name="placeholderText">
+         <string>按名称关键字查询</string>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <widget class="QPushButton" name="pbQuery">
+        <property name="text">
+         <string>查询</string>
+        </property>
+        <property name="shortcut">
+         <string>Enter</string>
+        </property>
+        <property name="default">
+         <bool>true</bool>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <widget class="QPushButton" name="pbSet">
+        <property name="text">
+         <string>重置</string>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <spacer name="horizontalSpacer_2">
+        <property name="orientation">
+         <enum>Qt::Horizontal</enum>
+        </property>
+        <property name="sizeHint" stdset="0">
+         <size>
+          <width>40</width>
+          <height>20</height>
+         </size>
+        </property>
+       </spacer>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item>
+    <widget class="TableView" name="tvData"/>
+   </item>
+   <item>
+    <widget class="Pagination" name="pagination" native="true"/>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout_2">
+     <property name="topMargin">
+      <number>0</number>
+     </property>
+     <item>
+      <widget class="QPushButton" name="pbAdd">
+       <property name="text">
+        <string>添加</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QPushButton" name="pbEdit">
+       <property name="text">
+        <string>修改</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QPushButton" name="pbRemove">
+       <property name="text">
+        <string>删除</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <spacer name="horizontalSpacer">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>40</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <layoutdefault spacing="6" margin="11"/>
+ <customwidgets>
+  <customwidget>
+   <class>Pagination</class>
+   <extends>QWidget</extends>
+   <header>Pagination.h</header>
+  </customwidget>
+  <customwidget>
+   <class>TableView</class>
+   <extends>QTableView</extends>
+   <header location="global">TableView.h</header>
+  </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>pbQuery</sender>
+   <signal>clicked()</signal>
+   <receiver>%1</receiver>
+   <slot>onQuery()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>338</x>
+     <y>31</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>328</x>
+     <y>-22</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>pbSet</sender>
+   <signal>clicked()</signal>
+   <receiver>%1</receiver>
+   <slot>onReset()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>409</x>
+     <y>38</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>420</x>
+     <y>-20</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>pbAdd</sender>
+   <signal>clicked()</signal>
+   <receiver>%1</receiver>
+   <slot>onAdd()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>38</x>
+     <y>594</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>4</x>
+     <y>590</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>pbEdit</sender>
+   <signal>clicked()</signal>
+   <receiver>%1</receiver>
+   <slot>onEdit()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>123</x>
+     <y>596</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>130</x>
+     <y>608</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>pbRemove</sender>
+   <signal>clicked()</signal>
+   <receiver>%1</receiver>
+   <slot>onRemove()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>222</x>
+     <y>590</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>284</x>
+     <y>614</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+ <slots>
+  <slot>onQuery()</slot>
+  <slot>onReset()</slot>
+  <slot>onAdd()</slot>
+  <slot>onEdit()</slot>
+  <slot>onRemove()</slot>
+ </slots>
+</ui>

+ 5 - 0
DataManage.pro

@@ -0,0 +1,5 @@
+TEMPLATE = subdirs
+
+SUBDIRS += \
+    AutoGenetateModelServiceUI \
+    DataManage

+ 156 - 0
DataManage/DataManage.pro

@@ -0,0 +1,156 @@
+QT       += core gui axcontainer
+
+greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
+
+CONFIG += c++11
+
+win32:CONFIG(release, debug|release){
+    DESTDIR = ../bin/release
+}
+else:win32:CONFIG(debug, debug|release){
+    DESTDIR = ../bin/debug
+}
+# You can make your code fail to compile if it uses deprecated APIs.
+# In order to do so, uncomment the following line.
+#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0
+
+SOURCES += \
+    entity/Airport.cpp \
+    forms/AirportWidget.cpp \
+    main.cpp \
+    mainwindow.cpp \
+    models/AirportModel.cpp \
+    models/ModelBase.cpp \
+    models/OrmModelBase.cpp \
+    services/AirportService.cpp \
+    services/Application.cpp \
+    services/ApplicationConfigurator.cpp \
+    services/DatabaseConnector.cpp \
+    services/Dict.cpp \
+    services/ServiceBase.cpp \
+    utils/DoubleValidator.cpp \
+    utils/FormBuilder.cpp \
+    utils/IxWidgetUtil.cpp \
+    utils/SqlGenerator_Oracle.cpp \
+    utils/excelinport.cpp \
+    widgets/AdvancedTableView.cpp \
+    widgets/CustomDelegate.cpp \
+    widgets/DialogTemplate.cpp \
+    widgets/FramelessHelper.cpp \
+    widgets/IxWidgets/AutoCompleteComBoxWidget.cpp \
+    widgets/IxWidgets/AutoCompleteTagEditWidget.cpp \
+    widgets/IxWidgets/CheckComboBoxWidget.cpp \
+    widgets/IxWidgets/ComboBoxWidget.cpp \
+    widgets/IxWidgets/DateTimeWidget.cpp \
+    widgets/IxWidgets/LineEditWidget.cpp \
+    widgets/IxWidgets/PathSelectorWidget.cpp \
+    widgets/IxWidgets/TagEditWidget.cpp \
+    widgets/MultipleTableView.cpp \
+    widgets/Pagination.cpp \
+    widgets/TabPage.cpp \
+    widgets/TableView.cpp \
+    widgets/Tag.cpp \
+    widgets/TagEdit.cpp \
+    widgets/TitleBar.cpp \
+    widgets/WidgetFactorys/AutoCompleteComBoxWidgetFactory.cpp \
+    widgets/WidgetFactorys/AutoCompleteTagEditWidgetFactory.cpp \
+    widgets/WidgetFactorys/CheckComboBoxWidgetFactory.cpp \
+    widgets/WidgetFactorys/ComboBoxWidgetFactory.cpp \
+    widgets/WidgetFactorys/DateTimeWidgetFactory.cpp \
+    widgets/WidgetFactorys/LineEditWidgetFactory.cpp \
+    widgets/WidgetFactorys/PathSelectorWidgetFactory.cpp \
+    widgets/WidgetFactorys/TagEditWidgetFactory.cpp \
+    widgets/WidgetFactorys/WidgetFactory.cpp \
+    widgets/WindowButtonGroup.cpp \
+    widgets/loadingindicator.cpp
+
+HEADERS += \
+    entity/Airport.h \
+    forms/AirportWidget.h \
+    mainwindow.h \
+    models/AirportModel.h \
+    models/ModelBase.h \
+    models/OrmModelBase.h \
+    models/QxModelBase.h \
+    services/AirportService.h \
+    services/Application.h \
+    services/ApplicationConfigurator.h \
+    services/DatabaseConnector.h \
+    services/Dict.h \
+    services/ServiceBase.h \
+    utils/DebugUtil.h \
+    utils/DoubleValidator.h \
+    utils/FormBuilder.h \
+    utils/IxWidgetUtil.h \
+    utils/MessageException.h \
+    utils/SqlGenerator_Oracle.h \
+    utils/charcode.h \
+    utils/excelinport.h \
+    utils/regExp.h \
+    utils/utils.h \
+    widgets/AdvancedTableView.h \
+    widgets/CustomDelegate.h \
+    widgets/DialogTemplate.h \
+    widgets/FramelessHelper.h \
+    widgets/IxWidgets/AutoCompleteComBoxWidget.h \
+    widgets/IxWidgets/AutoCompleteTagEditWidget.h \
+    widgets/IxWidgets/CheckComboBoxWidget.h \
+    widgets/IxWidgets/ComboBoxWidget.h \
+    widgets/IxWidgets/DateTimeWidget.h \
+    widgets/IxWidgets/IxWidget.h \
+    widgets/IxWidgets/LineEditWidget.h \
+    widgets/IxWidgets/PathSelectorWidget.h \
+    widgets/IxWidgets/TagEditWidget.h \
+    widgets/MultipleTableView.h \
+    widgets/Pagination.h \
+    widgets/TabPage.h \
+    widgets/TableView.h \
+    widgets/Tag.h \
+    widgets/TagEdit.h \
+    widgets/TitleBar.h \
+    widgets/WidgetFactorys/AutoCompleteComBoxWidgetFactory.h \
+    widgets/WidgetFactorys/AutoCompleteTagEditWidgetFactory.h \
+    widgets/WidgetFactorys/CheckComboBoxWidgetFactory.h \
+    widgets/WidgetFactorys/ComboBoxWidgetFactory.h \
+    widgets/WidgetFactorys/DateTimeWidgetFactory.h \
+    widgets/WidgetFactorys/IxWidgetFactory.h \
+    widgets/WidgetFactorys/LineEditWidgetFactory.h \
+    widgets/WidgetFactorys/PathSelectorWidgetFactory.h \
+    widgets/WidgetFactorys/TagEditWidgetFactory.h \
+    widgets/WidgetFactorys/WidgetFactory.h \
+    widgets/WindowButtonGroup.h \
+    widgets/loadingindicator.h
+
+FORMS += \
+    forms/AirportWidget.ui \
+    mainwindow.ui
+
+INCLUDEPATH += utils/ \
+               forms/ \
+               entity/ \
+               models/ \
+               services/ \
+               widgets/ \
+               widgets/IxWidgets/ \
+               widgets/WidgetFactorys/
+
+# Default rules for deployment.
+qnx: target.path = /tmp/$${TARGET}/bin
+else: unix:!android: target.path = /opt/$${TARGET}/bin
+!isEmpty(target.path): INSTALLS += target
+
+
+# QxOrm配置
+DEFINES += _BUILDING_QXORM
+include($$PWD/../libs/QxOrm/QxOrm.pri)
+
+win32:CONFIG(release, debug|release): LIBS += -L$$PWD/../libs/QxOrm/lib/ -lQxOrm
+else:win32:CONFIG(debug, debug|release): LIBS += -L$$PWD/../libs/QxOrm/lib/ -lQxOrmd
+
+INCLUDEPATH += $$PWD/../libs/QxOrm/include
+DEPENDPATH += $$PWD/../libs/QxOrm/include
+
+RESOURCES += \
+    MainWindow.qrc
+
+

+ 21 - 0
DataManage/MainWindow.qrc

@@ -0,0 +1,21 @@
+<RCC>
+    <qresource prefix="/">
+        <file>Resources/App.ico</file>
+        <file>Resources/bgLogin.jpg</file>
+        <file>Resources/loading.gif</file>
+        <file>Resources/logo.png</file>
+        <file>Resources/style.qss</file>
+        <file>Resources/arrow_down.png</file>
+        <file>Resources/arrow_left.png</file>
+        <file>Resources/arrow_right.png</file>
+        <file>Resources/arrow_up.png</file>
+        <file>Resources/btn_hidepanel.png</file>
+        <file>Resources/btn_hidepanel_hover.png</file>
+        <file>Resources/close.png</file>
+        <file>Resources/close_small.png</file>
+        <file>Resources/ico_checked.png</file>
+        <file>Resources/max.png</file>
+        <file>Resources/min.png</file>
+        <file>Resources/restore.png</file>
+    </qresource>
+</RCC>

BIN
DataManage/Resources/App.ico


BIN
DataManage/Resources/arrow_down.png


BIN
DataManage/Resources/arrow_left.png


BIN
DataManage/Resources/arrow_right.png


BIN
DataManage/Resources/arrow_up.png


BIN
DataManage/Resources/bgLogin.jpg


BIN
DataManage/Resources/btn_hidepanel.png


BIN
DataManage/Resources/btn_hidepanel_hover.png


BIN
DataManage/Resources/close.png


BIN
DataManage/Resources/close_small.png


BIN
DataManage/Resources/ico_checked.png


BIN
DataManage/Resources/loading.gif


BIN
DataManage/Resources/logo.png


BIN
DataManage/Resources/max.png


BIN
DataManage/Resources/min.png


BIN
DataManage/Resources/restore.png


+ 296 - 0
DataManage/Resources/style.qss

@@ -0,0 +1,296 @@
+QWidget
+{
+    font-family:Microsoft YaHei;
+}
+QMainWindow#MainWindowClass {
+	background-color:#535353;
+}
+
+QPushButton{
+	background-color:#55aaff;
+	color:white;
+	border-radius:2px;
+	padding:3px;
+	min-width:60px;
+	min-height:22px;
+}
+
+QPushButton:hover{
+	background-color:#407cff;
+	color:#eeeeee;
+}
+
+QLineEdit, QTextEdit, QComboBox, QDateTimeEdit{
+    background-color: #ffffff;
+    border: 1px solid #888888;
+    border-radius: 2px;
+    height:24px;
+    color: #333333;
+    padding-left:3px;
+}
+QLineEdit:focus, QTextEdit:focus, QComboBox:focus, QDateTimeEdit:focus{
+    background-color: #fdffe4;
+    border: 1px solid #555555;
+}
+QComboBox::drop-down{
+    width: 22px;
+    border-left: 1px solid #999999;
+    margin-top:5px;
+    margin-bottom:5px;
+}
+
+QComboBox QAbstractItemView {
+    color:#333333;
+    border: 1px solid #555555;
+    background-color: #ffffff;
+    /*selection-background-color: red;*/
+    border-radius:3px;
+}
+QComboBox QAbstractItemView::item {
+    height: 25px;   
+    background-color: #ffffff;
+}
+QComboBox QAbstractItemView::item:hover {
+    color: #FFFFFF;
+    background-color: #55aaff;   
+}
+QComboBox QAbstractItemView::item:selected {
+    color: #FFFFFF;
+    background-color: #55aaff;
+}
+
+QDateTimeEdit::down-arrow, QComboBox::down-arrow{
+    image: url(:/Resources/arrow_down.png);
+    height:5px;
+    width:10px;
+}
+QDateTimeEdit::up-arrow{
+    image: url(:/Resources/arrow_up.png);
+    height:5px;
+    width:10px;
+}
+QDateTimeEdit::up-button, QDateTimeEdit::down-button{
+    width: 22px;
+    border:0;
+}
+
+QTabWidget::pane{
+	border-top:3px solid #007acc;
+	background-color:#f0f0f0;
+}
+
+QTabWidget::tab-bar{
+	border:0;
+}
+
+QTabWidget QTabBar::tab{
+	padding:3px 10px;
+	background-color:#007acc;
+	color:#f0f0f0;
+	border-bottom:0;
+
+	border-top-left-radius:2px;
+	border-top-right-radius:2px;
+
+	height:18px;
+}
+
+QTabWidget QTabBar::tab:!selected{
+	color:#a0a0a0;
+	background-color:transparent;
+}
+
+
+QTabWidget QTabBar::tab:first:!selected{
+	border-left:1px solid #55aaff;
+}
+
+QTabWidget QTabBar::tab:last:!selected{
+	border-right:1px solid #55aaff;
+}
+
+
+QTabWidget QTabBar::tab:!selected:hover{
+	background-color:#1c97ea;
+	color:#eeeeee;
+}
+
+QTabWidget QTabBar::close-button {      
+    image: none;
+    /*subcontrol-position: left;
+}  
+QTabWidget QTabBar::close-button:hover {
+    image: url(:/Resources/close_small.png);
+    background-color:#f68197;
+}
+
+QToolBar {	
+    padding: 0;
+	margin:0;
+    padding-left:3px;
+	background-color:#535353;
+    spacing: 3px;
+    border-top: 1px solid #535353;
+}
+
+QToolBar QToolButton {
+	color:#e5e5e5;
+	border-radius:0;
+	margin-top:6px;
+	margin-left:5px;
+	margin-right:5px;
+    border-bottom:2px solid transparent;
+}
+
+QToolBar QToolButton:hover {
+	color:white;
+	border-bottom:2px solid white;
+}
+
+QToolBar::handle {
+	width:0;
+}
+
+QToolBar::separator {
+	background-color:#3e3e3e;
+	width:3px;
+	margin:2px;
+    border-radius: 2px;
+    border: 1px solid #535353;
+}
+
+QStatusBar::item {
+    border-right: 1px solid #777777;
+}
+
+QStatusBar QLabel {
+    color:#cccccc; 
+    padding:0 5px;
+}
+
+QHeaderView
+{
+    background:transparent;
+}
+QHeaderView::section:horizontal{
+    background:#EDF0F6;
+    color:#31364D;
+    border:0;
+    border-right:1px solid #cccccc;
+    min-width:80px;
+}
+QHeaderView::section:first{
+    border-top-left-radius:2px;
+    border:0;
+    border-right:1px solid #cccccc;
+    height:25px;   
+}
+QHeaderView::section:last{
+    border-top-right-radius:2px;
+}
+
+QTreeWidget, QTreeView, QTableView, QTableWidget, QGroupBox {
+    border:1px solid #cccccc;
+    border-radius: 2px;
+}
+QTableView::item:selected {
+    background: rgb(0,122,204);
+}
+QAbstractItemView::indicator, QCheckBox::indicator {
+    background-color: #f5f5f5;
+    border: 1px solid #666666;
+    border-radius: 2px;
+    width:14px;
+    height:14px;
+}
+QAbstractItemView::indicator:checked, QCheckBox::indicator:checked {
+    image: url(:/MainWindow/Resources/ico_checked.png);
+}
+QAbstractItemView{
+    outline:0px;
+}
+QScrollBar:vertical {
+     border: 0;
+     background: transparent;
+     width: 10px;
+     margin: 0;
+}
+QScrollBar::handle:vertical {
+    background: #cccccc;
+    min-height: 20px;
+    border-radius: 4px;
+        margin-left:1px;
+        margin-right:1px;
+}
+QScrollBar::add-line:vertical {
+    border: 0;
+    background: #4A4A4A;
+    height: 0;
+    subcontrol-position: bottom;
+    subcontrol-origin: margin;
+}
+QScrollBar::sub-line:vertical {
+    border: 0;
+    background: #4A4A4A;
+    height: 0;
+    subcontrol-position: top;
+    subcontrol-origin: margin;
+}
+QScrollBar::up-arrow:vertical {
+    background: url(':/Resources/arrow_up.png') no-repeat center;
+}
+QScrollBar::up-arrow:hover {
+    background: #999999 url(':/Resources/arrow_up.png') no-repeat center;
+}
+QScrollBar::down-arrow:vertical {
+    background: url(':/Resources/arrow_down.png') no-repeat center;
+}
+QScrollBar::down-arrow:hover {
+    background: #999999 url(':/Resources/arrow_down.png') no-repeat center;
+}
+QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {
+    background: none;
+}
+
+QScrollBar:horizontal {
+     border: 0;
+     background: transparent;
+     height: 10px;
+     margin: 0;
+}
+QScrollBar::handle:horizontal {
+    background: #cccccc;
+    min-width: 20px;
+    border-radius: 4px;
+        margin-top:1px;
+        margin-bottom:1px;
+}
+QScrollBar::add-line:horizontal {
+    border: 0;
+    background: #4A4A4A;
+    width: 0;
+    subcontrol-position: right;
+    subcontrol-origin: margin;
+}
+QScrollBar::sub-line:horizontal {
+    border: 0;
+    background: #4A4A4A;
+    width: 0;
+    subcontrol-position: left;
+    subcontrol-origin: margin;
+}
+QScrollBar::left-arrow:horizontal {
+    background: url(':/Resources/arrow_left.png') no-repeat center;
+}
+QScrollBar::left-arrow:hover {
+    background: #999999 url(':/Resources/arrow_left.png') no-repeat center;;
+}
+QScrollBar::right-arrow:horizontal {
+    background: url(':/Resources/arrow_right.png') no-repeat center;
+}
+QScrollBar::right-arrow:hover {
+    background: #999999 url(':/Resources/arrow_right.png') no-repeat center;
+}
+QScrollBar::add-page:horizontal, QScrollBar::sub-page:horizontal {
+    background: none;
+}

+ 115 - 0
DataManage/entity/Airport.cpp

@@ -0,0 +1,115 @@
+#include "Airport.h"
+#include "regExp.h"
+#include "Dict.h"
+#include "AutoCompleteComBoxWidget.h"
+#include "CheckComboBoxWidget.h"
+
+#include "charcode.h"
+
+QX_REGISTER_CPP_USER(Airport)
+
+namespace qx {
+
+    template <>
+    void register_class(QxClass<Airport> & t)
+    {
+        qx::IxDataMember * pData = NULL; Q_UNUSED(pData);
+        qx::IxSqlRelation * pRelation = NULL; Q_UNUSED(pRelation);
+        qx::IxFunction * pFct = NULL; Q_UNUSED(pFct);
+        qx::IxValidator * pValidator = NULL; Q_UNUSED(pValidator);
+
+        t.setName("T_CM_AIRPORT");
+
+        pData = t.id(& Airport::m_ID, "ID", 0);
+        pData->setDescription("编号");
+        pData->setAutoIncrement(true);
+
+        pData = t.data(& Airport::m_NAME, "NAME", 0, true, true);
+        pData->setDescription("名称");
+        pData->setRequired(true);
+
+        pData = t.data(& Airport::m_LONGITUDE, "LONGITUDE", 0, true, true);
+        pData->setDescription("经度");
+        pData->setMaxValue(180.0);
+        pData->setMinValue(-180.0);
+        pData->setPrecision(6);    //默认即是6位
+
+        pData = t.data(& Airport::m_LATITUDE, "LATITUDE", 0, true, true);
+        pData->setDescription("纬度");
+        pData->setMaxValue(90.0);
+        pData->setMinValue(-90.0);
+
+        pData = t.data(& Airport::m_HEIGHT, "HEIGHT", 0, true, true);
+        pData->setDescription("高度");
+        pData->setPropertyBag("regExp",REGEXP_DOUBLE(4,2));
+
+        pData = t.data(& Airport::m_NATION, "NATION", 0, true, true);
+        pData->setDescription("国别");
+        pData->setPropertyBag("dict",Dict::nationDict);
+//        pData->setPropertyBag("type",AutoCompleteComBoxWidget::type);
+        pData->setPropertyBag("type",CheckComboBoxWidget::type);
+
+        pData = t.data(& Airport::m_ISDELETE, "ISDELETE", 0, true, true);
+        pData->setDescription("是否删除");
+        pData->setPropertyBag("notShow",true);
+        pData->setPropertyBag("notInput",true);
+        qx::QxSoftDelete SoftDelete;
+        SoftDelete.setColumnName("ISDELETE");
+        SoftDelete.setMode(qx::QxSoftDelete::mode_flag);
+        t.setSoftDelete(SoftDelete);
+
+        pData = t.data(& Airport::m_IMPORTTIME, "IMPORTTIME", 0, true, true);
+        pData->setDescription("更新时间");
+        pData->setPropertyBag("notInput",true);
+        pData->setPropertyBag("notEditAble",true);
+
+        pData = t.data(& Airport::m_NOTE, "NOTE", 0, true, true);
+        pData->setDescription("备注");
+
+        qx::QxValidatorX<Airport> * pAllValidator = t.getAllValidator(); Q_UNUSED(pAllValidator);
+    }
+
+} // namespace qx
+
+Airport::Airport() : m_ID(0.0), m_LONGITUDE(0.0), m_LATITUDE(0.0), m_HEIGHT(0.0) { ; }
+
+Airport::Airport(const double & id) : m_ID(id), m_LONGITUDE(0.0), m_LATITUDE(0.0), m_HEIGHT(0.0) { ; }
+
+Airport::~Airport() { ; }
+
+double Airport::getID() const { return m_ID; }
+
+QString Airport::getNAME() const { return m_NAME; }
+
+double Airport::getLONGITUDE() const { return m_LONGITUDE; }
+
+double Airport::getLATITUDE() const { return m_LATITUDE; }
+
+double Airport::getHEIGHT() const { return m_HEIGHT; }
+
+QString Airport::getNATION() const{ return m_NATION; }
+
+QString Airport::getISDELETE() const { return m_ISDELETE; }
+
+QDateTime Airport::getIMPORTTIME() const { return m_IMPORTTIME; }
+
+QString Airport::getNOTE() const { return m_NOTE; }
+
+void Airport::setID(const double & val) { m_ID = val; }
+
+void Airport::setNAME(const QString & val) { m_NAME = val; }
+
+void Airport::setLONGITUDE(const double & val) { m_LONGITUDE = val; }
+
+void Airport::setLATITUDE(const double & val) { m_LATITUDE = val; }
+
+void Airport::setHEIGHT(const double & val) { m_HEIGHT = val; }
+
+void Airport::setNATION(const QString & val) { m_NATION = val; }
+
+void Airport::setISDELETE(const QString & val) { m_ISDELETE = val; }
+
+void Airport::setIMPORTTIME(const QDateTime & val) { m_IMPORTTIME = val; }
+
+void Airport::setNOTE(const QString & val) { m_NOTE = val; }
+

+ 74 - 0
DataManage/entity/Airport.h

@@ -0,0 +1,74 @@
+#ifndef AIRPORT_H
+#define AIRPORT_H
+
+#include "QxOrm.h"
+#include "precompiled.h"
+
+class Airport
+{
+
+   QX_REGISTER_FRIEND_CLASS(Airport)
+
+protected:
+
+   double m_ID;
+   QString m_NAME;
+   double m_LONGITUDE;
+   double m_LATITUDE;
+   double m_HEIGHT;
+   QString m_NATION;
+   QString m_ISDELETE;
+   QDateTime m_IMPORTTIME;
+   QString m_NOTE;
+
+public:
+
+   Airport();
+   Airport(const double & id);
+   virtual ~Airport();
+
+   double getID() const;
+   QString getNAME() const;
+   double getLONGITUDE() const;
+   double getLATITUDE() const;
+   double getHEIGHT() const;
+   QString getNATION() const;
+   QString getISDELETE() const;
+   QDateTime getIMPORTTIME() const;
+   QString getNOTE() const;
+
+   void setID(const double & val);
+   void setNAME(const QString & val);
+   void setLONGITUDE(const double & val);
+   void setLATITUDE(const double & val);
+   void setHEIGHT(const double & val);
+   void setNATION(const QString & val);
+   void setISDELETE(const QString & val);
+   void setIMPORTTIME(const QDateTime & val);
+   void setNOTE(const QString & val);
+
+public:
+
+   static QString column_ID(bool key = false) { Q_UNUSED(key); return "ID"; }
+   static QString column_NAME(bool key = false) { Q_UNUSED(key); return "NAME"; }
+   static QString column_LONGITUDE(bool key = false) { Q_UNUSED(key); return "LONGITUDE"; }
+   static QString column_LATITUDE(bool key = false) { Q_UNUSED(key); return "LATITUDE"; }
+   static QString column_HEIGHT(bool key = false) { Q_UNUSED(key); return "HEIGHT"; }
+   static QString column_ISDELETE(bool key = false) { Q_UNUSED(key); return "ISDELETE"; }
+   static QString column_IMPORTTIME(bool key = false) { Q_UNUSED(key); return "IMPORTTIME"; }
+   static QString column_NOTE(bool key = false) { Q_UNUSED(key); return "NOTE"; }
+
+public:
+
+   static QString table_name(bool key = false) { return (key ? QString("Airport") : QString("T_CM_AIRPORT")); }
+
+};
+
+typedef std::shared_ptr<Airport> Airport_ptr;
+typedef qx::QxCollection<double, Airport_ptr> list_of_Airport;
+typedef std::shared_ptr<list_of_Airport> list_of_Airport_ptr;
+
+QX_REGISTER_PRIMARY_KEY(Airport, double)
+QX_REGISTER_HPP_USER(Airport, qx::trait::no_base_class_defined, 0)
+
+#endif // AIRPORT_H

+ 188 - 0
DataManage/forms/AirportWidget.cpp

@@ -0,0 +1,188 @@
+#include "AirportWidget.h"
+#include "MessageException.h"
+#include "Airport.h"
+#include "Application.h"
+#include "CustomDelegate.h"
+
+#include <QMessageBox>
+
+#if _MSC_VER >= 1600
+#pragma execution_character_set("utf-8")
+#endif
+
+AirportWidget::AirportWidget(QWidget *parent)
+	: QWidget(parent)
+	, m_PageIndex(0)
+{
+	ui = new Ui::AirportWidget();
+	ui->setupUi(this);
+
+	init();
+	doQuery();
+
+}
+
+AirportWidget::~AirportWidget()
+{
+	delete ui;
+}
+
+void AirportWidget::init()
+{
+	initTableView();
+	initModel();
+	initService();
+	initPagination();
+	initFormBuild();
+}
+
+void AirportWidget::initTableView()
+{
+    ui->tvData->setEditTriggers(QAbstractItemView::DoubleClicked);
+    CustomDelegate *delegate = new CustomDelegate(this);
+    delegate->setClass<Airport>();
+    ui->tvData->setItemDelegate(delegate);
+}
+
+void AirportWidget::initModel()
+{
+	m_Model = new AirportModel(this);
+	ui->tvData->setModel(m_Model);
+    ui->tvData->hideColumns<Airport>();
+    connect(m_Model,&QAbstractItemModel::dataChanged, this, &AirportWidget::onDataChange);
+}
+
+void AirportWidget::initService()
+{
+	m_Service = new AirportService(this);
+}
+
+void AirportWidget::initFormBuild()
+{
+    m_FormBuilder = new FormBuilder(this);
+}
+
+void AirportWidget::initPagination()
+{
+	ui->pagination->setPageCount(0);
+	ui->pagination->setRecordCount(0);
+
+	connect(ui->pagination, &Pagination::selectPage, [=](int value) {
+		doQuery(value);
+	});
+}
+
+void AirportWidget::doQuery(int pageIndex /*= 0*/)
+{
+	QString name = ui->leQName->text();
+	try
+	{
+		m_Model->fetchByName(name, pageIndex);
+		ui->pagination->setRecordCount(m_Model->getTotalCount());
+		ui->pagination->setPageCount(m_Model->getPageCount());
+	}
+	catch (MessageException &e)
+	{
+		QMessageBox::critical(this, "错误", e.getMessage());
+	}
+}
+
+void AirportWidget::onQuery()
+{
+	doQuery();
+}
+
+void AirportWidget::onReset()
+{
+	ui->leQName->clear();
+	doQuery();
+}
+
+void AirportWidget::onAdd()
+{
+    QWidget *widget = m_FormBuilder->build<Airport>("添加机场");
+    m_FormBuilder->clear();
+	int result = Application::instance()->showModalDialog(widget, this);
+
+	if (result == QDialog::Accepted)
+	{
+        Airport_ptr obj = m_FormBuilder->getValue<Airport>();
+		try
+		{
+			m_Service->add(obj);
+		}
+		catch (MessageException &e)
+		{
+			QMessageBox::critical(this, "错误", e.getMessage());
+			return;
+		}
+		doQuery();
+	}
+}
+
+void AirportWidget::onEdit()
+{
+	QModelIndex index = ui->tvData->currentIndex();
+	if (!index.isValid())
+	{
+        QMessageBox::information(this, "提示", "请选中要修改的数据!");
+		return;
+	}
+	Airport_ptr oldObj = m_Model->getCollection()->_get<Airport_ptr>(index.row());
+	
+    QWidget *widget = m_FormBuilder->build<Airport>("修改机场");
+    m_FormBuilder->clear();
+    m_FormBuilder->fill(oldObj);
+
+	int result = Application::instance()->showModalDialog(widget, this);
+
+	if (result == QDialog::Accepted)
+	{
+		try{
+            Airport_ptr newObj = m_FormBuilder->getValue<Airport>();
+			newObj->setID(oldObj->getID());
+			m_Service->updateById(newObj);
+		}
+		catch (MessageException &e){
+			QMessageBox::critical(this, "错误", e.getMessage());
+			return;
+		}
+		doQuery();
+	}
+}
+
+void AirportWidget::onRemove()
+{
+	QModelIndex index = ui->tvData->currentIndex();
+	if (!index.isValid())
+	{
+        QMessageBox::information(this, "提示", "请选中要删除的数据!");
+		return;
+	}
+	QMessageBox::StandardButton msgBox;
+	msgBox = QMessageBox::question(this, "提示", "确定删除选中的数据吗?", QMessageBox::Yes | QMessageBox::No);
+
+	if (msgBox == QMessageBox::No)
+		return;
+
+	QSqlError error = m_Model->qxDeleteRow(index.row());
+	if (error.isValid())
+	{
+		QMessageBox::critical(this, "错误", error.text()); 
+		return;
+	}
+    m_Model->removeRow(index.row());
+}
+
+void AirportWidget::onDataChange(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles)
+{
+    if(roles.contains(Qt::DisplayRole) || roles.contains(Qt::EditRole))
+    {
+        if(m_Model->getLastError().isValid())
+        {
+            QMessageBox::information(this,"提示",m_Model->getLastErrorAsString());
+        }
+    }
+}
+
+

+ 45 - 0
DataManage/forms/AirportWidget.h

@@ -0,0 +1,45 @@
+#pragma once
+
+#include <QWidget>
+
+#include "AirportModel.h"
+#include "FormBuilder.h"
+#include "AirportService.h"
+#include "ui_AirportWidget.h"
+
+namespace Ui { class AirportWidget; };
+
+class AirportWidget : public QWidget
+{
+	Q_OBJECT
+
+public:
+	AirportWidget(QWidget *parent = Q_NULLPTR);
+	~AirportWidget();
+
+private:
+	void init();
+	void initTableView();
+	void initModel();
+	void initService();
+	void initPagination();
+	void initFormBuild();
+
+	void doQuery(int pageIndex = 0);
+
+
+private slots:
+	void onQuery();
+	void onReset();
+	void onAdd();
+	void onEdit();
+	void onRemove();
+    void onDataChange(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles);
+
+private:
+	Ui::AirportWidget *ui;
+	AirportModel *m_Model;
+    FormBuilder *m_FormBuilder;
+	AirportService *m_Service;
+	int m_PageIndex;
+};

+ 246 - 0
DataManage/forms/AirportWidget.ui

@@ -0,0 +1,246 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>AirportWidget</class>
+ <widget class="QWidget" name="AirportWidget">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>745</width>
+    <height>559</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>AirportWidget</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <property name="leftMargin">
+    <number>0</number>
+   </property>
+   <property name="topMargin">
+    <number>0</number>
+   </property>
+   <property name="rightMargin">
+    <number>0</number>
+   </property>
+   <property name="bottomMargin">
+    <number>0</number>
+   </property>
+   <item>
+    <widget class="QFrame" name="frame">
+     <property name="styleSheet">
+      <string notr="true">
+              QFrame{
+              border:1px solid #cccccc;
+              border-radius: 2px;
+              background-color: white;
+              }
+              QPushButton{
+              min-width:45px;
+              min-height:20px;
+              }
+            </string>
+     </property>
+     <property name="frameShape">
+      <enum>QFrame::StyledPanel</enum>
+     </property>
+     <property name="frameShadow">
+      <enum>QFrame::Raised</enum>
+     </property>
+     <layout class="QHBoxLayout" name="horizontalLayout">
+      <item>
+       <widget class="QLineEdit" name="leQName">
+        <property name="placeholderText">
+         <string>按名称关键字查询</string>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <widget class="QPushButton" name="pbQuery">
+        <property name="text">
+         <string>查询</string>
+        </property>
+        <property name="shortcut">
+         <string>Enter</string>
+        </property>
+        <property name="default">
+         <bool>true</bool>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <widget class="QPushButton" name="pbSet">
+        <property name="text">
+         <string>重置</string>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <spacer name="horizontalSpacer_2">
+        <property name="orientation">
+         <enum>Qt::Horizontal</enum>
+        </property>
+        <property name="sizeHint" stdset="0">
+         <size>
+          <width>40</width>
+          <height>20</height>
+         </size>
+        </property>
+       </spacer>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item>
+    <widget class="TableView" name="tvData"/>
+   </item>
+   <item>
+    <widget class="Pagination" name="pagination" native="true"/>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout_2">
+     <property name="topMargin">
+      <number>0</number>
+     </property>
+     <item>
+      <widget class="QPushButton" name="pbAdd">
+       <property name="text">
+        <string>添加</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QPushButton" name="pbEdit">
+       <property name="text">
+        <string>修改</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QPushButton" name="pbRemove">
+       <property name="text">
+        <string>删除</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <spacer name="horizontalSpacer">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>40</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <layoutdefault spacing="6" margin="11"/>
+ <customwidgets>
+  <customwidget>
+   <class>Pagination</class>
+   <extends>QWidget</extends>
+   <header>Pagination.h</header>
+  </customwidget>
+  <customwidget>
+   <class>TableView</class>
+   <extends>QTableView</extends>
+   <header location="global">TableView.h</header>
+  </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>pbQuery</sender>
+   <signal>clicked()</signal>
+   <receiver>AirportWidget</receiver>
+   <slot>onQuery()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>338</x>
+     <y>31</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>328</x>
+     <y>-22</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>pbSet</sender>
+   <signal>clicked()</signal>
+   <receiver>AirportWidget</receiver>
+   <slot>onReset()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>409</x>
+     <y>38</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>420</x>
+     <y>-20</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>pbAdd</sender>
+   <signal>clicked()</signal>
+   <receiver>AirportWidget</receiver>
+   <slot>onAdd()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>38</x>
+     <y>594</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>4</x>
+     <y>590</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>pbEdit</sender>
+   <signal>clicked()</signal>
+   <receiver>AirportWidget</receiver>
+   <slot>onEdit()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>123</x>
+     <y>596</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>130</x>
+     <y>608</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>pbRemove</sender>
+   <signal>clicked()</signal>
+   <receiver>AirportWidget</receiver>
+   <slot>onRemove()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>222</x>
+     <y>590</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>284</x>
+     <y>614</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+ <slots>
+  <slot>onQuery()</slot>
+  <slot>onReset()</slot>
+  <slot>onAdd()</slot>
+  <slot>onEdit()</slot>
+  <slot>onRemove()</slot>
+ </slots>
+</ui>

+ 46 - 0
DataManage/main.cpp

@@ -0,0 +1,46 @@
+#include "mainwindow.h"
+
+#include <QApplication>
+#include <QMessageBox>
+
+#include "charcode.h"
+#include "utils.h"
+#include "Application.h"
+
+int main(int argc, char *argv[])
+{
+    QApplication a(argc, argv);
+    a.setWindowIcon(QIcon(":/Resources/App.ico"));
+
+    //设置中文字体
+    a.setFont(QFont("Microsoft Yahei", 9));
+
+    QString qss = utils::readFile(":/Resources/style.qss");
+    a.setStyleSheet(qss);
+    try {
+        // 初始化服务层
+        Application::instance()->init();
+        if (!Application::instance()->getDatabaseConnector()->isOpen())
+        {
+            QMessageBox::critical(nullptr, "错误", "数据库不可访问,程序无法运行!");
+            return 0;
+        }
+        else
+        {
+            MainWindow w;
+            w.show();
+            return a.exec();
+        }
+    }
+    catch (MessageException &e)
+    {
+        QMessageBox::critical(0, "错误", e.getMessage());
+    }
+    catch (std::exception &e)
+    {
+        QString msg;
+        msg.append("错误: ");
+        msg.append(e.what());
+        QMessageBox::critical(0, "Error", msg);
+    }
+}

+ 31 - 0
DataManage/mainwindow.cpp

@@ -0,0 +1,31 @@
+#include "mainwindow.h"
+#include "ui_mainwindow.h"
+#include "AirportWidget.h"
+#include "QxOrm.h"
+
+#include <QDebug>
+#include <QHBoxLayout>
+
+static void getBytes(char *src, int srcLength, int length)
+{
+
+}
+
+MainWindow::MainWindow(QWidget *parent)
+    : QMainWindow(parent)
+    , ui(new Ui::MainWindow)
+{
+    ui->setupUi(this);
+    AirportWidget *widget = new AirportWidget(this);
+    QHBoxLayout *hLayout = new QHBoxLayout(this);
+    hLayout->addWidget(widget);
+    ui->centralwidget->setLayout(hLayout);
+    double lon;
+    getBytes((char*)&lon,sizeof(lon),3);
+}
+
+MainWindow::~MainWindow()
+{
+    delete ui;
+}
+

+ 21 - 0
DataManage/mainwindow.h

@@ -0,0 +1,21 @@
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include <QMainWindow>
+
+QT_BEGIN_NAMESPACE
+namespace Ui { class MainWindow; }
+QT_END_NAMESPACE
+
+class MainWindow : public QMainWindow
+{
+    Q_OBJECT
+
+public:
+    MainWindow(QWidget *parent = nullptr);
+    ~MainWindow();
+
+private:
+    Ui::MainWindow *ui;
+};
+#endif // MAINWINDOW_H

+ 31 - 0
DataManage/mainwindow.ui

@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MainWindow</class>
+ <widget class="QMainWindow" name="MainWindow">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>800</width>
+    <height>600</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>数据管理</string>
+  </property>
+  <widget class="QWidget" name="centralwidget"/>
+  <widget class="QMenuBar" name="menubar">
+   <property name="geometry">
+    <rect>
+     <x>0</x>
+     <y>0</y>
+     <width>800</width>
+     <height>23</height>
+    </rect>
+   </property>
+  </widget>
+  <widget class="QStatusBar" name="statusbar"/>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>

+ 32 - 0
DataManage/models/AirportModel.cpp

@@ -0,0 +1,32 @@
+#include "AirportModel.h"
+#include "MessageException.h"
+
+AirportModel::AirportModel(QObject *parent)
+: QxModelBase<Airport>(parent)
+{
+    setAutoUpdate();
+//    setShowEmptyLine(true);
+}
+
+AirportModel::~AirportModel()
+{
+}
+
+
+void AirportModel::fetchByName(const QString &name, int pageIndex)
+{
+    //关系t解决orcle标识符过长问题
+	qx::QxSqlQuery query;
+	if (!name.isEmpty())
+        query.where("t." + Airport::column_NAME()).containsString(name);
+    query.orderAsc("t." + Airport::column_ID());
+
+	QStringList relations;
+	relations << "<t>";
+
+	this->countWithRelation(query, relations);
+	this->limit(query, pageIndex);
+	QSqlError error = this->qxFetchByQuery(query, relations);
+	if (error.isValid())
+		throw MessageException(error.text());
+}

+ 14 - 0
DataManage/models/AirportModel.h

@@ -0,0 +1,14 @@
+#pragma once
+#include "QxModelBase.h"
+#include "Airport.h"
+
+class AirportModel : public QxModelBase<Airport>
+{
+	Q_OBJECT
+
+public:
+	AirportModel(QObject *parent);
+	~AirportModel();
+
+	void fetchByName(const QString &name, int pageIndex = 0);
+};

+ 93 - 0
DataManage/models/ModelBase.cpp

@@ -0,0 +1,93 @@
+#include "ModelBase.h"
+
+#include<QDebug>
+#include <QSqlField>
+
+ModelBase::ModelBase(QObject *parent)
+	: QSqlQueryModel(parent)
+	, totalCount(0)
+	, multiSelect(false)
+{
+	for (size_t i = 0; i < fields.length(); i++)
+	{
+		QPair<QString, QString> pari = fields.at(i);
+		setHeaderData(i, Qt::Horizontal, pari.first);
+	}
+}
+
+ModelBase::~ModelBase()
+{
+}
+
+void ModelBase::setQuery(const QSqlQuery &query)
+{
+	QSqlQueryModel::setQuery(query);
+	//checkStateMap.clear();
+
+	// 移除分页带来的rowno字段
+	if (record().count() > 0)
+	{
+		int columnIndex = columnCount() - 1;
+		QString columnName = record(0).fieldName(columnIndex).toLower();
+		if (columnName == "rowno");
+		removeColumn(columnIndex);
+	}
+}
+
+bool ModelBase::setData(const QModelIndex &index, const QVariant &value, int role)
+{
+	if (!index.isValid())
+		return false;
+	if (multiSelect && role == Qt::CheckStateRole && index.column() == 0)
+	{	
+		Qt::CheckState cs = value == Qt::Checked ? Qt::Checked : Qt::Unchecked;
+		checkStateMap[index.row()] = cs;
+		emit checkStateChanged(cs, record(index.row()));
+	}
+
+	return true;
+}
+
+Qt::ItemFlags ModelBase::flags(const QModelIndex &index) const
+{
+	if (!index.isValid())
+		return 0;
+
+	if (index.column() == 0)
+		return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable;
+
+	return  Qt::ItemIsEnabled | Qt::ItemIsSelectable;
+}
+
+/**
+* 输出表头显示
+*/
+QVariant ModelBase::headerData(int section, Qt::Orientation orientation, int role) const
+{
+	if ((role == Qt::DisplayRole || role == Qt::CheckStateRole) && orientation == Qt::Horizontal)
+	{
+		if (section < fields.count())
+		{
+			return fields.at(section).second;
+		}
+	}
+	return QVariant();
+}
+
+/**
+* 字段值格式化显示
+*/
+QVariant ModelBase::data(const QModelIndex &index, int role) const
+{
+	int row = index.row();
+	int col = index.column();
+
+	if (multiSelect && role == Qt::CheckStateRole && col == 0)
+	{
+		if (checkStateMap.contains(row))
+			return checkStateMap[row] == Qt::Checked ? Qt::Checked : Qt::Unchecked;
+		return Qt::Unchecked;
+	}
+
+	return QSqlQueryModel::data(index, role);
+}

+ 44 - 0
DataManage/models/ModelBase.h

@@ -0,0 +1,44 @@
+#pragma once
+
+#include <QSqlQueryModel>
+#include <QSqlRecord>
+#include "charcode.h"
+// 默认分页大小
+#define PAGE_SIZE	20	
+
+// 计算页数
+#define CALC_PAGE_COUNT(totalCount) ceil(totalCount*1.0/PAGE_SIZE)
+
+class ModelBase : public QSqlQueryModel
+{
+	Q_OBJECT
+
+public:
+	ModelBase(QObject *parent);
+	~ModelBase();
+
+	bool getMultiSelect() const { return multiSelect; }
+	void setMultiSelect(bool val) { multiSelect = val; }
+
+public:
+	void setQuery(const QSqlQuery &query);
+
+	const quint32 getTotalCount() { return totalCount; }
+
+	const quint32 getPageCount() { return CALC_PAGE_COUNT(totalCount); };
+
+signals:
+	void checkStateChanged(Qt::CheckState state, const QSqlRecord &record);
+
+protected:
+	QVariant headerData(int section, Qt::Orientation orientation, int role) const;
+	bool setData(const QModelIndex &, const QVariant &, int);
+	Qt::ItemFlags flags(const QModelIndex &) const;
+	QVariant data(const QModelIndex &index, int role) const;
+
+protected:
+	QMap<int, Qt::CheckState> checkStateMap;
+	QVector<QPair<QString, QString>> fields;
+	quint32 totalCount;
+	bool multiSelect;
+};

+ 82 - 0
DataManage/models/OrmModelBase.cpp

@@ -0,0 +1,82 @@
+#include "OrmModelBase.h"
+
+#include<QDebug>
+
+OrmModelBase::OrmModelBase(QObject* parent)
+	: qx::IxModel(parent)
+	, multiSelect(false)
+{
+}
+
+OrmModelBase::~OrmModelBase()
+{
+}
+
+bool OrmModelBase::setData(const QModelIndex& index, const QVariant& value, int role)
+{
+	if (!index.isValid())
+		return false;
+	if (role == Qt::CheckStateRole && index.column() == 0 && multiSelect)
+	{
+		Qt::CheckState cs = value == Qt::Checked ? Qt::Checked : Qt::Unchecked;
+		int row = index.row();
+		checkStateMap[row] = cs;
+		emit checkStateChanged(cs, row);
+		return true;
+	}
+	bool result = qx::IxModel::setData(index, value, role);
+	if (!result)
+		raiseEvent_dataChanged(index, index);
+	return result;
+}
+
+Qt::ItemFlags OrmModelBase::flags(const QModelIndex& index) const
+{
+	if (!index.isValid())
+		return 0;
+
+	if (index.column() == 0)
+		return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable;
+
+	return  Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable;
+}
+
+/**
+* 字段值格式化显示
+*/
+QVariant OrmModelBase::data(const QModelIndex& index, int role) const
+{
+	int row = index.row();
+	int col = index.column();
+	if (role == Qt::CheckStateRole && col == 0 && multiSelect)
+	{
+		if (checkStateMap.contains(row))
+			return checkStateMap[row] == Qt::Checked ? Qt::Checked : Qt::Unchecked;
+		return Qt::Unchecked;
+	}
+	else if (role == Qt::TextAlignmentRole)
+	{
+		return Qt::AlignCenter;
+	}
+	else if (role == Qt::DisplayRole || role == Qt::EditRole)
+	{
+		QVariantMap dict = getDataMember(index.column())->getPropertyBag("dict").toMap();
+		if (dict.size() > 0)
+		{
+			return dict[qx::IxModel::data(index, role).toString()];
+		}
+	}
+	return qx::IxModel::data(index, role);
+}
+
+
+void OrmModelBase::limit(qx::QxSqlQuery & query, int pageIndex)
+{
+	query.limit(pageSize - 1, pageIndex*pageSize + 1); 
+}
+
+void OrmModelBase::count(const qx::QxSqlQuery  &query)
+{
+	totalCount = this->qxCount(query); 
+}
+

+ 46 - 0
DataManage/models/OrmModelBase.h

@@ -0,0 +1,46 @@
+#pragma once
+#include "QxModelView.h"
+
+class MultipleTableView;
+
+class OrmModelBase : public qx::IxModel
+{
+	friend MultipleTableView;
+	Q_OBJECT
+public:
+	static const int pageSize = 20;
+
+public:
+	OrmModelBase(QObject *parent);
+	virtual ~OrmModelBase();
+
+	bool getMultiSelect() const { return multiSelect; }
+
+	void setMultiSelect(bool val) { multiSelect = val; }
+
+	const int getTotalCount() { return totalCount; }
+
+	const int getPageCount() { return ceil(totalCount*1.0 / pageSize); };
+
+	void setAutoUpdate(){ setAutoUpdateDatabase(e_auto_update_on_field_change); };
+
+signals:
+	void checkStateChanged(Qt::CheckState state, int row);
+
+public:
+    bool setData(const QModelIndex &, const QVariant &, int role= Qt::EditRole) override;
+
+    Qt::ItemFlags flags(const QModelIndex &) const override;
+
+    QVariant data(const QModelIndex &index, int role) const override;
+
+protected:
+	void limit(qx::QxSqlQuery &query, int pageIndex);
+
+	void count(const qx::QxSqlQuery  &query);
+
+protected:
+	QMap<int, Qt::CheckState> checkStateMap;
+	bool multiSelect;
+	long totalCount;
+};

+ 86 - 0
DataManage/models/QxModelBase.h

@@ -0,0 +1,86 @@
+#pragma once
+#include "QxModelView.h"
+#include "QxOrm.h"
+#include "OrmModelBase.h"
+
+template<typename T>
+class QxModelBase : public qx::QxModel<T, OrmModelBase>
+{
+public :
+	QxModelBase(QObject * parent = nullptr) 
+		:qx::QxModel<T, OrmModelBase>(parent), 
+		isAutoInsert(false){};
+
+	virtual ~QxModelBase(){ ; };
+
+    void setAutoInsert(bool isAutoInsert = true){ this->isAutoInsert = isAutoInsert; }
+
+protected:
+	bool isAutoInsert;
+
+public:
+	virtual QSqlError qxSaveRowData(int row, const QStringList & column = QStringList(), QSqlDatabase * pDatabase = nullptr)
+	{
+		if (!this->m_pDataMemberId) { this->m_lastError = QSqlError("[QxOrm] problem with 'qxSaveRowData()' method : 'data member id not registered'", "", QSqlError::UnknownError); return this->m_lastError; }
+		type_ptr pItem = getRowItemAt(row); if (!pItem) { return QSqlError(); }
+		QVariant id = this->m_pDataMemberId->toVariant(pItem.get());
+		bool bExist = qx::trait::is_valid_primary_key(id);
+		if (bExist) { bExist = qx::dao::exist((*pItem), this->database(pDatabase)); }
+		if (bExist) { this->m_lastError = qx::dao::update((*pItem), this->database(pDatabase), column); }
+		else if (isAutoInsert){ this->m_lastError = qx::dao::insert((*pItem), this->database(pDatabase)); }
+		return this->m_lastError;
+	}
+
+	virtual void insertDirtyRowToModel() 
+	{
+		qx::QxModel<T, OrmModelBase>::insertDirtyRowToModel();
+	}
+
+	void countWithRelation(const qx::QxSqlQuery  &query, const QStringList &relation)
+	{
+		qx::dao::count_with_relation<T>(totalCount, relation, query);
+	}
+
+	virtual QSqlError qxFetchRow(int row, const QStringList & relation, QSqlDatabase * pDatabase)
+	{
+		using namespace qx;
+		type_ptr pItem = getRowItemAt(row); if (!pItem) { return QSqlError(); }
+		if (relation.count() == 0)
+		{
+			this->m_lastError = qx::dao::fetch_by_id((*pItem), this->database(pDatabase), this->m_lstColumns);
+		}
+		else
+		{
+			QxSqlQuery query;
+			query.where("t." + m_pDataMemberId->getKey()).isEqualTo(m_pDataMemberId->toVariant(pItem.get()));
+			QStringList relations;
+			relations << "<t>";
+			QString placeholder[] = { "b", "c", "d", "e", "f", "g", "h" };
+			int i = 0;
+			for (auto dataMember : m_lstDataMember)
+			{
+				if (dataMember->hasSqlRelation())
+				{
+					relations << dataMember->getKey() + "<" + placeholder[i] + ">";
+					i++;
+				}
+			}
+			this->m_lastError = qx::dao::fetch_by_query_with_relation(relations, query, (*pItem), this->database(pDatabase));
+		}
+		if (this->m_lastError.isValid())
+		{
+			return this->m_lastError;
+		}
+
+		QModelIndex idxTopLeft = this->index(row, 0);
+		QModelIndex idxBottomRight = this->index(row, (this->m_lstDataMember.count() - 1));
+		this->raiseEvent_dataChanged(idxTopLeft, idxBottomRight);
+		updateKey(row);
+		return this->m_lastError;
+	}
+
+	std::shared_ptr<T> getByRow(int row) const
+	{
+		return m_model.getByIndex(row);
+	}
+};

+ 10 - 0
DataManage/services/AirportService.cpp

@@ -0,0 +1,10 @@
+#include "AirportService.h"
+
+AirportService::AirportService(QObject *parent)
+: ServiceBase(parent)
+{
+}
+
+AirportService::~AirportService()
+{
+}

+ 11 - 0
DataManage/services/AirportService.h

@@ -0,0 +1,11 @@
+#pragma once
+#include "ServiceBase.h"
+
+class AirportService : public ServiceBase
+{
+	Q_OBJECT
+
+public:
+	AirportService(QObject *parent = nullptr);
+	~AirportService();
+};

+ 122 - 0
DataManage/services/Application.cpp

@@ -0,0 +1,122 @@
+#include "Application.h"
+
+#include <qdatetime.h>
+#include <QtCore/QCoreApplication>
+#include <QFrame>
+#include <QVBoxLayout>
+#include <QDialog>
+
+#include "../utils/MessageException.h"
+#include "../widgets/TitleBar.h"
+#include "../widgets/DialogTemplate.h"
+
+Application *Application::m_instance = NULL;
+
+/**
+ * @brief Application::instance 单例模式,方便调用
+ * @return Application实例
+ */
+Application *Application::instance()
+{
+    static QMutex mutex;
+    if (!m_instance)
+    {
+        QMutexLocker locker(&mutex);
+        if (!m_instance)
+        {
+            m_instance = new Application;
+        }
+    }
+
+    return m_instance;
+}
+
+Application::Application():
+    inited(false),
+    configurator(0),
+    dbConnector(0)
+{
+
+}
+
+
+Application::~Application()
+{
+    if(m_instance != NULL)
+    {
+        m_instance->uninit();
+
+        delete  m_instance;
+        m_instance = NULL;
+    }
+}
+
+void Application::init()
+{
+    if(inited)
+        return;
+
+    try 
+    {
+        // 初始化系统配置模块
+        configurator = new ApplicationConfigurator();
+        configurator->init();
+
+        sendMessage("加载配置文件成功", false);
+
+        // 初始化数据库连接模块
+        dbConnector = new DatabaseConnector();
+		dbConnector->init(configurator->getDbName(),
+                          configurator->getDbHostName(),
+						  configurator->getDbPort(),
+                          configurator->getDbUserName(),
+                          configurator->getDbPassword());
+        sendMessage("系统启动成功!", false);
+
+        inited = true;
+    }
+    catch (MessageException& e)
+    { 
+        sendMessage(e.getMessage(), true);
+    }
+}
+
+void Application::uninit()
+{
+    if (dbConnector)
+    {
+        delete dbConnector;
+    }
+    if (configurator)
+    {
+        delete configurator;
+    }
+}
+
+void Application::showLoading(const QString &msg)
+{
+	emit loading(true, msg);
+}
+
+void Application::hideLoading()
+{
+	emit loading(false);
+}
+
+int Application::showModalDialog(QWidget *contentWidget, QWidget *parent)
+{
+	DialogTemplate *dt = new DialogTemplate(contentWidget, parent);
+	contentWidget->setParent((QWidget*)dt);
+	dt->setWindowTitle(contentWidget->windowTitle());
+	dt->setWindowIcon(QIcon(":/MainWindow/Resources/App.ico"));
+	return dt->exec();
+}
+
+void Application::sendMessage(const QString &msg, bool err)
+{
+    QDateTime currentTime = QDateTime::currentDateTime();
+    QString showMsg = "时间:" + currentTime.toString("yyyy-MM-dd hh:mm:ss");
+    showMsg.append("\t" + msg);
+    emit message(showMsg, err);
+}
+

+ 51 - 0
DataManage/services/Application.h

@@ -0,0 +1,51 @@
+#ifndef APPLICATION_H
+#define APPLICATION_H
+
+#include <QObject>
+#include <QString>
+#include <QMutex>
+#include <QMutexLocker>
+#include <QSqlRecord>
+
+#include "ApplicationConfigurator.h"
+#include "DatabaseConnector.h"
+
+
+class Application : public QObject
+{
+    Q_OBJECT
+
+public:
+    static Application* instance();
+
+private:
+    Application();
+    ~Application();
+
+    static Application* m_instance;
+
+public:
+    void init();
+
+    ApplicationConfigurator *getConfigurator() const { return configurator; };
+    DatabaseConnector *getDatabaseConnector() const { return dbConnector; };
+
+	void showLoading(const QString &msg);
+	void hideLoading();
+
+	int showModalDialog(QWidget *contentWidget, QWidget *parent);
+
+signals:
+	void message(const QString &msg, bool err);
+	void loading(bool show, const QString &msg = "");
+
+private:    
+    void uninit();
+	void sendMessage(const QString &msg, bool err = false);
+
+    bool inited;
+    ApplicationConfigurator* configurator;
+    DatabaseConnector* dbConnector;    
+};
+
+#endif // APPLICATION_H

+ 59 - 0
DataManage/services/ApplicationConfigurator.cpp

@@ -0,0 +1,59 @@
+#include "ApplicationConfigurator.h"
+
+#include <QCoreApplication>
+#include <QTextCodec>
+#include <QFile>
+#include <QDir>
+#include <QDebug>
+
+ApplicationConfigurator::ApplicationConfigurator() :
+    iniSettings(0)
+{
+
+}
+
+ApplicationConfigurator::~ApplicationConfigurator()
+{
+    if(iniSettings)
+    {
+        delete iniSettings;
+    }
+}
+
+
+/**
+ * @brief ApplicationConfigurator::init 初始化配置文件并加载配置参数
+ */
+void ApplicationConfigurator::init()
+{
+    QString filename = QCoreApplication::applicationDirPath() + "\\config.ini";
+    iniSettings = new QSettings(filename, QSettings::IniFormat);
+    iniSettings->setIniCodec(QTextCodec::codecForName("System"));
+
+    // 数据库连接参数
+    dbName = iniSettings->value("Database/dbName", "").toString();
+	dbPort = iniSettings->value("Database/dbPort", 1521).toUInt();
+    dbHostName = iniSettings->value("Database/dbHostName", "").toString();
+    dbUserName = iniSettings->value("Database/dbUserName", "").toString();
+    dbPassword = iniSettings->value("Database/dbPassword", "").toString();
+
+}
+
+/**
+ * @brief ApplicationConfigurator::save 保存配置参数到配置文件
+ */
+void ApplicationConfigurator::save()
+{
+    // 数据库连接参数
+    iniSettings->beginGroup("Database");
+
+    iniSettings->setValue("dbName", dbName);
+	iniSettings->setValue("dbPort", dbPort);
+    iniSettings->setValue("dbHostName", dbHostName);
+    iniSettings->setValue("dbUserName", dbUserName);
+    iniSettings->setValue("dbPassword", dbPassword);
+
+	iniSettings->endGroup();
+}
+
+

+ 91 - 0
DataManage/services/ApplicationConfigurator.h

@@ -0,0 +1,91 @@
+#ifndef APPLICATIONCONFIGURATOR_H
+#define APPLICATIONCONFIGURATOR_H
+
+#include <QtCore/qglobal.h>
+#include <QString>
+#include <QSettings>
+
+class ApplicationConfigurator
+{
+public:
+    ApplicationConfigurator();
+    virtual ~ApplicationConfigurator();
+
+    void init();
+    void save();
+
+    QString getDbName() const { return dbName; };
+    void setDbName(const QString &value) { dbName = value; };
+
+	quint16 getDbPort() const { return dbPort; };
+	void setDbPort(const quint16 value) { dbPort = value; };
+
+    QString getDbHostName() const { return dbHostName; };
+    void setDbHostName(const QString &value) { dbHostName = value; };
+
+    QString getDbUserName() const { return dbUserName; };
+    void setDbUserName(const QString &value) { dbUserName = value; };
+
+    QString getDbPassword() const { return dbPassword; };
+    void setDbPassword(const QString &value) { dbPassword = value; };
+
+	quint32 getAirportCount() const { return airportCount; };
+	void setAirportCount(const quint32 &value) { airportCount = value; };
+
+	quint32 getTrackLineCount() const { return trackLineCount; };
+	void setTrackLineCount(const quint32 &value) { trackLineCount = value; };
+
+	quint32 getTurnPointCount() const { return turnPointCount; };
+	void setTurnPointCount(const quint32 &value) { turnPointCount = value; };
+
+	double getAlpha() const { return alpha; };
+	void setAlpha(const double value) { alpha = value; };
+
+	int getDisPercent() const { return disPercent; };
+	void setDisPercent(const int value) { disPercent = value; };
+
+	quint32 getInsertCount() const { return insertCount; };
+	void setInsertCount(const quint32 value) { insertCount = value; };
+
+	double getAlt() const { return alt; };
+	void setAlt(const double value) { alt = value; };
+
+	double getSpeed() const { return speed; };
+	void setSpeed(const double value) { speed = value; };
+
+	QString getDictTable(const QString &name) const { 
+		if (dicts.contains(name)){
+			return dicts[name];
+		}
+
+		return "";
+	};
+
+private:
+	void loadDictTables();
+
+private:
+    QString dbName;
+	quint16 dbPort;
+    QString dbHostName;
+    QString dbUserName;
+    QString dbPassword;
+
+	quint32 airportCount;
+	quint32 trackLineCount;
+	quint32 turnPointCount;
+	double alpha;
+	int disPercent;
+	quint32 insertCount;
+	double alt;
+	double speed;
+
+
+	QString dictCounty;
+
+private:
+    QSettings *iniSettings;
+	QHash < QString, QString > dicts;
+};
+
+#endif // APPLICATIONCONFIGURATOR_H

+ 84 - 0
DataManage/services/DatabaseConnector.cpp

@@ -0,0 +1,84 @@
+#include "DatabaseConnector.h"
+#include "MessageException.h"
+#include "QxOrm.h"
+#include "SqlGenerator_Oracle.h"
+
+#include <QSqlDatabase>
+#include <QSqlError>
+#include <QSqlDriver>
+#include <QDebug>
+#include <QMessageBox>
+
+DatabaseConnector::DatabaseConnector()
+	:status(false)
+{
+}
+
+DatabaseConnector::~DatabaseConnector()
+{
+}
+
+/**
+ * @brief DatabaseConnector::init 连接数据库
+ * @param databaseName 数据库名
+ * @param hostName 主机
+ * @param userName 用户名
+ * @param password 密码
+ */
+void DatabaseConnector::init(const QString &databaseName,
+                             const QString &hostName,
+							 const quint16 port,
+                             const QString &userName,
+                             const QString &password)
+{
+    qx::QxSqlDatabase *qxSqlDatabase = qx::QxSqlDatabase::getSingleton();
+    qxSqlDatabase->setDriverName("QOCI");
+    qxSqlDatabase->setDatabaseName(databaseName);
+    qxSqlDatabase->setHostName(hostName);
+    qxSqlDatabase->setUserName(userName);
+    qxSqlDatabase->setPassword(password);
+    qxSqlDatabase->setPort(port);
+    std::shared_ptr<SqlGenerator_Oracle> sqlGenerator_ptr= std::make_shared<SqlGenerator_Oracle>();
+    qxSqlDatabase->setSqlGenerator(sqlGenerator_ptr);
+}
+
+/**
+ * @brief DatabaseConnector::isOpen 数据库是否已连接
+ * @return 是否连接
+ */
+bool DatabaseConnector::isOpen()
+{
+	status = qx::QxSqlDatabase::getSingleton()->getDatabase().isOpen();
+    return  status;
+}
+
+void DatabaseConnector::transaction()
+{
+	bool ret = qx::QxSqlDatabase::getSingleton()->getDatabase().transaction();
+	if (!ret)
+	{
+		QString msg = qx::QxSqlDatabase::getSingleton()->getDatabase().lastError().text();
+		qDebug() << "transaction:" << msg;
+		throw MessageException("开启事务失败!");
+	}
+}
+
+void DatabaseConnector::commit()
+{
+	bool ret = qx::QxSqlDatabase::getSingleton()->getDatabase().commit();
+	if (!ret)
+	{
+		qDebug() << "commit:" << qx::QxSqlDatabase::getSingleton()->getDatabase().lastError().text();
+		throw MessageException("提交事务失败!");
+	}
+}
+
+void DatabaseConnector::rollback()
+{
+	bool ret = qx::QxSqlDatabase::getSingleton()->getDatabase().rollback();
+	if (!ret)
+	{
+		qDebug() << "rollback:" << qx::QxSqlDatabase::getSingleton()->getDatabase().lastError().text();
+		throw MessageException("回滚事务失败!");
+	}
+}

+ 29 - 0
DataManage/services/DatabaseConnector.h

@@ -0,0 +1,29 @@
+#ifndef DATABASECONNECTOR_H
+#define DATABASECONNECTOR_H
+
+#include <QObject>
+#include <QTimer>
+
+class DatabaseConnector : public QObject
+{
+    Q_OBJECT
+
+public:
+    explicit DatabaseConnector();
+    ~DatabaseConnector();
+
+    void init(const QString &databaseName,
+              const QString &hostName,
+			  const quint16 port,
+              const QString &userName,
+              const QString &password);
+    bool isOpen();
+
+	void transaction();
+	void commit();
+    void rollback();
+private:
+    bool status;
+};
+
+#endif // DATABASECONNECTOR_H

+ 14 - 0
DataManage/services/Dict.cpp

@@ -0,0 +1,14 @@
+#include "Dict.h"
+#include "charcode.h"
+
+QVariantMap Dict::nationDict = {
+    {"1","中国"},
+    {"2","美国"},
+    {"3","日本"},
+    {"4","韩国"}
+};
+
+Dict::Dict()
+{
+
+}

+ 14 - 0
DataManage/services/Dict.h

@@ -0,0 +1,14 @@
+#ifndef DICT_H
+#define DICT_H
+
+#include <QVariantMap>
+
+class Dict
+{
+public:
+    Dict();
+
+    static QVariantMap nationDict;
+};
+
+#endif // DICT_H

+ 10 - 0
DataManage/services/ServiceBase.cpp

@@ -0,0 +1,10 @@
+#include "ServiceBase.h"
+
+ServiceBase::ServiceBase(QObject *parent)
+	: QObject(parent)
+{
+}
+
+ServiceBase::~ServiceBase()
+{
+}

+ 59 - 0
DataManage/services/ServiceBase.h

@@ -0,0 +1,59 @@
+#pragma once
+
+#include <QObject>
+#include "QxOrm.h"
+#include "charcode.h"
+
+class ServiceBase : public QObject
+{
+	Q_OBJECT
+
+public:
+	ServiceBase(QObject *parent);
+	~ServiceBase();
+
+	//************************************
+	// Method:    add
+	// FullName:  ServiceBase::add
+	// Returns:   void
+	// Parameter: T & t 实体对象
+	// Parameter: QSqlDatabase * database  默认为空,QxOrm内部自动开启事务,如果多条记录操作,则需传入有效的database,有调用者控制事务
+	//************************************
+	template<typename T>
+	static void add(T &t, QSqlDatabase *database = nullptr)
+	{
+		QSqlError error = qx::dao::insert(t, database);
+		if (error.isValid())
+            throw MessageException("插入失败:" + error.text());
+	}
+
+	//************************************
+	// Method:    updateById
+	// FullName:  ServiceBase::updateById
+	// Returns:   void
+	// Parameter: T & t 实体对象
+	// Parameter: QSqlDatabase * database 默认为空,QxOrm内部自动开启事务,如果多条记录操作,则需传入有效的database,有调用者控制事务
+	//************************************
+	template<typename T>
+	static void updateById(T &t, QSqlDatabase *database = nullptr)
+	{
+		QSqlError error = qx::dao::update(t, database);
+		if (error.isValid())
+            throw MessageException("更新失败:" + error.text());
+	}
+
+	//************************************
+	// Method:    deleteById
+	// FullName:  ServiceBase::deleteById
+	// Returns:   void
+	// Parameter: T & t 实体对象
+	// Parameter: QSqlDatabase * database 默认为空,QxOrm内部自动开启事务,如果多条记录操作,则需传入有效的database,有调用者控制事务
+	//************************************
+	template<typename T>
+	static void deleteById(T &t, QSqlDatabase *database = nullptr)
+	{
+		QSqlError error = qx::dao::delete_by_id(t, database);
+		if (error.isValid())
+            throw MessageException("删除失败:" + error.text());
+	}
+};

+ 11 - 0
DataManage/utils/DebugUtil.h

@@ -0,0 +1,11 @@
+#ifndef DEBUGUTIL_H
+#define DEBUGUTIL_H
+#include <QDebug>
+
+#ifndef NODEBUG
+    #define Debug(x) qDebug() << #x << ":" << (x);
+#else
+    #define Debug(x)
+#endif // DEBUG
+
+#endif // DEBUGUTIL_H

+ 38 - 0
DataManage/utils/DoubleValidator.cpp

@@ -0,0 +1,38 @@
+#include "DoubleValidator.h"
+
+DoubleValidator::DoubleValidator(double bottom, double top, int decimals, QObject * parent /*= nullptr*/)
+	:QDoubleValidator(bottom, top, decimals, parent)
+{
+
+}
+
+DoubleValidator::~DoubleValidator()
+{
+}
+
+DoubleValidator::State DoubleValidator::validate(QString &s, int &i) const
+{
+	if (s.isEmpty() || s == "-") {
+		return QValidator::Intermediate;
+	}
+
+	QChar decimalPoint = locale().decimalPoint();
+
+	if (s.indexOf(decimalPoint) != -1) {
+		int charsAfterPoint = s.length() - s.indexOf(decimalPoint) - 1;
+
+		if (charsAfterPoint > decimals()) {
+			return QValidator::Invalid;
+		}
+	}
+
+	bool ok;
+	double d = locale().toDouble(s, &ok);
+
+	if (ok && d >= bottom() && d <= top()) {
+		return QValidator::Acceptable;
+	}
+	else {
+		return QValidator::Invalid;
+	}
+}

+ 17 - 0
DataManage/utils/DoubleValidator.h

@@ -0,0 +1,17 @@
+#ifndef DOUBLEVALIDATOR_H
+#define DOUBLEVALIDATOR_H
+
+#include <QDoubleValidator>
+
+class DoubleValidator : public QDoubleValidator
+{
+	Q_OBJECT
+
+public:
+	DoubleValidator(double bottom, double top, int decimals, QObject * parent = nullptr);
+	~DoubleValidator();
+
+	DoubleValidator::State validate(QString &s, int &i) const override;
+};
+
+#endif // DOUBLEVALIDATOR_H

+ 64 - 0
DataManage/utils/FormBuilder.cpp

@@ -0,0 +1,64 @@
+#include "FormBuilder.h"
+#include "ComboBoxWidget.h"
+#include "LineEditWidget.h"
+#include "charcode.h"
+#include "PathSelectorWidget.h"
+#include "TagEditWidget.h"
+#include "AutoCompleteTagEditWidget.h"
+#include "DateTimeWidget.h"
+#include "charcode.h"
+
+FormBuilder::FormBuilder(QObject *parent)
+	: QObject(parent)
+    , mainWidget(nullptr)
+	, factorys(new WidgetFactory(this))
+{
+}
+
+FormBuilder::~FormBuilder()
+{
+}
+
+void FormBuilder::clear()
+{
+    foreach(auto &item, ixWidgets)
+    {
+        item.second->clearInput();
+    }
+}
+
+void FormBuilder::onSavePressed()
+{
+    foreach(auto &item, ixWidgets)
+    {
+        if(item.first->getRequired() && item.second->isValueNull() )
+        {
+            QMessageBox::warning(nullptr, "提示", QString("请输入 %1 !").arg(item.first->getDescription()));
+            return;
+        }
+    }
+    ((QDialog*)(mainWidget->parent()))->accept();
+}
+
+QLabel *FormBuilder::buildLabel(QString text, bool required, QWidget *parent)
+{
+    QLabel* label = new QLabel(parent);
+    if (required)
+        text = "<span style='color:red;font-size:12pt'>*</span>" + text;
+    text += ":";
+    label->setText(text);
+    return label;
+}
+
+
+bool FormBuilder::isInput(qx::IxDataMember *dataMember)
+{
+    if (dataMember->getIsPrimaryKey() || dataMember->getPropertyBag("notInput").toBool())
+        return false;
+    return true;
+}
+
+
+
+
+

+ 178 - 0
DataManage/utils/FormBuilder.h

@@ -0,0 +1,178 @@
+#ifndef IXWIDGETUTIL_H
+#define IXWIDGETUTIL_H
+
+#include <QGridLayout>
+#include <QScrollArea>
+#include <QLabel>
+#include <QListView>
+#include <QPushButton>
+#include <QMessageBox>
+
+#include "QxOrm.h"
+#include "IxWidgetFactory.h"
+#include "WidgetFactory.h"
+
+class FormBuilder : public QObject
+{
+    Q_OBJECT
+public:
+    FormBuilder(QObject * parent = nullptr);
+    ~FormBuilder();
+
+	//************************************
+	// Method:    build
+    // FullName:  FormBuilder::build 根据实体类的各数据成员的属性构造输入界面
+	// Access:    public 
+	// Returns:   QWidget*
+	// Qualifier:
+	// Parameter: const QString & title 界面标题
+	// Parameter: quint32 minWidth 最大宽度
+	// Parameter: T t 实体类对象,非智能指针
+	//************************************
+	template<typename T>
+    QWidget* build(const QString &title, quint32 minWidth = 1000);
+
+    //************************************
+    // Method:    getValue
+    // FullName:  FormBuilder::getValue   获取用户输入数据的实体类对象
+    // Access:    public 
+    // Returns:   返回实体类的智能指针
+    // Qualifier:
+    //************************************
+    template<typename T>
+	std::shared_ptr<T> getValue()
+	{
+		std::shared_ptr<T> pOwner = std::make_shared<T>();
+		foreach(auto &item, ixWidgets)
+		{
+			item.first->fromVariant(pOwner.get(), item.second->getValue());
+		}
+		return pOwner;
+	}
+
+	//************************************
+	// Method:    fill
+    // FullName:  FormBuilder::fill  从实体类T中取字段值填充进界面
+	// Access:    public 
+	// Returns:   void
+	// Qualifier:
+	// Parameter: T & t  需传入实体类的智能指针, 且其关联的实体类要和构造界面的build函数中的实体类T保持一致
+	//************************************
+	template<typename T>
+    void fill(std::shared_ptr<T> &t)
+	{
+		if (!mainWidget || !t)
+			return;
+		foreach(auto &item, ixWidgets)
+		{
+			item.second->setValue(item.first->toVariant(t.get()));
+		}
+	}
+
+    void clear();
+
+private slots:
+	void onSavePressed();
+
+private:
+    QLabel* buildLabel(QString text, bool required, QWidget* parent);
+
+    bool isInput(qx::IxDataMember *dataMember);
+
+private:
+    QWidget* mainWidget;
+
+	WidgetFactory *factorys;
+
+	QList<QPair<qx::IxDataMember*, IxWidget*>> ixWidgets;
+};
+
+
+template<typename T>
+inline QWidget* FormBuilder::build(const QString &title, quint32 minWidth)
+{
+    if (mainWidget != nullptr)
+    {
+        mainWidget->setMinimumWidth(minWidth);
+        mainWidget->setWindowTitle(title);
+        return mainWidget;
+    }
+    mainWidget = new QWidget;
+    mainWidget->setMinimumWidth(minWidth);
+    mainWidget->setWindowTitle(title);
+
+    QVBoxLayout* widgetLayout = new QVBoxLayout(mainWidget);
+
+    QScrollArea* scrollArea = new QScrollArea(mainWidget);
+    QWidget* scrollAreaContent = new QWidget(scrollArea);
+    QGridLayout* layout = new QGridLayout(scrollAreaContent);
+    qint16 row = -1, col = 0, count = 0;
+
+    QWidget* input = nullptr;
+    qx::IxDataMemberX* dataMembers = qx::QxClass<T>::getSingleton()->getDataMemberX();
+    for (int i = 0; i < dataMembers->size(); ++i)
+    {
+        qx::IxDataMember* dataMember = dataMembers->get(i);
+        if (!isInput(dataMember))
+			continue;
+		IxWidgetFactory_ptr widgetFactory = factorys->getFactory(dataMember);
+        if(!widgetFactory)
+            continue;
+        widgetFactory->create(dataMember,mainWidget);
+        input =  widgetFactory->getWidget();
+        IxWidget *iWidget = widgetFactory->getIxWidget();
+        iWidget->setName(dataMember->getName());
+        ixWidgets << qMakePair(dataMember,iWidget);
+
+		QLabel* label = buildLabel(dataMember->getDescription(), dataMember->getRequired(), mainWidget);
+        if (count % 2 == 0)
+        {
+            row++;
+            col = 0;
+        }
+        else
+        {
+            col += 2;
+            label->setStyleSheet("margin-left:15px");
+        }
+        count++;
+
+        if (input != nullptr)
+        {
+            input->setObjectName(dataMember->getName());
+            input->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
+            layout->addWidget(label, row, col, Qt::AlignRight);
+            layout->addWidget(input, row, col + 1);
+        }
+    }
+
+    // 添加到布局中
+
+    QPushButton* pbSave = new QPushButton(scrollAreaContent);
+    QPushButton* pbCancel = new QPushButton(scrollAreaContent);
+    QHBoxLayout* layoutButton = new QHBoxLayout(scrollAreaContent);
+    layoutButton->addStretch();
+    layoutButton->addWidget(pbSave);
+    layoutButton->addWidget(pbCancel);
+    pbSave->setText(QStringLiteral("保存"));
+	pbCancel->setText(QStringLiteral("取消"));
+
+    connect(pbSave, &QPushButton::clicked, this, &FormBuilder::onSavePressed);
+    connect(pbCancel, &QPushButton::pressed, [=]() {
+        ((QDialog*)(mainWidget->parent()))->reject();
+        });
+
+    widgetLayout->addWidget(scrollArea);
+    widgetLayout->addLayout(layoutButton);
+    widgetLayout->setContentsMargins(15, 15, 15, 15);
+    widgetLayout->setSpacing(10);
+    layout->setVerticalSpacing(15);
+
+    scrollArea->setWidgetResizable(true);
+    scrollArea->setFrameStyle(0);
+    scrollArea->setWidget(scrollAreaContent);
+    scrollArea->setStyleSheet("background-color:transparent;");
+
+    return mainWidget;
+}
+#endif

+ 15 - 0
DataManage/utils/IxWidgetUtil.cpp

@@ -0,0 +1,15 @@
+#include "IxWidgetUtil.h"
+#include <QVariant>
+
+QList<IxWidget *> IxWidgetUtil::findIxWidgets(const QWidget *parent)
+{
+    QList<IxWidget *> ixWidgets;
+    QList<QWidget*> widgets = parent->findChildren<QWidget*>();
+    foreach (QWidget* widget, widgets)
+    {
+        QVariant property = widget->property("IxWidget");
+        if(property.canConvert<IxWidget*>())
+            ixWidgets << property.value<IxWidget*>();
+    }
+    return ixWidgets;
+}

+ 12 - 0
DataManage/utils/IxWidgetUtil.h

@@ -0,0 +1,12 @@
+#ifndef IXWIDGETUTIL_H
+#define IXWIDGETUTIL_H
+
+#include "IxWidget.h"
+#include <QWidget>
+
+class IxWidgetUtil
+{
+    static QList<IxWidget*> findIxWidgets(const QWidget* parent);
+};
+
+#endif // IXWIDGETUTIL_H

+ 23 - 0
DataManage/utils/MessageException.h

@@ -0,0 +1,23 @@
+#ifndef MESSAGEEXCEPTION_H
+#define MESSAGEEXCEPTION_H
+
+#include <exception>
+#include <QString>
+
+class MessageException : public std::exception
+{
+public:
+    MessageException(const QString &msg):message(msg){};
+    ~MessageException() throw() {};
+
+    virtual const char* what() const throw () {
+        return "MessageException";
+    }
+
+    QString getMessage() const {return message;};
+
+private:
+    QString message;
+};
+
+#endif // MESSAGEEXCEPTION_H

+ 41 - 0
DataManage/utils/SqlGenerator_Oracle.cpp

@@ -0,0 +1,41 @@
+#include "SqlGenerator_Oracle.h"
+#include <qdebug.h>
+
+SqlGenerator_Oracle::SqlGenerator_Oracle()
+	: QxSqlGenerator_Oracle()
+{
+	setManageLastInsertId(true);
+	setOldLimitSyntax(true);
+}
+
+SqlGenerator_Oracle::~SqlGenerator_Oracle()
+{
+}
+
+void SqlGenerator_Oracle::onBeforeInsert(qx::dao::detail::IxDao_Helper * pDaoHelper, void * pOwner) const
+{
+	autoAssignUpdateTime(pDaoHelper, pOwner);
+	QxSqlGenerator_Oracle::onBeforeInsert(pDaoHelper, pOwner);
+}
+
+void SqlGenerator_Oracle::onBeforeUpdate(qx::dao::detail::IxDao_Helper * pDaoHelper, void * pOwner) const
+{
+	autoAssignUpdateTime(pDaoHelper, pOwner);
+	QxSqlGenerator_Oracle::onBeforeUpdate(pDaoHelper, pOwner);
+}
+
+void SqlGenerator_Oracle::onBeforeSqlPrepare(qx::dao::detail::IxDao_Helper * pDaoHelper, QString & sql) const
+{
+}
+
+void SqlGenerator_Oracle::autoAssignUpdateTime(qx::dao::detail::IxDao_Helper * pDaoHelper, void * pOwner)const
+{
+	qx::IxDataMemberX *pDataMembers = pDaoHelper->getDataMemberX();
+	QString timeFieldName;
+	if (pDataMembers->exist("UPDATETIME"))
+		timeFieldName = "UPDATETIME";
+    else if (pDataMembers->exist("IMPORTTIME"))
+		timeFieldName = "IMPORTTIME";
+	if (!timeFieldName.isEmpty())
+			pDataMembers->get(timeFieldName)->fromVariant(pOwner, QDateTime::currentDateTime());
+}

+ 22 - 0
DataManage/utils/SqlGenerator_Oracle.h

@@ -0,0 +1,22 @@
+#pragma once
+
+#include "QxOrm.h"
+
+class SqlGenerator_Oracle : public qx::dao::detail::QxSqlGenerator_Oracle
+{
+
+public:
+	SqlGenerator_Oracle();
+	~SqlGenerator_Oracle();
+
+	virtual void onBeforeInsert(qx::dao::detail::IxDao_Helper * pDaoHelper, void * pOwner) const;
+	//virtual void onAfterInsert(qx::dao::detail::IxDao_Helper * pDaoHelper, void * pOwner) const;
+	virtual void onBeforeUpdate(qx::dao::detail::IxDao_Helper * pDaoHelper, void * pOwner) const;
+	//virtual void onAfterUpdate(qx::dao::detail::IxDao_Helper * pDaoHelper, void * pOwner) const;
+	//virtual void onBeforeDelete(qx::dao::detail::IxDao_Helper * pDaoHelper, void * pOwner) const;
+	//virtual void onAfterDelete(qx::dao::detail::IxDao_Helper * pDaoHelper, void * pOwner) const;
+	//virtual void checkSqlInsert(qx::dao::detail::IxDao_Helper * pDaoHelper, QString & sql) const;
+	virtual void onBeforeSqlPrepare(qx::dao::detail::IxDao_Helper * pDaoHelper, QString & sql) const;
+private:
+	void autoAssignUpdateTime(qx::dao::detail::IxDao_Helper * pDaoHelper, void * pOwner)const;
+};

+ 3 - 0
DataManage/utils/charcode.h

@@ -0,0 +1,3 @@
+#if _MSC_VER >= 1600
+#pragma execution_character_set("utf-8")
+#endif

+ 85 - 0
DataManage/utils/excelinport.cpp

@@ -0,0 +1,85 @@
+#include "excelinport.h"
+#include "DebugUtil.h"
+#include "MessageException.h"
+#include "charcode.h"
+
+#include <QMessageBox>
+
+ExcelInport::ExcelInport(QObject *parent)
+	: QObject(parent)
+	, excel(nullptr)
+	, workbook(nullptr)
+	, currentWorkSheet(nullptr)
+	, startRow(-1)
+	, startColumn(-1)
+{
+}
+
+void ExcelInport::openExcel(const QString &filename)
+{
+	excel = new QAxObject("Excel.Application", this);
+    if(excel == nullptr)
+		throw MessageException("请安装office");
+
+    excel->dynamicCall("SetVisible(bool)",false);
+	QAxObject *workbooks = excel->querySubObject("Workbooks");
+	if (!workbooks)
+		throw MessageException("Excel打开失败");
+	workbook = workbooks->querySubObject("Open(QString,QVariant,QVariant)", filename, 3, true);
+	if (!workbook)
+		throw MessageException("Excel打开失败");
+	currentWorkSheet = workbook->querySubObject("WorkSheets(int)", 1);
+	if (!currentWorkSheet)
+		throw MessageException("打开Excel工作薄失败");
+	QAxObject *usedrange = currentWorkSheet->querySubObject("UsedRange");
+	startRow = usedrange->property("Row").toInt();
+	startColumn = usedrange->property("Column").toInt();
+}
+
+QAxObject *ExcelInport::getCurrentUserRange()
+{
+	return currentWorkSheet->querySubObject("UsedRange");
+}
+
+
+int ExcelInport::getRows()
+{
+	QAxObject *rowObj = getCurrentUserRange()->querySubObject("Rows");
+	return rowObj->property("Count").toInt();
+}
+
+int ExcelInport::getColumns()
+{
+	QAxObject *columnObj = getCurrentUserRange()->querySubObject("Columns");
+	return columnObj->property("Count").toInt();
+}
+
+QVariant ExcelInport::getValue(int row, int column)
+{
+	QAxObject *cell = currentWorkSheet->querySubObject("Cells(int,int)", row + startRow, column + startColumn );
+	if (cell)
+		return cell->property("Value");
+	return QVariant();
+}
+
+void ExcelInport::closeExcel()
+{
+	if (workbook != nullptr)
+	{
+		workbook->dynamicCall("Close(Boolean)", false);
+		workbook = nullptr;
+	}
+
+	if (excel != nullptr)
+	{
+		excel->dynamicCall("Quit()");
+		delete excel;
+		excel = nullptr;
+		currentWorkSheet = nullptr;
+		startRow = -1;
+		startColumn = -1;
+	}
+}
+
+
+

+ 34 - 0
DataManage/utils/excelinport.h

@@ -0,0 +1,34 @@
+#ifndef EXCELINPORT_H
+#define EXCELINPORT_H
+
+#include <QObject>
+#include <QAxObject>
+
+class ExcelInport : public QObject
+{
+    Q_OBJECT
+public:
+    explicit ExcelInport(QObject *parent = nullptr);
+
+    void openExcel(const QString &filename);
+
+    void closeExcel();
+
+	int getRows();
+
+	int getColumns();
+
+	QVariant getValue(int row, int column);
+
+private:
+	QAxObject *getCurrentUserRange();
+
+private:
+    QAxObject *excel;
+    QAxObject *workbook;
+	QAxObject *currentWorkSheet;
+
+	int startRow, startColumn;
+};
+
+#endif // EXCELINPORT_H

+ 11 - 0
DataManage/utils/regExp.h

@@ -0,0 +1,11 @@
+#ifndef REGEXP_H
+#define REGEXP_H
+
+/**
+* integer_size ÕûÊýλ¸öÊý
+* decimals_size СÊýλ¸öÊý
+ */
+#define REGEXP_DOUBLE(integer_size,decimals_size) QString("^([-+]?([0]|[1-9][0-9]{0,%1})[.][0-9]{0,%2})$").arg(integer_size-1).arg(decimals_size)
+#define REGEXP_INT(integer_size) QString("^[-+]?[0]|[1-9][0-9]{0,%1}$").arg(integer_size-1)
+
+#endif // REGEXP_H

+ 30 - 0
DataManage/utils/utils.h

@@ -0,0 +1,30 @@
+#pragma once
+
+#include "MessageException.h"
+
+#include <QString>
+#include <QFile>
+
+#if _MSC_VER >= 1600
+#pragma execution_character_set("utf-8")
+#endif
+
+class utils
+{
+public:
+	static const QString readFile(const QString &fileName)
+	{
+		QFile file(fileName);
+		if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
+            throw MessageException("读取文件失败!");
+
+		QString result;
+		while (!file.atEnd())
+		{
+			QByteArray line = file.readLine();
+			result.append(line);
+		}
+
+		return result;
+	}
+};

+ 333 - 0
DataManage/widgets/AdvancedTableView.cpp

@@ -0,0 +1,333 @@
+#include "AdvancedTableView.h"
+
+#include <QHBoxLayout>
+#include <QVBoxLayout>
+#include <QHeaderView>
+#include <QScrollBar>
+#include <QSqlQueryModel>
+#include <QMenu>
+
+
+#if _MSC_VER >= 1600
+#pragma execution_character_set("utf-8")
+#endif
+
+
+#define SELECTED_VIEW_DEFAULT_WIDTH		200					// 选择区默认宽度
+#define ROLE_PK							Qt::UserRole+1		// Role主键
+
+AdvancedTableView::AdvancedTableView(QWidget *parent)
+	: QTableView(parent)
+	, wgtContainer(nullptr)
+	, twSelected(nullptr)
+	, lblCounter(nullptr)
+	, btnExpand(nullptr)
+	, btnCollapse(nullptr)
+	, selectedViewState(Normal)
+	, multipleSelect(false)
+	, inited(false)
+	, selectedRecords(nullptr)
+{
+	// 设置默认样式
+	horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
+	setSelectionBehavior(QAbstractItemView::SelectRows);
+	setAlternatingRowColors(true);
+}
+
+AdvancedTableView::~AdvancedTableView()
+{
+	if (selectedRecords != nullptr)
+	{
+		delete selectedRecords;
+		selectedRecords = nullptr;
+	}
+	delete 	btnExpand;
+		delete btnCollapse;
+}			   	
+
+void AdvancedTableView::setMultipleSelect(bool value)
+{
+	if (value)
+	{
+		init();
+		wgtContainer->show();
+		multipleSelect = true;
+	}
+	else
+	{
+		//wgtContainer->hide();
+		multipleSelect = false;
+	}
+}
+
+const QStringList AdvancedTableView::getSelectedPKs()
+{
+	QStringList retval;
+
+	Q_ASSERT(!pkFieldName.isEmpty());
+
+	if (selectedRecords == nullptr)
+		return retval;
+
+	for (size_t i = 0; i < selectedRecords->length(); i++)
+	{
+		retval << selectedRecords->at(i).value(pkFieldName).toString();
+	}
+
+	return retval;
+}
+
+const QVariant AdvancedTableView::getSelectedPK()
+{
+	Q_ASSERT(!pkFieldName.isEmpty());
+
+	QVariant result;
+	QModelIndexList list = selectedIndexes();
+	if (list.count() <= 0)
+		return result;
+
+	QModelIndex index = this->selectionModel()->currentIndex();
+	QSqlQueryModel* sqm = (QSqlQueryModel*)model();
+	QSqlRecord record = sqm->record(index.row());
+	return record.value(pkFieldName);
+}
+
+const QSqlRecord AdvancedTableView::getSelectedRecord()
+{
+	QSqlRecord result;
+	QModelIndexList list = selectedIndexes();
+	if (list.count() <= 0)
+		return result;
+
+	QModelIndex index = this->selectionModel()->currentIndex();
+	QSqlQueryModel* sqm = (QSqlQueryModel*)model();
+	result = sqm->record(index.row());
+
+	return result;
+}
+
+void AdvancedTableView::resizeEvent(QResizeEvent *event)
+{
+	if (wgtContainer != nullptr)
+	{
+		wgtContainer->setGeometry(width() - SELECTED_VIEW_DEFAULT_WIDTH, 0, SELECTED_VIEW_DEFAULT_WIDTH, height());
+		selectedViewState = Normal;
+	}
+
+	//this->update();
+	QTableView::resizeEvent(event);
+}
+
+void AdvancedTableView::setModel(QAbstractItemModel *model)
+{
+	QTableView::setModel(model);
+
+	if (twSelected != nullptr)
+	{
+		cloneHeaderLabels();
+		connect(model, SIGNAL(checkStateChanged(Qt::CheckState, const QSqlRecord &)), this, SLOT(checkStateChanged(Qt::CheckState, const QSqlRecord &)), Qt::UniqueConnection);
+	}
+}
+
+void AdvancedTableView::checkStateChanged(Qt::CheckState state, const QSqlRecord &record)
+{
+	switch (state)
+	{
+	case Qt::Unchecked:
+		unselectRecord(record);
+		break;
+	case Qt::PartiallyChecked:
+		break;
+	case Qt::Checked:
+		selectRecord(record);
+		break;
+	}
+}
+
+void AdvancedTableView::expandSelectedView()
+{
+	if (selectedViewState == Normal)
+	{
+		int w = width() / 2;
+		wgtContainer->setGeometry(w, 0, w, height());
+		selectedViewState = Max;
+	}
+	else if (selectedViewState == Min)
+	{
+		wgtContainer->setGeometry(width() - SELECTED_VIEW_DEFAULT_WIDTH, 0, SELECTED_VIEW_DEFAULT_WIDTH, height());
+		selectedViewState = Normal;
+		twSelected->show();
+	}
+}
+
+void AdvancedTableView::collapseSelectedView()
+{
+	if (selectedViewState == Normal)
+	{
+		int w = 25;
+		if (verticalScrollBar()->isVisible())
+			w += verticalScrollBar()->width() + 10;
+
+		wgtContainer->setGeometry(width() - w, 0, w, height());
+		selectedViewState = Min;
+		twSelected->hide();
+	}
+	else if (selectedViewState == Max)
+	{
+		wgtContainer->setGeometry(width() - SELECTED_VIEW_DEFAULT_WIDTH, 0, SELECTED_VIEW_DEFAULT_WIDTH, height());
+		selectedViewState = Normal;
+	}
+}
+
+void AdvancedTableView::removeRow()
+{
+	if (twSelected == nullptr)
+		return;
+
+	QModelIndex index = twSelected->currentIndex();
+	twSelected->removeRow(index.row());
+	if (selectedRecords != nullptr)
+		selectedRecords->remove(index.row());
+
+	lblCounter->setText(QString::number(twSelected->rowCount()));
+	if (twSelected->rowCount() == 0)
+		lblCounter->hide();
+}
+
+void AdvancedTableView::init()
+{
+	if (inited)
+		return;
+
+	wgtContainer = new QWidget(this);
+	QHBoxLayout *layout = new QHBoxLayout(this);
+	QVBoxLayout *layoutButtn = new QVBoxLayout(this);
+	layout->setContentsMargins(0, 0, 0, 0);
+	layout->setSpacing(0);
+	layoutButtn->setContentsMargins(0, 0, 0, 3);
+	layoutButtn->setSpacing(3);
+	wgtContainer->setLayout(layout);
+
+	lblCounter = new QLabel(this);
+	//btnExpand = new QPushButton(this);
+	//btnCollapse = new QPushButton(this);
+	btnExpand = new QPushButton();
+	btnCollapse = new QPushButton();
+	btnExpand->setToolTip("展开");
+	btnCollapse->setToolTip("收起");
+	//btnExpand->setFixedSize(25, 16);
+	//btnCollapse->setFixedSize(25, 16);
+
+	lblCounter->setAlignment(Qt::AlignCenter);
+	lblCounter->setFixedSize(20, 20);
+	lblCounter->setStyleSheet("QLabel{ border-radius:10px; border:1px solid gray; background-color:white; font-size:10px; }");
+	lblCounter->hide();
+	btnExpand->setStyleSheet("QPushButton{border-image:url(resources/arrow_left.png); background-color:white;min-width:25;min-height:16; } QPushButton:hover{border-image:url(resources/arrow_left_hover.png)}");
+	btnCollapse->setStyleSheet("QPushButton{border-image:url(resources/arrow_right.png); background-color:white; min-width:25;min-height:16;}  QPushButton:hover{border-image:url(resources/arrow_right_hover.png)}");
+
+	layoutButtn->addStretch();
+	layoutButtn->addWidget(lblCounter);
+	layoutButtn->addWidget(btnExpand);
+	layoutButtn->addWidget(btnCollapse);
+	layoutButtn->addSpacing(16);
+	connect(btnExpand, &QPushButton::pressed, this, &AdvancedTableView::expandSelectedView);
+	connect(btnCollapse, &QPushButton::pressed, this, &AdvancedTableView::collapseSelectedView);
+
+	twSelected = new QTableWidget(this);
+	twSelected->setEditTriggers(QAbstractItemView::NoEditTriggers);
+	twSelected->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
+	twSelected->setSelectionBehavior(QAbstractItemView::SelectRows);
+	twSelected->setAlternatingRowColors(true);
+	twSelected->setContextMenuPolicy(Qt::CustomContextMenu);
+	twSelected->verticalHeader()->hide();
+
+	QMenu *menu = new QMenu(this);
+	menu->addAction("删除", this, SLOT(removeRow()));
+	connect(twSelected, &QTableView::customContextMenuRequested, [=](const QPoint &){
+		menu->exec(QCursor::pos());
+	});
+
+	layout->addLayout(layoutButtn);
+	layout->addWidget(twSelected);
+
+	wgtContainer->raise();
+
+
+	selectedRecords = new QVector<QSqlRecord>;
+
+	inited = true;
+}
+
+void AdvancedTableView::cloneHeaderLabels()
+{
+	QStringList headers;
+	for (int i = 0; i < model()->columnCount(); i++)
+	{
+		headers.append(model()->headerData(i, Qt::Horizontal).toString());
+	}
+
+	twSelected->setColumnCount(headers.count());
+	twSelected->setHorizontalHeaderLabels(headers);
+}
+
+void AdvancedTableView::selectRecord(const QSqlRecord &record)
+{
+	if (twSelected == nullptr)
+		return;
+
+	Q_ASSERT(!pkFieldName.isEmpty());
+
+	// 检查是否存在
+	for (size_t i = 0; i < twSelected->rowCount(); i++)
+	{
+		QTableWidgetItem *item = twSelected->item(i, 0);
+		if (item->data(ROLE_PK) == record.value(pkFieldName))
+		{
+			return;
+		}
+	}
+
+	int row = twSelected->rowCount();
+	twSelected->setRowCount(row + 1);
+
+	for (int col = 0; col < model()->columnCount(); col++)
+	{
+		QTableWidgetItem *item = new QTableWidgetItem(record.value(col).toString());
+		twSelected->setItem(row, col, item);
+
+		if (pkFieldName == record.fieldName(col))
+		{
+			item->setData(ROLE_PK, record.value(col));
+		}
+	}
+
+	if (selectedRecords != nullptr)
+		selectedRecords->append(record);
+
+	lblCounter->setText(QString::number(twSelected->rowCount()));
+	lblCounter->show();
+}
+
+void AdvancedTableView::unselectRecord(const QSqlRecord &record)
+{
+	if (twSelected == nullptr)
+		return;
+
+	Q_ASSERT(!pkFieldName.isEmpty());
+
+	for (size_t i = 0; i < twSelected->rowCount(); i++)
+	{
+		QTableWidgetItem *item = twSelected->item(i, 0);
+		if (item->data(ROLE_PK) == record.value(pkFieldName))
+		{
+			twSelected->removeRow(i);
+			if (selectedRecords != nullptr)
+				selectedRecords->remove(i);
+			break;
+		}
+
+	}
+	lblCounter->setText(QString::number(twSelected->rowCount()));
+	if (twSelected->rowCount() == 0)
+		lblCounter->hide();
+}

+ 60 - 0
DataManage/widgets/AdvancedTableView.h

@@ -0,0 +1,60 @@
+#pragma once
+
+#include <QTableView>
+#include <QTableWidget>
+#include <QSqlRecord>
+#include <QPushButton>
+#include <QLabel>
+#include <QSqlRecord>
+
+class AdvancedTableView : public QTableView
+{
+	Q_OBJECT
+
+	enum SelectedViewState {
+		Normal,
+		Max,
+		Min
+	};
+
+public:
+	AdvancedTableView(QWidget *parent);
+	~AdvancedTableView();
+
+	void setMultipleSelect(bool value);
+	void setPKFieldName(const QString &fieldName) { pkFieldName = fieldName; };
+	const QVector<QSqlRecord> *getSelectedRecords() { return selectedRecords; };
+	const QStringList getSelectedPKs();
+	const QVariant getSelectedPK();
+	const QSqlRecord getSelectedRecord();
+
+public:
+	void setModel(QAbstractItemModel *model) override;
+
+public slots:
+	void checkStateChanged(Qt::CheckState state, const QSqlRecord &);
+	void expandSelectedView();
+	void collapseSelectedView();
+	void removeRow();
+
+protected:
+	void resizeEvent(QResizeEvent *event) override;	
+
+private:
+	void init();
+	void cloneHeaderLabels();
+	void selectRecord(const QSqlRecord &record);
+	void unselectRecord(const QSqlRecord &record);
+
+private:
+	QWidget				*wgtContainer;
+	QTableWidget		*twSelected;
+	QLabel				*lblCounter;
+	QPushButton			*btnExpand;
+	QPushButton			*btnCollapse;
+	SelectedViewState	selectedViewState;
+	bool				multipleSelect;
+	bool				inited;
+	QString				pkFieldName;
+	QVector<QSqlRecord>	*selectedRecords;
+};

+ 39 - 0
DataManage/widgets/CustomDelegate.cpp

@@ -0,0 +1,39 @@
+#include "CustomDelegate.h"
+#include <QComboBox>
+#include <QDebug>
+
+CustomDelegate::CustomDelegate(QObject *parent)
+    : QItemDelegate(parent)
+    , factorys(new WidgetFactory(this))
+{
+}
+
+CustomDelegate::~CustomDelegate()
+{
+}
+
+QWidget * CustomDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
+{
+	qx::IxDataMember *dataMember = dataMembers->get(index.column());
+    if (dataMember->getPropertyBag("notEditAble").toBool())
+		return nullptr;
+	IxWidgetFactory_ptr facory = factorys->getFactory(dataMember);
+	facory->create(dataMember, parent);
+	return facory->getWidget();
+}
+
+void CustomDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
+{
+//	if (editor == nullptr)
+//		return;
+
+//    IxWidgetFactory_ptr facory = factorys->getFactory(dataMembers->get(index.column()));
+//	facory->getIxWidget()->setValue(index.model()->data(index));
+    QItemDelegate::setEditorData(editor,index);
+}
+
+void CustomDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
+{
+	IxWidgetFactory_ptr facory = factorys->getFactory(dataMembers->get(index.column()));
+	model->setData(index, facory->getIxWidget()->getValue());
+}

+ 31 - 0
DataManage/widgets/CustomDelegate.h

@@ -0,0 +1,31 @@
+#pragma once
+
+#include <qitemdelegate.h>
+#include "QxOrm.h"
+#include "IxWidget.h"
+#include "WidgetFactory.h"
+
+class CustomDelegate : public QItemDelegate
+{
+	Q_OBJECT
+
+public:
+	CustomDelegate(QObject *parent = nullptr);
+	~CustomDelegate();
+
+	template<typename T>
+	void setClass()
+	{
+		dataMembers = qx::QxClass<T>::getSingleton()->getDataMemberX();
+	}
+
+	QWidget * createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
+
+	void setEditorData(QWidget *editor, const QModelIndex &index) const override;
+
+	void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override;
+
+private:
+	qx::IxDataMemberX *dataMembers;
+	WidgetFactory *factorys;
+};

+ 37 - 0
DataManage/widgets/DialogTemplate.cpp

@@ -0,0 +1,37 @@
+#include "DialogTemplate.h"
+#include "FramelessHelper.h"
+
+#include <QVBoxLayout>
+
+DialogTemplate::DialogTemplate(QWidget *contentWidget, QWidget *parent)
+	: QDialog(parent)
+	, m_pTitleBar(new TitleBar(this, false))
+{
+	Q_ASSERT(contentWidget != nullptr);
+	
+	setAttribute(Qt::WA_TranslucentBackground);
+
+	FramelessHelper *pHelper = new FramelessHelper(this);
+	pHelper->setTitleHeight(m_pTitleBar->height());
+
+	QVBoxLayout *layout = new QVBoxLayout(this);
+	layout->setMargin(0);
+	layout->setContentsMargins(0, 0, 0, 0);
+	layout->setSpacing(0);
+	layout->addWidget(m_pTitleBar);
+	layout->addWidget(contentWidget);
+	setLayout(layout);
+
+	//setStyleSheet("DialogTemplate{background-color:#535353; padding:1px;}");
+	contentWidget->setObjectName("contentWidget");
+    contentWidget->setStyleSheet("#contentWidget{border:1px solid #535353; border-top:0px; border-bottom-left-radius:5px; border-bottom-right-radius:5px;background-color:white;}");
+	m_pTitleBar->setObjectName("titleBar");
+	m_pTitleBar->setStyleSheet("\
+		#titleBar{background-color:#2d2d30; border:1px solid #535353; border-bottom:0px; border-top-left-radius:5px; border-top-right-radius:5px;}\
+		QLabel{color:#eeeeee}\
+		#SACloseWindowButton{border-top-right-radius:5px;}");
+}
+
+DialogTemplate::~DialogTemplate()
+{
+}

+ 17 - 0
DataManage/widgets/DialogTemplate.h

@@ -0,0 +1,17 @@
+#pragma once
+
+#include <QDialog>
+
+#include "TitleBar.h"
+
+class DialogTemplate : public QDialog
+{
+	Q_OBJECT
+
+public:
+	DialogTemplate(QWidget *contentWidget, QWidget *parent);
+	~DialogTemplate();
+
+private:
+	TitleBar *m_pTitleBar;
+};

+ 647 - 0
DataManage/widgets/FramelessHelper.cpp

@@ -0,0 +1,647 @@
+#include "FramelessHelper.h"
+#include <QRect>
+#include <QRubberBand>
+#include <QMouseEvent>
+#include <QHoverEvent>
+#include <QApplication>
+
+class WidgetData;
+/*****
+ * FramelessHelperPrivate
+ * 存储界面对应的数据集合,以及是否可移动、可缩放属性
+*****/
+class FramelessHelperPrivate
+{
+public:
+    QHash<QWidget*, WidgetData*> m_widgetDataHash;
+    bool m_bWidgetMovable        : true;
+    bool m_bWidgetResizable      : true;
+    bool m_bRubberBandOnResize   : true;
+    bool m_bRubberBandOnMove     : true;
+};
+/*****
+ * CursorPosCalculator
+ * 计算鼠标是否位于左、上、右、下、左上角、左下角、右上角、右下角
+*****/
+class CursorPosCalculator
+{
+public:
+    explicit CursorPosCalculator();
+    void reset();
+    void recalculate(const QPoint &globalMousePos, const QRect &frameRect);
+
+public:
+    bool m_bOnEdges              : true;
+    bool m_bOnLeftEdge           : true;
+    bool m_bOnRightEdge          : true;
+    bool m_bOnTopEdge            : true;
+    bool m_bOnBottomEdge         : true;
+    bool m_bOnTopLeftEdge        : true;
+    bool m_bOnBottomLeftEdge     : true;
+    bool m_bOnTopRightEdge       : true;
+    bool m_bOnBottomRightEdge    : true;
+
+    static int m_nBorderWidth;
+    static int m_nTitleHeight;
+};
+
+int CursorPosCalculator::m_nBorderWidth = 5;
+int CursorPosCalculator::m_nTitleHeight = 30;
+
+/***** CursorPosCalculator *****/
+CursorPosCalculator::CursorPosCalculator()
+{
+    reset();
+}
+
+void CursorPosCalculator::reset()
+{
+    m_bOnEdges = false;
+    m_bOnLeftEdge = false;
+    m_bOnRightEdge = false;
+    m_bOnTopEdge = false;
+    m_bOnBottomEdge = false;
+    m_bOnTopLeftEdge = false;
+    m_bOnBottomLeftEdge = false;
+    m_bOnTopRightEdge  = false;
+    m_bOnBottomRightEdge = false;
+}
+
+void CursorPosCalculator::recalculate(const QPoint &gMousePos, const QRect &frameRect)
+{
+    int globalMouseX = gMousePos.x();
+    int globalMouseY = gMousePos.y();
+
+    int frameX = frameRect.x();
+    int frameY = frameRect.y();
+
+    int frameWidth = frameRect.width();
+    int frameHeight = frameRect.height();
+
+    m_bOnLeftEdge = (globalMouseX >= frameX &&
+                  globalMouseX <= frameX + m_nBorderWidth );
+
+
+    m_bOnRightEdge = (globalMouseX >= frameX + frameWidth - m_nBorderWidth &&
+                   globalMouseX <= frameX + frameWidth);
+
+    m_bOnTopEdge = (globalMouseY >= frameY &&
+                 globalMouseY <= frameY + m_nBorderWidth );
+
+    m_bOnBottomEdge = (globalMouseY >= frameY + frameHeight - m_nBorderWidth &&
+                    globalMouseY <= frameY + frameHeight);
+
+    m_bOnTopLeftEdge = m_bOnTopEdge && m_bOnLeftEdge;
+    m_bOnBottomLeftEdge = m_bOnBottomEdge && m_bOnLeftEdge;
+    m_bOnTopRightEdge = m_bOnTopEdge && m_bOnRightEdge;
+    m_bOnBottomRightEdge = m_bOnBottomEdge && m_bOnRightEdge;
+
+    m_bOnEdges = m_bOnLeftEdge || m_bOnRightEdge || m_bOnTopEdge || m_bOnBottomEdge;
+}
+
+/*****
+ * WidgetData
+ * 更新鼠标样式、移动窗体、缩放窗体
+*****/
+class WidgetData
+{
+public:
+    explicit WidgetData(FramelessHelperPrivate *d, QWidget *pTopLevelWidget);
+    ~WidgetData();
+    QWidget* widget();
+    // 处理鼠标事件-划过、按下、释放、移动
+    bool handleWidgetEvent(QEvent *event);
+    // 更新橡皮筋状态
+    void updateRubberBandStatus();
+
+private:
+    // 更新鼠标样式
+    void updateCursorShape(const QPoint &gMousePos);
+    // 重置窗体大小
+    void resizeWidget(const QPoint &gMousePos);
+    // 移动窗体
+    void moveWidget(const QPoint &gMousePos);
+    // 处理鼠标按下
+    bool handleMousePressEvent(QMouseEvent *event);
+    // 处理鼠标释放
+    bool handleMouseReleaseEvent(QMouseEvent *event);
+    // 处理鼠标移动
+    bool handleMouseMoveEvent(QMouseEvent *event);
+    // 处理鼠标离开
+    bool handleLeaveEvent(QEvent *event);
+    // 处理鼠标进入
+    bool handleHoverMoveEvent(QHoverEvent *event);
+    //处理鼠标双击事件
+    bool handleDoubleClickedMouseEvent(QMouseEvent *event);
+
+private:
+    FramelessHelperPrivate *d;
+    QRubberBand *m_pRubberBand;
+    QWidget *m_pWidget;
+    QPoint m_ptDragPos;
+    CursorPosCalculator m_pressedMousePos;
+    CursorPosCalculator m_moveMousePos;
+    bool m_bLeftButtonPressed;
+    bool m_bCursorShapeChanged;
+    bool m_bLeftButtonTitlePressed;
+    Qt::WindowFlags m_windowFlags;
+};
+
+/***** WidgetData *****/
+WidgetData::WidgetData(FramelessHelperPrivate *_d, QWidget *pTopLevelWidget)
+{
+    d = _d;
+    m_pWidget = pTopLevelWidget;
+    m_bLeftButtonPressed = false;
+    m_bCursorShapeChanged = false;
+    m_bLeftButtonTitlePressed = false;
+    m_pRubberBand = NULL;
+
+    m_windowFlags = m_pWidget->windowFlags();
+    m_pWidget->setMouseTracking(true);
+    m_pWidget->setAttribute(Qt::WA_Hover, true);
+
+    updateRubberBandStatus();
+}
+
+WidgetData::~WidgetData()
+{
+    m_pWidget->setMouseTracking(false);
+    m_pWidget->setWindowFlags(m_windowFlags);
+    m_pWidget->setAttribute(Qt::WA_Hover, false);
+
+    delete m_pRubberBand;
+    m_pRubberBand = NULL;
+}
+
+QWidget* WidgetData::widget()
+{
+    return m_pWidget;
+}
+
+bool WidgetData::handleWidgetEvent(QEvent *event)
+{
+    switch (event->type())
+    {
+    case QEvent::MouseButtonPress:
+        return handleMousePressEvent(static_cast<QMouseEvent*>(event));
+    case QEvent::MouseButtonRelease:
+        return handleMouseReleaseEvent(static_cast<QMouseEvent*>(event));
+    case QEvent::MouseMove:
+        return handleMouseMoveEvent(static_cast<QMouseEvent*>(event));
+    case QEvent::Leave:
+        return handleLeaveEvent(static_cast<QMouseEvent*>(event));
+    case QEvent::HoverMove:
+        return handleHoverMoveEvent(static_cast<QHoverEvent*>(event));
+    case QEvent::MouseButtonDblClick:
+        return handleDoubleClickedMouseEvent(static_cast<QMouseEvent*>(event));
+    default:
+        break;
+    }
+    return false;
+}
+
+void WidgetData::updateRubberBandStatus()
+{
+    if (d->m_bRubberBandOnMove || d->m_bRubberBandOnResize)
+    {
+        if (NULL == m_pRubberBand)
+            m_pRubberBand = new QRubberBand(QRubberBand::Rectangle);
+    }
+    else
+    {
+        delete m_pRubberBand;
+        m_pRubberBand = NULL;
+    }
+}
+
+void WidgetData::updateCursorShape(const QPoint &gMousePos)
+{
+    if (m_pWidget->isFullScreen() || m_pWidget->isMaximized())
+    {
+        if (m_bCursorShapeChanged)
+        {
+            m_pWidget->unsetCursor();
+        }
+        return;
+    }
+
+    m_moveMousePos.recalculate(gMousePos, m_pWidget->frameGeometry());
+
+    if(m_moveMousePos.m_bOnTopLeftEdge || m_moveMousePos.m_bOnBottomRightEdge)
+    {
+        m_pWidget->setCursor( Qt::SizeFDiagCursor );
+        m_bCursorShapeChanged = true;
+    }
+    else if(m_moveMousePos.m_bOnTopRightEdge || m_moveMousePos.m_bOnBottomLeftEdge)
+    {
+        m_pWidget->setCursor( Qt::SizeBDiagCursor );
+        m_bCursorShapeChanged = true;
+    }
+    else if(m_moveMousePos.m_bOnLeftEdge || m_moveMousePos.m_bOnRightEdge)
+    {
+        m_pWidget->setCursor( Qt::SizeHorCursor );
+        m_bCursorShapeChanged = true;
+    }
+    else if(m_moveMousePos.m_bOnTopEdge || m_moveMousePos.m_bOnBottomEdge)
+    {
+        m_pWidget->setCursor( Qt::SizeVerCursor );
+        m_bCursorShapeChanged = true;
+    }
+    else
+    {
+        if (m_bCursorShapeChanged)
+        {
+            m_pWidget->unsetCursor();
+            m_bCursorShapeChanged = false;
+        }
+    }
+}
+
+void WidgetData::resizeWidget(const QPoint &gMousePos)
+{
+    QRect origRect;
+
+    if (d->m_bRubberBandOnResize)
+        origRect = m_pRubberBand->frameGeometry();
+    else
+        origRect = m_pWidget->frameGeometry();
+
+    int left = origRect.left();
+    int top = origRect.top();
+    int right = origRect.right();
+    int bottom = origRect.bottom();
+    origRect.getCoords(&left, &top, &right, &bottom);
+
+    int minWidth = m_pWidget->minimumWidth();
+    int minHeight = m_pWidget->minimumHeight();
+
+    if (m_pressedMousePos.m_bOnTopLeftEdge)
+    {
+        left = gMousePos.x();
+        top = gMousePos.y();
+    }
+    else if (m_pressedMousePos.m_bOnBottomLeftEdge)
+    {
+        left = gMousePos.x();
+        bottom = gMousePos.y();
+    }
+    else if (m_pressedMousePos.m_bOnTopRightEdge)
+    {
+        right = gMousePos.x();
+        top = gMousePos.y();
+    }
+    else if (m_pressedMousePos.m_bOnBottomRightEdge)
+    {
+        right = gMousePos.x();
+        bottom = gMousePos.y();
+    }
+    else if (m_pressedMousePos.m_bOnLeftEdge)
+    {
+        left = gMousePos.x();
+    }
+    else if (m_pressedMousePos.m_bOnRightEdge)
+    {
+        right = gMousePos.x();
+    }
+    else if (m_pressedMousePos.m_bOnTopEdge)
+    {
+        top = gMousePos.y();
+    }
+    else if (m_pressedMousePos.m_bOnBottomEdge)
+    {
+        bottom = gMousePos.y();
+    }
+
+    QRect newRect(QPoint(left, top), QPoint(right, bottom));
+
+    if (newRect.isValid())
+    {
+        if (minWidth > newRect.width())
+        {
+            if (left != origRect.left())
+                newRect.setLeft(origRect.left());
+            else
+                newRect.setRight(origRect.right());
+        }
+        if (minHeight > newRect.height())
+        {
+            if (top != origRect.top())
+                newRect.setTop(origRect.top());
+            else
+                newRect.setBottom(origRect.bottom());
+        }
+
+        if (d->m_bRubberBandOnResize)
+        {
+            m_pRubberBand->setGeometry(newRect);
+        }
+        else
+        {
+            m_pWidget->setGeometry(newRect);
+        }
+    }
+}
+
+void WidgetData::moveWidget(const QPoint& gMousePos)
+{
+    if (d->m_bRubberBandOnMove)
+    {
+        m_pRubberBand->move(gMousePos - m_ptDragPos);
+    }
+    else
+    {
+        m_pWidget->move(gMousePos - m_ptDragPos);
+    }
+}
+
+bool WidgetData::handleMousePressEvent(QMouseEvent *event)
+{
+    if (event->button() == Qt::LeftButton)
+    {
+        m_bLeftButtonPressed = true;
+        m_bLeftButtonTitlePressed = event->pos().y() < m_moveMousePos.m_nTitleHeight;
+
+        QRect frameRect = m_pWidget->frameGeometry();
+        m_pressedMousePos.recalculate(event->globalPos(), frameRect);
+
+        m_ptDragPos = event->globalPos() - frameRect.topLeft();
+
+        if (m_pressedMousePos.m_bOnEdges)
+        {
+            if(m_pWidget->isMaximized())
+            {
+                //窗口在最大化状态时,点击边界不做任何处理
+                return false;
+            }
+            if (d->m_bRubberBandOnResize)
+            {
+                m_pRubberBand->setGeometry(frameRect);
+                m_pRubberBand->show();
+                return true;
+            }
+        }
+        else if (d->m_bRubberBandOnMove && m_bLeftButtonTitlePressed)
+        {
+            if(m_pWidget->isMaximized())
+            {
+                //窗口在最大化状态时,点击标题栏不做任何处理
+                return false;
+            }
+            m_pRubberBand->setGeometry(frameRect);
+            m_pRubberBand->show();
+            return true;
+        }
+    }
+    return false;
+}
+
+bool WidgetData::handleMouseReleaseEvent(QMouseEvent *event)
+{
+    if (event->button() == Qt::LeftButton)
+    {
+        m_bLeftButtonPressed = false;
+        m_bLeftButtonTitlePressed = false;
+        m_pressedMousePos.reset();
+        if (m_pRubberBand && m_pRubberBand->isVisible())
+        {
+            m_pRubberBand->hide();
+            m_pWidget->setGeometry(m_pRubberBand->geometry());
+            return true;
+        }
+    }
+    return false;
+}
+
+bool WidgetData::handleMouseMoveEvent(QMouseEvent *event)
+{
+    if (m_bLeftButtonPressed)
+    {
+        if (d->m_bWidgetResizable && m_pressedMousePos.m_bOnEdges)
+        {
+            if(m_pWidget->isMaximized())
+            {
+                //窗口在最大化状态时,点击边界不做任何处理
+                return false;
+            }
+            resizeWidget(event->globalPos());
+            return true;
+        }
+        else if (d->m_bWidgetMovable && m_bLeftButtonTitlePressed)
+        {
+            if(m_pWidget->isMaximized())
+            {
+                //窗口在最大化状态时,点击标题栏不做任何处理
+                return false;
+            }
+            moveWidget(event->globalPos());
+            return true;
+        }
+        return false;
+    }
+    else if (d->m_bWidgetResizable)
+    {
+        updateCursorShape(event->globalPos());
+    }
+    return false;
+}
+
+bool WidgetData::handleLeaveEvent(QEvent *event)
+{
+    Q_UNUSED(event)
+    if (!m_bLeftButtonPressed)
+    {
+        m_pWidget->unsetCursor();
+        return true;
+    }
+    return false;
+}
+
+bool WidgetData::handleHoverMoveEvent(QHoverEvent *event)
+{
+    if (d->m_bWidgetResizable)
+    {
+        updateCursorShape(m_pWidget->mapToGlobal(event->pos()));
+    }
+    return false;
+}
+
+bool WidgetData::handleDoubleClickedMouseEvent(QMouseEvent *event)
+{
+    if(event->button() == Qt::LeftButton)
+    {
+        if(m_pWidget)
+        {
+            bool titlePressed = event->pos().y() < m_moveMousePos.m_nTitleHeight;
+            if(titlePressed)
+            {
+                if(m_pWidget->isMaximized())
+                {
+                    m_pWidget->showNormal();
+                }
+                else
+                {
+                    m_pWidget->showMaximized();
+                }
+                return true;
+            }
+        }
+    }
+    return false;
+}
+
+FramelessHelper::FramelessHelper(QObject *parent)
+    : QObject(parent),
+      d(new FramelessHelperPrivate())
+{
+    d->m_bWidgetMovable = true;
+    d->m_bWidgetResizable = true;
+    d->m_bRubberBandOnResize = false;
+    d->m_bRubberBandOnMove = false;
+    if(parent)
+    {
+        QWidget* w = qobject_cast<QWidget*>(parent);
+        if(w)
+        {
+            w->setWindowFlags(w->windowFlags()|Qt::FramelessWindowHint);
+            setWidgetMovable(true);  //设置窗体可移动
+            setWidgetResizable(true);  //设置窗体可缩放
+            setRubberBandOnMove(true);  //设置橡皮筋效果-可移动
+            setRubberBandOnResize(true);  //设置橡皮筋效果-可缩放
+            activateOn(w);  //激活当前窗体
+        }
+    }
+}
+
+FramelessHelper::~FramelessHelper()
+{
+    QList<QWidget*> keys = d->m_widgetDataHash.keys();
+    int size = keys.size();
+    for (int i = 0; i < size; ++i)
+    {
+        delete d->m_widgetDataHash.take(keys[i]);
+    }
+
+    delete d;
+}
+
+bool FramelessHelper::eventFilter(QObject *obj, QEvent *event)
+{
+    switch (event->type())
+    {
+    case QEvent::MouseMove:
+    case QEvent::HoverMove:
+    case QEvent::MouseButtonPress:
+    case QEvent::MouseButtonRelease:
+    case QEvent::MouseButtonDblClick:
+    case QEvent::Leave:
+    {
+        WidgetData *data = d->m_widgetDataHash.value(static_cast<QWidget*>(obj));
+        if (data)
+        {
+            return data->handleWidgetEvent(event);
+        }
+        break;
+    }
+    default:
+        break;
+    }
+    return QObject::eventFilter(obj, event);
+}
+
+void FramelessHelper::activateOn(QWidget *topLevelWidget)
+{
+    if (!d->m_widgetDataHash.contains(topLevelWidget))
+    {
+        WidgetData *data = new WidgetData(d, topLevelWidget);
+        d->m_widgetDataHash.insert(topLevelWidget, data);
+
+        topLevelWidget->installEventFilter(this);
+    }
+}
+
+void FramelessHelper::removeFrom(QWidget *topLevelWidget)
+{
+    WidgetData *data = d->m_widgetDataHash.take(topLevelWidget);
+    if (data)
+    {
+        topLevelWidget->removeEventFilter(this);
+        delete data;
+    }
+}
+
+void FramelessHelper::setRubberBandOnMove(bool movable)
+{
+    d->m_bRubberBandOnMove = movable;
+    QList<WidgetData*> list = d->m_widgetDataHash.values();
+    foreach (WidgetData *data, list)
+    {
+        data->updateRubberBandStatus();
+    }
+}
+
+void FramelessHelper::setWidgetMovable(bool movable)
+{
+    d->m_bWidgetMovable = movable;
+}
+
+void FramelessHelper::setWidgetResizable(bool resizable)
+{
+    d->m_bWidgetResizable = resizable;
+}
+
+void FramelessHelper::setRubberBandOnResize(bool resizable)
+{
+    d->m_bRubberBandOnResize = resizable;
+    QList<WidgetData*> list = d->m_widgetDataHash.values();
+    foreach (WidgetData *data, list)
+    {
+        data->updateRubberBandStatus();
+    }
+}
+
+void FramelessHelper::setBorderWidth(uint width)
+{
+    if (width > 0)
+    {
+        CursorPosCalculator::m_nBorderWidth = width;
+    }
+}
+
+void FramelessHelper::setTitleHeight(uint height)
+{
+    if (height > 0)
+    {
+        CursorPosCalculator::m_nTitleHeight = height;
+    }
+}
+
+bool FramelessHelper::widgetMovable()
+{
+    return d->m_bWidgetMovable;
+}
+
+bool FramelessHelper::widgetResizable()
+{
+    return d->m_bWidgetResizable;
+}
+
+bool FramelessHelper::rubberBandOnMove()
+{
+    return d->m_bRubberBandOnMove;
+}
+
+bool FramelessHelper::rubberBandOnResisze()
+{
+    return d->m_bRubberBandOnResize;
+}
+
+uint FramelessHelper::borderWidth()
+{
+    return CursorPosCalculator::m_nBorderWidth;
+}
+
+uint FramelessHelper::titleHeight()
+{
+    return CursorPosCalculator::m_nTitleHeight;
+}

+ 48 - 0
DataManage/widgets/FramelessHelper.h

@@ -0,0 +1,48 @@
+#ifndef FRAMELESSHELPER_H
+#define FRAMELESSHELPER_H
+
+
+#include <QObject>
+
+class QWidget;
+class FramelessHelperPrivate;
+
+class FramelessHelper : public QObject
+{
+    Q_OBJECT
+
+public:
+    explicit FramelessHelper(QObject *parent);
+    ~FramelessHelper();
+    // 激活窗体
+    void activateOn(QWidget *topLevelWidget);
+    // 移除窗体
+    void removeFrom(QWidget *topLevelWidget);
+    // 设置窗体移动
+    void setWidgetMovable(bool movable);
+    // 设置窗体缩放
+    void setWidgetResizable(bool resizable);
+    // 设置橡皮筋移动
+    void setRubberBandOnMove(bool movable);
+    // 设置橡皮筋缩放
+    void setRubberBandOnResize(bool resizable);
+    // 设置边框的宽度
+    void setBorderWidth(uint width);
+    // 设置标题栏高度
+    void setTitleHeight(uint height);
+    bool widgetResizable();
+    bool widgetMovable();
+    bool rubberBandOnMove();
+    bool rubberBandOnResisze();
+    uint borderWidth();
+    uint titleHeight();
+
+protected:
+    // 事件过滤,进行移动、缩放等
+    virtual bool eventFilter(QObject *obj, QEvent *event);
+
+private:
+    FramelessHelperPrivate *d;
+};
+
+#endif // FRAMELESSHELPER_H

+ 33 - 0
DataManage/widgets/IxWidgets/AutoCompleteComBoxWidget.cpp

@@ -0,0 +1,33 @@
+#include "AutoCompleteComBoxWidget.h"
+
+#include <QCompleter>
+#include <QLineEdit>
+
+const QString AutoCompleteComBoxWidget::type = "AutoCompleteComBox";
+
+AutoCompleteComBoxWidget::AutoCompleteComBoxWidget(QWidget *parent)
+    : ComboBoxWidget(parent)
+{
+	setEditable(true);
+}
+
+AutoCompleteComBoxWidget::~AutoCompleteComBoxWidget()
+{
+}
+
+void AutoCompleteComBoxWidget::setOptions(const QVariantMap &options)
+{
+	ComboBoxWidget::setOptions(options);
+
+	QCompleter *completer = new QCompleter(options.keys(), this);
+	completer->setCompletionMode(QCompleter::PopupCompletion);
+	completer->setFilterMode(Qt::MatchContains);
+	setCompleter(completer);
+}
+
+void AutoCompleteComBoxWidget::clear()
+{
+	ComboBoxWidget::clear();
+	lineEdit()->clear();
+}
+

+ 22 - 0
DataManage/widgets/IxWidgets/AutoCompleteComBoxWidget.h

@@ -0,0 +1,22 @@
+#pragma once
+
+#include <QComboBox>
+#include "ComboBoxWidget.h"
+#include "IxWidget.h"
+
+class AutoCompleteComBoxWidget : public ComboBoxWidget// , IxWidget
+{
+	Q_OBJECT
+public:
+	static const QString type;
+
+public:
+	AutoCompleteComBoxWidget(QWidget *parent = nullptr);
+
+	~AutoCompleteComBoxWidget();
+
+	void setOptions(const QVariantMap &options);
+
+	virtual void clear();
+
+};

+ 151 - 0
DataManage/widgets/IxWidgets/AutoCompleteTagEditWidget.cpp

@@ -0,0 +1,151 @@
+#include "AutoCompleteTagEditWidget.h"
+
+#include <QCompleter>
+#include <QStringListModel>
+#include <QTimer>
+#include <QMessageBox>
+#include <QEvent>
+#include <QDebug>
+
+#if _MSC_VER >= 1600
+#pragma execution_character_set("utf-8")
+#endif
+
+
+const QString AutoCompleteTagEditWidget::type = "AutoCompleteTagEdit";
+
+AutoCompleteTagEditWidget::AutoCompleteTagEditWidget(QWidget *parent)
+: TagEditWidget(parent)
+{
+    init();
+}
+
+void AutoCompleteTagEditWidget::init()
+{
+    QCompleter *completer = new QCompleter(this);
+    QStringListModel *slm = new QStringListModel(this);
+    completer->setModel(slm);
+    completer->setCaseSensitivity(Qt::CaseInsensitive);
+    setCompleter(completer);
+
+    connect(completer, SIGNAL(activated(const QString &)), this, SLOT(onItemSlected(const QString &)));
+	disconnect(this, &QLineEdit::returnPressed, this, &TagEditWidget::onEnter);
+
+	installEventFilter(this);
+}
+
+void AutoCompleteTagEditWidget::setObjectName(const QString &name)
+{
+    QObject::setObjectName(name);
+    setName(name);
+
+    QVariant property;
+    property.setValue(static_cast<IxWidget*>(this));
+    setProperty("IxWidget",property);
+}
+
+void AutoCompleteTagEditWidget::setOptions(QVariantMap options)
+{
+    QStringListModel *slm = (QStringListModel*)this->completer()->model();
+
+    if(!options.isEmpty())
+    {
+        QStringList texts;
+		for (auto iterOption = options.begin(); iterOption != options.end(); iterOption++)
+		{
+			texts << iterOption.key();
+        }
+        slm->setStringList(texts);
+		this->options = options;
+    }
+}
+
+void AutoCompleteTagEditWidget::onEnter()
+{
+	QString str = text().trimmed();
+	if (str.isEmpty())
+		return;
+
+	if (!options.contains(str))
+	{
+		QMessageBox::warning(nullptr, "提示", QString("输入的值无效,请从检索结果中选择!"));
+		clear();
+		return;
+	}
+
+	addTag(str);
+}
+
+void AutoCompleteTagEditWidget::onItemSlected(const QString &text)
+{
+    addTag(text);
+    QTimer::singleShot(100, this, SLOT(clear()));
+}
+
+bool AutoCompleteTagEditWidget::eventFilter(QObject * watched, QEvent * event)
+{
+	if (event->type() == QEvent::FocusOut) {
+		onEnter();
+		return true;
+	}
+
+	return QLineEdit::eventFilter(watched, event);
+}
+
+void AutoCompleteTagEditWidget::addTag(const QString &text)
+{
+	TagEditWidget::addTag(text);
+}
+
+QStringList AutoCompleteTagEditWidget::getTextList()
+{
+    QStringList texts;
+    Tag *tag;
+
+    foreach(tag, tags)
+    {
+        texts << tag->text();
+    }
+
+    return texts;
+}
+
+QStringList AutoCompleteTagEditWidget::getValueList()
+{
+    QStringList values;
+    Tag *tag;
+
+    foreach(tag, tags)
+    {
+        values << options[tag->text()].toString();
+    }
+
+    return values;
+}
+
+void AutoCompleteTagEditWidget::setValueList(const QStringList &values)
+{
+	clear();
+	for (int i = 0; i < values.length(); i++)
+	{
+		for (auto iterOption = options.begin(); iterOption != options.end(); iterOption++)
+		{
+			if (iterOption.value() == values[i])
+			{
+				addTag(iterOption.key());
+				break;
+			}
+		}
+	}
+}
+
+
+QVariant AutoCompleteTagEditWidget::getValue()
+{
+	return getValueList().join(",");
+}
+
+void AutoCompleteTagEditWidget::setValue(const QVariant &value)
+{
+	setValueList(value.toString().split(","));
+}

+ 45 - 0
DataManage/widgets/IxWidgets/AutoCompleteTagEditWidget.h

@@ -0,0 +1,45 @@
+#ifndef AUTOCOMPLETETAGEDIT_H
+#define AUTOCOMPLETETAGEDIT_H
+
+#include "TagEditWidget.h"
+#include "IxWidgetFactory.h"
+
+class AutoCompleteTagEditWidget : public TagEditWidget
+{
+    Q_OBJECT
+public:
+	static const QString type;
+
+public:
+	explicit AutoCompleteTagEditWidget(QWidget *parent = nullptr);
+
+    void setObjectName(const QString &name);
+
+	QVariant getValue();
+
+	void setValue(const QVariant &value) override;
+
+	void setOptions(QVariantMap options);
+
+    QStringList getTextList();
+    QStringList getValueList();
+	void setValueList(const QStringList &values);
+
+protected:
+	bool eventFilter(QObject * watched, QEvent * event) override;
+	void addTag(const QString &text);
+
+private:
+    void init();
+
+public slots:
+	void onEnter();
+
+private slots:
+    void onItemSlected(const QString &text);
+
+private:
+	QVariantMap options;
+};
+
+#endif // AUTOCOMPLETETAGEDIT_H

+ 86 - 0
DataManage/widgets/IxWidgets/CheckComboBoxWidget.cpp

@@ -0,0 +1,86 @@
+#include "CheckComboBoxWidget.h"
+
+#include <QAbstractItemView>
+#include <QMouseEvent>
+#include <QLineEdit>
+
+const QString CheckComboBoxWidget::type = "CheckComboBox";
+
+CheckComboBoxWidget::CheckComboBoxWidget(QWidget *parent)
+    :ComboBoxWidget(parent)
+{
+    view()->viewport()->installEventFilter(this);
+    setEditable(true);
+}
+
+QVariant CheckComboBoxWidget::getValue() const
+{
+    return dictValues.join(_delimiter);
+}
+
+void CheckComboBoxWidget::setValue(const QVariant& value)
+{
+    foreach(auto & var, value.toList())
+    {
+        dictValues << var.toString();
+    }
+    lineEdit()->setText(dictValues.join(_delimiter));
+}
+
+bool CheckComboBoxWidget::isValueNull() const
+{
+    return dictValues.size();
+}
+
+void CheckComboBoxWidget::clearInput()
+{
+    dictValues.clear();
+    lineEdit()->clear();
+    for (int i = 0; i < count(); i++)
+    {
+        setItemData(i,false,Qt::CheckStateRole);
+    }
+}
+
+
+bool CheckComboBoxWidget::eventFilter(QObject * watched, QEvent * event)
+{
+    if (event->type() == QEvent::MouseButtonRelease)
+    {
+        QModelIndex ind = view()->indexAt(((QMouseEvent*)event)->pos());
+        bool checked = view()->model()->data(ind, Qt::CheckStateRole).toBool();
+        view()->model()->setData(ind, !checked, Qt::CheckStateRole);
+        return true;
+    }
+    return QObject::eventFilter(watched, event);
+}
+
+void CheckComboBoxWidget::hidePopup()
+{
+    QStringList values;
+    dictValues.clear();
+    for (int i = 0; i < count(); i++)
+    {
+        if (itemData(i, Qt::CheckStateRole).toBool())
+        {
+            values << itemText(i);
+            dictValues << itemData(i).toString();
+            setCurrentIndex(i);
+        }
+    }
+    setCurrentText(values.join(_delimiter));
+    emit selectedText(values);
+    QComboBox::hidePopup();
+}
+
+void CheckComboBoxWidget::showPopup()
+{
+    QStringList values = currentText().split(_delimiter);
+
+    for (int i = 1; i<count(); i++)
+    {
+        setItemData(i, values.contains(itemText(i)), Qt::CheckStateRole);
+    }
+    QComboBox::showPopup();
+}
+

+ 47 - 0
DataManage/widgets/IxWidgets/CheckComboBoxWidget.h

@@ -0,0 +1,47 @@
+#ifndef CHECKCOMBOBOXWIDGET_H
+#define CHECKCOMBOBOXWIDGET_H
+
+//#include <QComboBox>
+#include "IxWidget.h"
+#include "ComboBoxWidget.h"
+
+class CheckComboBoxWidget : public ComboBoxWidget
+{
+    Q_OBJECT
+public:
+    static const QString type;
+
+public:
+    CheckComboBoxWidget(QWidget *parent = nullptr);
+
+public:
+    virtual QVariant getValue() const;
+
+    virtual void setValue(const QVariant &value);
+
+    virtual bool isValueNull() const;
+
+    virtual void clearInput();
+
+public:
+    bool eventFilter(QObject * watched, QEvent * event) ;
+
+    void hidePopup() ;
+
+    void showPopup() ;
+
+    void setDelimiter(QString str){ _delimiter = str; }
+
+    const QStringList getDictValues(){ return dictValues; }
+
+signals:
+    void selectedText(QStringList);
+
+private:
+    QString _delimiter = ",";
+
+    QStringList  dictValues;
+
+};
+
+#endif // CHECKCOMBOBOXWIDGET_H

+ 67 - 0
DataManage/widgets/IxWidgets/ComboBoxWidget.cpp

@@ -0,0 +1,67 @@
+#include "ComboBoxWidget.h"
+#include "DebugUtil.h"
+
+const QString ComboBoxWidget::type = "ComboBox";
+
+ComboBoxWidget::ComboBoxWidget(QWidget *parent)
+    :QComboBox(parent)
+{
+    setStyleSheet("QComboBox QAbstractItemView {\
+        color:#333333;\
+        border: 1px solid #555555;\
+        background-color: #ffffff;\
+        border-radius:3px;\
+    }");
+}
+
+QVariant ComboBoxWidget::getValue() const
+{
+    return currentData();
+}
+
+void ComboBoxWidget::setValue(const QVariant &value)
+{
+    setCurrentIndex(0);
+    for (int index = 0; index < count(); ++index)
+    {
+        if (value == itemData(index))
+        {
+            setCurrentIndex(index);
+        }
+    }
+}
+
+bool ComboBoxWidget::isValueNull() const
+{
+    if(currentIndex() == 0)
+        return true;
+    return false;
+}
+
+void ComboBoxWidget::clearInput()
+{
+    setCurrentIndex(0);
+}
+
+void ComboBoxWidget::setOptions(const QVariantMap &options)
+{
+    QComboBox::clear();
+    addItem(QStringLiteral("请选择"), -1);
+    for (auto iter = options.cbegin(); iter != options.cend(); ++iter)
+    {
+        //		addItem(iter.key(), iter.value());
+        addItem(iter.value().toString(), iter.key());
+    }
+}
+
+void ComboBoxWidget::setObjectName(const QString &name)
+{
+    QObject::setObjectName(name);
+    setName(name);
+
+    QVariant property;
+    property.setValue(static_cast<IxWidget*>(this));
+    setProperty("IxWidget",property);
+}
+
+

+ 35 - 0
DataManage/widgets/IxWidgets/ComboBoxWidget.h

@@ -0,0 +1,35 @@
+#ifndef COMBOBOXWIDGET_H
+#define COMBOBOXWIDGET_H
+
+#include <QComboBox>
+#include "IxWidget.h"
+#include "IxWidgetFactory.h"
+
+class ComboBoxWidget : public QComboBox,public IxWidget
+{
+    Q_OBJECT
+public:
+	static const QString type;
+
+public:
+    ComboBoxWidget(QWidget *parent);
+
+public:
+     QVariant getValue() const override;
+
+     void setValue(const QVariant &value) override;
+
+     bool isValueNull() const override;
+
+     void clearInput() override;
+
+     void setObjectName(const QString &name);
+
+public:
+	void setOptions(const QVariantMap &options);
+
+};
+
+
+
+#endif // COMBOBOXWIDGET_H

+ 38 - 0
DataManage/widgets/IxWidgets/DateTimeWidget.cpp

@@ -0,0 +1,38 @@
+#include "DateTimeWidget.h"
+
+const QString DateTimeWidget::type = "DateTime";
+
+DateTimeWidget::DateTimeWidget(QWidget *parent)
+	: QDateTimeEdit(parent)
+{
+}
+
+QVariant DateTimeWidget::getValue() const
+{
+	return dateTime();
+}
+
+void DateTimeWidget::setValue(const QVariant &value)
+{
+	setDateTime(value.toDateTime());
+}
+
+bool DateTimeWidget::isValueNull() const
+{
+	return false;
+}
+
+void DateTimeWidget::clearInput()
+{
+    setDateTime(QDateTime::currentDateTime());
+}
+
+void DateTimeWidget::setObjectName(const QString &name)
+{
+    QObject::setObjectName(name);
+    setName(name);
+
+    QVariant property;
+    property.setValue(static_cast<IxWidget*>(this));
+    setProperty("IxWidget",property);
+}

+ 28 - 0
DataManage/widgets/IxWidgets/DateTimeWidget.h

@@ -0,0 +1,28 @@
+#pragma once
+
+#include <QDateTimeEdit>
+#include "IxWidget.h"
+#include "IxWidgetFactory.h"
+
+class DateTimeWidget : public QDateTimeEdit, public IxWidget
+{
+	Q_OBJECT
+public:
+	static const QString type;
+
+public:
+	DateTimeWidget(QWidget *parent);
+
+	~DateTimeWidget() = default;
+
+public:
+    QVariant getValue() const override;
+
+	void setValue(const QVariant &value) override;
+
+    bool isValueNull() const  override;
+
+    void clearInput() override;
+
+    void setObjectName(const QString &name);
+};

+ 31 - 0
DataManage/widgets/IxWidgets/IxWidget.h

@@ -0,0 +1,31 @@
+#ifndef IXWIDGET_H
+#define IXWIDGET_H
+
+#include <QMetaType>
+
+class IxWidget
+{
+public:
+    IxWidget() = default;
+
+    virtual ~IxWidget() = default;
+
+	virtual QVariant getValue() const = 0;
+
+    virtual void setValue(const QVariant &value) = 0;
+
+	virtual bool isValueNull() const = 0;
+
+    virtual void clearInput() = 0;
+
+ public:
+    QString getName() const { return name; }
+
+	void setName(const QString &name){ this->name = name; }
+	
+protected:
+    QString name;
+};
+Q_DECLARE_METATYPE(IxWidget*)
+#endif // IXWIDGET_H
+

+ 44 - 0
DataManage/widgets/IxWidgets/LineEditWidget.cpp

@@ -0,0 +1,44 @@
+#include "LineEditWidget.h"
+#include <QRegExpValidator>
+
+const QString LineEditWidget::type = "LineEdit";
+
+LineEditWidget::LineEditWidget(QWidget *parent)
+    :QLineEdit(parent)
+{
+}
+
+
+void LineEditWidget::setObjectName(const QString &name)
+{
+	QObject::setObjectName(name);
+	setName(name);
+
+    QVariant property;
+    property.setValue(static_cast<IxWidget*>(this));
+    setProperty("IxWidget",property);
+}
+
+QVariant LineEditWidget::getValue() const
+{
+    return text().trimmed();
+}
+
+void LineEditWidget::setValue(const QVariant &value)
+{
+	if (value.type() != QMetaType::QString && value.toDouble() == 0)
+		setText("");
+	else 
+		setText(value.toString());
+}
+
+bool LineEditWidget::isValueNull() const
+{
+    return text().trimmed().isEmpty();
+}
+
+void LineEditWidget::clearInput()
+{
+    clear();
+}
+

+ 28 - 0
DataManage/widgets/IxWidgets/LineEditWidget.h

@@ -0,0 +1,28 @@
+#ifndef LINEEDITWIDGET_H
+#define LINEEDITWIDGET_H
+
+#include <QLineEdit>
+#include "IxWidget.h"
+
+class LineEditWidget : public QLineEdit, public IxWidget
+{
+	Q_OBJECT
+public:
+	static const QString type;
+
+public:
+    LineEditWidget(QWidget *parent);
+
+	void setObjectName(const QString &name);
+
+public:
+	QVariant getValue() const override;
+
+	void setValue(const QVariant &value) override;
+
+	bool isValueNull() const override;
+
+	void clearInput() override;
+};
+
+#endif // LINEEDITWIDGET_H

+ 34 - 0
DataManage/widgets/IxWidgets/PathSelectorWidget.cpp

@@ -0,0 +1,34 @@
+#include "PathSelectorWidget.h"
+
+#include <QFileDialog>
+
+const QString PathSelectorWidget::type = "PathSelector";
+
+PathSelectorWidget::PathSelectorWidget(QWidget *parent)
+: LineEditWidget(parent)
+    , btn(new QPushButton(this))
+{
+    init();
+}
+
+void PathSelectorWidget::init()
+{    
+    btn->setText("选择路径");
+	btn->setStyleSheet("border:0;color:#ffffff;background-color:#55aaff;border-radius:0;border-top-right-radius:1px;border-bottom-right-radius:1px;min-height:18px;min-width:40px");
+    connect(btn, &QPushButton::pressed, this, &PathSelectorWidget::onButtonClick);
+
+    setReadOnly(true);
+}
+
+void PathSelectorWidget::resizeEvent(QResizeEvent *event)
+{
+    Q_UNUSED(event)
+	btn->setGeometry(width() - 61, 1, 60, height() - 2);
+}
+
+void PathSelectorWidget::onButtonClick()
+{
+    QString path = QFileDialog::getExistingDirectory(this, "选择路径");
+    setText(path);
+}
+

Alguns arquivos não foram mostrados porque muitos arquivos mudaram nesse diff