645 lines
20 KiB
C++
Raw Normal View History

2024-11-25 17:15:44 +08:00
#include "trainreport.h"
#include "ui_trainreport.h"
#include "cdatabaseinterface.h"
#include <QDebug>
#include <QPdfWriter>
#include <QPainter>
#include <QPrinter>
#include <QFileDialog>
#include <QMessageBox>
#include "gamecontrol.h"
#include "currentuserdata.h"
TrainReport::TrainReport(QDialog *parent) :
QDialog(parent),
ui(new Ui::TrainReport)
{
ui->setupUi(this);
this->setWindowFlags(Qt::FramelessWindowHint); //设置无边框
setAttribute(Qt::WA_TranslucentBackground,true);//设置透明
m_chart1 = new QChart();
m_chart2 = new QChart();
m_chart3 = new QChart();
}
TrainReport::~TrainReport()
{
if(m_chart1)
delete m_chart1;
if(m_chart2)
delete m_chart2;
if(m_chart3)
delete m_chart3;
delete ui;
}
void TrainReport::setReportData(const ST_TrainReport& st_trainReport,int type)
{
ui->save_Btn->setVisible(type);
ui->noSave_Btn->setVisible(type);
ui->import_Btn->setVisible(true);
ui->label->setText(tr("上下肢主被动康复训练仪报告"));
m_st_trainReport = st_trainReport;
ui->name_Label->setText(st_trainReport.name);
QString sex = st_trainReport.sex == 1 ? tr("") :tr("");
ui->sex_Label->setText(sex);
ui->phone_Label->setText(st_trainReport.phone);
if(1<= st_trainReport.age && st_trainReport.age <= 90)
ui->age_Label->setText(QString::number(st_trainReport.age) );
ui->trainMode_Label->setText(getTrainMode(st_trainReport.trainMode));
QString bodyStr;
switch(st_trainReport.bodyIndex)
{
case 0:
bodyStr = tr("水平上肢");
break;
case 1:
bodyStr = tr("下肢");
break;
case 2:
bodyStr = tr("上下肢");
break;
case 3:
bodyStr = tr("垂直上肢");
break;
}
qDebug() <<"最终模式"<< st_trainReport.bodyIndex;
ui->trainPart_Label->setText(bodyStr);
//图标的训练部位
ui->trainPartIcon_Label->setText(bodyStr);
// "yyyy-MM-dd hh:mm:ss")截取年月日输出;
ui->reportDate_Label->setText(st_trainReport.startTimeStr.mid(0,10));
ui->msg_Label->setText(st_trainReport.markMsg);
//实际训练总时间、主被动时间
//qDebug() <<"Time"<< st_trainReport.trainTime;
int trainTimeMin = st_trainReport.trainTime/60;
int trainTimeSec = st_trainReport.trainTime%60;
/*
int leftBalanceActiveTime = st_trainReport.activeTime/60;
int rightBalancePassiveTime = st_trainReport.passiveTime/60;
//主被动模式:多出30秒主被动选择加1min
if(st_trainReport.trainMode == 7 || st_trainReport.trainMode == 10 )
{
if(st_trainReport.trainTime % 60 >= 30)
{
leftBalanceActiveTime++;
}
else if(st_trainReport.passiveTime % 60 >= 30)
rightBalancePassiveTime++;
else if(trainTimeMin==0) //这种是小于1min且在
{
trainTimeMin = 1;
rightBalancePassiveTime++;
}
//用户不玩,产生空的数据空的图像
if(st_trainReport.activeTime ==0 && st_trainReport.passiveTime==0)
{
}
}
//非主被动同时训练总时间小于1min设置1min
if(trainTimeMin == 0 && !(st_trainReport.trainMode == 7 || st_trainReport.trainMode == 10))
{
trainTimeMin = 1;
switch(st_trainReport.trainMode)
{
case 0:
leftBalanceActiveTime = 0;
rightBalancePassiveTime = 1;
break;
case 1:
leftBalanceActiveTime = 1;
rightBalancePassiveTime = 0;
break;
case 2:
leftBalanceActiveTime = 0;
rightBalancePassiveTime = 1;
break;
case 3:
leftBalanceActiveTime = 0;
rightBalancePassiveTime = 1;
break;
default :
leftBalanceActiveTime = 0;
rightBalancePassiveTime = 1;
break;
}
}
*/
//训练时间和主被动时间
ui->trainTime_Label->setText(QString::number(trainTimeMin)+":"+QString::number(trainTimeSec));
// ui->leftBalance_Label->setText(QString::number(leftBalanceActiveTime));
//ui->rightBalance_Label->setText(QString::number(rightBalancePassiveTime));
//int leftBalance = st_trainReport.leftBalance;
//if(leftBalance > 100 || leftBalance < 0)
// leftBalance = 50;
// int rightBalance = st_trainReport.rightBalance;
//if(rightBalance > 100 || rightBalance < 0)
// rightBalance = 50;
// int trainTimeSec = st_trainReport.trainTime%60;
// ui->trainTime_Label->setText(QString::number(trainTimeMin) + "min " + QString::number(trainTimeSec)+"s");
//训练总距离、左右距离
ui->trainLength_Label->setText(QString::number(st_trainReport.upLimpLength + st_trainReport.downLimpLength,'f',0));
// ui->upLimpLength_Label->setText(QString::number(st_trainReport.upLimpLength,'f',0) );
// ui->downLimpLength_Label->setText(QString::number(st_trainReport.downLimpLength,'f',0));
//痉挛
ui->spasmTimes_Label->setText(QString::number(st_trainReport.spasmTimes)/*+"次"*/);
//档位
ui->avgResistance_Label->setText(QString::number(st_trainReport.averangeResistance) );
ui->maxResistance_Label->setText(QString::number(st_trainReport.maxResistance) );
// ui->minResistance_Label->setText(QString::number(st_trainReport.minResistance) );
drawPieChart(st_trainReport);
ui->maxSpeed_Label->setText(QString::number(st_trainReport.maxSpeed));
ui->averageSpeed_Label->setText(QString::number(st_trainReport.averageSpeed));
this->exec();
}
void TrainReport::drawPieChart(const ST_TrainReport& st_trainReport)
{
//绘制第1个饼状图
m_chart1->removeAllSeries();
ui->graphicsView_1->setChart(m_chart1);
QPieSeries *series1 = new QPieSeries(m_chart1);//创建QPieSeries
// if(st_trainReport.)
if(st_trainReport.bodyIndex == 1)
{
series1->append("左平衡",st_trainReport.leftBalance); //添加个部分
series1->append("右平衡",st_trainReport.rightBalance);
}
else {
series1->append("左平衡",st_trainReport.rightBalance); //添加个部分
series1->append("右平衡",st_trainReport.leftBalance);
}
//设置缩放因子
series1->setPieSize(1);
//添加每个饼状部分
QPieSlice *slice1_1 = series1->slices().at(0); //第一个扇形
QPieSlice *slice1_2 = series1->slices().at(1);
slice1_1->setColor(QColor(85, 173, 249));
slice1_2->setColor(QColor(180, 226, 254));
//图注可见
slice1_1->setLabelVisible(true);
slice1_2->setLabelVisible(true);
//饼状每个部分标签位置
slice1_1->setLabelPosition(QPieSlice::LabelInsideNormal);
slice1_2->setLabelPosition(QPieSlice::LabelInsideNormal);
//图注位置
m_chart1->addSeries(series1);
m_chart1->legend()->setAlignment(Qt::AlignBottom);
m_chart1->legend()->hide();
//每个饼快占得比例(0-1)
qreal slice_1_Percentage = slice1_1->percentage();
qreal slice_2_Percentage= slice1_2->percentage();
slice1_1->setLabel(QString::number(qRound(slice_1_Percentage*100))+"%");
slice1_2->setLabel(QString::number(qRound(slice_2_Percentage*100))+"%");
//四舍五入取整
ui->slice1_1Percentage_Label->setText(QString::number(qRound(slice_1_Percentage*100))+"%");
ui->slice1_2Percentage_Label->setText(QString::number(qRound(slice_2_Percentage*100))+"%");
ui->slice1_1Percentage_Label->hide();
ui->slice1_2Percentage_Label->hide();
//slice1_1->setLabel(slice1_1->label()+":"+QString::number(qRound(slice_1_Percentage*100))+"%");
//slice1_2->setLabel(slice1_2->label()+":"+QString::number(qRound(slice_2_Percentage*100))+"%");
//绘制第2个饼状图
m_chart2->removeAllSeries();
ui->graphicsView_2->setChart(m_chart2);
QPieSeries *series2 = new QPieSeries(m_chart2);//创建QPieSeries
int activeTime,passiveTime;
//主动模式和单主动只有主动时间和距离
if(st_trainReport.trainMode == 1 || st_trainReport.trainMode == 9)
{
activeTime = 1;
passiveTime = 0;
}
else if(st_trainReport.trainMode == 0 || st_trainReport.trainMode == 3 || st_trainReport.trainMode == 4)
{ //助力当主被动处理
activeTime = 0;
passiveTime = 1;
} else { //主被动切换(助力模式)
if(st_trainReport.activeTime == 0 && st_trainReport.passiveTime ==0)
{//如果用户不玩,防止空数据空表
activeTime = 1;
passiveTime = 1;
}
else
{
activeTime = st_trainReport.activeTime;
passiveTime = st_trainReport.passiveTime;
}
}
series2->append(tr("主动时间"),activeTime);
series2->append(tr("被动时间"),passiveTime); //添加个部分
//设置缩放因子
series2->setPieSize(1);
//添加每个饼状部分
QPieSlice *slice2_1 = series2->slices().at(0); //第一个扇形
QPieSlice *slice2_2 = series2->slices().at(1);
slice2_1->setColor(QColor(146, 175, 246));
slice2_2->setColor(QColor(147, 139, 246));
//图注可见
slice2_1->setLabelVisible(true);
slice2_2->setLabelVisible(true);
//饼状每个部分标签位置
slice2_1->setLabelPosition(QPieSlice::LabelInsideNormal);
slice2_2->setLabelPosition(QPieSlice::LabelInsideNormal);
//图注位置
m_chart2->addSeries(series2);
m_chart2->legend()->setAlignment(Qt::AlignBottom);
m_chart2->legend()->hide();
//每个饼块占得比例(0-1)
qreal slice2_1_Percentage = slice2_1->percentage();
qreal slice2_2_Percentage= slice2_2->percentage();
slice2_1->setLabel(QString::number(qRound(slice2_1_Percentage*100))+"%");
slice2_2->setLabel(QString::number(qRound(slice2_2_Percentage*100))+"%");
//四舍五入取整
ui->slice2_1Percentage_Label->setText(QString::number(qRound(slice2_1_Percentage*100))+"%");
ui->slice2_2Percentage_Label->setText(QString::number(qRound(slice2_2_Percentage*100))+"%");
ui->slice2_1Percentage_Label->hide();
ui->slice2_2Percentage_Label->hide();
/****绘制第3个饼状图****/
m_chart3->removeAllSeries();
ui->graphicsView_3->setChart(m_chart3);
QPieSeries *series3 = new QPieSeries(m_chart3);//创建QPieSeries
int activeLength,passiveLength;
if(st_trainReport.trainMode == 1 || st_trainReport.trainMode == 9)
{
activeLength = 1;
passiveLength = 0;
}
else if(st_trainReport.trainMode == 0 || st_trainReport.trainMode == 3 || st_trainReport.trainMode == 4 )
{
activeLength = 0;
passiveLength = 1;
} else { //主被动切换-助力和主被动
if(st_trainReport.upLimpLength ==0 && st_trainReport.downLimpLength== 0 /*st_trainReport.upLimpLength == 0 && st_trainReport.downLimpLength ==0*/)
{//如果用户不玩,防止空数据空表
activeLength = 0;
passiveLength = 1;
qDebug()<<"Yes";
}
else
{
activeLength = st_trainReport.activeTime * 1.4;
passiveLength = st_trainReport.passiveTime ;
}
}
qDebug()<<"主动和被动TIme"<<st_trainReport.activeTime<<st_trainReport.passiveTime;
series3->append(tr("主动距离"),activeLength);
series3->append(tr("被动距离"),passiveLength); //添加个部分
//设置缩放因子
series3->setPieSize(1);
//添加每个饼状部分
QPieSlice *slice3_1 = series3->slices().at(0); //第一个扇形
QPieSlice *slice3_2 = series3->slices().at(1);
slice3_1->setColor(QColor(170, 194, 4));//被动颜色
slice3_2->setColor(QColor(210, 224, 126));//主动颜色
//图注可见
slice3_1->setLabelVisible(true);
slice3_2->setLabelVisible(true);
//饼状每个部分标签位置
slice3_1->setLabelPosition(QPieSlice::LabelInsideNormal);
slice3_2->setLabelPosition(QPieSlice::LabelInsideNormal);
//图注位置
m_chart3->addSeries(series3);
m_chart3->legend()->setAlignment(Qt::AlignBottom);
m_chart3->legend()->hide();
//每个饼快占得比例(0-1)
qreal slice3_1_Percentage = slice3_1->percentage();
qreal slice3_2_Percentage= slice3_2->percentage();
slice3_1->setLabel(QString::number(qRound(slice3_1_Percentage*100))+"%");
slice3_2->setLabel(QString::number(qRound(slice3_2_Percentage*100))+"%");
//四舍五入取整
// ui->slice3_1Percentage_Label->setText(QString::number(qRound(slice3_1_Percentage*100))+"%");
// ui->slice3_2Percentage_Label->setText(QString::number(qRound(slice3_2_Percentage*100))+"%");
ui->slice3_1Percentage_Label->hide();
ui->slice3_2Percentage_Label->hide();
qDebug()<<"主动和被动距离"<<st_trainReport.upLimpLength<<st_trainReport.downLimpLength;
}
QString TrainReport::getTrainMode(int8_t mode)
{
QString modeName;
switch(mode)
{
case 0:
modeName = tr("被动");
break;
case 1:
modeName = tr("主动");
break;
case 2:
modeName = tr("助力");
break;
case 3:
modeName = tr("等速");
break;
case 4: //四肢被动
modeName = tr("被动");
break;
case 5:
modeName = tr("上肢带下肢");
break;
case 6:
modeName = tr("下肢带上肢");
break;
case 7:
modeName = tr("主被动");
break;
case 8:
modeName = tr("FES");
break;
case 10:
modeName = tr("主被动");
break;
}
return modeName;
}
ST_TrainReport TrainReport::getReportDataByStartTime(QString startTimeStr)
{
QString queryStr(QString("select * from TrainReportTable where startTimeStr = '%1'").arg(startTimeStr));
if(CDatabaseInterface::getInstance()->exec(queryStr))
{
if(CDatabaseInterface::getInstance()->getValuesSize() > 0)
{
m_st_trainReport = variantMapToTrainReport(CDatabaseInterface::getInstance()->getValues(0,1).at(0));
}
else
qDebug()<<"TrainReport::getReportDataByStartTime:未查到符合要求数据";
}
else
qDebug()<<"TrainReport::getReportDataByStartTime"<<CDatabaseInterface::getInstance()->getLastError();
return m_st_trainReport;
}
bool TrainReport::deleteReportByStartTime(QString startTimeStr)
{
QString table("TrainReportTable");
return CDatabaseInterface::getInstance()->deleteRowTable(table,"startTimeStr",startTimeStr);
}
void TrainReport::pixmapImportPDF(const QPixmap &pixmap, QString fileName)
{
QString filePath;
filePath = QFileDialog::getSaveFileName(NULL,"保存文件",fileName,tr("*.pdf"));
QFile pdfFile(filePath);
if(!pdfFile.open(QIODevice::WriteOnly))
{
QMessageBox::warning(NULL,tr("导出文件"),tr("文件打开失败"));
return;
}
QPdfWriter *pdfWriter = new QPdfWriter(&pdfFile);
QPainter *pic_painter = new QPainter(pdfWriter);
pdfWriter->setPageSize(QPagedPaintDevice::A4);
pdfWriter->setResolution(QPrinter::ScreenResolution);
QRect rect = pic_painter->viewport();
int factor = rect.width()/pixmap.width();
pic_painter->scale(factor,factor);
pic_painter->drawPixmap(10,10,pixmap);
delete pic_painter;
delete pdfWriter;
pdfFile.close();
QMessageBox::information(NULL,tr("提示"),tr("报告导出成功"));
this->close();
}
void TrainReport::on_close_Btn_clicked()
{
this->close();
}
void TrainReport::on_noSave_Btn_clicked()
{
this->close();
}
void TrainReport::on_save_Btn_clicked()
{
QString table("TrainParamTable");
ST_TrainParam st_trainParam = GameControl::getInstance()->getTrainParam();
int ID = CurrentUserData::getInstace()->getCurrentPatientMsg().ID;
QString queryStr(QString("select * from TrainParamTable where ID = '%1' order by 'ID'").arg(ID));
if(CDatabaseInterface::getInstance()->exec(queryStr))
{
if(CDatabaseInterface::getInstance()->getValuesSize()>0)
{
//st_trainParam = variantMapToTrainParam(CDatabaseInterface::getInstance()->getValues(0,1).at(0));
CDatabaseInterface::getInstance()->deleteRowTable(table,"ID",QString::number(ID));
}
}
if(!CDatabaseInterface::getInstance()->insertRowTable(table,TrainParamToVariantMap(st_trainParam)))
{
qDebug()<<"插入处方信息失败!"<<CDatabaseInterface::getInstance()->getLastError();
}
//将数据存储到数据库中
QString tableName("TrainReportTable");
if(!CDatabaseInterface::getInstance()->insertRowTable(tableName,trainReportToVariantMap(m_st_trainReport)))
qDebug()<<"训练报告存储失败"<<CDatabaseInterface::getInstance()->getLastError();
else
{
QMessageBox::warning(NULL,tr("保存"),tr("报告保存成功"));
this->close();
}
//将训练保存到训练记录中
ST_TrainRecord st_trainRecord;
st_trainRecord.ID = m_st_trainReport.ID;
st_trainRecord.trainTime = m_st_trainReport.trainTime/60;
if(st_trainRecord.trainTime < 1)
st_trainRecord.trainTime = 1;
switch(m_st_trainReport.bodyIndex)
{
case 0:
st_trainRecord.bodyPart = tr("水平上肢");
break;
case 1:
st_trainRecord.bodyPart = tr("下肢");
break;
case 2:
st_trainRecord.bodyPart = tr("上下肢");
break;
case 3:
st_trainRecord.bodyPart = tr("垂直上肢");
break;
}
st_trainRecord.score = (m_st_trainReport.upLimpLength + m_st_trainReport.downLimpLength)*3;
st_trainRecord.startTime = QDateTime::fromString(m_st_trainReport.startTimeStr,"yyyy-MM-dd hh:mm:ss");
st_trainRecord.startTimeStr = m_st_trainReport.startTimeStr;
QString modeName;
switch(m_st_trainReport.trainMode)
{
case 0:
modeName = tr("被动");
break;
case 1:
modeName = tr("主动");
break;
case 2:
modeName = tr("助力");
break;
case 3:
modeName = tr("等速");
break;
case 4: //四肢被动
modeName = tr("被动");
break;
case 5:
modeName = tr("上肢带下肢");
break;
case 6:
modeName = tr("下肢带上肢");
break;
case 7:
modeName = tr("主被动");
break;
case 8:
modeName = tr("FES");
break;
case 9:
modeName = tr("主动");
break;
case 10:
modeName = tr("主被动");
break;
case 11:
;
break;
case 12:
;
break;
}
st_trainRecord.trainMode = modeName;
if(!CDatabaseInterface::getInstance()->insertRowTable("TrainRecordTable",trainRecordToVariantMap(st_trainRecord)))
{
qDebug()<<"TrainRecord::on_createData_Btn_clicked"<<CDatabaseInterface::getInstance()->getLastError();
}
}
//导出报告
void TrainReport::on_import_Btn_clicked()
{
QDateTime dateTime = QDateTime::fromString(m_st_trainReport.startTimeStr,"yyyy-MM-dd hh:mm:ss");
QString fileName;
fileName.append(m_st_trainReport.name +"-"+ QString::number(m_st_trainReport.ID));
fileName.append("-");
fileName.append(dateTime.toString("yyyyMMddhhmmss"));
ui->import_Btn->setVisible(false);
ui->save_Btn->setVisible(false);
ui->noSave_Btn->setVisible(false);
pixmapImportPDF(ui->groupBox->grab(),fileName);
}
void TrainReport::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event)
QPainter painter(this);
painter.fillRect(rect(),QColor(0,0,0,100));
}
void TrainReport::changeEvent(QEvent* event)
{
switch (event->type())
{
case QEvent::LanguageChange:
ui->retranslateUi(this);
break;
default:
QWidget::changeEvent(event);
break;
}
}