создал менеджер донатов
- добавление - удаление - сохранение
This commit is contained in:
@@ -0,0 +1,175 @@
|
||||
#include "donationmanager.h"
|
||||
#include "udatabase.h"
|
||||
#include <QRegularExpression>
|
||||
#include <QDebug>
|
||||
|
||||
DonationManager::DonationManager(uDataBase *db, QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_db(db)
|
||||
{
|
||||
}
|
||||
|
||||
bool DonationManager::loadFromDatabase()
|
||||
{
|
||||
if (!m_db) return false;
|
||||
// Предполагаем, что в uDataBase есть метод loadAllDonationTriggers()
|
||||
m_triggers = m_db->loadAllDonationTriggers();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DonationManager::addTrigger(const QString &name, const QString &rule)
|
||||
{
|
||||
if (name.isEmpty() || rule.isEmpty()) return false;
|
||||
|
||||
DonationTrigger trig;
|
||||
trig.name = name;
|
||||
trig.rule = rule;
|
||||
|
||||
if (!parseRule(rule, trig)) {
|
||||
qWarning() << "Invalid rule:" << rule;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Сохраняем в БД (метод saveDonationTrigger должен вернуть id)
|
||||
int newId = m_db->saveDonationTrigger(trig);
|
||||
if (newId < 0) return false;
|
||||
|
||||
trig.id = newId;
|
||||
m_triggers.append(trig);
|
||||
emit dataChanged();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DonationManager::deleteTrigger(int id)
|
||||
{
|
||||
if (!m_db->deleteDonationTrigger(id)) return false;
|
||||
|
||||
for (int i = 0; i < m_triggers.size(); ++i) {
|
||||
if (m_triggers[i].id == id) {
|
||||
m_triggers.removeAt(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
emit dataChanged();
|
||||
return true;
|
||||
}
|
||||
|
||||
QList<DonationTrigger> DonationManager::getAllTriggers() const
|
||||
{
|
||||
return m_triggers;
|
||||
}
|
||||
|
||||
QString DonationManager::matchDonation(double amount) const
|
||||
{
|
||||
const DonationTrigger *best = nullptr;
|
||||
int bestPriority = 999; // чем меньше, тем выше приоритет
|
||||
|
||||
for (const DonationTrigger &t : m_triggers) {
|
||||
bool ok = false;
|
||||
switch (t.priority) {
|
||||
case 1: // exact
|
||||
if (qFuzzyCompare(amount, t.minValue))
|
||||
ok = true;
|
||||
break;
|
||||
case 2: // range
|
||||
if (amount >= t.minValue && amount <= t.maxValue)
|
||||
ok = true;
|
||||
break;
|
||||
case 3: // greater / greater-equal
|
||||
if (t.isGreaterEqual) {
|
||||
if (amount >= t.minValue) ok = true;
|
||||
} else {
|
||||
if (amount > t.minValue) ok = true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ok) {
|
||||
// Сравниваем приоритет
|
||||
if (t.priority < bestPriority) {
|
||||
best = &t;
|
||||
bestPriority = t.priority;
|
||||
}
|
||||
// Если приоритет одинаковый, применяем дополнительные правила:
|
||||
else if (t.priority == bestPriority) {
|
||||
if (bestPriority == 2) {
|
||||
// Для диапазонов выбираем более узкий (меньше разница max-min)
|
||||
double bestRange = best->maxValue - best->minValue;
|
||||
double thisRange = t.maxValue - t.minValue;
|
||||
if (thisRange < bestRange) {
|
||||
best = &t;
|
||||
}
|
||||
}
|
||||
else if (bestPriority == 3) {
|
||||
// Для больше/больше-равно выбираем наибольшее пороговое значение (minValue)
|
||||
if (t.minValue > best->minValue) {
|
||||
best = &t;
|
||||
}
|
||||
}
|
||||
// Для exact приоритет 1 – только одно значение, совпадение уже есть.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return best ? best->name : QString();
|
||||
}
|
||||
|
||||
bool DonationManager::parseRule(const QString &rule, DonationTrigger &t) const
|
||||
{
|
||||
QString r = rule.trimmed();
|
||||
if (r.isEmpty()) return false;
|
||||
|
||||
// Точное равенство: =123
|
||||
if (r.startsWith('=')) {
|
||||
QString numStr = r.mid(1);
|
||||
bool ok;
|
||||
double val = numStr.toDouble(&ok);
|
||||
if (!ok) return false;
|
||||
t.priority = 1;
|
||||
t.minValue = val;
|
||||
t.maxValue = val;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Диапазон: 100-200
|
||||
if (r.contains('-')) {
|
||||
QStringList parts = r.split('-', Qt::SkipEmptyParts);
|
||||
if (parts.size() != 2) return false;
|
||||
bool ok1, ok2;
|
||||
double a = parts[0].toDouble(&ok1);
|
||||
double b = parts[1].toDouble(&ok2);
|
||||
if (!ok1 || !ok2 || a > b) return false;
|
||||
t.priority = 2;
|
||||
t.minValue = a;
|
||||
t.maxValue = b;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Больше/больше-равно
|
||||
if (r.startsWith(">=")) {
|
||||
QString numStr = r.mid(2);
|
||||
bool ok;
|
||||
double val = numStr.toDouble(&ok);
|
||||
if (!ok) return false;
|
||||
t.priority = 3;
|
||||
t.minValue = val;
|
||||
t.maxValue = 0;
|
||||
t.isGreaterEqual = true;
|
||||
return true;
|
||||
}
|
||||
if (r.startsWith('>')) {
|
||||
QString numStr = r.mid(1);
|
||||
bool ok;
|
||||
double val = numStr.toDouble(&ok);
|
||||
if (!ok) return false;
|
||||
t.priority = 3;
|
||||
t.minValue = val;
|
||||
t.maxValue = 0;
|
||||
t.isGreaterEqual = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
Reference in New Issue
Block a user