TTW_Bot/donationmanager.cpp

176 lines
5.0 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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;
}