- Implement `cleanupOldData` in `DatabaseManager` to remove outdated entries and optimize storage. - Introduce `unlockScreen` in `AdbUtils` and integrate it into common scripts for screen unlocking. - Enhance `GeneralLogDAO` to support screenshot storage and retrieval. - Expand `FileLogWindow` with screenshot viewer and horizontal layout. - Add device ID migration logic in `BankProfileDAO` and `MaterialDAO`. - Improve error handling in `EventHandler` by saving and logging screenshots for critical events.
388 lines
14 KiB
C++
388 lines
14 KiB
C++
#include <QSqlQuery>
|
||
#include <QSqlError>
|
||
#include <QVariant>
|
||
#include <QSettings>
|
||
#include "BankProfileDAO.h"
|
||
#include "DatabaseManager.h"
|
||
#include "db/BankProfileInfo.h"
|
||
|
||
bool BankProfileDAO::upsertApplication(const BankProfileInfo &info) {
|
||
QSqlQuery query(DatabaseManager::instance().database());
|
||
|
||
query.prepare(R"(
|
||
INSERT INTO bank_profiles (device_id, pin_code, name, code, package, status, comment, install, pin_code_checked,
|
||
bank_profile_id, full_name, phone)
|
||
VALUES (:device_id, :pin_code, :name, :code, :package, :status, :comment, :install, :pin_code_checked,
|
||
:bank_profile_id, :full_name, :phone)
|
||
ON CONFLICT(device_id, code)
|
||
DO UPDATE SET
|
||
pin_code = CASE WHEN excluded.pin_code != '' THEN excluded.pin_code ELSE bank_profiles.pin_code END,
|
||
name = excluded.name,
|
||
package = CASE WHEN excluded.package != '' THEN excluded.package ELSE bank_profiles.package END,
|
||
status = excluded.status,
|
||
comment = excluded.comment,
|
||
install = excluded.install,
|
||
pin_code_checked = excluded.pin_code_checked,
|
||
bank_profile_id = CASE WHEN excluded.bank_profile_id != '' THEN excluded.bank_profile_id ELSE bank_profiles.bank_profile_id END,
|
||
full_name = CASE WHEN excluded.full_name != '' THEN excluded.full_name ELSE bank_profiles.full_name END,
|
||
phone = CASE WHEN excluded.phone != '' THEN excluded.phone ELSE bank_profiles.phone END
|
||
)");
|
||
|
||
query.bindValue(":device_id", info.deviceId);
|
||
query.bindValue(":pin_code", info.pinCode);
|
||
query.bindValue(":name", info.name);
|
||
query.bindValue(":code", info.code);
|
||
query.bindValue(":package", info.package);
|
||
query.bindValue(":status", info.status);
|
||
query.bindValue(":comment", info.comment);
|
||
query.bindValue(":install", info.install ? "yes" : "no");
|
||
query.bindValue(":pin_code_checked", info.pinCodeChecked ? "yes" : "no");
|
||
query.bindValue(":bank_profile_id", info.bankProfileId);
|
||
query.bindValue(":full_name", info.fullName);
|
||
query.bindValue(":phone", info.phone);
|
||
|
||
if (!query.exec()) {
|
||
qWarning() << "Ошибка при вставке/обновлении application:" << query.lastError().text();
|
||
return false;
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
bool BankProfileDAO::updatePinCode(const QString &appId, const QString &pinCode) {
|
||
QSqlQuery query(DatabaseManager::instance().database());
|
||
|
||
query.prepare(R"(
|
||
UPDATE bank_profiles
|
||
SET pin_code = :pin_code
|
||
WHERE id = :id
|
||
)");
|
||
|
||
query.bindValue(":pin_code", pinCode);
|
||
query.bindValue(":id", appId);
|
||
|
||
if (!query.exec()) {
|
||
qWarning() << "Ошибка при обновлении PIN-кода приложения:" << query.lastError().text();
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
bool BankProfileDAO::update(
|
||
const int &appId,
|
||
const QString &pinCode,
|
||
const QString &comment,
|
||
const QString &status
|
||
) {
|
||
QSqlQuery query(DatabaseManager::instance().database());
|
||
|
||
query.prepare(R"(
|
||
UPDATE bank_profiles
|
||
SET pin_code = :pin_code, comment = :comment, status = :status
|
||
WHERE id = :id
|
||
)");
|
||
|
||
query.bindValue(":id", appId);
|
||
query.bindValue(":comment", comment);
|
||
query.bindValue(":pin_code", pinCode);
|
||
query.bindValue(":status", status);
|
||
|
||
if (!query.exec()) {
|
||
qWarning() << "Ошибка при обновлении PIN-кода приложения:" << query.lastError().text();
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
bool BankProfileDAO::updatePinCodeStatus(
|
||
const int &appId,
|
||
const QString &pinCodeStatus,
|
||
const QString &comment
|
||
) {
|
||
QSqlQuery query(DatabaseManager::instance().database());
|
||
|
||
query.prepare(R"(
|
||
UPDATE bank_profiles
|
||
SET pin_code_checked = :pin_code_checked, comment = :comment
|
||
WHERE id = :id
|
||
)");
|
||
|
||
query.bindValue(":id", appId);
|
||
query.bindValue(":comment", comment);
|
||
query.bindValue(":pin_code_checked", pinCodeStatus);
|
||
|
||
if (!query.exec()) {
|
||
qWarning() << "Ошибка при обновлении PIN-кода приложения:" << query.lastError().text();
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
|
||
bool BankProfileDAO::updateComment(const int appId, const QString &comment) {
|
||
QSqlQuery query(DatabaseManager::instance().database());
|
||
query.prepare("UPDATE bank_profiles SET comment = :comment WHERE id = :id");
|
||
query.bindValue(":comment", comment);
|
||
query.bindValue(":id", appId);
|
||
if (!query.exec()) {
|
||
qWarning() << "Ошибка при обновлении комментария:" << query.lastError().text();
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
BankProfileInfo parseApplication(const QSqlQuery &query) {
|
||
BankProfileInfo app;
|
||
app.id = query.value("id").toInt();
|
||
app.deviceId = query.value("device_id").toString();
|
||
app.pinCode = query.value("pin_code").toString();
|
||
app.code = query.value("code").toString();
|
||
app.name = query.value("name").toString();
|
||
app.package = query.value("package").toString();
|
||
app.status = query.value("status").toString();
|
||
app.comment = query.value("comment").toString();
|
||
app.install = query.value("install").toString() == "yes";
|
||
app.pinCodeChecked = query.value("pin_code_checked").toString() == "yes";
|
||
app.phone = query.value("phone").toString();
|
||
app.email = query.value("email").toString();
|
||
app.fullName = query.value("full_name").toString();
|
||
app.bankProfileId = query.value("bank_profile_id").toString();
|
||
app.currency = query.value("currency").toString();
|
||
app.amount = query.value("amount").toDouble();
|
||
return app;
|
||
}
|
||
|
||
BankProfileInfo BankProfileDAO::getApplication(const QString &deviceId, const QString &appCode) {
|
||
QSqlQuery query(DatabaseManager::instance().database());
|
||
|
||
query.prepare(R"(
|
||
SELECT id, device_id, pin_code, code, name, package, status, comment, install, pin_code_checked, phone, email, full_name, bank_profile_id, currency, amount
|
||
FROM bank_profiles
|
||
WHERE device_id = :device_id AND code = :code
|
||
LIMIT 1
|
||
)");
|
||
|
||
query.bindValue(":device_id", deviceId);
|
||
query.bindValue(":code", appCode);
|
||
|
||
if (!query.exec()) {
|
||
qWarning() << "Ошибка при получении приложений по deviceId:" << query.lastError().text();
|
||
return {};
|
||
}
|
||
|
||
while (query.next()) {
|
||
return parseApplication(query);
|
||
}
|
||
return {};
|
||
}
|
||
|
||
QList<BankProfileInfo> BankProfileDAO::getApplicationsByDeviceId(const QString &deviceId) {
|
||
QSqlQuery query(DatabaseManager::instance().database());
|
||
QList<BankProfileInfo> list;
|
||
|
||
query.prepare(R"(
|
||
SELECT id, device_id, pin_code, code, name, package, status, comment, install, pin_code_checked, phone, email, full_name, bank_profile_id, currency, amount
|
||
FROM bank_profiles
|
||
WHERE device_id = :device_id AND install = 'yes'
|
||
)");
|
||
query.bindValue(":device_id", deviceId);
|
||
|
||
if (!query.exec()) {
|
||
qWarning() << "Ошибка при получении приложений по deviceId:" << query.lastError().text();
|
||
return {};
|
||
}
|
||
|
||
while (query.next()) {
|
||
list.append(parseApplication(query));
|
||
}
|
||
|
||
return list;
|
||
}
|
||
|
||
QList<BankProfileInfo> BankProfileDAO::getAllApplicationsByDeviceId(const QString &deviceId) {
|
||
QSqlQuery query(DatabaseManager::instance().database());
|
||
QList<BankProfileInfo> list;
|
||
|
||
query.prepare(R"(
|
||
SELECT id, device_id, pin_code, code, name, package, status, comment, install, pin_code_checked, phone, email, full_name, bank_profile_id, currency, amount
|
||
FROM bank_profiles
|
||
WHERE device_id = :device_id
|
||
)");
|
||
query.bindValue(":device_id", deviceId);
|
||
|
||
if (!query.exec()) {
|
||
qWarning() << "Ошибка при получении всех приложений по deviceId:" << query.lastError().text();
|
||
return {};
|
||
}
|
||
|
||
while (query.next()) {
|
||
list.append(parseApplication(query));
|
||
}
|
||
|
||
return list;
|
||
}
|
||
|
||
bool BankProfileDAO::updateProfileInfo(
|
||
const int &appId,
|
||
const QString &fullName,
|
||
const QString &phone,
|
||
const QString &email
|
||
) {
|
||
QSqlQuery query(DatabaseManager::instance().database());
|
||
|
||
query.prepare(R"(
|
||
UPDATE bank_profiles
|
||
SET full_name = :full_name, phone = :phone, email = :email
|
||
WHERE id = :id
|
||
)");
|
||
|
||
query.bindValue(":id", appId);
|
||
query.bindValue(":full_name", fullName);
|
||
query.bindValue(":phone", phone);
|
||
query.bindValue(":email", email);
|
||
|
||
if (!query.exec()) {
|
||
qWarning() << "Ошибка при обновлении профиля приложения:" << query.lastError().text();
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
bool BankProfileDAO::updateAmount(const int appId, const double amount) {
|
||
QSqlQuery query(DatabaseManager::instance().database());
|
||
query.prepare("UPDATE bank_profiles SET amount = :amount WHERE id = :id");
|
||
query.bindValue(":amount", amount);
|
||
query.bindValue(":id", appId);
|
||
if (!query.exec()) {
|
||
qWarning() << "Ошибка при обновлении amount в application:" << query.lastError().text();
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
bool BankProfileDAO::updateBankProfileId(const int appId, const QString &bankProfileId) {
|
||
QSqlQuery query(DatabaseManager::instance().database());
|
||
query.prepare("UPDATE bank_profiles SET bank_profile_id = :bank_profile_id WHERE id = :id");
|
||
query.bindValue(":bank_profile_id", bankProfileId);
|
||
query.bindValue(":id", appId);
|
||
if (!query.exec()) {
|
||
qWarning() << "Ошибка при обновлении bank_profile_id:" << query.lastError().text();
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
QList<BankProfileInfo> BankProfileDAO::findAllByBankProfileId(const QString &bankProfileId) {
|
||
QList<BankProfileInfo> list;
|
||
QSqlQuery query(DatabaseManager::instance().database());
|
||
query.prepare(R"(
|
||
SELECT id, device_id, pin_code, code, name, package, status, comment, install, pin_code_checked, phone, email, full_name, bank_profile_id, currency, amount
|
||
FROM bank_profiles
|
||
WHERE bank_profile_id = :bank_profile_id
|
||
)");
|
||
query.bindValue(":bank_profile_id", bankProfileId);
|
||
if (!query.exec()) {
|
||
qWarning() << "Ошибка при поиске bank_profiles по bank_profile_id:" << query.lastError().text();
|
||
return list;
|
||
}
|
||
while (query.next()) {
|
||
list.append(parseApplication(query));
|
||
}
|
||
return list;
|
||
}
|
||
|
||
bool BankProfileDAO::activateAppsForDevice(const QString &deviceId) {
|
||
QSqlQuery query(DatabaseManager::instance().database());
|
||
query.prepare(R"(
|
||
UPDATE bank_profiles SET status = 'active'
|
||
WHERE device_id = :device_id AND install = 'yes' AND pin_code_checked = 'yes'
|
||
)");
|
||
query.bindValue(":device_id", deviceId);
|
||
if (!query.exec()) {
|
||
qWarning() << "Ошибка при активации приложений:" << query.lastError().text();
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
bool BankProfileDAO::deactivateAppsForDevice(const QString &deviceId) {
|
||
QSqlQuery query(DatabaseManager::instance().database());
|
||
query.prepare(R"(
|
||
UPDATE bank_profiles SET status = 'off'
|
||
WHERE device_id = :device_id AND install = 'yes'
|
||
)");
|
||
query.bindValue(":device_id", deviceId);
|
||
if (!query.exec()) {
|
||
qWarning() << "Ошибка при деактивации приложений:" << query.lastError().text();
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
bool BankProfileDAO::checkInstalledApps(const QString &deviceId, const QSet<QString> &apps) {
|
||
QSqlQuery query(DatabaseManager::instance().database());
|
||
const QSettings settings("config.ini", QSettings::IniFormat);
|
||
QStringList banks = settings.value("apps/list", QStringList()).toStringList();
|
||
|
||
// Сбросить install = 'no' для банков которых нет в текущем apps/list
|
||
if (!banks.isEmpty()) {
|
||
QStringList placeholders;
|
||
for (int i = 0; i < banks.size(); ++i) placeholders << "?";
|
||
query.prepare(QString(R"(
|
||
UPDATE bank_profiles SET install = 'no'
|
||
WHERE device_id = ? AND code NOT IN (%1)
|
||
)").arg(placeholders.join(",")));
|
||
query.addBindValue(deviceId);
|
||
for (const QString &bank : banks) query.addBindValue(bank);
|
||
if (!query.exec()) {
|
||
qWarning() << "Ошибка при сбросе install:" << query.lastError().text();
|
||
}
|
||
}
|
||
|
||
for (const QString &bank: banks) {
|
||
QString package = settings.value(bank + "/android_package_name").toString();
|
||
QString name = settings.value(bank + "/name").toString();
|
||
|
||
const QString currency = settings.value(bank + "/currency").toString();
|
||
|
||
query.prepare(R"(
|
||
INSERT INTO bank_profiles (device_id, name, code, package, status, install, pin_code_checked, currency)
|
||
VALUES (:device_id, :name, :code, :package, :status, :install, :pin_code_checked, :currency)
|
||
ON CONFLICT(device_id, code)
|
||
DO UPDATE SET
|
||
install = excluded.install,
|
||
currency = CASE WHEN excluded.currency != '' THEN excluded.currency ELSE currency END
|
||
)");
|
||
|
||
query.bindValue(":device_id", deviceId);
|
||
query.bindValue(":code", bank);
|
||
query.bindValue(":name", name);
|
||
query.bindValue(":package", package);
|
||
query.bindValue(":status", "off");
|
||
query.bindValue(":pin_code_checked", "no");
|
||
query.bindValue(":install", apps.contains(package) ? "yes" : "no");
|
||
query.bindValue(":currency", currency);
|
||
|
||
if (!query.exec()) {
|
||
qWarning() << "Ошибка при проверке приложений:" << query.lastError().text();
|
||
return false;
|
||
}
|
||
}
|
||
|
||
|
||
return true;
|
||
}
|
||
|
||
bool BankProfileDAO::migrateDeviceId(const QString &oldDeviceId, const QString &newDeviceId) {
|
||
QSqlQuery query(DatabaseManager::instance().database());
|
||
query.prepare("UPDATE bank_profiles SET device_id = :new_id WHERE device_id = :old_id");
|
||
query.bindValue(":new_id", newDeviceId);
|
||
query.bindValue(":old_id", oldDeviceId);
|
||
if (!query.exec()) {
|
||
qWarning() << "[BankProfileDAO] migrateDeviceId failed:" << query.lastError().text();
|
||
return false;
|
||
}
|
||
qDebug() << "[BankProfileDAO] migrated" << query.numRowsAffected() << "profiles from" << oldDeviceId << "to" << newDeviceId;
|
||
return true;
|
||
}
|