1
0
forked from BRT/arc
arc/views/bank/AccountSettingsWindow.cpp
2025-07-31 11:32:52 +05:00

353 lines
16 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 "AccountSettingsWindow.h"
#include <QLabel>
#include <QMessageBox>
#include <QPushButton>
#include <QScrollArea>
#include <QCoreApplication>
#include <QVBoxLayout>
#include <QHeaderView>
#include <QJsonArray>
#include <QJsonObject>
#include <QThread>
#include "birbank/LoginAndCheckAccountsBirbankScript.h"
#include "toss/LoginAndCheckAccountsTossScript.h"
#include "dao/AccountDAO.h"
#include "dao/ApplicationDAO.h"
#include "device/EditBankAccountDialog.h"
#include "device/EditBankDialog.h"
#include "net/NetworkService.h"
AccountSettingsWindow::AccountSettingsWindow(
QWidget *parent, QString deviceId, QString deviceName, const ApplicationInfo &app
) : QWidget(parent,
Qt::Window
| Qt::WindowTitleHint
| Qt::WindowSystemMenuHint
| Qt::WindowCloseButtonHint
| Qt::WindowMinMaxButtonsHint),
m_deviceId(std::move(deviceId)),
m_deviceName(std::move(deviceName)),
m_applicationInfo(app) {
setWindowTitle("Настройки банка [" + app.name + "]");
setMinimumSize(800, 400);
setMaximumSize(1000, 800);
resize(800, 400);
// 1. Редактирование пин-кода
// 2. Включение/отключения банка
// 3. Работа с картами (вкл/выкл) и редактирование цифр
// 4. Запуск проверки пин-код и парсинга аккаунтов
auto *mainLayout = new QVBoxLayout(this);
// Скролл-область
auto *scrollArea = new QScrollArea(this);
scrollArea->setWidgetResizable(true);
// Виджет-контейнер, в котором будет layout с таблицами и лейблами
auto *contentWidget = new QWidget;
auto *layout = new QVBoxLayout(contentWidget);
// Убираем отступы и рамку
contentWidget->setContentsMargins(0, 0, 0, 0); // Убираем отступы
layout->setContentsMargins(4, 4, 4, 4); // Убираем отступы у layout
// scrollArea->setStyleSheet("border: none;"); // Убираем рамку
layout->setAlignment(Qt::AlignTop);
QHBoxLayout *row1 = new QHBoxLayout();
QString status = QString("Статус: ") + (m_applicationInfo.status == "active"
? "<span style='color:green;'>Активен</span>"
: "<span style='color:red;'>Неактивен</span>") +
QString(", пин-код: ") + (m_applicationInfo.pinCodeChecked
? "<span style='color:green;'>Проверен</span>"
: "<span style='color:red;'>Не проверен</span>");
m_statusLabel = new QLabel(status);
m_statusLabel->setTextFormat(Qt::RichText);
row1->addWidget(m_statusLabel);
QPushButton *editBankBtn = new QPushButton("Редактировать");
editBankBtn->setStyleSheet(
"background-color: green;"
"color: white;"
);
editBankBtn->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
row1->addWidget(editBankBtn);
connect(editBankBtn, &QPushButton::clicked, this, [this]() {
BankEditDialog dlg(m_applicationInfo, this);
if (dlg.exec() == QDialog::Accepted) {
const QString pinCode = dlg.firstValue();
const QString comment = dlg.secondValue();
bool on = dlg.toggled();
if (!ApplicationDAO::update(m_applicationInfo.id, pinCode, comment, on ? "active" : "off")) {
qDebug() << "Cant update bank data";
} else {
m_applicationInfo.pinCode = pinCode;
m_applicationInfo.comment = comment;
m_applicationInfo.status = on ? "active" : "off";
QString status = QString("Статус: ") + (on
? "<span style='color:green;'>Активен</span>"
: "<span style='color:red;'>Неактивен</span>") +
QString(", пин-код: ") + (m_applicationInfo.pinCodeChecked
? "<span style='color:green;'>Проверен</span>"
: "<span style='color:red;'>Не проверен</span>");
m_statusLabel->setText(status);
m_commentLabel->setText(comment);
sendAppStatus(m_applicationInfo.deviceId, m_applicationInfo.code, on ? "active" : "off");
}
}
});
layout->addLayout(row1);
QHBoxLayout *commentRow = new QHBoxLayout();
m_commentLabel = new QLabel(m_applicationInfo.comment);
m_commentLabel->setStyleSheet(
"color: gray;"
"margin-bottom: 8px;"
);
commentRow->addWidget(m_commentLabel);
layout->addLayout(commentRow);
QPushButton *soloButton = new QPushButton("Запустить проверку пин-кода");
soloButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
// soloButton->setStyleSheet("");
soloButton->setStyleSheet(
"background-color: orange;"
"color: white;"
);
QObject::connect(soloButton, &QPushButton::clicked, [&, this]() {
if (!m_applicationInfo.pinCode.isEmpty()) {
QMessageBox msgBox(this);
msgBox.setWindowTitle(tr("Запустить проверку пин-кода?"));
msgBox.setText(
"Запуститься скрипт проверки входа в банк " + m_applicationInfo.name +
" по пин-коду. Окно с настройками закроется.");
QPushButton *deleteBtn = msgBox.addButton(tr("Запустить"), QMessageBox::AcceptRole);
QPushButton *closeBtn = msgBox.addButton(tr("Отмена"), QMessageBox::RejectRole);
msgBox.setDefaultButton(closeBtn);
msgBox.setModal(true);
msgBox.exec();
if (msgBox.clickedButton() == deleteBtn) {
startCheckPinCode(m_applicationInfo.code);
close();
}
}
});
layout->addWidget(soloButton);
layout->addWidget(new QLabel("Счета"));
QTableWidget *tableWidget = new QTableWidget(this);
tableWidget->setSelectionMode(QAbstractItemView::NoSelection);
tableWidget->setFocusPolicy(Qt::NoFocus);
reloadContent(tableWidget);
tableWidget->resizeColumnsToContents();
layout->addWidget(tableWidget);
QPushButton *addAccountButton = new QPushButton("Добавить аккаунт");
addAccountButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
AccountInfo account;
connect(addAccountButton, &QPushButton::clicked, this, [this, tableWidget, account]() {
EditBankAccountDialog dlg(account, this);
if (dlg.exec() == QDialog::Accepted) {
const QString cardNumber = dlg.cardNumberValue();
const QString currency = dlg.currencyValue();
bool on = dlg.toggled();
AccountInfo accountInfo;
accountInfo.currency = currency;
accountInfo.description = cardNumber;
accountInfo.amount = 0;
accountInfo.appCode = m_applicationInfo.code;
accountInfo.deviceId = m_deviceId;
accountInfo.status = on ? AccountStatus::Active : AccountStatus::Off;
accountInfo.lastNumbers = cardNumber.right(4);
if (!AccountDAO::upsertAccount(accountInfo)) {
qDebug() << "Cant insert bank account data";
} else {
reloadContent(tableWidget);
tableWidget->resizeColumnsToContents();
updateAccountData(accountInfo);
}
}
});
layout->addWidget(addAccountButton);
tableWidget->resizeRowsToContents();
// Добавим вертикальный Spacer в конец, чтобы прокручиваемая область не растягивала контент
// QSpacerItem *spacer = new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding);
// layout->addItem(spacer);
contentWidget->setLayout(layout);
scrollArea->setWidget(contentWidget);
mainLayout->addWidget(scrollArea);
setLayout(mainLayout);
}
void AccountSettingsWindow::startCheckPinCode(const QString &appCode) {
if (appCode == "birbank") {
const auto thread = new QThread(nullptr);
auto *worker = new LoginAndCheckAccountsBirbankScript(m_deviceId, appCode, nullptr);
worker->moveToThread(thread);
connect(thread, &QThread::started, worker, &LoginAndCheckAccountsBirbankScript::start);
connect(worker, &LoginAndCheckAccountsBirbankScript::finished, thread, &QThread::quit);
connect(worker, &LoginAndCheckAccountsBirbankScript::finished, worker, &QObject::deleteLater);
connect(thread, &QThread::finished, thread, &QObject::deleteLater);
thread->start();
} else if (appCode == "toss") {
const auto thread = new QThread(nullptr);
auto *worker = new LoginAndCheckAccountsTossScript(m_deviceId, appCode, nullptr);
worker->moveToThread(thread);
connect(thread, &QThread::started, worker, &LoginAndCheckAccountsTossScript::start);
connect(worker, &LoginAndCheckAccountsTossScript::finished, thread, &QThread::quit);
connect(worker, &LoginAndCheckAccountsTossScript::finished, worker, &QObject::deleteLater);
connect(thread, &QThread::finished, thread, &QObject::deleteLater);
thread->start();
}
}
void AccountSettingsWindow::sendAppStatus(const QString &deviceId, const QString &code, const QString &status) {
QJsonObject obj;
obj["code"] = code;
obj["status"] = status;
auto *paymentThread = new QThread;
auto *networkService = new NetworkService;
networkService->moveToThread(paymentThread);
networkService->setDeviceId(deviceId);
networkService->setPayload(QJsonDocument(obj).toJson());
QObject::connect(paymentThread, &QThread::started, networkService, &NetworkService::postAppStatus);
QObject::connect(networkService, &NetworkService::finished, paymentThread, &QThread::quit);
QObject::connect(networkService, &NetworkService::finished, networkService, &QObject::deleteLater);
QObject::connect(paymentThread, &QThread::finished, paymentThread, &QThread::deleteLater);
paymentThread->start();
}
void AccountSettingsWindow::updateAccountData(const AccountInfo &account) {
QJsonArray list;
QJsonObject obj;
obj["appName"] = account.appCode;
obj["lastNumbers"] = account.lastNumbers;
obj["amount"] = account.amount;
obj["description"] = account.description;
obj["currency"] = account.currency;
obj["status"] = accountStatusToString(account.status);
list.append(obj);
auto *paymentThread = new QThread;
auto *networkService = new NetworkService;
networkService->moveToThread(paymentThread);
networkService->setDeviceId(account.deviceId);
networkService->setPayload(QJsonDocument(list).toJson());
QObject::connect(paymentThread, &QThread::started, networkService, &NetworkService::postAccountsData);
QObject::connect(networkService, &NetworkService::finished, paymentThread, &QThread::quit);
QObject::connect(networkService, &NetworkService::finished, networkService, &QObject::deleteLater);
QObject::connect(paymentThread, &QThread::finished, paymentThread, &QThread::deleteLater);
paymentThread->start();
}
void AccountSettingsWindow::reloadContent(QTableWidget *tableWidget) {
QList<AccountInfo> accounts = AccountDAO::getAccounts(m_deviceId, m_applicationInfo.code);
tableWidget->clearContents();
tableWidget->setRowCount(accounts.length());
tableWidget->setColumnCount(7);
tableWidget->setHorizontalHeaderLabels({
"Время обновления",
"Номер",
"",
"Сумма",
"Валюта",
"Статус",
""
});
tableWidget->setWordWrap(true);
tableWidget->setTextElideMode(Qt::ElideNone);
tableWidget->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft | Qt::AlignVCenter);
tableWidget->horizontalHeader()->setSectionResizeMode(5, QHeaderView::ResizeToContents);
tableWidget->verticalHeader()->setSectionResizeMode(6, QHeaderView::ResizeToContents);
tableWidget->horizontalHeader()->setSectionResizeMode(1, QHeaderView::Stretch);
for (int k = 0; k < accounts.size(); ++k) {
const AccountInfo &account = accounts[k];
QTableWidgetItem *time = new QTableWidgetItem(account.updateTime.toString("dd.MM.yyyy HH:mm:ss"));
time->setTextAlignment(Qt::AlignLeft | Qt::AlignVCenter);
time->setFlags(time->flags() & ~Qt::ItemIsEditable);
tableWidget->setItem(k, 0, time);
QTableWidgetItem *desc = new QTableWidgetItem(account.description);
desc->setTextAlignment(Qt::AlignLeft | Qt::AlignVCenter);
desc->setFlags(desc->flags() & ~Qt::ItemIsEditable);
tableWidget->setItem(k, 1, desc);
QTableWidgetItem *lastNumbers = new QTableWidgetItem(account.lastNumbers);
lastNumbers->setTextAlignment(Qt::AlignLeft | Qt::AlignVCenter);
lastNumbers->setFlags(lastNumbers->flags() & ~Qt::ItemIsEditable);
tableWidget->setItem(k, 2, lastNumbers);
QTableWidgetItem *amount = new QTableWidgetItem(QString::number(account.amount));
amount->setTextAlignment(Qt::AlignLeft | Qt::AlignVCenter);
amount->setFlags(amount->flags() & ~Qt::ItemIsEditable);
tableWidget->setItem(k, 3, amount);
QTableWidgetItem *currency = new QTableWidgetItem(account.currency);
currency->setTextAlignment(Qt::AlignLeft | Qt::AlignVCenter);
currency->setFlags(currency->flags() & ~Qt::ItemIsEditable);
tableWidget->setItem(k, 4, currency);
QTableWidgetItem *status = new QTableWidgetItem(accountStatusToUiString(account.status));
status->setTextAlignment(Qt::AlignLeft | Qt::AlignVCenter);
status->setFlags(status->flags() & ~Qt::ItemIsEditable);
if (account.status != AccountStatus::Active) {
status->setForeground(QBrush(Qt::red));
}
tableWidget->setItem(k, 5, status);
auto *editBankAccountBtn = new QPushButton("Редактировать", tableWidget);
tableWidget->setCellWidget(k, 6, editBankAccountBtn);
connect(editBankAccountBtn, &QPushButton::clicked, this, [this, tableWidget, account]() {
EditBankAccountDialog dlg(account, this);
if (dlg.exec() == QDialog::Accepted) {
const QString cardNumber = dlg.cardNumberValue();
const QString currency = dlg.currencyValue();
bool on = dlg.toggled();
if (!AccountDAO::updateAccountById(account.id, on ? "active" : "off", cardNumber, currency)) {
qDebug() << "Cant update bank account data";
} else {
reloadContent(tableWidget);
AccountInfo accountInfo;
accountInfo.currency = currency;
accountInfo.description = cardNumber;
accountInfo.amount = account.amount;
accountInfo.currency = currency;
accountInfo.appCode = m_applicationInfo.code;
accountInfo.deviceId = m_deviceId;
accountInfo.status = on ? AccountStatus::Active : AccountStatus::Off;
accountInfo.lastNumbers = cardNumber.right(4);
updateAccountData(accountInfo);
}
}
});
}
}