Files
SimpleAccount/mainwidget.cpp
2026-02-27 12:29:27 +08:00

344 lines
11 KiB
C++

#include "mainwidget.h"
#include "./ui_mainwidget.h"
#include "filterform.h"
#include <QDir>
#include <QFileDialog>
#include <QInputDialog>
#include <QMessageBox>
#include <QPainter>
#include <QProcess>
MainWidget::MainWidget(QWidget* parent) : QDialog(parent), ui(new Ui::MainWidget)
{
ui->setupUi(this);
BaseInit();
Init();
RefreshData();
setWindowTitle("账单记录器V1.0.5");
Calculate();
auto size = Util::GetMainSize();
resize(size.first, size.second);
setWindowFlags(windowFlags() & ~Qt::WindowMaximizeButtonHint);
setWindowIcon(QIcon("://resource/ico.ico"));
}
MainWidget::~MainWidget()
{
delete ui;
}
void MainWidget::Init()
{
Util::Init();
auto dbPath = Util::GetWorkDir() + "/account.db";
sqlOpr_ = std::make_unique<ACTSqlOpr>();
if (!sqlOpr_->OpenDb(dbPath)) {
QMessageBox::warning(this, "错误", QString::fromStdString(sqlOpr_->GetLastErr()));
return;
}
comSqlOpr_ = std::make_unique<ComSqlOpr>(sqlOpr_->GetDb());
repaySqlOpr_ = std::make_unique<RepaySqlOpr>(sqlOpr_->GetDb());
statistic_ = std::make_shared<Statistic>(repaySqlOpr_);
auto mediaDir = Util::GetMediaDir();
if (!QDir(QString::fromStdString(mediaDir)).exists()) {
QDir().mkdir(QString::fromStdString(mediaDir));
}
ui->timeEdit->setDisplayFormat("HH:mm:ss");
ui->rbNoLimit->setChecked(true);
ui->btnRecord->setStyleSheet("background-color: #b1a5ccff;");
ui->dateEdit->setDate(QDate::currentDate());
ui->timeEdit->setTime(QTime::currentTime());
ui->cbClassify->setEditable(true);
ui->edCash->setValidator(new QDoubleValidator(0.0, 10000000.0, 2, this));
ui->edHighCash->setValidator(new QDoubleValidator(0.0, 10000000.0, 2, this));
ui->edLowCash->setValidator(new QDoubleValidator(0.0, 10000000.0, 2, this));
ui->edDays->setValidator(new QIntValidator(0, 10000000, this));
ui->lbTotal->setStyleSheet("QLabel {"
"font-size: 20px;"
"color: blue;"
"}");
ui->lbCurCash->setStyleSheet("QLabel {"
"color: blue;"
"}");
ui->lbCredit->setStyleSheet("QLabel {"
"color: blue;"
"}");
connect(ui->btnClassifyAdd, &QPushButton::clicked, this, &MainWidget::AddClassify);
connect(ui->btnClassifyDel, &QPushButton::clicked, this, &MainWidget::DelClassify);
connect(ui->btnRecord, &QPushButton::clicked, this, &MainWidget::Record);
connect(ui->btnSet, &QPushButton::clicked, this, [this]() {
QProcess process;
auto editor = Util::GetEditor();
QStringList args;
args << QString::fromStdString(Util::GetConfigPath());
process.startDetached(QString::fromStdString(editor), args);
process.waitForStarted();
});
connect(ui->btnSearch, &QPushButton::clicked, this, &MainWidget::Search);
connect(ui->btnSetNow, &QPushButton::clicked, this, [this]() {
ui->dateEdit->setDate(QDate::currentDate());
ui->timeEdit->setTime(QTime::currentTime());
});
connect(ui->btnAddFile, &QPushButton::clicked, this, &MainWidget::SelectImg);
connect(ui->btnClearFile, &QPushButton::clicked, this, [this]() { ui->edFile->clear(); });
}
bool MainWidget::RefreshData()
{
if (!RefreshClassify()) {
return false;
}
return true;
}
bool MainWidget::Calculate()
{
AccountRecordList list;
if (!sqlOpr_->GetAccountList(list)) {
QMessageBox::warning(this, "错误", QString::fromStdString(sqlOpr_->GetLastErr()));
return false;
}
// 计算账户余额等信息
statistic_->Calculate(list);
auto* d = SharedData::instance();
auto curCash = static_cast<int32_t>(Util::GetCurCash() * 100);
auto curSave = static_cast<int32_t>(Util::GetCurSave() * 100);
auto curRemain = d->ttCashIn_ - d->ttCashOut_ + curCash - d->ttCashPay_ + d->ttCreditCash_;
ui->lbCurCash->setText(QString::number(curRemain / 100.0));
auto creditOutTotal = d->ttCreditOut_ - d->ttCashPay_ + d->ttCreditCash_;
QString credit = QString("%1/%2").arg(creditOutTotal / 100.0, 0, 'f', 2).arg(d->ttCreditIn_ / 100.0, 0, 'f', 2);
ui->lbCredit->setText(credit);
auto youHave = curRemain + d->ttCreditIn_ - (d->ttCreditOut_ + d->ttCreditCash_ - d->ttCashPay_);
ui->lbTotal->setText("" + QString::number(youHave / 100.0));
return true;
}
void MainWidget::closeEvent(QCloseEvent* event)
{
auto size = this->size();
Util::SetMainSize(size.width(), size.height());
QWidget::closeEvent(event);
}
void MainWidget::BaseInit()
{
ui->cbCashType->addItem("现金支出");
ui->cbCashType->addItem("现金收入");
ui->cbCashType->addItem("信用支出");
ui->cbCashType->addItem("信用收入");
ui->cbCashType->addItem("信用借款");
ui->cbCashType->setCurrentIndex(0);
}
bool MainWidget::RefreshClassify()
{
ClassifyRecordList classifyList;
if (!comSqlOpr_->GetClassifyList(classifyList)) {
QMessageBox::warning(this, "错误", QString::fromStdString(comSqlOpr_->GetLastErr()));
return false;
}
ui->cbClassify->clear();
for (const auto& classify : classifyList) {
ui->cbClassify->addItem(QString::fromStdString(classify.value));
}
if (!classifyList.empty()) {
ui->cbClassify->setCurrentIndex(0);
}
return true;
}
void MainWidget::SelectImg()
{
QString imagePath =
QFileDialog::getOpenFileName(this, "选择图片", QDir::homePath(), "图片文件 (*.jpg *.jpeg *.png *.bmp *.gif)");
if (imagePath.isEmpty()) {
return;
}
ui->edFile->setText(imagePath);
}
bool MainWidget::AddClassify()
{
// 弹出输入对话框
bool ok;
QString text = QInputDialog::getText(this, tr("添加分类"), tr("请输入分类名称:"), QLineEdit::Normal, "", &ok);
text = text.trimmed();
if (!ok || text.isEmpty()) {
return false;
}
// 先检查是否已存在
if (comSqlOpr_->CheckClassifyExist(text.toStdString())) {
QMessageBox::warning(this, tr("错误"), tr("分类已存在"));
return false;
}
CommonRecord record;
record.key = "分类";
record.value = text.toStdString();
record.type = "";
if (!comSqlOpr_->InserItem(record)) {
QMessageBox::warning(this, tr("错误"), tr("添加分类失败"));
return false;
}
RefreshClassify();
return true;
}
bool MainWidget::DelClassify()
{
auto curClassify = ui->cbClassify->currentText();
if (curClassify == "默认") {
QMessageBox::warning(this, "错误", "默认分类无法删除");
return false;
}
if (QMessageBox::question(this, "删除分类", QString("确定删除分类<%1>吗?").arg(curClassify)) != QMessageBox::Yes) {
return false;
}
if (!comSqlOpr_->DeleteItem(curClassify.toStdString())) {
QMessageBox::warning(this, "错误", QString::fromStdString(comSqlOpr_->GetLastErr()));
return false;
}
RefreshClassify();
return true;
}
void MainWidget::Record()
{
// 确认添加
if (QMessageBox::question(this, "确认添加", "确定添加记录吗?") != QMessageBox::Yes) {
return;
}
// 款项分类
auto curType = ui->cbCashType->currentText();
// 基础分类
auto curClassify = ui->cbClassify->currentText();
// 记录事项
auto thing = ui->lineEdit->text().trimmed();
if (thing.isEmpty()) {
QMessageBox::warning(this, "错误", "记录事项不能为空");
return;
}
// 时间日期
auto date = ui->dateEdit->date();
auto time = ui->timeEdit->time();
QDateTime dateTime(date, time);
auto dateTimeStr = dateTime.toString("yyyy-MM-dd HH:mm:ss");
// 金额
// 查看附件
auto attach = ui->edFile->text().trimmed();
if (!attach.isEmpty()) {
QFile file(attach);
if (!file.exists()) {
QMessageBox::warning(this, "错误", "附件文件不存在");
return;
}
}
AccountRecord record;
record.money = Util::CashInt(ui->edCash->text().toDouble());
record.thing = thing.toStdString();
record.dt = dateTimeStr.toStdString();
record.classify = curClassify.toStdString();
record.payType = curType.toStdString();
if (!attach.isEmpty()) {
record.additionFile = Util::NewUUIDName(attach).toStdString();
}
if (!sqlOpr_->AppendAccount(record)) {
QMessageBox::warning(this, "错误", QString::fromStdString(sqlOpr_->GetLastErr()));
return;
}
if (!attach.isEmpty()) {
QFile::copy(attach, QString::fromStdString(Util::GetMediaDir() + "/" + record.additionFile));
};
Calculate();
QMessageBox::information(this, "提示", "添加成功");
}
void MainWidget::Search()
{
auto* d = SharedData::instance();
if (ui->ckType->isChecked()) {
d->flType = true;
d->type = ui->cbCashType->currentText();
} else {
d->flType = false;
}
if (ui->ckKey->isChecked()) {
d->flKeys = true;
d->key = ui->edKey->text().trimmed();
if (d->key.isEmpty()) {
QMessageBox::warning(this, "错误", "搜索关键字不能为空");
return;
}
} else {
d->flKeys = false;
}
if (ui->ckDays->isChecked()) {
d->flDays = true;
if (ui->edDays->text().isEmpty()) {
QMessageBox::warning(this, "错误", "天数不能为空");
return;
}
d->days = ui->edDays->text().toInt();
} else {
d->flDays = false;
}
if (ui->rbBetween->isChecked()) {
d->filter = CashFilter::FIL_BETWEEN;
if (ui->edLowCash->text().isEmpty() || ui->edHighCash->text().isEmpty()) {
QMessageBox::warning(this, "错误", "金额范围不能为空");
return;
}
d->lowMoney = static_cast<int>(ui->edLowCash->text().toDouble() * 100);
d->highMoney = static_cast<int>(ui->edHighCash->text().toDouble() * 100);
} else if (ui->rbHigh->isChecked()) {
d->filter = CashFilter::FIL_HIGHER;
if (ui->edHighCash->text().isEmpty()) {
QMessageBox::warning(this, "错误", "金额高范围不能为空");
return;
}
d->highMoney = static_cast<int>(ui->edHighCash->text().toDouble() * 100);
} else if (ui->rbLow->isChecked()) {
d->filter = CashFilter::FIL_LOWER;
if (ui->edLowCash->text().isEmpty()) {
QMessageBox::warning(this, "错误", "金额低范围不能为空");
return;
}
d->lowMoney = static_cast<int>(ui->edLowCash->text().toDouble() * 100);
} else {
d->filter = CashFilter::FIL_NO_LIMIT;
}
if (ui->ckClassify->isChecked()) {
d->flClassify = true;
d->classify = ui->cbClassify->currentText();
} else {
d->flClassify = false;
}
FilterForm* filterForm = new FilterForm(this, sqlOpr_, comSqlOpr_, repaySqlOpr_);
filterForm->exec();
Calculate();
}