344 lines
11 KiB
C++
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();
|
|
} |