Commit e6812a0b by gujin.wang

添加一个核销线程,用来处理由于网络失败所导致的核销失败

parent 96735c51
...@@ -24,7 +24,8 @@ SOURCES += \ ...@@ -24,7 +24,8 @@ SOURCES += \
fmp_forceclose_dialog.cpp \ fmp_forceclose_dialog.cpp \
fmp_payfailed_dialog.cpp \ fmp_payfailed_dialog.cpp \
cquerythread.cpp \ cquerythread.cpp \
fmp_detaildialog.cpp fmp_detaildialog.cpp \
reversethread.cpp
HEADERS +=\ HEADERS +=\
fmp_epay.h \ fmp_epay.h \
...@@ -43,7 +44,8 @@ HEADERS +=\ ...@@ -43,7 +44,8 @@ HEADERS +=\
fmp_forceclose_dialog.h \ fmp_forceclose_dialog.h \
fmp_payfailed_dialog.h \ fmp_payfailed_dialog.h \
cquerythread.h \ cquerythread.h \
fmp_detaildialog.h fmp_detaildialog.h \
reversethread.h
unix { unix {
target.path = /usr/lib target.path = /usr/lib
......
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
#define FMP_EPAY_I_H #define FMP_EPAY_I_H
#include <fmp_plugin_i.h> #include <fmp_plugin_i.h>
#include "fmp_epay_def.h" #include "fmp_epay_def.h"
...@@ -10,6 +9,7 @@ ...@@ -10,6 +9,7 @@
* 业务插件接口,必须继承自 FMPluginInterface * 业务插件接口,必须继承自 FMPluginInterface
* @brief The FMPePayInterface class * @brief The FMPePayInterface class
*/ */
class FMPDataBase;
class FMPePayInterface : public QObject, public FMPluginInterface class FMPePayInterface : public QObject, public FMPluginInterface
{ {
Q_OBJECT Q_OBJECT
......
...@@ -42,7 +42,8 @@ FMPePayPrivate::FMPePayPrivate(FMPePay *parent) ...@@ -42,7 +42,8 @@ FMPePayPrivate::FMPePayPrivate(FMPePay *parent)
_watcher(nullptr), _watcher(nullptr),
_reverse_flag(false), _reverse_flag(false),
_is_api(false), _is_api(false),
_queryThread(nullptr) _queryThread(nullptr),
_reverseThread(nullptr)
{ {
Q_Q(FMPePay); Q_Q(FMPePay);
_watcher = new QFutureWatcher<QByteArray>(); _watcher = new QFutureWatcher<QByteArray>();
...@@ -85,7 +86,8 @@ FMPePayPrivate::FMPePayPrivate(FMPePay *parent) ...@@ -85,7 +86,8 @@ FMPePayPrivate::FMPePayPrivate(FMPePay *parent)
"code varchar(20)," "code varchar(20),"
"pid varchar(20)," "pid varchar(20),"
"total_amount integer,"//卡券抵扣额,以分为单位 "total_amount integer,"//卡券抵扣额,以分为单位
"redeem_json text)"; //卡券核销时的请求字符串,用于后续冲正 "redeem_json text," //卡券核销时的请求字符串,用于后续冲正
"need_reverse boolean default 0)"; //改卡券是否需要冲正
FMP_INFO() << "create table sql: " << sql; FMP_INFO() << "create table sql: " << sql;
if(_db->creat(sql) == false) if(_db->creat(sql) == false)
{ {
...@@ -96,6 +98,13 @@ FMPePayPrivate::FMPePayPrivate(FMPePay *parent) ...@@ -96,6 +98,13 @@ FMPePayPrivate::FMPePayPrivate(FMPePay *parent)
if(_queryThread==nullptr) if(_queryThread==nullptr)
_queryThread=new CQueryThread(this); _queryThread=new CQueryThread(this);
if(_reverseThread == nullptr)
{
_reverseThread = new ReverseThread(this);
connect(_reverseThread, &ReverseThread::finished, _reverseThread, &ReverseThread::deleteLater);
_reverseThread->start();
}
//读取配置文件信息 //读取配置文件信息
QString apppath=QCoreApplication::applicationDirPath(); QString apppath=QCoreApplication::applicationDirPath();
QSettings *settings = new QSettings(QString("%1/FreemudPOS.ini").arg(apppath), QSettings::IniFormat); QSettings *settings = new QSettings(QString("%1/FreemudPOS.ini").arg(apppath), QSettings::IniFormat);
...@@ -144,6 +153,12 @@ FMPePayPrivate::~FMPePayPrivate() ...@@ -144,6 +153,12 @@ FMPePayPrivate::~FMPePayPrivate()
delete _queryThread; delete _queryThread;
_queryThread = nullptr; _queryThread = nullptr;
} }
if(_reverseThread != nullptr)
{
_reverseThread->Stop();
_reverseThread->wait();
}
} }
void FMPePayPrivate::Uninit() void FMPePayPrivate::Uninit()
...@@ -998,10 +1013,8 @@ void FMPePayPrivate::writeOrderToSqlite() ...@@ -998,10 +1013,8 @@ void FMPePayPrivate::writeOrderToSqlite()
//并重置pay_total变量 //并重置pay_total变量
//并对已核销的卡券进行冲正 //并对已核销的卡券进行冲正
_payDialog->_pay_total = 0; _payDialog->_pay_total = 0;
if(_dbWrite[FMP_RPAY_PAY_RETURN_STATUSCODE].toInt() != ERROR_ORDER_STATUS){
_payDialog->Reverse(); _payDialog->Reverse();
} }
}
FMP_INFO() << "writeOrderToSqlite json : " << _dbWrite; FMP_INFO() << "writeOrderToSqlite json : " << _dbWrite;
} }
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
#include "fmp_epay.h" #include "fmp_epay.h"
#include "cquerythread.h" #include "cquerythread.h"
#include "reversethread.h"
#include <QObject> #include <QObject>
#include <QFuture> #include <QFuture>
#include <QJsonObject> #include <QJsonObject>
...@@ -74,6 +75,7 @@ public: ...@@ -74,6 +75,7 @@ public:
void WriteRedeemToSqlite(QJsonObject redeemInfo); void WriteRedeemToSqlite(QJsonObject redeemInfo);
FMPDataBase* GetDB()const; FMPDataBase* GetDB()const;
private: private:
void ControlReverseJson(); void ControlReverseJson();
...@@ -115,6 +117,7 @@ public: ...@@ -115,6 +117,7 @@ public:
FMPNetworkInterface *_network; FMPNetworkInterface *_network;
bool _is_api; bool _is_api;
CQueryThread *_queryThread; CQueryThread *_queryThread;
ReverseThread *_reverseThread;
QString _pos_trans_id; QString _pos_trans_id;
private: private:
bool _reverse_flag; bool _reverse_flag;
......
...@@ -1216,17 +1216,30 @@ void FMPPayDialog::Reverse() ...@@ -1216,17 +1216,30 @@ void FMPPayDialog::Reverse()
redeem->StartService(); redeem->StartService();
foreach (QJsonObject obj, _reverses) foreach (QJsonObject obj, _reverses)
{ {
FMPDataBase* database = nullptr;
QString coupon = obj["transactions"].toArray()[0].toObject()["code"].toString();
QJsonObject result = redeem->Reverse(obj); QJsonObject result = redeem->Reverse(obj);
if(result["statusCode"].toInt() == 100) int statusCode = result["statusCode"].toInt();
if(statusCode == 100)
{ {
//如果冲正成功,则从数据库中删除该券的核销记录 //如果冲正成功,则从数据库中删除该券的核销记录
QString coupon = obj["transactions"].toArray()[0].toObject()["code"].toString(); database = _control->GetDB();
FMPDataBase* database = _control->GetDB();
if(!database->dlt(DEFAULT_REDEEM_TABLE, "code="+coupon)) if(!database->dlt(DEFAULT_REDEEM_TABLE, "code="+coupon))
{ {
FMP_ERROR() << "delete from redeem_table failed. code=" << coupon; FMP_ERROR() << "delete from redeem_table failed. code=" << coupon;
} }
} }
else if(statusCode == 104)
{
//网络失败,则更新该条记录状态,以便重试
database = _control->GetDB();
QVariantHash hash;
hash.insert("need_reverse", 1);
if(!database->update(DEFAULT_REDEEM_TABLE, hash, "code="+coupon))
{
FMP_ERROR() << "update failed. code=" << coupon;
}
}
} }
_reverses.clear(); _reverses.clear();
} }
#include "reversethread.h"
#include "fmp_epay_i.h"
#include "fmp_epay_p.h"
#include "fmp_redeem_i.h"
#include "fmp_database.h"
#include <QSqlQuery>
ReverseThread::ReverseThread(FMPePayPrivate* fmPay, QObject* parent)
:QThread(parent),
_stop(0),
_fmPay(fmPay)
{
}
void ReverseThread::run()
{
while(_stop.testAndSetAcquire(0, 0))
{
sleep(5);
trySend();
}
}
void ReverseThread::trySend()
{
FMPDataBase* db = _fmPay->GetDB();
if(db == nullptr)
return;
QStringList keys;
keys << "code" << "redeem_json";
QSqlQuery query;
if(!db->find(DEFAULT_REDEEM_TABLE, query, keys, "need_reverse=1"))
return;
while(query.next())
{
QByteArray json = query.value("redeem_json").toByteArray();
QString code = query.value("code").toString();
QJsonParseError e;
QJsonDocument doc = QJsonDocument::fromJson(json, &e);
if(e.error != QJsonParseError::NoError)
continue;
QJsonObject rev = doc.object();
FMPRedeemInterface* redeem = FMP::GetService<FMPRedeemInterface>();
if(redeem == nullptr)
continue;
redeem->StartService();
QJsonObject result = redeem->Reverse(rev);
if(result["statusCode"].toInt() != 100)
continue;
//冲正成功,删除该条核销记录
QString condition = "code=" + code;
db->dlt(DEFAULT_REDEEM_TABLE, condition);
}
}
void ReverseThread::Stop()
{
_stop = 1;
}
#ifndef REVERSETHREAD_H
#define REVERSETHREAD_H
#include <QThread>
#include <QAtomicInt>
//尝试冲正被核销的卡券
class FMPePayPrivate;
class ReverseThread : public QThread
{
public:
ReverseThread(FMPePayPrivate* fmPay, QObject* parent = 0);
void Stop();
protected:
void run()Q_DECL_OVERRIDE;
private:
void trySend();
private:
QAtomicInt _stop;
FMPePayPrivate* _fmPay;
};
#endif // REVERSETHREAD_H
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment