2025-03-24 18:13:06 +08:00
|
|
|
|
#include "attributeTableModel.h"
|
2025-04-08 20:02:38 +08:00
|
|
|
|
#include "attributeNamespace.h"
|
2025-03-24 18:13:06 +08:00
|
|
|
|
#include "logger.h"
|
|
|
|
|
|
#include "sqlQueryExecutor.h"
|
|
|
|
|
|
|
2025-03-25 17:58:48 +08:00
|
|
|
|
AttributeTableModel::AttributeTableModel(const ModelAttributeGroup& modelAttributeGroup, QObject* parent, const QString& connection, const QString& tableName)
|
2025-03-24 18:13:06 +08:00
|
|
|
|
: QAbstractTableModel(parent)
|
|
|
|
|
|
, m_connection(connection)
|
|
|
|
|
|
, m_tableName(tableName)
|
2025-03-25 17:58:48 +08:00
|
|
|
|
, m_modelAttributeGroup(modelAttributeGroup)
|
2025-03-24 18:13:06 +08:00
|
|
|
|
{
|
2025-03-25 17:58:48 +08:00
|
|
|
|
m_paginationInfo.entriesPerPage = 100;
|
|
|
|
|
|
m_paginationInfo.currentPage = 1;
|
|
|
|
|
|
m_paginationInfo.totalEntries = 0;
|
2025-03-24 18:13:06 +08:00
|
|
|
|
|
2025-04-08 20:02:38 +08:00
|
|
|
|
getDataTypesFromDB();
|
2025-03-27 21:01:25 +08:00
|
|
|
|
iniDisplayField();
|
2025-04-01 16:45:30 +08:00
|
|
|
|
refresh();
|
2025-03-24 18:13:06 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
AttributeTableModel::~AttributeTableModel()
|
|
|
|
|
|
{}
|
|
|
|
|
|
|
2025-03-27 14:47:51 +08:00
|
|
|
|
QModelIndex AttributeTableModel::index(int row, int column, const QModelIndex& parent) const
|
|
|
|
|
|
{
|
|
|
|
|
|
if(!hasIndex(row, column, parent))
|
|
|
|
|
|
return QModelIndex();
|
|
|
|
|
|
|
|
|
|
|
|
int dataCol = column - 1;
|
2025-04-11 17:14:17 +08:00
|
|
|
|
if(dataCol > m_displayField.count())
|
2025-03-27 14:47:51 +08:00
|
|
|
|
return QModelIndex();
|
|
|
|
|
|
|
|
|
|
|
|
return createIndex(row, column);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-03-24 18:13:06 +08:00
|
|
|
|
QVariant AttributeTableModel::data(const QModelIndex& index, int role) const
|
|
|
|
|
|
{
|
|
|
|
|
|
if(!index.isValid())
|
|
|
|
|
|
return QVariant();
|
|
|
|
|
|
|
|
|
|
|
|
int row = index.row();
|
|
|
|
|
|
int col = index.column();
|
2025-03-25 17:58:48 +08:00
|
|
|
|
int globalRow = (m_paginationInfo.currentPage - 1) * m_paginationInfo.entriesPerPage + row;
|
2025-03-24 18:13:06 +08:00
|
|
|
|
|
|
|
|
|
|
if(index.column() == 0) //第一列显示行号
|
|
|
|
|
|
{
|
|
|
|
|
|
switch (role)
|
|
|
|
|
|
{
|
|
|
|
|
|
case Qt::DisplayRole:
|
|
|
|
|
|
{
|
2025-03-27 14:47:51 +08:00
|
|
|
|
QString mark;
|
2025-03-24 18:13:06 +08:00
|
|
|
|
if(m_modifiedRows.contains(globalRow))
|
|
|
|
|
|
{
|
|
|
|
|
|
switch(m_modifiedRows[globalRow].state)
|
|
|
|
|
|
{
|
|
|
|
|
|
case Modified:
|
2025-03-27 14:47:51 +08:00
|
|
|
|
mark = "*";
|
2025-03-24 18:13:06 +08:00
|
|
|
|
break;
|
|
|
|
|
|
case New:
|
2025-03-27 14:47:51 +08:00
|
|
|
|
mark = "+";
|
2025-03-24 18:13:06 +08:00
|
|
|
|
break;
|
2025-04-11 17:14:17 +08:00
|
|
|
|
case New | Modified:
|
|
|
|
|
|
mark = "+";
|
|
|
|
|
|
break;
|
2025-03-24 18:13:06 +08:00
|
|
|
|
case Deleted:
|
2025-03-27 14:47:51 +08:00
|
|
|
|
mark = "-";
|
2025-03-24 18:13:06 +08:00
|
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-03-27 14:47:51 +08:00
|
|
|
|
return QString::number(globalRow + 1) + mark;
|
2025-03-24 18:13:06 +08:00
|
|
|
|
}
|
|
|
|
|
|
case Qt::DecorationRole:
|
|
|
|
|
|
return QVariant();
|
|
|
|
|
|
case Qt::TextAlignmentRole:
|
|
|
|
|
|
return Qt::AlignCenter; //行号居中展示
|
|
|
|
|
|
default:
|
|
|
|
|
|
return QVariant();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
int dataCol = col - 1;
|
|
|
|
|
|
const RowData& rowData = m_currentPageData[row];
|
|
|
|
|
|
if (role == Qt::DisplayRole || role == Qt::EditRole)
|
2025-04-08 20:02:38 +08:00
|
|
|
|
{
|
|
|
|
|
|
if(dataCol == 2) //数据类型,存储的是id,展示text
|
|
|
|
|
|
{
|
|
|
|
|
|
int dataTypeID = rowData.values.value(dataCol).toInt();
|
|
|
|
|
|
const QString& dataTypeText = m_dataTypes.value(dataTypeID).type;
|
|
|
|
|
|
if(!dataTypeText.isEmpty())
|
|
|
|
|
|
return dataTypeText;
|
2025-04-09 12:14:33 +08:00
|
|
|
|
// else
|
|
|
|
|
|
// return dataTypeID;
|
2025-04-08 20:02:38 +08:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
return rowData.values.value(dataCol);
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (role == Qt::UserRole + AttributeEidt::EditStatus) //在相关代理Delegate类实现中同步进行处理(文字加粗等效果)
|
2025-04-09 12:14:33 +08:00
|
|
|
|
{
|
|
|
|
|
|
//return (rowData.state != Clean);
|
|
|
|
|
|
if(rowData.state == New) //新增列,整行加粗
|
|
|
|
|
|
return true;
|
|
|
|
|
|
else //其它情况只对修改单元格加粗
|
|
|
|
|
|
return rowData.cellModified.value(dataCol, false);
|
|
|
|
|
|
}
|
2025-03-24 18:13:06 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return QVariant();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool AttributeTableModel::setData(const QModelIndex &index, const QVariant &value, int role)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (role != Qt::EditRole || index.column() == 0)
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
2025-03-27 21:01:25 +08:00
|
|
|
|
// QModelIndex numberIndex = createIndex(index.row(), 0);
|
|
|
|
|
|
// QString text = numberIndex.data(Qt::DisplayRole).toString();
|
|
|
|
|
|
// qDebug() << text;
|
|
|
|
|
|
// if(text.contains("-")) //删除状态不可编辑
|
|
|
|
|
|
// return false;
|
|
|
|
|
|
|
2025-03-24 18:13:06 +08:00
|
|
|
|
int row = index.row();
|
2025-03-25 17:58:48 +08:00
|
|
|
|
int globalRow = (m_paginationInfo.currentPage - 1) * m_paginationInfo.entriesPerPage + row;
|
2025-03-24 18:13:06 +08:00
|
|
|
|
int dataCol = index.column() - 1; //第一列显示了行号
|
|
|
|
|
|
//记录修改
|
|
|
|
|
|
RowData modifiedRow = m_currentPageData[row];
|
2025-04-08 20:02:38 +08:00
|
|
|
|
if(dataCol == 2) //数据类型
|
|
|
|
|
|
{
|
|
|
|
|
|
QString dataType = value.toString();
|
|
|
|
|
|
int id = getDataTypeID(dataType);
|
|
|
|
|
|
modifiedRow.values[dataCol] = id;
|
|
|
|
|
|
//qDebug() << "dataType-id: " << id;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
modifiedRow.values[dataCol] = value;
|
2025-04-09 12:14:33 +08:00
|
|
|
|
modifiedRow.cellModified[dataCol] = true; //标记单元格
|
2025-04-11 17:14:17 +08:00
|
|
|
|
const int attributeID = modifiedRow.values.last().toInt();
|
|
|
|
|
|
if(attributeID == -1) //纯新建
|
|
|
|
|
|
modifiedRow.state = (modifiedRow.state == New) ? New : Modified;
|
|
|
|
|
|
else
|
|
|
|
|
|
modifiedRow.state = (modifiedRow.state == New) ? modifiedRow.state |= Modified : Modified; //新建时从已有数据进行的加载,然后再次编辑就会变为叠加态
|
2025-03-24 18:13:06 +08:00
|
|
|
|
|
|
|
|
|
|
m_modifiedRows[globalRow] = modifiedRow;
|
|
|
|
|
|
m_currentPageData[row] = modifiedRow;
|
|
|
|
|
|
|
2025-04-08 20:02:38 +08:00
|
|
|
|
emit dataChanged(index, index, {role, Qt::UserRole + AttributeEidt::EditStatus});
|
2025-04-02 14:58:42 +08:00
|
|
|
|
emit syncDataStatus(m_modifiedRows.isEmpty(), m_paginationInfo);
|
2025-03-24 18:13:06 +08:00
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
QVariant AttributeTableModel::headerData(int section, Qt::Orientation orientation, int role) const
|
|
|
|
|
|
{
|
|
|
|
|
|
if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
|
|
|
|
|
|
{
|
|
|
|
|
|
if(section == 0)
|
|
|
|
|
|
return role == Qt::DisplayRole ? "No." : QVariant();
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
2025-03-28 17:40:59 +08:00
|
|
|
|
QString headerText = m_displayField.value(section - 1).displayName;
|
|
|
|
|
|
if(!m_displayField.value(section - 1).dataType.isEmpty())
|
|
|
|
|
|
headerText = headerText + "\n" + m_displayField.value(section - 1).dataType;
|
|
|
|
|
|
|
|
|
|
|
|
return headerText;
|
2025-03-24 18:13:06 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return QAbstractTableModel::headerData(section, orientation, role);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int AttributeTableModel::rowCount(const QModelIndex& parent) const
|
|
|
|
|
|
{
|
|
|
|
|
|
return m_currentPageData.count();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int AttributeTableModel::columnCount(const QModelIndex &) const
|
|
|
|
|
|
{
|
2025-03-27 21:01:25 +08:00
|
|
|
|
return m_displayField.isEmpty() ? 0 : m_displayField.count() + 1;
|
2025-03-24 18:13:06 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Qt::ItemFlags AttributeTableModel::flags(const QModelIndex &index) const
|
|
|
|
|
|
{
|
|
|
|
|
|
Qt::ItemFlags flags = QAbstractTableModel::flags(index);
|
2025-04-11 17:14:17 +08:00
|
|
|
|
if(m_modelAttributeGroup.modelID < 0) //表示当前加载数据对象是所有属性,前端UI是属性选择器,选择器为非可编辑状态
|
|
|
|
|
|
return flags;
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
QModelIndex numberIndex = createIndex(index.row(), 0);
|
|
|
|
|
|
QString text = numberIndex.data(Qt::DisplayRole).toString();
|
|
|
|
|
|
|
|
|
|
|
|
if (index.column() != 0 && !text.contains("-")) //行号列和处于删除状态的item不能编辑
|
|
|
|
|
|
flags = flags | Qt::ItemIsEditable;
|
|
|
|
|
|
return flags;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool AttributeTableModel::attributeTypeExistsInCurrentGroup(int id, const QString& type)
|
|
|
|
|
|
{
|
|
|
|
|
|
//先查找内存数据
|
|
|
|
|
|
for(RowData rowData : m_currentPageData)
|
|
|
|
|
|
{
|
|
|
|
|
|
if(rowData.values[0] == type)
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//再从数据库中查找,因为内存只存储当前页的数据
|
|
|
|
|
|
if(id != -1) //说明是之前创建过的属性(数据库中已存在)
|
|
|
|
|
|
return SqlQueryExecutor::instance().attributeTypeUseByModelGroup(m_connection, id, m_modelAttributeGroup.modelID, m_modelAttributeGroup.groupID);
|
|
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void AttributeTableModel::updateRowThroughExisitingAttribute(int row, int attributeID)
|
|
|
|
|
|
{
|
|
|
|
|
|
//qDebug() << "row:" << row << " attributeID:" << attributeID;
|
|
|
|
|
|
QStringList columns;
|
|
|
|
|
|
for(int i = 0; i < m_displayField.count(); i++)
|
|
|
|
|
|
columns << m_displayField.at(i).originalName;
|
|
|
|
|
|
Attribute attribute;
|
|
|
|
|
|
attribute.id = attributeID;
|
|
|
|
|
|
if(SqlQueryExecutor::instance().getAttributeInfo(m_connection, columns.join(", "), attribute))
|
|
|
|
|
|
{
|
|
|
|
|
|
RowData updateRow = m_currentPageData[row];
|
|
|
|
|
|
//updateRow.values.resize(m_displayField.count() + 1);
|
|
|
|
|
|
updateRow.values[0] = attribute.type;
|
|
|
|
|
|
updateRow.values[1] = attribute.name;
|
|
|
|
|
|
updateRow.values[2] = attribute.dataTypeID;
|
|
|
|
|
|
updateRow.values[3] = attribute.dataLength;
|
|
|
|
|
|
updateRow.values[4] = attribute.defaultValue;
|
|
|
|
|
|
updateRow.values[5] = attribute.id;//将id存入最后,不做显示,删除或者修改数据的时候会用到
|
|
|
|
|
|
|
|
|
|
|
|
for(int i = 0; i < m_displayField.count(); i++)
|
|
|
|
|
|
updateRow.cellModified[i] = true; //标记单元格
|
|
|
|
|
|
updateRow.state = (updateRow.state == New) ? New : Modified;
|
|
|
|
|
|
|
|
|
|
|
|
m_currentPageData[row] = updateRow;
|
|
|
|
|
|
int globalRow = (m_paginationInfo.currentPage - 1) * m_paginationInfo.entriesPerPage + row;
|
|
|
|
|
|
m_modifiedRows[globalRow] = updateRow;
|
|
|
|
|
|
|
|
|
|
|
|
QModelIndex topLeft = index(row, 1, QModelIndex());
|
|
|
|
|
|
QModelIndex bottomRight = index(row, m_displayField.count(), QModelIndex());
|
|
|
|
|
|
emit dataChanged(topLeft, bottomRight);
|
|
|
|
|
|
}
|
2025-03-24 18:13:06 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-03-27 21:01:25 +08:00
|
|
|
|
void AttributeTableModel::iniDisplayField()
|
|
|
|
|
|
{
|
|
|
|
|
|
FieldInfo field1;
|
|
|
|
|
|
field1.originalName = "attribute";
|
|
|
|
|
|
field1.displayName = QString::fromWCharArray(L"属性类别");
|
2025-03-31 16:01:49 +08:00
|
|
|
|
//field1.dataType = "character varying(128)";
|
2025-03-27 21:01:25 +08:00
|
|
|
|
m_displayField.append(field1);
|
|
|
|
|
|
|
|
|
|
|
|
FieldInfo field2;
|
|
|
|
|
|
field2.originalName = "attribute_name";
|
|
|
|
|
|
field2.displayName = QString::fromWCharArray(L"属性名称");
|
2025-03-31 16:01:49 +08:00
|
|
|
|
//field2.dataType = "character varying(64)";
|
2025-03-27 21:01:25 +08:00
|
|
|
|
m_displayField.append(field2);
|
|
|
|
|
|
|
|
|
|
|
|
FieldInfo field3;
|
|
|
|
|
|
field3.originalName = "data_type_id";
|
|
|
|
|
|
field3.displayName = QString::fromWCharArray(L"数据类型");
|
2025-04-08 20:02:38 +08:00
|
|
|
|
field3.dataType = "character varying(64)";
|
2025-03-27 21:01:25 +08:00
|
|
|
|
m_displayField.append(field3);
|
|
|
|
|
|
|
|
|
|
|
|
FieldInfo field4;
|
|
|
|
|
|
field4.originalName = "length_precision";
|
2025-03-31 16:01:49 +08:00
|
|
|
|
field4.displayName = QString::fromWCharArray(L"数据长度");
|
|
|
|
|
|
//field4.dataType = "integer";
|
2025-03-27 21:01:25 +08:00
|
|
|
|
m_displayField.append(field4);
|
|
|
|
|
|
|
|
|
|
|
|
FieldInfo field5;
|
|
|
|
|
|
field5.originalName = "default_value";
|
|
|
|
|
|
field5.displayName = QString::fromWCharArray(L"默认值");
|
2025-03-31 16:01:49 +08:00
|
|
|
|
//field5.dataType = "character varying(64)";
|
2025-03-27 21:01:25 +08:00
|
|
|
|
m_displayField.append(field5);
|
2025-03-31 16:01:49 +08:00
|
|
|
|
|
|
|
|
|
|
QHash<QString, QString> fieldType = SqlQueryExecutor::instance().getFiledType(m_connection, "attribute", "basic");
|
|
|
|
|
|
for(int i = 0; i < m_displayField.count(); i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
QString strFiled = m_displayField.at(i).originalName;
|
2025-04-08 20:02:38 +08:00
|
|
|
|
if(strFiled == "data_type_id") //数据类型以字符串的方式显示
|
|
|
|
|
|
continue;
|
2025-03-31 16:01:49 +08:00
|
|
|
|
m_displayField[i].dataType = fieldType.value(strFiled);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-04-08 20:02:38 +08:00
|
|
|
|
void AttributeTableModel::getDataTypesFromDB()
|
2025-03-31 16:01:49 +08:00
|
|
|
|
{
|
|
|
|
|
|
QString strSQL = "SELECT * FROM basic.data_type ORDER BY id ASC";
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
QSqlQuery query = SqlQueryExecutor::instance().executeSQL(m_connection, strSQL);
|
|
|
|
|
|
while(query.next())
|
|
|
|
|
|
{
|
|
|
|
|
|
DataType dataType;
|
|
|
|
|
|
dataType.id = query.value(0).toInt();
|
|
|
|
|
|
dataType.type = query.value(1).toString();
|
|
|
|
|
|
dataType.db = query.value(2).toString();
|
|
|
|
|
|
m_dataTypes.insert(dataType.id, dataType);
|
2025-04-08 20:02:38 +08:00
|
|
|
|
m_reversalDataTypes.insert(dataType.type, dataType.id);
|
2025-03-31 16:01:49 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (const DatabaseException& e)
|
|
|
|
|
|
{
|
|
|
|
|
|
LOG_ERROR("SQL", QString::fromWCharArray(L"获取数据类型失败"));
|
|
|
|
|
|
}
|
2025-03-27 21:01:25 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-04-08 20:02:38 +08:00
|
|
|
|
int AttributeTableModel::getDataTypeID(const QString& type)
|
|
|
|
|
|
{
|
|
|
|
|
|
return m_reversalDataTypes.value(type, 11); //11是VARCHAR的id,作为默认值
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-03-24 18:13:06 +08:00
|
|
|
|
void AttributeTableModel::loadPageData()
|
|
|
|
|
|
{
|
2025-03-26 15:57:08 +08:00
|
|
|
|
m_currentPageData.clear();
|
|
|
|
|
|
|
2025-04-01 16:45:30 +08:00
|
|
|
|
/*if (m_tableName.isEmpty())
|
2025-03-24 18:13:06 +08:00
|
|
|
|
{
|
|
|
|
|
|
LOG_ERROR("DB", QString("Attribute table name is empty, load data failed"));
|
|
|
|
|
|
return;
|
2025-04-01 16:45:30 +08:00
|
|
|
|
}*/
|
2025-03-24 18:13:06 +08:00
|
|
|
|
|
|
|
|
|
|
beginResetModel();
|
|
|
|
|
|
|
2025-04-11 17:14:17 +08:00
|
|
|
|
QStringList columns;
|
|
|
|
|
|
for(int i = 0; i < m_displayField.count(); i++)
|
|
|
|
|
|
columns << m_displayField.at(i).originalName;
|
2025-04-01 16:45:30 +08:00
|
|
|
|
|
2025-04-11 17:14:17 +08:00
|
|
|
|
if(m_modelAttributeGroup.modelID < 0) //表示当前加载数据对象是所有属性
|
|
|
|
|
|
{
|
|
|
|
|
|
columns.append("id"); //将id放到最后,和按照具体模型、具体属性组读取数据方式时逻辑统一,具体见下面分支逻辑
|
|
|
|
|
|
QString strSQL = QString("SELECT %1 FROM basic.attribute LIMIT %2 OFFSET %3")
|
|
|
|
|
|
.arg(columns.join(", "))
|
|
|
|
|
|
.arg(m_paginationInfo.entriesPerPage)
|
|
|
|
|
|
.arg((m_paginationInfo.currentPage - 1) * m_paginationInfo.entriesPerPage);
|
|
|
|
|
|
try
|
2025-03-24 18:13:06 +08:00
|
|
|
|
{
|
2025-04-11 17:14:17 +08:00
|
|
|
|
QSqlQuery query = SqlQueryExecutor::instance().executeSQL(m_connection, strSQL);
|
|
|
|
|
|
while(query.next())
|
2025-03-26 15:57:08 +08:00
|
|
|
|
{
|
2025-04-01 16:45:30 +08:00
|
|
|
|
RowData data;
|
2025-04-11 17:14:17 +08:00
|
|
|
|
for(int i = 0; i < columns.count(); i++)
|
|
|
|
|
|
data.values.append(query.value(i));
|
2025-04-01 16:45:30 +08:00
|
|
|
|
m_currentPageData.append(data);
|
2025-03-26 15:57:08 +08:00
|
|
|
|
}
|
2025-03-24 18:13:06 +08:00
|
|
|
|
}
|
2025-04-11 17:14:17 +08:00
|
|
|
|
catch (const DatabaseException& e)
|
|
|
|
|
|
{
|
|
|
|
|
|
LOG_ERROR("SQL", QString::fromWCharArray(L"获取属性信息失败(所有属性)。"));
|
|
|
|
|
|
}
|
2025-03-24 18:13:06 +08:00
|
|
|
|
}
|
2025-04-11 17:14:17 +08:00
|
|
|
|
else //按具体模型的具体属性组读取数据
|
2025-03-24 18:13:06 +08:00
|
|
|
|
{
|
2025-04-22 17:45:37 +08:00
|
|
|
|
QString strSQL = "";
|
|
|
|
|
|
bool isPublicGroup = SqlQueryExecutor::instance().isPublicAttributeGroup(m_connection, m_modelAttributeGroup.groupID);
|
|
|
|
|
|
if(isPublicGroup)
|
|
|
|
|
|
strSQL = QString("SELECT attribute_id FROM basic.model_attribute_public WHERE attribute_group_id = %1 LIMIT %2 OFFSET %3")
|
|
|
|
|
|
.arg(m_modelAttributeGroup.groupID)
|
|
|
|
|
|
.arg(m_paginationInfo.entriesPerPage)
|
|
|
|
|
|
.arg((m_paginationInfo.currentPage - 1) * m_paginationInfo.entriesPerPage);
|
|
|
|
|
|
else
|
|
|
|
|
|
strSQL = QString("SELECT attribute_id FROM basic.model_attribute WHERE model_type_id = %1 AND attribute_group_id = %2 LIMIT %3 OFFSET %4")
|
|
|
|
|
|
.arg(m_modelAttributeGroup.modelID)
|
|
|
|
|
|
.arg(m_modelAttributeGroup.groupID)
|
|
|
|
|
|
.arg(m_paginationInfo.entriesPerPage)
|
|
|
|
|
|
.arg((m_paginationInfo.currentPage - 1) * m_paginationInfo.entriesPerPage);
|
2025-04-11 17:14:17 +08:00
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
QSqlQuery query = SqlQueryExecutor::instance().executeSQL(m_connection, strSQL);
|
|
|
|
|
|
while(query.next())
|
|
|
|
|
|
{
|
|
|
|
|
|
Attribute attribute;
|
|
|
|
|
|
attribute.id = query.value(0).toInt();
|
|
|
|
|
|
if(SqlQueryExecutor::instance().getAttributeInfo(m_connection, columns.join(", "), attribute))
|
|
|
|
|
|
{
|
|
|
|
|
|
RowData data;
|
|
|
|
|
|
data.values.append(attribute.type);
|
|
|
|
|
|
data.values.append(attribute.name);
|
|
|
|
|
|
data.values.append(attribute.dataTypeID);
|
|
|
|
|
|
data.values.append(attribute.dataLength);
|
|
|
|
|
|
data.values.append(attribute.defaultValue);
|
|
|
|
|
|
data.values.append(attribute.id);//将id存入最后,不做显示,删除或者修改数据的时候会用到
|
|
|
|
|
|
m_currentPageData.append(data);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (const DatabaseException& e)
|
|
|
|
|
|
{
|
|
|
|
|
|
LOG_ERROR("SQL", QString::fromWCharArray(L"获取属性信息失败。modelID:%1, groupID:%2").arg(m_modelAttributeGroup.modelID, m_modelAttributeGroup.groupID));
|
|
|
|
|
|
}
|
2025-03-24 18:13:06 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
endResetModel();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-03-26 15:57:08 +08:00
|
|
|
|
void AttributeTableModel::setPageSize(int size)
|
|
|
|
|
|
{
|
|
|
|
|
|
if(m_paginationInfo.entriesPerPage != size && size > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_paginationInfo.entriesPerPage = size;
|
|
|
|
|
|
refresh();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
int AttributeTableModel::pageSize() const
|
|
|
|
|
|
{
|
|
|
|
|
|
return m_paginationInfo.entriesPerPage;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void AttributeTableModel::setCurrentPage(int page)
|
|
|
|
|
|
{
|
|
|
|
|
|
if(m_paginationInfo.currentPage != page && page > 0 && page <= totalPages())
|
|
|
|
|
|
{
|
|
|
|
|
|
m_paginationInfo.currentPage = page;
|
|
|
|
|
|
refresh();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
int AttributeTableModel::currentPage() const
|
|
|
|
|
|
{
|
|
|
|
|
|
return m_paginationInfo.currentPage;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int AttributeTableModel::totalPages() const
|
|
|
|
|
|
{
|
|
|
|
|
|
return qCeil(static_cast<qreal>(m_paginationInfo.totalEntries) / m_paginationInfo.entriesPerPage);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void AttributeTableModel::previousPage()
|
|
|
|
|
|
{
|
|
|
|
|
|
if(m_paginationInfo.entriesPerPage == 1)
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
setCurrentPage(m_paginationInfo.entriesPerPage--);
|
|
|
|
|
|
}
|
|
|
|
|
|
void AttributeTableModel::nextPage()
|
|
|
|
|
|
{
|
|
|
|
|
|
if(m_paginationInfo.entriesPerPage == totalPages())
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
setCurrentPage(m_paginationInfo.entriesPerPage++);
|
|
|
|
|
|
}
|
|
|
|
|
|
void AttributeTableModel::firstPage()
|
|
|
|
|
|
{
|
|
|
|
|
|
if(m_paginationInfo.entriesPerPage == 1)
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
setCurrentPage(1);
|
|
|
|
|
|
}
|
|
|
|
|
|
void AttributeTableModel::lastPage()
|
|
|
|
|
|
{
|
|
|
|
|
|
if(m_paginationInfo.entriesPerPage == totalPages())
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
setCurrentPage(totalPages());
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-03-24 18:13:06 +08:00
|
|
|
|
void AttributeTableModel::updateTotalCount()
|
|
|
|
|
|
{
|
2025-04-01 16:45:30 +08:00
|
|
|
|
/*if (m_tableName.isEmpty())
|
2025-03-24 18:13:06 +08:00
|
|
|
|
{
|
|
|
|
|
|
LOG_ERROR("SQL", QString::fromWCharArray(L"属性表名称为空,获取属性数量失败"));
|
|
|
|
|
|
return;
|
2025-04-01 16:45:30 +08:00
|
|
|
|
}*/
|
2025-03-24 18:13:06 +08:00
|
|
|
|
|
2025-04-11 17:14:17 +08:00
|
|
|
|
if(m_modelAttributeGroup.modelID < 0)
|
|
|
|
|
|
m_paginationInfo.totalEntries = SqlQueryExecutor::instance().getAllAttributeCount(m_connection);
|
|
|
|
|
|
else
|
|
|
|
|
|
m_paginationInfo.totalEntries = SqlQueryExecutor::instance().getAttributeCount(m_connection, m_modelAttributeGroup.modelID, m_modelAttributeGroup.groupID);
|
2025-03-24 18:13:06 +08:00
|
|
|
|
}
|
2025-03-25 20:53:15 +08:00
|
|
|
|
|
2025-04-11 17:14:17 +08:00
|
|
|
|
QList<AttributeTableModel::RowData> AttributeTableModel::filterRowsByEditState(EditStateFlag state)
|
2025-04-01 14:37:41 +08:00
|
|
|
|
{
|
|
|
|
|
|
QList<RowData> result;
|
|
|
|
|
|
for(auto it = m_modifiedRows.begin(); it != m_modifiedRows.end(); it++)
|
|
|
|
|
|
{
|
2025-04-11 17:14:17 +08:00
|
|
|
|
if(it.value().state.testFlag(state))
|
2025-04-01 14:37:41 +08:00
|
|
|
|
result.append(it.value());
|
|
|
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-04-01 16:45:30 +08:00
|
|
|
|
/*void AttributeTableModel::setTable(const QString& tableName)
|
2025-03-26 15:57:08 +08:00
|
|
|
|
{
|
|
|
|
|
|
if(m_tableName == tableName)
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
m_tableName = tableName;
|
|
|
|
|
|
m_modifiedRows.clear();
|
|
|
|
|
|
refresh();
|
2025-04-01 16:45:30 +08:00
|
|
|
|
}*/
|
2025-03-26 15:57:08 +08:00
|
|
|
|
|
|
|
|
|
|
void AttributeTableModel::refresh()
|
|
|
|
|
|
{
|
|
|
|
|
|
if(!m_modifiedRows.isEmpty())
|
|
|
|
|
|
{
|
|
|
|
|
|
emit showMessage(type_question, QString::fromWCharArray(L"提示"),
|
2025-04-02 15:57:00 +08:00
|
|
|
|
QString::fromWCharArray(L"有编辑数据还未提交,确认刷新放弃提交吗?"));
|
|
|
|
|
|
if(g_msgDlgBtn == btn_No)
|
|
|
|
|
|
return;
|
2025-03-26 15:57:08 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-04-02 15:57:00 +08:00
|
|
|
|
m_modifiedRows.clear();
|
2025-03-26 15:57:08 +08:00
|
|
|
|
loadPageData();
|
|
|
|
|
|
updateTotalCount();
|
|
|
|
|
|
emit syncDataStatus(m_modifiedRows.isEmpty(), m_paginationInfo);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-03-27 14:47:51 +08:00
|
|
|
|
void AttributeTableModel::insertRecord(int row)
|
|
|
|
|
|
{
|
|
|
|
|
|
if(row < 0 || row > rowCount())
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
RowData newRow;
|
|
|
|
|
|
newRow.state = New;
|
2025-04-11 17:14:17 +08:00
|
|
|
|
newRow.values.resize(m_displayField.count() + 1); //多出一个位置给id
|
|
|
|
|
|
newRow.values.last() = -1;
|
2025-04-09 12:14:33 +08:00
|
|
|
|
//newRow.values[2] = 11;
|
2025-03-27 14:47:51 +08:00
|
|
|
|
|
|
|
|
|
|
int globalRow = (m_paginationInfo.currentPage - 1) * m_paginationInfo.entriesPerPage + row;
|
|
|
|
|
|
m_modifiedRows[globalRow] = newRow;
|
|
|
|
|
|
|
|
|
|
|
|
beginInsertRows(QModelIndex(), row, row);
|
|
|
|
|
|
m_currentPageData.insert(row, newRow);
|
|
|
|
|
|
endInsertRows();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void AttributeTableModel::removeRecord(int row)
|
2025-03-26 15:57:08 +08:00
|
|
|
|
{
|
2025-03-27 14:47:51 +08:00
|
|
|
|
if(row < 0 || row > rowCount())
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
2025-04-02 10:44:52 +08:00
|
|
|
|
/*emit showMessage(type_question, QString::fromWCharArray(L"提示"),
|
2025-03-27 14:47:51 +08:00
|
|
|
|
QString::fromWCharArray(L"确认要删除该记录吗?"));
|
|
|
|
|
|
if(g_msgDlgBtn == btn_No)
|
2025-04-02 10:44:52 +08:00
|
|
|
|
return;*/
|
2025-03-27 14:47:51 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int globalRow = (m_paginationInfo.currentPage - 1) * m_paginationInfo.entriesPerPage + row;
|
2025-03-31 16:01:49 +08:00
|
|
|
|
if(m_currentPageData.at(row).state == New) //新添加未提交的记录,直接删除
|
2025-03-27 14:47:51 +08:00
|
|
|
|
{
|
2025-03-27 21:01:25 +08:00
|
|
|
|
beginRemoveRows(QModelIndex(), row, row);
|
2025-03-27 14:47:51 +08:00
|
|
|
|
m_modifiedRows.remove(globalRow);
|
2025-03-27 21:01:25 +08:00
|
|
|
|
m_currentPageData.removeAt(row);
|
|
|
|
|
|
endRemoveRows();
|
2025-03-27 14:47:51 +08:00
|
|
|
|
}
|
2025-03-31 16:01:49 +08:00
|
|
|
|
else //整行画红线进行标记
|
2025-03-27 14:47:51 +08:00
|
|
|
|
{
|
|
|
|
|
|
m_currentPageData[row].state = Deleted;
|
|
|
|
|
|
m_modifiedRows[globalRow] = m_currentPageData[row];
|
2025-03-27 21:01:25 +08:00
|
|
|
|
m_modifiedRows[globalRow].state = Deleted;
|
|
|
|
|
|
|
|
|
|
|
|
QModelIndex topLeft = createIndex(row, 0);
|
|
|
|
|
|
QModelIndex bottomRight = createIndex(row, columnCount() - 1);
|
|
|
|
|
|
emit dataChanged(topLeft, bottomRight, {Qt::DisplayRole});
|
2025-03-27 14:47:51 +08:00
|
|
|
|
}
|
2025-03-26 15:57:08 +08:00
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-04-01 14:37:41 +08:00
|
|
|
|
void AttributeTableModel::submitChanges()
|
|
|
|
|
|
{
|
|
|
|
|
|
QList<RowData> insertRows = filterRowsByEditState(New);
|
2025-04-02 10:44:52 +08:00
|
|
|
|
bool insertCompleted = false;
|
|
|
|
|
|
QList<RowData> deleteRows = filterRowsByEditState(Deleted);
|
|
|
|
|
|
bool deleteCompleted = false;
|
2025-04-02 14:58:42 +08:00
|
|
|
|
QList<RowData> updateRows = filterRowsByEditState(Modified);
|
|
|
|
|
|
bool updateCompleted = false;
|
2025-04-01 14:37:41 +08:00
|
|
|
|
|
2025-04-02 14:58:42 +08:00
|
|
|
|
//插入操作
|
2025-04-01 14:37:41 +08:00
|
|
|
|
if(!insertRows.isEmpty())
|
|
|
|
|
|
{
|
|
|
|
|
|
QList<Attribute> insertAttributes;
|
|
|
|
|
|
for(const RowData& rowData : insertRows)
|
|
|
|
|
|
{
|
|
|
|
|
|
QString type = rowData.values.value(0).toString();
|
|
|
|
|
|
QString name = rowData.values.value(1).toString();
|
|
|
|
|
|
if(type.isEmpty() || name.isEmpty())
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
int dataTypeID = rowData.values.value(2).toInt();
|
|
|
|
|
|
int dataLength = -1;
|
|
|
|
|
|
if(rowData.values.value(3).isValid())
|
|
|
|
|
|
dataLength = rowData.values.value(3).toInt();
|
2025-04-02 10:44:52 +08:00
|
|
|
|
QString defaultValue = "null";
|
|
|
|
|
|
if(rowData.values.value(4).isValid())
|
|
|
|
|
|
defaultValue = rowData.values.value(4).toString();
|
2025-04-02 14:58:42 +08:00
|
|
|
|
|
2025-04-11 17:14:17 +08:00
|
|
|
|
int id = -1;
|
|
|
|
|
|
if(rowData.values.size() == m_displayField.count() +1)
|
|
|
|
|
|
id = rowData.values.value(m_displayField.count()).toInt();
|
|
|
|
|
|
insertAttributes.emplace_back(id, name, type, dataTypeID, dataLength, defaultValue);
|
2025-04-01 14:37:41 +08:00
|
|
|
|
}
|
2025-04-02 10:44:52 +08:00
|
|
|
|
insertCompleted = SqlQueryExecutor::instance().batchInsertAttributes(m_connection, m_modelAttributeGroup.modelID, m_modelAttributeGroup.groupID, insertAttributes);
|
2025-04-01 14:37:41 +08:00
|
|
|
|
}
|
2025-04-02 14:58:42 +08:00
|
|
|
|
//删除操作
|
2025-04-02 10:44:52 +08:00
|
|
|
|
if(!deleteRows.isEmpty())
|
2025-04-01 14:37:41 +08:00
|
|
|
|
{
|
2025-04-02 10:44:52 +08:00
|
|
|
|
QList<int> deleteAttributes;
|
|
|
|
|
|
for(const RowData& rowData : deleteRows)
|
|
|
|
|
|
{
|
|
|
|
|
|
if(rowData.values.count() != m_displayField.count() + 1) //loadPageData时,会把属性id放到valuse的最后,并且不做展示
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
deleteAttributes.push_back(rowData.values.last().toInt());
|
|
|
|
|
|
}
|
|
|
|
|
|
deleteCompleted = SqlQueryExecutor::instance().batchDeleteAttributes(m_connection, m_modelAttributeGroup.modelID, m_modelAttributeGroup.groupID, deleteAttributes);
|
2025-04-01 14:37:41 +08:00
|
|
|
|
}
|
2025-04-02 14:58:42 +08:00
|
|
|
|
//更新操作
|
|
|
|
|
|
if(!updateRows.isEmpty())
|
|
|
|
|
|
{
|
|
|
|
|
|
QList<Attribute> updateAttributes;
|
|
|
|
|
|
for(const RowData& rowData : updateRows)
|
|
|
|
|
|
{
|
|
|
|
|
|
if(rowData.values.count() != m_displayField.count() + 1) //loadPageData时,会把属性id放到valuse的最后,并且不做展示
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
int id = rowData.values.last().toInt();
|
|
|
|
|
|
QString type = rowData.values.value(0).toString();
|
|
|
|
|
|
QString name = rowData.values.value(1).toString();
|
|
|
|
|
|
int dataTypeID = rowData.values.value(2).toInt();
|
|
|
|
|
|
int dataLength = -1;
|
|
|
|
|
|
if(rowData.values.value(3).isValid())
|
|
|
|
|
|
dataLength = rowData.values.value(3).toInt();
|
|
|
|
|
|
QString defaultValue = "null";
|
|
|
|
|
|
if(rowData.values.value(4).isValid())
|
|
|
|
|
|
defaultValue = rowData.values.value(4).toString();
|
|
|
|
|
|
|
|
|
|
|
|
updateAttributes.emplace_back(id, name, type, dataTypeID, dataLength, defaultValue);
|
|
|
|
|
|
}
|
|
|
|
|
|
updateCompleted = SqlQueryExecutor::instance().batchUpdateAttributes(m_connection, m_modelAttributeGroup.modelID, m_modelAttributeGroup.groupID, updateAttributes);
|
|
|
|
|
|
}
|
2025-04-02 10:44:52 +08:00
|
|
|
|
|
2025-04-02 14:58:42 +08:00
|
|
|
|
if( (!insertRows.isEmpty() && !insertCompleted)
|
|
|
|
|
|
&& (!deleteRows.isEmpty() && !deleteCompleted)
|
|
|
|
|
|
&& (!updateRows.isEmpty() && !updateCompleted) )
|
2025-04-02 10:44:52 +08:00
|
|
|
|
{
|
2025-04-01 14:37:41 +08:00
|
|
|
|
emit showMessage(type_warning, QString::fromWCharArray(L"错误"), QString::fromWCharArray(L"数据提交失败,详情可查看日志文件"));
|
2025-04-02 10:44:52 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
m_modifiedRows.clear();
|
|
|
|
|
|
refresh();
|
2025-04-01 14:37:41 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-04-02 15:57:00 +08:00
|
|
|
|
void AttributeTableModel::cancleChanges()
|
|
|
|
|
|
{
|
|
|
|
|
|
if(m_modifiedRows.isEmpty())
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
m_modifiedRows.clear();
|
|
|
|
|
|
loadPageData();
|
|
|
|
|
|
updateTotalCount();
|
|
|
|
|
|
emit syncDataStatus(m_modifiedRows.isEmpty(), m_paginationInfo);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-03-25 20:53:15 +08:00
|
|
|
|
void AttributeTableModel::triggerSyncSignal()
|
|
|
|
|
|
{
|
|
|
|
|
|
emit syncDataStatus(m_modifiedRows.isEmpty(), m_paginationInfo);
|
|
|
|
|
|
}
|