Files
HIS-GUI/gui/dialogs/payment_management_dialog.cpp
2026-04-07 21:30:39 +08:00

690 lines
28 KiB
C++

#include "payment_management_dialog.h"
#include "core/his_core.h"
#include "models/payment.h"
#include "models/settlement.h"
#include "models/patient.h"
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QLabel>
#include <QTableWidget>
#include <QTableWidgetItem>
#include <QPushButton>
#include <QTabWidget>
#include <QMessageBox>
#include <QTextEdit>
#include <QLineEdit>
#include <QHeaderView>
#include <QTreeWidget>
#include <QTreeWidgetItem>
#include <QStackedWidget>
#include <QtCharts/QChartView>
#include <QtCharts/QBarSeries>
#include <QtCharts/QBarSet>
#include <QtCharts/QBarCategoryAxis>
#include <QtCharts/QValueAxis>
#include <QtCharts/QPieSeries>
#include <QtCharts/QPieSlice>
#include <QFont>
#include <QColor>
#include <ctime>
#include <iomanip>
#include <sstream>
#include <map>
PaymentManagementDialog::PaymentManagementDialog(core::HisCore& core, QWidget* parent)
: QDialog(parent), core_(core) {
setWindowTitle("支付管理");
setModal(false);
setMinimumSize(1000, 600);
setupUI();
onRefreshPayments();
}
void PaymentManagementDialog::setupUI() {
QVBoxLayout* mainLayout = new QVBoxLayout(this);
// Create tab widget
tabWidget_ = new QTabWidget();
connect(tabWidget_, &QTabWidget::currentChanged, this, &PaymentManagementDialog::onTabChanged);
// ========== Payment Tab ==========
QWidget* paymentWidget = new QWidget();
QVBoxLayout* paymentLayout = new QVBoxLayout(paymentWidget);
// Payment table
paymentTable_ = new QTableWidget();
paymentTable_->setColumnCount(9);
paymentTable_->setHorizontalHeaderLabels(
{"支付ID", "患者ID", "患者姓名", "金额", "支付方式", "类型", "时间", "状态", "描述"});
paymentTable_->horizontalHeader()->setStretchLastSection(true);
paymentTable_->setSelectionBehavior(QAbstractItemView::SelectRows);
paymentTable_->setSelectionMode(QAbstractItemView::SingleSelection);
connect(paymentTable_, &QTableWidget::itemSelectionChanged,
this, &PaymentManagementDialog::onPaymentSelectionChanged);
paymentLayout->addWidget(paymentTable_);
// Search filter
QHBoxLayout* filterLayout = new QHBoxLayout();
filterLayout->addWidget(new QLabel("搜索:"));
statusFilterEdit_ = new QLineEdit();
statusFilterEdit_->setPlaceholderText("输入关键词搜索任意字段...");
filterLayout->addWidget(statusFilterEdit_);
QPushButton* filterButton = new QPushButton("搜索");
connect(filterButton, &QPushButton::clicked, this, &PaymentManagementDialog::onFilterByStatus);
filterLayout->addWidget(filterButton);
QPushButton* clearButton = new QPushButton("清除");
connect(clearButton, &QPushButton::clicked, [this]() {
statusFilterEdit_->clear();
loadPaymentRecords();
});
filterLayout->addWidget(clearButton);
paymentLayout->addLayout(filterLayout);
// Button layout
QHBoxLayout* paymentButtonLayout = new QHBoxLayout();
refreshButton_ = new QPushButton("刷新");
connect(refreshButton_, &QPushButton::clicked, this, &PaymentManagementDialog::onRefreshPayments);
paymentButtonLayout->addWidget(refreshButton_);
refundButton_ = new QPushButton("退款");
connect(refundButton_, &QPushButton::clicked, this, &PaymentManagementDialog::onRefundPayment);
paymentButtonLayout->addWidget(refundButton_);
paymentButtonLayout->addStretch();
paymentLayout->addLayout(paymentButtonLayout);
// Statistics label
statisticsLabel_ = new QLabel("统计信息: 加载中...");
paymentLayout->addWidget(statisticsLabel_);
tabWidget_->addTab(paymentWidget, "支付记录");
// ========== Settlement Tab ==========
QWidget* settlementWidget = new QWidget();
QVBoxLayout* settlementLayout = new QVBoxLayout(settlementWidget);
// Search layout
QHBoxLayout* settlementSearchLayout = new QHBoxLayout();
settlementSearchLayout->addWidget(new QLabel("搜索病人(ID/姓名/手机号):"));
settlementSearchEdit_ = new QLineEdit();
settlementSearchEdit_->setPlaceholderText("请输入搜索关键词...");
settlementSearchLayout->addWidget(settlementSearchEdit_);
settlementSearchButton_ = new QPushButton("搜索");
connect(settlementSearchButton_, &QPushButton::clicked,
this, &PaymentManagementDialog::onSearchSettlements);
settlementSearchLayout->addWidget(settlementSearchButton_);
settlementLayout->addLayout(settlementSearchLayout);
// 使用树形结构显示每个患者的支付记录
settlementTree_ = new QTreeWidget();
settlementTree_->setColumnCount(5);
settlementTree_->setHeaderLabels({"支付ID", "支付类型", "支付金额", "支付方式", "状态"});
settlementTree_->header()->setStretchLastSection(true);
settlementTree_->setAlternatingRowColors(true);
settlementLayout->addWidget(settlementTree_);
// Button layout
QHBoxLayout* settlementButtonLayout = new QHBoxLayout();
settlementRefreshButton_ = new QPushButton("刷新");
connect(settlementRefreshButton_, &QPushButton::clicked,
this, [this]() { loadSettlementRecords(); });
settlementButtonLayout->addWidget(settlementRefreshButton_);
settlementButtonLayout->addStretch();
settlementLayout->addLayout(settlementButtonLayout);
tabWidget_->addTab(settlementWidget, "结算单");
// ========== Reports Tab ==========
QWidget* reportWidget = new QWidget();
QVBoxLayout* reportLayout = new QVBoxLayout(reportWidget);
// 创建按钮让用户刷新图表数据
QHBoxLayout* reportButtonLayout = new QHBoxLayout();
dailyReportButton_ = new QPushButton("每日报表");
dailyReportButton_->setStyleSheet("QPushButton { background-color: #4CAF50; color: white; padding: 8px 16px; border-radius: 4px; font-weight: bold; }");
connect(dailyReportButton_, &QPushButton::clicked,
this, &PaymentManagementDialog::onGenerateDailyReport);
reportButtonLayout->addWidget(dailyReportButton_);
monthlyReportButton_ = new QPushButton("月报表");
monthlyReportButton_->setStyleSheet("QPushButton { background-color: #2196F3; color: white; padding: 8px 16px; border-radius: 4px; font-weight: bold; }");
connect(monthlyReportButton_, &QPushButton::clicked,
this, &PaymentManagementDialog::onGenerateMonthlyReport);
reportButtonLayout->addWidget(monthlyReportButton_);
revenueReportButton_ = new QPushButton("收入总报表");
revenueReportButton_->setStyleSheet("QPushButton { background-color: #FF9800; color: white; padding: 8px 16px; border-radius: 4px; font-weight: bold; }");
connect(revenueReportButton_, &QPushButton::clicked,
this, &PaymentManagementDialog::onGenerateRevenueReport);
reportButtonLayout->addWidget(revenueReportButton_);
reportButtonLayout->addStretch();
reportLayout->addLayout(reportButtonLayout);
// 创建带图表的stacked widget
QTabWidget* chartTabWidget = new QTabWidget();
// ===== 每日收入图表 =====
dailyChartWidget_ = new QWidget();
QVBoxLayout* dailyChartLayout = new QVBoxLayout(dailyChartWidget_);
// 每日报表标题
QLabel* dailyTitleLabel = new QLabel("📊 每日收入报表");
dailyTitleLabel->setStyleSheet("font-size: 18px; font-weight: bold; color: #333; padding: 10px;");
dailyTitleLabel->setAlignment(Qt::AlignCenter);
dailyChartLayout->addWidget(dailyTitleLabel);
// 创建条形图显示每日收入
QChart* dailyChart = new QChart();
dailyChart->setTitle("最近7天收入趋势");
dailyChart->setAnimationDuration(500);
dailyChart->setAnimationOptions(QChart::AllAnimations);
QBarSeries* dailyBarSeries = new QBarSeries();
QBarSet* dailyBarSet = new QBarSet("每日收入");
// 从真实数据获取最近7天收入
auto dailyData = core_.paymentManagementService.getDailyRevenueData(7);
for (const auto& pair : dailyData) {
*dailyBarSet << pair.second;
}
dailyBarSeries->append(dailyBarSet);
dailyChart->addSeries(dailyBarSeries);
QStringList dailyCategories;
for (const auto& pair : dailyData) {
dailyCategories << QString::fromStdString(pair.first);
}
QBarCategoryAxis* dailyAxisX = new QBarCategoryAxis();
dailyAxisX->append(dailyCategories);
dailyChart->addAxis(dailyAxisX, Qt::AlignBottom);
dailyBarSeries->attachAxis(dailyAxisX);
QValueAxis* dailyAxisY = new QValueAxis();
dailyAxisY->setTitleText("收入 (¥)");
dailyAxisY->setMin(0);
dailyChart->addAxis(dailyAxisY, Qt::AlignLeft);
dailyBarSeries->attachAxis(dailyAxisY);
QChartView* dailyChartView = new QChartView(dailyChart);
dailyChartView->setRenderHint(QPainter::Antialiasing);
dailyChartView->setMinimumSize(600, 350);
dailyChartLayout->addWidget(dailyChartView);
// 计算本周总收入和今日收入
double weekTotal = 0.0;
double todayRevenue = 0.0;
if (!dailyData.empty()) {
todayRevenue = dailyData.back().second;
for (const auto& pair : dailyData) {
weekTotal += pair.second;
}
}
// 每日统计信息
QLabel* dailyStatsLabel = new QLabel(QString("📈 今日收入: ¥%1 | 本周总收入: ¥%2 | 共 %3 笔交易")
.arg(todayRevenue, 0, 'f', 2)
.arg(weekTotal, 0, 'f', 2)
.arg(dailyData.size()));
dailyStatsLabel->setStyleSheet("font-size: 14px; padding: 10px; background-color: #E8F5E9; border-radius: 5px;");
dailyStatsLabel->setAlignment(Qt::AlignCenter);
dailyChartLayout->addWidget(dailyStatsLabel);
chartTabWidget->addTab(dailyChartWidget_, "每日");
// ===== 月度收入图表 =====
monthlyChartWidget_ = new QWidget();
QVBoxLayout* monthlyChartLayout = new QVBoxLayout(monthlyChartWidget_);
// 月报表标题
QLabel* monthlyTitleLabel = new QLabel("📊 月度收入报表");
monthlyTitleLabel->setStyleSheet("font-size: 18px; font-weight: bold; color: #333; padding: 10px;");
monthlyTitleLabel->setAlignment(Qt::AlignCenter);
monthlyChartLayout->addWidget(monthlyTitleLabel);
// 创建条形图显示月度收入
QChart* monthlyChart = new QChart();
monthlyChart->setTitle("最近6个月收入趋势");
monthlyChart->setAnimationDuration(500);
monthlyChart->setAnimationOptions(QChart::AllAnimations);
QBarSeries* monthlyBarSeries = new QBarSeries();
QBarSet* monthlyBarSet = new QBarSet("月度收入");
// 从真实数据获取最近6个月收入
auto monthlyData = core_.paymentManagementService.getMonthlyRevenueData(6);
for (const auto& pair : monthlyData) {
*monthlyBarSet << pair.second;
}
monthlyBarSeries->append(monthlyBarSet);
monthlyChart->addSeries(monthlyBarSeries);
QStringList monthlyCategories;
for (const auto& pair : monthlyData) {
monthlyCategories << QString::fromStdString(pair.first);
}
QBarCategoryAxis* monthlyAxisX = new QBarCategoryAxis();
monthlyAxisX->append(monthlyCategories);
monthlyChart->addAxis(monthlyAxisX, Qt::AlignBottom);
monthlyBarSeries->attachAxis(monthlyAxisX);
QValueAxis* monthlyAxisY = new QValueAxis();
monthlyAxisY->setTitleText("收入 (¥)");
monthlyAxisY->setMin(0);
monthlyChart->addAxis(monthlyAxisY, Qt::AlignLeft);
monthlyBarSeries->attachAxis(monthlyAxisY);
QChartView* monthlyChartView = new QChartView(monthlyChart);
monthlyChartView->setRenderHint(QPainter::Antialiasing);
monthlyChartView->setMinimumSize(600, 350);
monthlyChartLayout->addWidget(monthlyChartView);
// 计算本月收入
double monthTotal = 0.0;
for (const auto& pair : monthlyData) {
monthTotal += pair.second;
}
// 月度统计信息
QLabel* monthlyStatsLabel = new QLabel(QString("📈 本月收入: ¥%1 | 统计月份: %2 个月")
.arg(monthTotal, 0, 'f', 2)
.arg(monthlyData.size()));
monthlyStatsLabel->setStyleSheet("font-size: 14px; padding: 10px; background-color: #E3F2FD; border-radius: 5px;");
monthlyStatsLabel->setAlignment(Qt::AlignCenter);
monthlyChartLayout->addWidget(monthlyStatsLabel);
chartTabWidget->addTab(monthlyChartWidget_, "每月");
// ===== 收入分类饼图 =====
revenueChartWidget_ = new QWidget();
QVBoxLayout* revenueChartLayout = new QVBoxLayout(revenueChartWidget_);
// 总报表标题
QLabel* revenueTitleLabel = new QLabel("📊 收入分类总报表");
revenueTitleLabel->setStyleSheet("font-size: 18px; font-weight: bold; color: #333; padding: 10px;");
revenueTitleLabel->setAlignment(Qt::AlignCenter);
revenueChartLayout->addWidget(revenueTitleLabel);
// 创建饼图显示收入分类
QChart* revenueChart = new QChart();
revenueChart->setTitle("收入来源分布");
revenueChart->setAnimationDuration(500);
revenueChart->setAnimationOptions(QChart::AllAnimations);
QPieSeries* pieSeries = new QPieSeries();
pieSeries->setHoleSize(0.35);
// 从真实数据获取收入分类
auto revenueByType = core_.paymentManagementService.getRevenueByType();
// 颜色数组
QColor colors[] = {
QColor("#4CAF50"), QColor("#2196F3"), QColor("#FF9800"),
QColor("#9C27B0"), QColor("#F44336"), QColor("#00BCD4"),
QColor("#795548"), QColor("#607D8B")
};
int colorIndex = 0;
double totalRevenue = 0.0;
for (const auto& pair : revenueByType) {
totalRevenue += pair.second;
}
for (const auto& pair : revenueByType) {
double percentage = totalRevenue > 0 ? (pair.second / totalRevenue * 100) : 0;
QPieSlice* slice = new QPieSlice(
QString::fromStdString(pair.first) + QString(" ¥%1 (%2%)")
.arg(pair.second, 0, 'f', 2)
.arg(percentage, 0, 'f', 1),
pair.second);
slice->setBrush(colors[colorIndex % 8]);
slice->setLabelVisible(true);
slice->setLabelPosition(QPieSlice::LabelOutside);
pieSeries->append(slice);
colorIndex++;
}
revenueChart->addSeries(pieSeries);
revenueChart->legend()->setVisible(true);
revenueChart->legend()->setAlignment(Qt::AlignRight);
QChartView* revenueChartView = new QChartView(revenueChart);
revenueChartView->setRenderHint(QPainter::Antialiasing);
revenueChartView->setMinimumSize(600, 350);
revenueChartLayout->addWidget(revenueChartView);
// 计算总统计数据
auto stats = core_.paymentManagementService.getPaymentStatistics();
// 总收入统计信息
QLabel* revenueStatsLabel = new QLabel(QString("💰 总收入: ¥%1 | 已完成支付: %2笔 | 待支付: %3笔 | 已退款: %4笔")
.arg(stats.TotalRevenue, 0, 'f', 2)
.arg(stats.CompletedPayments)
.arg(stats.PendingPayments)
.arg(stats.RefundedPayments));
revenueStatsLabel->setStyleSheet("font-size: 14px; padding: 10px; background-color: #FFF3E0; border-radius: 5px;");
revenueStatsLabel->setAlignment(Qt::AlignCenter);
revenueChartLayout->addWidget(revenueStatsLabel);
chartTabWidget->addTab(revenueChartWidget_, "总收入");
reportLayout->addWidget(chartTabWidget);
reportLabel_ = new QLabel("报表内容将在此显示");
tabWidget_->addTab(reportWidget, "报表");
mainLayout->addWidget(tabWidget_);
setLayout(mainLayout);
}
void PaymentManagementDialog::loadPaymentRecords() {
paymentTable_->setRowCount(0);
int row = 0;
core_.paymentManagementService.getAllPayments([&](const Payment& payment) {
paymentTable_->insertRow(row);
paymentTable_->setItem(row, 0, new QTableWidgetItem(QString::fromStdString(payment.PaymentID)));
paymentTable_->setItem(row, 1, new QTableWidgetItem(QString::fromStdString(payment.PatientID)));
// 获取患者姓名
const Patient* patient = core_.patientService.findPatient(payment.PatientID);
QString patientName = patient ? QString::fromStdString(patient->Name) : "未知患者";
paymentTable_->setItem(row, 2, new QTableWidgetItem(patientName));
paymentTable_->setItem(row, 3, new QTableWidgetItem(QString::number(payment.Amount, 'f', 2)));
paymentTable_->setItem(row, 4, new QTableWidgetItem(QString::fromStdString(payment.getMethodString())));
paymentTable_->setItem(row, 5, new QTableWidgetItem(QString::fromStdString(payment.PaymentType)));
paymentTable_->setItem(row, 6, new QTableWidgetItem(QString::number(payment.PaymentTime)));
paymentTable_->setItem(row, 7, new QTableWidgetItem(QString::fromStdString(payment.Status)));
paymentTable_->setItem(row, 8, new QTableWidgetItem(QString::fromStdString(payment.Description)));
row++;
});
updateStatistics();
}
void PaymentManagementDialog::loadSettlementRecords() {
settlementTree_->clear();
// 使用map按患者ID分组存储支付记录
std::map<std::string, std::vector<const Payment*>> patientPayments;
// 收集所有已完成的支付记录并按患者分组
core_.paymentManagementService.getAllPayments([&](const Payment& payment) {
// 只显示已完成的支付记录
if (payment.Status == "Completed") {
patientPayments[payment.PatientID].push_back(&payment);
}
});
// 构建树形结构
for (const auto& pair : patientPayments) {
const std::string& patientId = pair.first;
const std::vector<const Payment*>& payments = pair.second;
// 获取患者信息
const Patient* patient = core_.patientService.findPatient(patientId);
QString patientName = patient ? QString::fromStdString(patient->Name) : "未知患者";
QString contact = patient ? QString::fromStdString(patient->Contact) : "";
// 创建患者节点(父节点)
QString patientInfo = QString("%1 (%2) 手机: %3, 共%4笔支付")
.arg(QString::fromStdString(patientId))
.arg(patientName)
.arg(contact)
.arg(payments.size());
QTreeWidgetItem* patientItem = new QTreeWidgetItem(QStringList() << patientInfo);
patientItem->setData(0, Qt::UserRole, QString::fromStdString(patientId));
patientItem->setExpanded(true); // 默认展开
// 添加患者节点的汇总信息
double totalAmount = 0.0;
for (const Payment* p : payments) {
totalAmount += p->Amount;
// 创建支付记录子节点
QTreeWidgetItem* paymentItem = new QTreeWidgetItem(patientItem);
paymentItem->setText(0, QString::fromStdString(p->PaymentID));
paymentItem->setText(1, QString::fromStdString(p->PaymentType));
paymentItem->setText(2, QString::number(p->Amount, 'f', 2));
paymentItem->setText(3, QString::fromStdString(p->getMethodString()));
paymentItem->setText(4, QString::fromStdString(p->Status));
}
// 在父节点中添加汇总信息
patientItem->setText(2, QString::number(totalAmount, 'f', 2));
settlementTree_->addTopLevelItem(patientItem);
}
// 设置患者列宽以显示完整信息
settlementTree_->setColumnWidth(0, 400);
}
void PaymentManagementDialog::onSearchSettlements() {
QString keyword = settlementSearchEdit_->text();
settlementTree_->clear();
// 收集支付记录
std::map<std::string, std::vector<const Payment*>> patientPayments;
if (keyword.isEmpty()) {
// 如果关键词为空,显示所有已完成支付记录
core_.paymentManagementService.getAllPayments([&](const Payment& payment) {
if (payment.Status == "Completed") {
patientPayments[payment.PatientID].push_back(&payment);
}
});
} else {
// 搜索匹配的患者,然后显示其支付记录
std::string keywordStd = keyword.toStdString();
core_.paymentManagementService.getAllPayments([&](const Payment& payment) {
if (payment.Status == "Completed") {
// 获取患者信息进行匹配
const Patient* patient = core_.patientService.findPatient(payment.PatientID);
if (patient) {
// 检查患者ID、姓名、手机号是否包含关键词
if (patient->PatientID.find(keywordStd) != std::string::npos ||
patient->Name.find(keywordStd) != std::string::npos ||
patient->Contact.find(keywordStd) != std::string::npos) {
patientPayments[payment.PatientID].push_back(&payment);
}
}
}
});
}
// 构建树形结构
for (const auto& pair : patientPayments) {
const std::string& patientId = pair.first;
const std::vector<const Payment*>& payments = pair.second;
const Patient* patient = core_.patientService.findPatient(patientId);
QString patientName = patient ? QString::fromStdString(patient->Name) : "未知患者";
QString contact = patient ? QString::fromStdString(patient->Contact) : "";
QString patientInfo = QString("%1 (%2) 手机: %3, 共%4笔支付")
.arg(QString::fromStdString(patientId))
.arg(patientName)
.arg(contact)
.arg(payments.size());
QTreeWidgetItem* patientItem = new QTreeWidgetItem(QStringList() << patientInfo);
patientItem->setData(0, Qt::UserRole, QString::fromStdString(patientId));
patientItem->setExpanded(true);
double totalAmount = 0.0;
for (const Payment* p : payments) {
totalAmount += p->Amount;
QTreeWidgetItem* paymentItem = new QTreeWidgetItem(patientItem);
paymentItem->setText(0, QString::fromStdString(p->PaymentID));
paymentItem->setText(1, QString::fromStdString(p->PaymentType));
paymentItem->setText(2, QString::number(p->Amount, 'f', 2));
paymentItem->setText(3, QString::fromStdString(p->getMethodString()));
paymentItem->setText(4, QString::fromStdString(p->Status));
}
patientItem->setText(2, QString::number(totalAmount, 'f', 2));
settlementTree_->addTopLevelItem(patientItem);
}
settlementTree_->setColumnWidth(0, 400);
}
void PaymentManagementDialog::updateStatistics() {
auto stats = core_.paymentManagementService.getPaymentStatistics();
std::stringstream ss;
ss << "总收入: ¥" << std::fixed << std::setprecision(2) << stats.TotalRevenue
<< " | 已完成支付: " << stats.CompletedPayments << "笔 (¥" << stats.CompletedAmount
<< ") | 待支付: " << stats.PendingPayments << "笔 (¥" << stats.PendingAmount
<< ") | 已退款: " << stats.RefundedPayments << "笔 (¥" << stats.RefundedAmount << ")";
statisticsLabel_->setText(QString::fromStdString(ss.str()));
}
void PaymentManagementDialog::onRefreshPayments() {
loadPaymentRecords();
}
void PaymentManagementDialog::onRefundPayment() {
if (paymentTable_->currentRow() < 0) {
QMessageBox::warning(this, "警告", "请先选择一条支付记录");
return;
}
int row = paymentTable_->currentRow();
QString paymentID = paymentTable_->item(row, 0)->text();
// TODO: Add reason dialog
std::string reason = "Manual refund";
if (core_.paymentManagementService.processRefund(paymentID.toStdString(), reason)) {
QMessageBox::information(this, "退款成功", "支付记录已退款");
onRefreshPayments();
} else {
QMessageBox::warning(this, "退款失败", "无法退款该支付记录");
}
}
void PaymentManagementDialog::onPaymentSelectionChanged() {
// Update any details when selection changes
}
void PaymentManagementDialog::onFilterByStatus() {
QString keyword = statusFilterEdit_->text();
if (keyword.isEmpty()) {
loadPaymentRecords();
return;
}
paymentTable_->setRowCount(0);
int row = 0;
std::string keywordStd = keyword.toStdString();
// 使用 getAllPayments 并匹配所有字段
core_.paymentManagementService.getAllPayments([&](const Payment& payment) {
// 检查所有字段是否包含关键词
bool matches = false;
// 检查支付ID
if (payment.PaymentID.find(keywordStd) != std::string::npos) {
matches = true;
}
// 检查患者ID
else if (payment.PatientID.find(keywordStd) != std::string::npos) {
matches = true;
}
// 检查患者姓名
else {
const Patient* patient = core_.patientService.findPatient(payment.PatientID);
if (patient && patient->Name.find(keywordStd) != std::string::npos) {
matches = true;
}
// 检查金额
else if (std::to_string(payment.Amount).find(keywordStd) != std::string::npos) {
matches = true;
}
// 检查支付方式
else if (payment.getMethodString().find(keywordStd) != std::string::npos) {
matches = true;
}
// 检查支付类型
else if (payment.PaymentType.find(keywordStd) != std::string::npos) {
matches = true;
}
// 检查状态
else if (payment.Status.find(keywordStd) != std::string::npos) {
matches = true;
}
// 检查描述
else if (payment.Description.find(keywordStd) != std::string::npos) {
matches = true;
}
}
if (matches) {
paymentTable_->insertRow(row);
paymentTable_->setItem(row, 0, new QTableWidgetItem(QString::fromStdString(payment.PaymentID)));
paymentTable_->setItem(row, 1, new QTableWidgetItem(QString::fromStdString(payment.PatientID)));
// 获取患者姓名
const Patient* patient = core_.patientService.findPatient(payment.PatientID);
QString patientName = patient ? QString::fromStdString(patient->Name) : "未知患者";
paymentTable_->setItem(row, 2, new QTableWidgetItem(patientName));
paymentTable_->setItem(row, 3, new QTableWidgetItem(QString::number(payment.Amount, 'f', 2)));
paymentTable_->setItem(row, 4, new QTableWidgetItem(QString::fromStdString(payment.getMethodString())));
paymentTable_->setItem(row, 5, new QTableWidgetItem(QString::fromStdString(payment.PaymentType)));
paymentTable_->setItem(row, 6, new QTableWidgetItem(QString::number(payment.PaymentTime)));
paymentTable_->setItem(row, 7, new QTableWidgetItem(QString::fromStdString(payment.Status)));
paymentTable_->setItem(row, 8, new QTableWidgetItem(QString::fromStdString(payment.Description)));
row++;
}
});
}
void PaymentManagementDialog::onTabChanged(int index) {
if (index == 1) {
loadSettlementRecords();
}
}
void PaymentManagementDialog::onGenerateDailyReport() {
auto report = core_.paymentManagementService.generateDailyReport("Today");
displayStatistics("每日报表", QString::fromStdString(report));
}
void PaymentManagementDialog::onGenerateMonthlyReport() {
auto report = core_.paymentManagementService.generateMonthlyReport("This Month");
displayStatistics("月报表", QString::fromStdString(report));
}
void PaymentManagementDialog::onGenerateRevenueReport() {
auto report = core_.paymentManagementService.generateRevenueReport();
displayStatistics("收入总报表", QString::fromStdString(report));
}
void PaymentManagementDialog::displayStatistics(const QString& title, const QString& content) {
QMessageBox msgBox(this);
msgBox.setWindowTitle(title);
msgBox.setText(content);
msgBox.setTextFormat(Qt::PlainText);
msgBox.exec();
}