完成充值页面的所有功能(不包括写卡);新建消费页面,完成跳转和查询卡函数。

This commit is contained in:
Jingfan Ke 2024-07-30 22:32:30 +08:00
parent 9b227f3a14
commit 8968bba852
9 changed files with 792 additions and 11 deletions

View File

@ -11,7 +11,9 @@ CONFIG += c++17
SOURCES += \
VCD.cpp \
VCDOurs.cpp \
consumePage.cpp \
databaseAPI.cpp \
depositPage.cpp \
deviceAPI.cpp \
main.cpp \
mainwindow.cpp \

51
consumePage.cpp Normal file
View File

@ -0,0 +1,51 @@
#include "mainwindow.h"
#include "ui_mainwindow.h"
/**
* @brief
*
* @param void
* @return void
* @author
* @date 2024-07-30
*/
void MainWindow::on_ConsumptionAction_triggered()
{
ui->stackedWidget->setCurrentWidget(ui->consumePage);
}
/**
* @brief
*
*
* Inventory的查询结果10
* @param void
* @return void
* @author
* @date 2024-07-30
*/
void MainWindow::on_consumeInventoryButton_clicked()
{
if (!reader.is_connected())
{
QMessageBox::warning(this, QString("提示"), QString("读卡器未连接,请设置。"));
if (ui->stackedWidget->currentWidget() != ui->settingPage)
{
ui->stackedWidget->setCurrentWidget(ui->settingPage);
}
return;
}
QStringList cardIdList = reader.inventory(10); // 最多显示10张卡
ui->consumeCardIdBox->clear();
if (cardIdList.empty())
{
QMessageBox::warning(this, "提示", "未发现卡片,请将卡片放置于读卡器上方。");
}
else
{
ui->consumeCardIdBox->addItems(cardIdList);
}
}

329
depositPage.cpp Normal file
View File

@ -0,0 +1,329 @@
#include "mainwindow.h"
#include "ui_mainwindow.h"
/**
* @brief
*
* @param void
* @return void
* @author
* @date 2024-07-30
*/
void MainWindow::on_depositAction_triggered()
{
ui->depositUserIdBox->clear();
depositUserIdFilled = false;
ui->stackedWidget->setCurrentWidget(ui->depositPage);
}
/**
* @brief
*
*
* Inventory的查询结果10
* @param void
* @return void
* @author
* @date 2024-07-30
*/
void MainWindow::on_depositInventoryButton_clicked()
{
if (!reader.is_connected())
{
QMessageBox::warning(this, QString("提示"), QString("读卡器未连接,请设置。"));
if (ui->stackedWidget->currentWidget() != ui->settingPage)
{
ui->stackedWidget->setCurrentWidget(ui->settingPage);
}
return;
}
QStringList cardIdList = reader.inventory(10); // 最多显示10张卡
ui->depositCardIdBox->clear();
if (cardIdList.empty())
{
QMessageBox::warning(this, "提示", "未发现卡片,请将卡片放置于读卡器上方。");
}
else
{
ui->depositCardIdBox->addItems(cardIdList);
}
}
/**
* @brief
*
* @param void
* @return void
* @details
*
*
* `topUpCard`
* @author
* @date 2024-07-30
*/
void MainWindow::on_depositByCardIdButton_clicked()
{
if (!softwareReady())
{
QMessageBox::warning(this, QString("提示"), QString("数据库未连接,请设置。"));
if (ui->stackedWidget->currentWidget() != ui->settingPage)
{
ui->stackedWidget->setCurrentWidget(ui->settingPage);
}
return;
}
if (!reader.is_connected())
{
QMessageBox::warning(this, QString("提示"), QString("读卡器未连接,请设置。"));
if (ui->stackedWidget->currentWidget() != ui->settingPage)
{
ui->stackedWidget->setCurrentWidget(ui->settingPage);
}
return;
}
if (!device.is_depositAllowed())
{
QMessageBox::warning(this, QString("提示"), QString("本设备不支持充值。"));
return;
}
if (ui->depositCardIdBox->currentIndex() == -1)
{
QMessageBox::warning(this, "提示", "请放置卡片并点击查询按钮。");
return;
}
QString cardId = ui->depositCardIdBox->currentText();
double topUpValue = ui->depositValueBox->value();
if (!(topUpValue > 0.00))
{
QMessageBox::warning(this, "提示", "请输入大于0.00的充值金额。");
return;
}
bool success = false;
QString info;
double originalBalance, finalBalance;
QString recordId;
success = topUpCard(cardId, topUpValue, originalBalance, finalBalance, recordId, info);
if (!success)
{
QMessageBox::warning(this, "提示", info + QString("\n充值失败。"));
return;
}
QString depositResultMessage = QString("充值成功:") + QString::number(topUpValue) + QString("\n");
depositResultMessage += QString("原余额:") + QString::number(originalBalance) + QString("\n");
depositResultMessage += QString("充值后余额:") + QString::number(finalBalance) + QString("\n");
depositResultMessage += QString("充值设备:") + device.getName() + QString("\n");
depositResultMessage += QString("交易记录号:") + recordId + QString("\n");
QMessageBox::information(this, "充值成功", depositResultMessage);
return;
}
/**
* @brief /
* //
* @param void
* @return void
* @details
*
* /
* /
* `topUpCard`
* @author
* @date 2024-07-30
*/
void MainWindow::on_depositByUserIdButton_clicked()
{
if (!softwareReady())
{
QMessageBox::warning(this, QString("提示"), QString("数据库未连接,请设置。"));
if (ui->stackedWidget->currentWidget() != ui->settingPage)
{
ui->stackedWidget->setCurrentWidget(ui->settingPage);
}
return;
}
if (!device.is_depositAllowed())
{
QMessageBox::warning(this, QString("提示"), QString("本设备不支持充值。"));
return;
}
if (!depositUserIdFilled)
{
QMessageBox::warning(this, "提示", "请填写学/工号。");
return;
}
int userId = ui->depositUserIdBox->value();
double topUpValue = ui->depositValueBox->value();
if (!(topUpValue > 0.00))
{
QMessageBox::warning(this, "提示", "请输入大于0.00的充值金额。");
return;
}
QSqlQuery query(db->getDatabase());
bool success = false;
query.prepare(QString("select id from card "
"where userId = :userId;"));
query.bindValue(":userId", userId);
success = query.exec();
if (!success)
{
QMessageBox::warning(this, "提示", "数据库异常。充值失败。");
return;
}
if (!query.next())
{
QMessageBox::warning(this, "提示", "学/工号未绑定卡。充值失败。");
return;
}
QString cardId = query.value("id").toString();
QString info;
double originalBalance = 0, finalBalance = 0;
QString recordId;
success = topUpCard(cardId, topUpValue, originalBalance, finalBalance, recordId, info);
if (!success)
{
QMessageBox::warning(this, "提示", info + QString("\n充值失败。"));
return;
}
QString depositResultMessage = QString("充值成功:") + QString::number(topUpValue) + QString("\n");
depositResultMessage += QString("原余额:") + QString::number(originalBalance) + QString("\n");
depositResultMessage += QString("充值后余额:") + QString::number(finalBalance) + QString("\n");
depositResultMessage += QString("充值设备:") + device.getName() + QString("\n");
depositResultMessage += QString("交易记录号:") + recordId + QString("\n");
QMessageBox::information(this, "充值成功", depositResultMessage);
return;
}
/**
* @brief
*
* `sp_depositCard`
* @param cardId
* @param topUpValue
* @param originalBalance
* @param finalBalance
* @param recordId
* @param info
* @return bool
* - true
* - false
* @details
*
*
* 9999.99
* `sp_depositCard`
* @author
* @date 2024-07-30
*/
bool MainWindow::topUpCard(QString cardId, double topUpValue, double &originalBalance, double &finalBalance, QString &recordId, QString &info)
{
if (!device.is_depositAllowed())
{
info = "设备不支持充值。";
return false;
}
QSqlQuery query(db->getDatabase());
bool success;
query.prepare(QString("select userId, `status`, balance from card "
"where id = :cardId;"));
query.bindValue(":cardId", cardId);
success = query.exec();
if (!success)
{
info = "数据库异常。";
return false;
}
if (!query.next())
{
info = "卡号不存在。";
return false;
}
int cardStatus = query.value("status").toInt();
if (cardStatus == -1)
{
info = "此卡已被挂失。";
return false;
}
if (cardStatus == 0)
{
info = "此卡未被启用。";
return false;
}
originalBalance = query.value("balance").toDouble();
int userId = query.value("userId").toInt();
if (originalBalance + topUpValue > (double)9999.99)
{
info = "充值金额超过限额。卡余额不得超过9999.99元。";
return false;
}
QDateTime currentTime = QDateTime::currentDateTime();
recordId = getRecordId(currentTime, userId, 1);
query.finish();
query.prepare(QString("call sp_depositCard (:cardId, :value, :recordId, :device, :time, :type, @newBalance);"));
query.bindValue(":cardId", cardId);
query.bindValue(":value", topUpValue);
query.bindValue(":recordId", recordId);
query.bindValue(":device", device.getId());
query.bindValue(":time", currentTime.toString("yyyy-MM-dd hh:mm:ss"));
query.bindValue(":type", 1);
success = query.exec();
if (!success)
{
info = "数据库异常。";
return false;
}
query.exec("select @newBalance;");
query.next();
finalBalance = query.value("@newBalance").toDouble();
/// @todo 写卡
return true;
}
/**
* @brief
* ID
* @param currentTime
* @param userId /
* @param recordType
* - 0
* - 1
* @return QString 30
* @details
* ID转换为11位长度的字符串0
* 4
* @author
* @date 2024-07-30
*/
QString MainWindow::getRecordId(QDateTime currentTime, int userId, int recordType)
{
QString timeStr = currentTime.toString("yyyyMMddhhmmss"); // 第0-13位时间
QString userIdStr = QString::number(userId).rightJustified(11, '0'); // 第14-24位用户学/工号
QString typeStr = QString::number(recordType); // 第25位记录类型
QString randomHex = QString::number(QRandomGenerator::global()->bounded(0x10000), 16).rightJustified(4, '0'); // 第26-29位随机十六进制数
QString recordId = timeStr + userIdStr + typeStr + randomHex; // 共30位
return recordId;
}

View File

@ -33,7 +33,7 @@ bool Device::is_depositAllowed()
/**
* @brief
*
* ID
* @param name
* @param db
* @return void
@ -43,7 +43,7 @@ bool Device::is_depositAllowed()
void Device::setDevice(QString name, Database* db)
{
QSqlQuery query(db->getDatabase());
query.prepare(QString("select depositAllowed from device "
query.prepare(QString("select id, depositAllowed from device "
"where name = :name;"));
query.bindValue(":name", name);
query.exec();
@ -51,12 +51,14 @@ void Device::setDevice(QString name, Database* db)
{
verified = true;
this->name = name;
depositAllowed = query.value(0).toBool();
depositAllowed = query.value("depositAllowed").toBool();
id = query.value("id").toInt();
}
else
{
verified = false;
depositAllowed = false;
id = -1;
}
}
@ -64,7 +66,7 @@ void Device::setDevice(QString name, Database* db)
/**
* @brief
* @param void
* @return QString类name属性
* @return QString
* - "未指定设备名"
* -
* - "(可充值)"
@ -85,9 +87,9 @@ QString Device::getNameAndDepositAllowed()
/**
* @brief
* @param void
* @return QString类name属性
* - "未指定设备名"
* -
* @return QString name属性
* - "未指定设备名"
* -
* @author
* @date 2024-07-29
*/
@ -96,3 +98,19 @@ QString Device::getName()
if (verified) return name;
else return QString("未指定设备名");
}
/**
* @brief ID
* @param void
* @return int ID
* - -1
* - ID
* @author
* @date 2024-07-30
*/
int Device::getId()
{
if (verified) return id;
else return -1;
}

View File

@ -19,12 +19,14 @@ private:
bool verified = false;
bool depositAllowed = false;
QString name = QString("未指定设备名");
int id = -1;
public:
void setDevice(QString name, Database *db);
QString getName();
QString getNameAndDepositAllowed();
int getId();
bool is_verified();
bool is_depositAllowed();

View File

@ -5,6 +5,8 @@
#include "quitAppPage.cpp"
#include "newCardPage.cpp"
#include "reportLossPage.cpp"
#include "depositPage.cpp"
#include "consumePage.cpp"
MainWindow::MainWindow(QWidget *parent)
@ -44,10 +46,13 @@ MainWindow::MainWindow(QWidget *parent)
ui->userIdBox->clear();
newCardUserIdFilled = false;
connect(ui->userIdBox, &QSpinBox::valueChanged, [this]{ newCardUserIdFilled = true; });
ui->reportLossUserIdBox->clear();
reportLossUserIdFilled = false;
connect(ui->reportLossUserIdBox, &QSpinBox::valueChanged, [this]{ reportLossUserIdFilled = true; });
connect(ui->depositUserIdBox, &QSpinBox::valueChanged, [this]{ depositUserIdFilled = true; });
// 设置启动页面
ui->stackedWidget->setCurrentWidget(ui->settingPage);
@ -58,4 +63,3 @@ MainWindow::~MainWindow()
{
delete ui;
}

View File

@ -8,6 +8,8 @@
#include <QMessageBox>
#include <QSqlQuery>
#include <QInputDialog>
#include <QDateTime>
#include <QRandomGenerator>
#include <readerAPI.h>
#include <databaseAPI.h>
@ -36,12 +38,15 @@ public:
bool verifyUser(int userId, QString prompt, QString &info);
bool transferCard(int userId, QString newCardId, QString oldCardId, QString &info);
bool reopenCard(QString cardId, QString &info);
bool topUpCard(QString cardId, double topUpValue, double &originalBalance, double &finalBalance, QString &recordId, QString &info);
QString getRecordId(QDateTime currentTime, int userId, int recordType);
private slots:
void on_settingAction_triggered();
void on_quitAppAction_triggered();
void on_NewCardAction_triggered();
void on_reportLossAction_triggered();
void on_depositAction_triggered();
void on_connectReaderButton_clicked();
void on_confirmQuitButton_clicked();
@ -49,6 +54,14 @@ private slots:
void on_inventoryButton_clicked();
void on_newCardButton_clicked();
void on_reportLossButton_clicked();
void on_depositInventoryButton_clicked();
void on_depositByCardIdButton_clicked();
void on_depositByUserIdButton_clicked();
void on_consumeInventoryButton_clicked();
void on_ConsumptionAction_triggered();
private:
Ui::MainWindow *ui;
@ -67,5 +80,6 @@ private:
bool newCardUserIdFilled; ///< 开卡时:初始时学/工号填写框被清空该变量为false当用户填写后该变量为true
bool reportLossUserIdFilled; ///< 挂失时:初始时学/工号填写框被清空该变量为false当用户填写后该变量为true
bool depositUserIdFilled; ///< 充值时:初始时学/工号填写框被清空该变量为false当用户填写后该变量为true
};
#endif // MAINWINDOW_H

View File

@ -27,7 +27,7 @@
<bool>true</bool>
</property>
<property name="currentIndex">
<number>3</number>
<number>2</number>
</property>
<widget class="QWidget" name="quitAppPage">
<widget class="QPushButton" name="confirmQuitButton">
@ -233,7 +233,11 @@
</widget>
</item>
<item row="4" column="1">
<widget class="QLineEdit" name="passwordEdit"/>
<widget class="QLineEdit" name="passwordEdit">
<property name="echoMode">
<enum>QLineEdit::EchoMode::Password</enum>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="deviceLabel">
@ -265,6 +269,153 @@
</property>
</widget>
</widget>
<widget class="QWidget" name="consumePage">
<widget class="QWidget" name="verticalLayoutWidget_4">
<property name="geometry">
<rect>
<x>200</x>
<y>110</y>
<width>291</width>
<height>80</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_6">
<item>
<widget class="QLabel" name="label_9">
<property name="font">
<font>
<pointsize>11</pointsize>
</font>
</property>
<property name="text">
<string>消费</string>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignCenter</set>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_6">
<item>
<widget class="QLabel" name="label_10">
<property name="text">
<string>金额:</string>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="consumeValueBox">
<property name="minimumSize">
<size>
<width>200</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>200</width>
<height>16777215</height>
</size>
</property>
<property name="font">
<font>
<pointsize>15</pointsize>
<bold>true</bold>
</font>
</property>
<property name="prefix">
<string/>
</property>
<property name="suffix">
<string> ¥</string>
</property>
<property name="minimum">
<double>0.000000000000000</double>
</property>
<property name="maximum">
<double>300.000000000000000</double>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QWidget" name="horizontalLayoutWidget_4">
<property name="geometry">
<rect>
<x>190</x>
<y>220</y>
<width>354</width>
<height>81</height>
</rect>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_7">
<item>
<widget class="QLabel" name="label_11">
<property name="text">
<string>请选择卡:</string>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="consumeCardIdBox">
<property name="minimumSize">
<size>
<width>200</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>200</width>
<height>16777215</height>
</size>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="consumeInventoryButton">
<property name="minimumSize">
<size>
<width>80</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>80</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>查询</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QPushButton" name="consumeButton">
<property name="geometry">
<rect>
<x>310</x>
<y>330</y>
<width>80</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>确定</string>
</property>
</widget>
</widget>
<widget class="QWidget" name="newCardPage">
<widget class="QWidget" name="gridLayoutWidget">
<property name="geometry">
@ -401,6 +552,216 @@
</property>
</widget>
</widget>
<widget class="QWidget" name="depositPage">
<widget class="QPushButton" name="depositByCardIdButton">
<property name="geometry">
<rect>
<x>440</x>
<y>310</y>
<width>80</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>按卡号充值</string>
</property>
</widget>
<widget class="QPushButton" name="depositByUserIdButton">
<property name="geometry">
<rect>
<x>170</x>
<y>310</y>
<width>91</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>按学/工号充值</string>
</property>
</widget>
<widget class="QWidget" name="horizontalLayoutWidget_2">
<property name="geometry">
<rect>
<x>330</x>
<y>220</y>
<width>354</width>
<height>81</height>
</rect>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLabel" name="label_6">
<property name="text">
<string>请选择卡:</string>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="depositCardIdBox">
<property name="minimumSize">
<size>
<width>200</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>200</width>
<height>16777215</height>
</size>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="depositInventoryButton">
<property name="minimumSize">
<size>
<width>80</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>80</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>查询</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="">
<property name="geometry">
<rect>
<x>50</x>
<y>220</y>
<width>249</width>
<height>81</height>
</rect>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QLabel" name="label_8">
<property name="text">
<string>请输入学/工号:</string>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="depositUserIdBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>150</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>150</width>
<height>16777215</height>
</size>
</property>
<property name="minimum">
<number>1000</number>
</property>
<property name="maximum">
<number>99999999</number>
</property>
<property name="value">
<number>21281280</number>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="verticalLayoutWidget">
<property name="geometry">
<rect>
<x>250</x>
<y>110</y>
<width>246</width>
<height>80</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label_5">
<property name="font">
<font>
<pointsize>11</pointsize>
</font>
</property>
<property name="text">
<string>充值</string>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignCenter</set>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<widget class="QLabel" name="label_7">
<property name="text">
<string>金额:</string>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="depositValueBox">
<property name="minimumSize">
<size>
<width>200</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>200</width>
<height>16777215</height>
</size>
</property>
<property name="font">
<font>
<pointsize>15</pointsize>
<bold>true</bold>
</font>
</property>
<property name="prefix">
<string/>
</property>
<property name="suffix">
<string> ¥</string>
</property>
<property name="maximum">
<double>9999.989999999999782</double>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</widget>
</widget>
</widget>
<widget class="QStatusBar" name="statusBar">

View File

@ -42,7 +42,7 @@ void MainWindow::on_inventoryButton_clicked()
ui->cardIdBox->clear();
if (cardIdList.empty())
{
QMessageBox::warning(this, "查询卡结果", "未发现卡片,请将卡片放置于读卡器上方。");
QMessageBox::warning(this, "提示", "未发现卡片,请将卡片放置于读卡器上方。");
}
else
{