DiagramDesigner/source/projectModelDlg.cpp

668 lines
23 KiB
C++
Raw Normal View History

2025-03-04 09:44:03 +08:00
#include <QMessageBox>
#include <QJsonArray>
#include "projectModelDlg.h"
#include "renameModel.h"
#include "dataBase.h"
#include "ui_projectModelDlg.h"
#include "global.h"
const QSet<QString> stringDataTypes = {"varchar", "char", "text", "date", "time", "timestamp"};
projectModelDlg::projectModelDlg(QWidget *parent)
: QDialog(parent)
, ui(new Ui::projectModelDlg)
,m_pRenameModel(nullptr)
,_viewModel(nullptr)
{
ui->setupUi(this);
this->setWindowFlags(Qt::FramelessWindowHint | windowFlags());
setWindowModality(Qt::WindowModal);
m_pRenameModel = new RenameModel(this);
if(m_pRenameModel)
m_pRenameModel->hide();
initial();
}
projectModelDlg::~projectModelDlg()
{
delete ui;
}
void projectModelDlg::initial()
{
connect(ui->btn_generate,&QPushButton::clicked,this,&projectModelDlg::onGenerateClicked);
connect(ui->btn_save,&QPushButton::clicked,this,&projectModelDlg::onSaveClicked);
connect(ui->btn_cancel,&QPushButton::clicked,this,&projectModelDlg::onCancelClicked);
connect(ui->btn_apply,&QPushButton::clicked,this,&projectModelDlg::onApplyClicked);
connect(ui->btn_revoke,&QPushButton::clicked,this,&projectModelDlg::onRevokeClicked);
connect(ui->cb_baseModel,&QComboBox::textActivated,this,&projectModelDlg::onBaseModelIndexChanged);
connect(ui->cb_projectModel,&QComboBox::textActivated,this,&projectModelDlg::onProjectIndexChanged);
connect(ui->cb_property,&QComboBox::textActivated,this,&projectModelDlg::onPropertyIndexChanged);
initialModel();
initialList();
update();
}
MapProperty projectModelDlg::addNewProject(const QString& sMeta,const QString& sProject) //todo:保存后生成新建
{
MapProperty mt;
QStringList lstProperty = getGroupList(sMeta);
//lstProperty<<QString("base")<<QString("seperation");
QMap<QString,QJsonObject> mapCheckState = DataBase::GetInstance()->getCheckStateFromManager(sProject); //获取选择状态
if(mapCheckState.isEmpty()) //无返回值,是新建目标
{
for(auto &property:lstProperty)
{
//todo:读取属性信息
QStringList lstName = getAttributeList(sMeta,property);
//lstName<<QString("apple")<<QString("banana")<<QString("orange");
PropertyPage struProperty;
struProperty.pBase = new QStandardItemModel(this);
struProperty.pSelect = new QStandardItemModel(this);
//propertyItem->appendRow(new QStandardItem(property)); //总览view
for(auto &name:lstName)
{
QStandardItem* pItem = new QStandardItem(name);
setItemAttribute(name,pItem);
struProperty.pBase->appendRow(pItem);
struProperty.mCheckState.insert(name,0); //初始都是未选择状态
}
mt.insert(property,struProperty);
}
}
else
{
for(auto &property:lstProperty)
{
QJsonObject obj = mapCheckState[property];
QJsonArray nodesJsonArray = obj["checkState"].toArray();
PropertyPage struProperty;
struProperty.pBase = new QStandardItemModel(this);
struProperty.pSelect = new QStandardItemModel(this);
for (QJsonValueRef nodeJson : nodesJsonArray)
{
QJsonObject node = nodeJson.toObject();
QString propertyName = node["name"].toString();
int nState = node["checked"].toInt();
QStandardItem* pItem = new QStandardItem(propertyName);
setItemAttribute(propertyName,pItem);
if(nState)
{
struProperty.pSelect->appendRow(pItem);
struProperty.mCheckState.insert(propertyName,1);
}
else
{
struProperty.pBase->appendRow(pItem);
struProperty.mCheckState.insert(propertyName,0);
}
}
mt.insert(property,struProperty);
}
}
return mt;
}
void projectModelDlg::initialModel()
{
_viewModel = new QStandardItemModel(this);
QStringList lstModel = getModelList();
//lstType<<QString("metaModel1")<<QString("metaModel2");
for(auto &model:lstModel)
{
MapProject mp;
QStringList lstProject;
lstProject<<QString::fromWCharArray(L"新建"); //每个类别都有未命名工程
QStandardItem* modelItem = new QStandardItem(model); //总览view类型
for(auto &proj:lstProject)
{
QStandardItem* propertyItem = new QStandardItem(proj);
modelItem->appendRow(propertyItem); //总览view名称
PropertyModel pm;
pm.mapProperty = addNewProject(model,proj);
mp.insert(proj,pm);
}
_viewModel->appendRow(modelItem);
//todo:读取存储,按分类遍历名称
m_mapTotal.insert(model,mp);
}
ui->treeView_model->setModel(_viewModel);
}
void projectModelDlg::initialList()
{
QStandardItemModel *model = new QStandardItemModel(this);
ui->listView_icon->setModel(model);
QStandardItem* pNon = new QStandardItem(QString::fromWCharArray(L"未选择"));
QStandardItem* pMotor = new QStandardItem("motor");
QStandardItem* pBus = new QStandardItem("bus");
pNon->setData(0,Qt::UserRole);
pMotor->setData(1,Qt::UserRole);
pBus->setData(2,Qt::UserRole);
model->appendRow(pNon);
model->appendRow(pMotor);
model->appendRow(pBus);
connect(ui->listView_icon,&QListView::clicked,this,&projectModelDlg::onIconClicked);
}
void projectModelDlg::update()
{
for(MapMeta::Iterator iter = m_mapTotal.begin();iter != m_mapTotal.end();++iter)
{
ui->cb_baseModel->addItem(iter.key());
}
}
void projectModelDlg::generate(const QString& str)
{
QString pre = QString("project_");
MapMeta::Iterator iter = m_mapTotal.find(_curMeta); //获取元模下的工程
if(iter != m_mapTotal.end())
{
MapProject mp = iter.value();
MapProject::Iterator ite = mp.find(_curProject); //获取工程下的属性组
if(ite != mp.end())
{
MapProperty mapProperty = ite.value().mapProperty;
bool createRes = true; //动态表生成结果
for(MapProperty::Iterator it = mapProperty.begin();it != mapProperty.end();++it){ //每个属性组单独生成表
QUuid uuid = QUuid::createUuid();
// 不带花括号的 UUID 字符串
QString noDashes = uuid.toString(QUuid::WithoutBraces);
QString uuidString = noDashes.replace("-", "");
QString sName = pre+it.key()+QString("_")+uuidString; //生成表名
QStringList fields;
fields.append("id SERIAL NOT NULL PRIMARY KEY");
fields.append("global_uuid uuid NOT NULL DEFAULT gen_random_uuid()");
fields.append("attribute_group VARCHAR(64) NOT NULL");
QJsonObject objState;
QJsonArray arrState;
QStandardItemModel* pSelectModel = it->pSelect;
QStandardItem *rootItem = pSelectModel->invisibleRootItem();
for (int row = 0; row < rootItem->rowCount(); ++row) { //遍历已选择列表
QStandardItem *childItem = rootItem->child(row);
if (childItem) {
QString s = combinePropertySql(childItem); //拼接单句sql
fields.append(s);
QJsonObject node; //保存已选择状态
node["name"] = rootItem->text();
node["checked"] = 1;
arrState.append(node);
}
}
QStandardItemModel* pBaseModel = it->pBase;
rootItem = pBaseModel->invisibleRootItem();
for (int row = 0; row < rootItem->rowCount(); ++row) { //遍历未选择列表
QStandardItem *childItem = rootItem->child(row);
if (childItem) {
QJsonObject node; //保存未选择状态
node["name"] = rootItem->text();
node["checked"] = 0;
arrState.append(node);
}
}
if(!DataBase::GetInstance()->createDynamicTable(sName,fields))
{
createRes = false;
}
else
{
objState["checkState"] = arrState;
DataBase::GetInstance()->insertProjectManager(sName,str,_curMeta,it.key(),ite.value().nType,objState);
}
}
if(createRes)
{
PropertyModel pm = m_mapTotal[_curMeta].take(_curProject); //取出要保存的对象,另存为新索引
m_mapTotal[_curMeta].insert(str,pm);
if(_curProject == QString::fromWCharArray(L"新建"))
{
ui->cb_projectModel->addItem(str);
addNewProject(_curMeta,_curProject);
QList<QStandardItem*> lst = _viewModel->findItems(_curMeta);
if(lst.size() == 1)
{
QStandardItem* item = lst[0];
item->appendRow(new QStandardItem(str));
}
}
_curProject = str;
}
else //创建失败
{
QMessageBox::information(NULL, QString::fromWCharArray(L"提示"), QString::fromWCharArray(L"创建表失败"));
}
}
}
}
QString projectModelDlg::getProjectName() const
{
return _curProject;
}
void projectModelDlg::onSaveClicked()
{
if(_curProject.isEmpty())
{
QMessageBox::information(NULL, QString::fromWCharArray(L"提示"), QString::fromWCharArray(L"请选择操作的工程对象"));
}
else
{
if(_curProject == QString::fromWCharArray(L"新建"))
{
if(m_pRenameModel)
{
m_pRenameModel->showCenter();
}
}
}
}
void projectModelDlg::onGenerateClicked()
{
}
void projectModelDlg::onCancelClicked()
{
hide();
}
void projectModelDlg::onApplyClicked()
{
if(_curProperty.isEmpty())
{
QMessageBox::information(NULL, QString::fromWCharArray(L"提示"), QString::fromWCharArray(L"请先选择属性"));
}
else
{
MapMeta::Iterator iter = m_mapTotal.find(_curMeta);
if(iter != m_mapTotal.end())
{
MapProject project = iter.value();
MapProject::Iterator it= project.find(_curProject);
if(it != project.end())
{
MapProperty property = it.value().mapProperty;
QModelIndex selected = ui->treeView_base->currentIndex();
QStandardItem* item = property[_curProperty].pBase->takeItem(selected.row());
if(item)
{
property[_curProperty].pSelect->appendRow(item);
property[_curProperty].pBase->removeRow(selected.row());
property[_curProperty].mCheckState[item->text()] = 1; //选择状态设为1
}
/*MapProperty::Iterator ite = property.find(_curProperty);
if(ite != property.end())
{
QStandardItemModel* pBase = ite.value().pBase;
QStandardItemModel* pSelect = ite.value().pSelect;
QModelIndex selected = ui->treeView_base->currentIndex();
QStandardItem* item = pBase->takeItem(selected.row()); // 根据index获取当前item
if(item)
{
pSelect->appendRow(item);
pBase->removeRow(selected.row());
}
}*/
}
}
}
}
void projectModelDlg::onRevokeClicked()
{
if(_curProperty.isEmpty())
{
QMessageBox::information(NULL, QString::fromWCharArray(L"提示"), QString::fromWCharArray(L"请先选择属性"));
}
else
{
MapMeta::Iterator iter = m_mapTotal.find(_curMeta);
if(iter != m_mapTotal.end())
{
MapProject project = iter.value();
MapProject::Iterator it= project.find(_curProject);
if(it != project.end())
{
MapProperty property = it.value().mapProperty;
QModelIndex selected = ui->treeView_sub->currentIndex();
QStandardItem* item = property[_curProperty].pSelect->takeItem(selected.row());
if(item)
{
property[_curProperty].pBase->appendRow(item);
property[_curProperty].pSelect->removeRow(selected.row());
property[_curProperty].mCheckState[item->text()] = 0; //选择状态设为0
}
/*MapProperty::Iterator ite = property.find(_curProperty);
if(ite != property.end())
{
QStandardItemModel* pBase = ite.value().pBase;
QStandardItemModel* pSelect = ite.value().pSelect;
QModelIndex selected = ui->treeView_sub->currentIndex();
QStandardItem* item = pSelect->takeItem(selected.row()); // 根据index获取当前item
if(item)
{
pBase->appendRow(item);
pSelect->removeRow(selected.row());
}
}*/
}
}
}
}
void projectModelDlg::onBaseModelIndexChanged(const QString& str)
{
if(_curMeta == str) //选择未改变
{
return;
}
if(ui->stackedWidget->currentIndex() !=1) //选择元模时隐藏iconlist
{
ui->stackedWidget->setCurrentIndex(1);
}
ui->treeView_base->setModel(nullptr);
ui->treeView_sub->setModel(nullptr);
MapMeta::Iterator iter = m_mapTotal.find(str);
if(iter != m_mapTotal.end())
{
//先清空已有
_curMeta = str;
_curProject = "";
_curProperty = "";
ui->cb_projectModel->clear();
ui->cb_property->clear();
MapProject project = iter.value();
for(MapProject::Iterator it = project.begin();it != project.end();++it)
{
ui->cb_projectModel->addItem(it.key());
}
}
}
void projectModelDlg::onProjectIndexChanged(const QString& str)
{
if(_curMeta.isEmpty())
{
QMessageBox::information(NULL, QString::fromWCharArray(L"提示"), QString::fromWCharArray(L"请先选择元模型"));
}
else
{
updateIconList();
if(_curProject == str) //选择未改变
{
return;
}
ui->treeView_base->setModel(nullptr);
ui->treeView_sub->setModel(nullptr);
MapMeta::Iterator iter = m_mapTotal.find(_curMeta);
if(iter != m_mapTotal.end())
{
MapProject project = iter.value();
MapProject::Iterator it= project.find(str);
if(it != project.end())
{
_curProject = str;
_curProperty = "";
ui->cb_property->clear();
MapProperty property = it.value().mapProperty;
for(MapProperty::Iterator ite = property.begin();ite != property.end();++ite)
{
ui->cb_property->addItem(ite.key());
}
}
}
}
}
void projectModelDlg::onPropertyIndexChanged(const QString& str)
{
if(_curProject.isEmpty())
{
QMessageBox::information(NULL, QString::fromWCharArray(L"提示"), QString::fromWCharArray(L"请先选择工程模型"));
}
else
{
if(_curProperty == str)
{
return;
}
ui->treeView_base->setModel(nullptr);
ui->treeView_sub->setModel(nullptr);
MapMeta::Iterator iter = m_mapTotal.find(_curMeta);
if(iter != m_mapTotal.end())
{
MapProject project = iter.value();
MapProject::Iterator it= project.find(_curProject);
if(it != project.end())
{
MapProperty property = it.value().mapProperty;
MapProperty::Iterator ite = property.find(str);
if(ite != property.end())
{
_curProperty = str;
ui->treeView_base->setModel(nullptr);
ui->treeView_sub->setModel(nullptr);
QStandardItemModel* pBase = ite.value().pBase;
QStandardItemModel* pSelect = ite.value().pSelect;
ui->treeView_base->setModel(pBase);
ui->treeView_sub->setModel(pSelect);
}
}
}
}
}
void projectModelDlg::onIconClicked(const QModelIndex &index)
{
QStandardItemModel *model = dynamic_cast<QStandardItemModel*>(ui->listView_icon->model());
if(model)
{
QStandardItem* pItem = model->itemFromIndex(index);
int id = pItem->data(Qt::UserRole).toInt();
}
}
//=============================================================================
QStringList projectModelDlg::getModelList() const
{
QMap<int,modelAttribute> modelMap = DataBase::GetInstance()->ModelAttribute();
QSet<QString> modelSet;
for(auto &model:modelMap)
{
modelSet.insert(model.modelType);
}
return QStringList(modelSet.values());
}
QStringList projectModelDlg::getGroupList(const QString& sM) const
{
QMap<int,attributeGroup> groupMap = DataBase::GetInstance()->AttributeGroup();
QMap<int,modelAttribute> modelMap = DataBase::GetInstance()->ModelAttribute();
QMap<int,attribute> attMap = DataBase::GetInstance()->Attribute();
QSet<int> groupSet;
QStringList groupList;
for(auto &model:modelMap) //遍历获取属性组id
{
if(model.modelType == sM)
{
int attId = model.attributeId;
groupSet.insert(attMap[attId].attributeGroup);
}
}
for(auto &id:groupSet) //取得id对应的组名
{
groupList.append(groupMap[id].group);
}
return groupList;
}
QStringList projectModelDlg::getAttributeList(const QString& sM,const QString& sG) const
{
QMap<int,attributeGroup> groupMap = DataBase::GetInstance()->AttributeGroup();
QMap<int,modelAttribute> modelMap = DataBase::GetInstance()->ModelAttribute();
QMap<int,attribute> attMap = DataBase::GetInstance()->Attribute();
int groupId = -1;
for(auto &group:groupMap)
{
if(group.group == sG) //根据group获取对应Id
{
groupId = group.id;
break;
}
}
QSet<int> attSet;
QStringList attList;
if(groupId != -1)
{
for(auto &model:modelMap) //获取当前模型,当前属性组下的属性
{
if(model.modelType == sM)
{
int attId = model.attributeId;
if(attMap[attId].attributeGroup == groupId) //当前属性的属性组id等于选定的属性组id
{
attSet.insert(model.attributeId);
}
}
}
for(auto &id:attSet) //取得id对应的组名
{
attList.append(attMap[id].attribute);
}
return attList;
}
return QStringList();
}
void projectModelDlg::setItemAttribute(const QString& name,QStandardItem* p)
{
QMap<int,attribute> attMap = DataBase::GetInstance()->Attribute();
for(auto &att:attMap)
{
if(name == att.attribute)
{
p->setData(att.id,Id);
p->setData(att.attribute,Attribute);
p->setData(att.dataType,DataType);
p->setData(att.lengthPrecision,LengthPrecision);
p->setData(att.scale,Scale);
p->setData(att.defaultValue,DefaultValue);
p->setData(att.valueRange,ValueRange);
p->setData(att.attributeGroup,AttributeGroup);
p->setData(att.isNotNull,IsNotNull);
p->setData(att.isPrimaryKey,IsPrimaryKey);
return;
}
}
}
QString projectModelDlg::combinePropertySql(const QStandardItem* pItem)
{
int id = pItem->data(Id).toInt();
QString attribute = pItem->data(Attribute).toString();
QString dataType = pItem->data(DataType).toString();
int lengthPrecision = pItem->data(LengthPrecision).toInt();
int scale = pItem->data(Scale).toInt();
QString defaultValue = pItem->data(DefaultValue).toString();
QString valueRange = pItem->data(ValueRange).toString();
int attributeGroup = pItem->data(AttributeGroup).toInt();
int isNotNull = pItem->data(IsNotNull).toInt();
int isPrimaryKey = pItem->data(IsPrimaryKey).toInt();
bool needsQuotes = stringDataTypes.contains(dataType);
// 处理数据类型及其长度精度
QString dataTypePart = dataType;
if (lengthPrecision > 0) {
dataTypePart += QString("(%1").arg(lengthPrecision);
if (scale > 0) {
dataTypePart += QString(",%1").arg(scale);
}
dataTypePart += ")";
}
// 开始拼接SQL
QString sql = QString("%1 %2").arg(attribute, dataTypePart);
// 处理约束条件
if (isNotNull != 0) {
sql += " NOT NULL";
}
if (!defaultValue.isEmpty()) {
QString defValue = defaultValue;
if (needsQuotes) {
// 转义单引号并包裹
defValue.replace("'", "''");
defValue = QString("'%1'").arg(defValue);
}
sql += QString(" DEFAULT %1").arg(defValue);
}
if (isPrimaryKey != 0) {
sql += " PRIMARY KEY";
}
return sql;
}
void projectModelDlg::updateIconList()
{
if(ui->stackedWidget->currentIndex() !=0)
{
ui->stackedWidget->setCurrentIndex(0);
}
MapProject mp = m_mapTotal[_curMeta];
int nType = mp[_curProject].nType;
QStandardItemModel *model = dynamic_cast<QStandardItemModel*>(ui->listView_icon->model());
if(model)
{
for (int row = 0; row < model->rowCount(); ++row)
{
QStandardItem* pItem = model->item(row);
int id = pItem->data(Qt::UserRole).toInt();
if(nType == id) //使用存储的序列号更新list
{
QModelIndex index = model->index(id,0);
ui->listView_icon->setCurrentIndex(index);
return;
}
}
}
}