Commit 7e265bef by NitefullWind

1. 修复一些Bug(FMVipServer, FMMsgWnd等)。 2. 根据请求可唤起支付插件。 3. 修改各接口URL的构造方式。

parent 2f19af5a
......@@ -54,6 +54,7 @@ int FMNetwork::send(const QString &url, const QByteArray &reqData, QByteArray &r
rspData = reply->readAll();
} else {
int err = reply->error();
rspData = reply->readAll();
error = FM_API_NETWORERROR;
errorMsg = netErrInfo(err);
}
......
......@@ -17,6 +17,8 @@ FMPVip::~FMPVip()
{
StopService();
FMPLoggerInterface::InitContext(nullptr, false);
if (d_ptr) {
delete d_ptr;
d_ptr = nullptr;
......
......@@ -28,7 +28,7 @@ int FMPVipPrivate::Init()
auto resend = new ReSend();
resend->start();
FMPVipServer::instance();
FMPVipServer::instance()->SetPluginContext(q->_ctx);
q->_inited = true;
......
......@@ -28,11 +28,16 @@ void FMPVipServer::Listen(quint16 port)
void FMPVipServer::Write(const QByteArray &data)
{
if(socket->write(data) == -1) {
FMP_ERROR() << "Write error: " <<socket->error() << socket->errorString();
if(!socket || socket->write(data) == -1) {
FMP_ERROR() << "Write error: " << (socket ? socket->errorString() : "connection closed.");
}
}
void FMPVipServer::SetPluginContext(ctkPluginContext *ctx)
{
dispatcher->setPluginContext(ctx);
}
void FMPVipServer::onNewConnection()
{
socket = nextPendingConnection();
......@@ -44,6 +49,7 @@ void FMPVipServer::onNewConnection()
void FMPVipServer::onDisconnected()
{
FMP_DEBUG() << "Socket disconnected.";
socket->close();
}
void FMPVipServer::onReadyRead()
......@@ -61,4 +67,9 @@ void FMPVipServer::onReadyRead()
dispatcher->doTask(recvData.mid(sizeof(FMSOCKEHEADER)), rspData);
Write(rspData);
socket->waitForBytesWritten();
socket->close();
socket->deleteLater();
socket = nullptr;
}
......@@ -6,6 +6,7 @@
#define FMSOCKFLAG 0x4d46
class FMVipDispatcher;
class ctkPluginContext;
typedef struct {
int flag;
......@@ -20,6 +21,8 @@ public:
void Listen(quint16 port);
void Write(const QByteArray &data);
void SetPluginContext(ctkPluginContext *ctx);
//signals:
private slots:
void onNewConnection();
......
#include <QMenu>
#include <QAction>
#include <QTimer>
#include <QJsonParseError>
#include "fmp_vip_settings.h"
#include <winsock2.h>
#include "fmvipdispatcher.h"
#include "fmtask.h"
#include "taskfactory.h"
#include "fmp_vip_server.h"
#include "tasklogin.h"
#include "taskpay.h"
#include "taskothers.h"
#include "taskfinal.h"
#include <ctkPluginContext.h>
#undef StartService
#include <fmp_epay_i.h>
FMVipDispatcher::FMVipDispatcher(QObject *parent) :
QObject(parent),
// FMApiRelay(),
// _posSocketTimer(new QTimer(this)),
fmTask(nullptr)
// server(new FMPVipServer(this))
fmTask(nullptr),
_ctx(nullptr)
{
// connect(this, SIGNAL(doTask()), this, SLOT(onDoTask()));
// _posSocketTimer->setInterval(5000);
// connect(_posSocketTimer, SIGNAL(timeout()), SLOT(onCheckSocket()));
// connect(this, SIGNAL(startSocketTimer()), _posSocketTimer, SLOT(start()));
// connect(this, SIGNAL(stopSocketTimer()), _posSocketTimer, SLOT(stop()));
// server->Listen(23770);
}
FMVipDispatcher::~FMVipDispatcher()
{
// del_p(_posSocketTimer);
}
//BOOL FMVipDispatcher::Transfer(LPSTR data, LPSTR &rsp, UINT &rsp_len)
//{
// if (strcmp(data, QuitCMD) != 0 && !_posSocketTimer->isActive()) {
// emit startSocketTimer();
// mutex.lock();
// reqData = QByteArray(data);
// emit doTask();
// condition.wait(&mutex);
// mutex.unlock();
// rsp = rspData.data();
// rsp_len = rspData.length();
// emit stopSocketTimer();
// }
// return true;
//}
void FMVipDispatcher::doTask(const QByteArray &reqData, QByteArray &rspData)
{
FMP_INFO() << "Recv POS reqData: " << reqData;
Session session;
QJsonParseError error;
QJsonDocument doc = QJsonDocument::fromJson(reqData, &error);
qDebug() << error.errorString();
QJsonObject jsonObj = doc.object();
FM_TYPE type = (FM_TYPE)jsonObj["fm_cmd"].toInt();
switch (type) {
case FM_Login: {
TaskLogin taskLogin(jsonObj, &session);
rspData = taskLogin.doTask();
break;
}
case FM_Pay: {
TaskPay taskPay(jsonObj, &session);
rspData = taskPay.doTask();
break;
}
fmTask = TaskFactory::Task(reqData);
if (fmTask == nullptr) {
rspData = QString::fromLocal8Bit("{\"msg:\":\"未知的请求类型\"}").toUtf8();
case FM_QR_Pay: {
if (_ctx) {
ctkServiceReference ref =_ctx->getServiceReference<FMPePayInterface>();
FMPePayInterface *epay = _ctx->getService<FMPePayInterface>(ref);
epay->DockPayRequest(reqData);
epay->StartService();
rspData = epay->DockPayRespond();
}
else {
rspData = QString::fromLocal8Bit("{\"msg:\":\"支付服务不可用\"}").toUtf8();
}
break;
}
case FM_Refund: {
QString fm_id = jsonObj[PosProps.Transaction].toObject()[PosProps.Fm_id].toString();
if(fm_id != "") {
TaskRefundOrder taskRefundOrder(jsonObj);
rspData = taskRefundOrder.doTask();
} else {
rspData = fmTask->doTask();
TaskRefundPay taskRefundPay(jsonObj);
rspData = taskRefundPay.doTask();
}
FMP_INFO() << "Send to pos: " << rspData;
// condition.wakeAll();
del_p(fmTask);
}
//void FMVipDispatcher::onCheckSocket()
//{
// if(_socket <=0 ) {
// emit stopSocketTimer();
// return;
// }
// WORD wVersionRequested;
// WSADATA wsaData;
// wVersionRequested = MAKEWORD(2, 2);
// WSAStartup(wVersionRequested, &wsaData);
// HANDLE closeEvent = WSACreateEvent();
// WSAEventSelect(_socket, closeEvent, FD_CLOSE);
// DWORD dwRet = WaitForSingleObject(closeEvent, 0);
// if(dwRet == WSA_WAIT_EVENT_0) {
// onDisconnected();
break;
}
// case FM_Order_Revoke: {
// TaskRefundPay taskRefundPay(jsonObj);
// rspData = taskRefundPay.doTask();
// break;
// }
case FM_QR_Refund: {
if (_ctx) {
ctkServiceReference ref =_ctx->getServiceReference<FMPePayInterface>();
FMPePayInterface *epay = _ctx->getService<FMPePayInterface>(ref);
epay->DockRefundRequest(reqData);
epay->StartService();
rspData = epay->DockRefundRespond();
}
else {
rspData = QString::fromLocal8Bit("{\"msg:\":\"退款服务不可用\"}").toUtf8();
}
break;
}
case FM_Final: {
TaskFinal taskFinal(jsonObj, &session);
rspData = taskFinal.doTask();
break;
}
default:
rspData = QString::fromLocal8Bit("{\"msg:\":\"未知的请求类型\"}").toUtf8();
break;
}
// WSACloseEvent(closeEvent);
// WSACleanup();
//}
FMP_INFO() << "Send to pos: " << rspData;
}
//void FMVipDispatcher::onDisconnected()
//{
// fmTask->stopTask();
// FMMsgWnd::FailureWnd(QString::fromLocal8Bit("操作时间过长,POS已断开Socket连接,请重新操作!"));
// condition.wakeAll();
//}
void FMVipDispatcher::setPluginContext(ctkPluginContext *ctx)
{
if (ctx && _ctx != ctx) {
try {
//! Verify pointer
ctx->getPlugin();
_ctx = ctx;
}
catch(const ctkException&) {
FMP_ERROR() << "Invalid context:" << ctx;
}
}
}
......@@ -5,10 +5,10 @@
#include <QMutex>
#include <QWaitCondition>
#include <QSystemTrayIcon>
//#include "fmapirelay.h"
class FMTask;
class FMPVipServer;
class ctkPluginContext;
class FMVipDispatcher : public QObject/*, public FMApiRelay*/
{
......@@ -19,29 +19,11 @@ public:
void doTask(const QByteArray &reqData, QByteArray &rspData);
private:
QMutex mutex;
QWaitCondition condition;
// QByteArray reqData;
// QByteArray rspData;
QTimer *_posSocketTimer;
FMTask *fmTask;
FMPVipServer *server;
//protected:
//// BOOL Transfer(LPSTR data, LPSTR &rsp, UINT &rsp_len);
void setPluginContext(ctkPluginContext *ctx);
//signals:
// void doTask();
// void startSocketTimer();
// void stopSocketTimer();
//public slots:
// void onDoTask();
// void onCheckSocket();
// void onDisconnected();
private:
FMTask * fmTask;
ctkPluginContext* _ctx;
};
#endif // FMVIPDISPATCHER_H
......@@ -24,15 +24,32 @@ const static int FM_Server_Type[] = {1001,1006,1002,1003,1007,1004,1004,1005};
// 请求类型的枚举值
enum FM_TYPE {
FM_Login,
FM_Coupon,
FM_Login = 1001,
FM_Pay = 1003,
FM_Refund = 1004,
FM_Final = 1007,
FM_Coupon = 1009,
FM_Fund,
FM_Pay,
FM_Final,
FM_Order_Refund,
FM_Charge_Refund,
FM_Order_Revoke
FM_Order_Revoke,
FM_QR_Pay = 10031,
FM_QR_Refund = 10041,
FM_Refund_Pay,
FM_Refund_Order
};
// 会员服务端请求URL
#ifndef FMREQURLMAP
#define FMREQURLMAP
typedef std::map<int, QString> FMReqUrlMap;
const FMReqUrlMap::value_type FMReqUrlMapPairs[] =
{
FMReqUrlMap::value_type(FM_Login, "auth"),
FMReqUrlMap::value_type(FM_Pay, "pay"),
FMReqUrlMap::value_type(FM_Final, "order"),
FMReqUrlMap::value_type(FM_Refund_Pay, "refund"),
FMReqUrlMap::value_type(FM_Refund_Order, "correct")
};
const FMReqUrlMap ReqUrl(FMReqUrlMapPairs, FMReqUrlMapPairs + (sizeof FMReqUrlMapPairs / sizeof FMReqUrlMapPairs[0]));
#endif
// JSON数据各字段名称
#ifndef POSPROPS
......@@ -43,6 +60,7 @@ struct PP{
AppId = "appId";
PartnerId = "partnerId";
T = "t";
Sign = "sign";
StoreId = "store_id";
PosId = "pos_id";
OperatorId = "operator_id";
......@@ -51,13 +69,19 @@ struct PP{
FM_Type = "FM_Type";
TransId = "trans_id";
Member_sign = "member_sign";
Account = "account";
Type_code = "type_code";
Type_name = "type_name";
Name = "name";
Sex = "sex";
Birthday = "birthday";
Amount = "amount";
Mobile = "mobile";
Phone = "phone";
Fm_open_id = "fm_open_id";
CanPay = "CanPay";
Address = "address";
Email = "email";
Score = "score";
......@@ -74,8 +98,13 @@ struct PP{
Transaction = "transactions";
OrderAmount = "order_amount";
PaidAmount = "paid_amount";
NeedAmount = "need_amount";
StandardAmount = "standard_amount";
Fm_id = "fm_id";
Settlement = "settlement";
Fm_transId = "fm_transId";
Pro_amount = "pro_amount";
Pay_amount = "pay_amount";
Pay_ids = "pay_ids";
Pay_id = "pay_id";
......@@ -105,6 +134,7 @@ struct PP{
QString AppId ;
QString PartnerId ;
QString T ;
QString Sign ;
QString StoreId ;
QString PosId ;
QString OperatorId ;
......@@ -113,13 +143,19 @@ struct PP{
QString FM_Type ;
QString TransId ;
QString Member_sign ;
QString Account ;
QString Type_code ;
QString Type_name ;
QString Name ;
QString Sex ;
QString Birthday ;
QString Amount ;
QString Mobile ;
QString Phone ;
QString Fm_open_id ;
QString CanPay ;
QString Address ;
QString Email ;
QString Score ;
......@@ -136,9 +172,16 @@ struct PP{
QString Coupons ;
QString Transaction ;
QString OrderAmount ;
QString NeedAmount ;
QString PaidAmount ;
QString StandardAmount ;
QString Fm_id ;
QString Settlement ;
QString Fm_transId ;
QString Pro_amount ;
QString Pay_amount ;
// 支付方式
QString Pay_ids ;
QString Pay_id ;
......@@ -180,10 +223,18 @@ const PropsMap::value_type PropsMapPairs[] =
PropsMap::value_type(PosProps.StoreId, "storeId"),
PropsMap::value_type(PosProps.PosId, "stationId"),
PropsMap::value_type(PosProps.OperatorId, "operatorId"),
PropsMap::value_type(PosProps.Mobile, "mobile"),
PropsMap::value_type(PosProps.Phone, "mobile"),
PropsMap::value_type(PosProps.TransId, "transId"),
PropsMap::value_type(PosProps.Coupon, "couponCode"),
PropsMap::value_type(PosProps.BussinessDate,"businessDate")
PropsMap::value_type(PosProps.BussinessDate,"businessDate"),
PropsMap::value_type(PosProps.Fm_id, "memberTransId"),
PropsMap::value_type(PosProps.Fm_open_id, "account"),
PropsMap::value_type(PosProps.Account, "memberNo"),
PropsMap::value_type(PosProps.CouponList, "coupon_list"),
PropsMap::value_type(PosProps.PaidAmount, "payAmount"),
PropsMap::value_type(PosProps.OrderAmount, "totalAmount"),
PropsMap::value_type(PosProps.Pay_id, "typeModeFlag"),
PropsMap::value_type(PosProps.Pay_amount, "amount"),
};
static PropsMap PosToServerProps(PropsMapPairs, PropsMapPairs + (sizeof(PropsMapPairs)/sizeof(PropsMapPairs[0])));
......
......@@ -107,13 +107,14 @@ bool FMTask::sendToServer(bool isShowMsg)
serverReqJsonObj[PosProps.PartnerId] = PARTNER_ID;
serverReqJsonObj[PosProps.T] = QString::number(QDateTime::currentMSecsSinceEpoch());
serverReqJsonObj[ServerProps(PosProps.Fm_cmd)] = FM_Server_Type[FM_Type()];
serverReqJsonObj[ServerProps(PosProps.Fm_cmd)] = QString::number(FM_Type());
serverReqJsonObj[PosProps.Sign] = sign();
packageServerReq();
QJsonDocument json(serverReqJsonObj);
QByteArray data = json.toJson(QJsonDocument::Compact);
url = QString("%1?sign=%2").arg(FMPVipSettings::instance()->getServerUrl()).arg(sign());
url = FMPVipSettings::instance()->getServerUrl() + "/" + ReqUrl.at(FM_Type());
QByteArray rspData;
FMNetwork net;
......
#include "taskfactory.h"
#include "tasklogin.h"
#include "taskpay.h"
#include "taskfund.h"
#include "taskfinal.h"
#include "taskothers.h"
#include "global.h"
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonParseError>
#include <QDebug>
//#include "taskfactory.h"
//#include "tasklogin.h"
//#include "taskpay.h"
//#include "taskfund.h"
//#include "taskfinal.h"
//#include "taskothers.h"
//#include "global.h"
//#include <QJsonDocument>
//#include <QJsonObject>
//#include <QJsonParseError>
//#include <QDebug>
TaskFactory::TaskFactory(QObject *parent) : QObject(parent)
{
//TaskFactory::TaskFactory(QObject *parent) : QObject(parent)
//{
}
//}
FMTask* TaskFactory::Task(QByteArray data)
{
QJsonParseError error;
QJsonDocument doc = QJsonDocument::fromJson(data, &error);
QJsonObject jsonObj = doc.object();
//FMTask* TaskFactory::Task(QByteArray data)
//{
// QJsonParseError error;
// QJsonDocument doc = QJsonDocument::fromJson(data, &error);
// QJsonObject jsonObj = doc.object();
FMTask* task = nullptr;
// FMTask* task = nullptr;
FM_TYPE type = (FM_TYPE)FM_Type_List.indexOf(jsonObj["fm_cmd"].toString());
switch (type) {
case FM_Login: {
task = new TaskLogin(jsonObj);
break;
}
case FM_Fund: {
task = new TaskFund(jsonObj);
break;
}
case FM_Pay: {
task = new TaskPay(jsonObj);
break;
}
case FM_Final: {
task = new TaskFinal(jsonObj);
break;
}
case FM_Coupon: {
task = new TaskCoupon(jsonObj);
break;
}
case FM_Order_Refund: {
task = new TaskRefundOrder(jsonObj);
break;
}
case FM_Order_Revoke: {
task = new TaskRefundPay(jsonObj);
break;
}
case FM_Charge_Refund: {
task = new TaskRefundOrder(jsonObj);
break;
}
default:
break;
}
// FM_TYPE type = (FM_TYPE)FM_Type_List.indexOf(jsonObj["fm_cmd"].toString());
// switch (type) {
// case FM_Login: {
// task = new TaskLogin(jsonObj);
// break;
// }
// case FM_Fund: {
// task = new TaskFund(jsonObj);
// break;
// }
// case FM_Pay: {
// task = new TaskPay(jsonObj);
// break;
// }
// case FM_Final: {
// task = new TaskFinal(jsonObj);
// break;
// }
// case FM_Coupon: {
// task = new TaskCoupon(jsonObj);
// break;
// }
// case FM_Order_Refund: {
// task = new TaskRefundOrder(jsonObj);
// break;
// }
// case FM_Order_Revoke: {
// task = new TaskRefundPay(jsonObj);
// break;
// }
// case FM_Charge_Refund: {
// task = new TaskRefundOrder(jsonObj);
// break;
// }
// default:
// break;
// }
return task;
}
// return task;
//}
#ifndef TASKFACTORY_H
#define TASKFACTORY_H
//#ifndef TASKFACTORY_H
//#define TASKFACTORY_H
#include <QObject>
#include "fmtask.h"
//#include <QObject>
//#include "fmtask.h"
class TaskFactory : public QObject
{
Q_OBJECT
public:
explicit TaskFactory(QObject *parent = 0);
static FMTask* Task(QByteArray data);
};
//class TaskFactory : public QObject
//{
// Q_OBJECT
//public:
// explicit TaskFactory(QObject *parent = 0);
// static FMTask* Task(QByteArray data);
//};
#endif // TASKFACTORY_H
//#endif // TASKFACTORY_H
......@@ -3,8 +3,8 @@
#include <QDateTime>
#include <QJsonDocument>
TaskFinal::TaskFinal(QJsonObject &jsonObj, QObject *parent)
:FMTaskNoWnd(jsonObj, FM_Final, 0, parent)
TaskFinal::TaskFinal(QJsonObject &jsonObj, Session *session, QObject *parent)
:FMTaskNoWnd(jsonObj, FM_Final, session, parent)
{
}
......
......@@ -6,7 +6,7 @@ class TaskFinal : public FMTaskNoWnd
{
Q_OBJECT
public:
explicit TaskFinal(QJsonObject &jsonObj, QObject* parent=0);
explicit TaskFinal(QJsonObject &jsonObj, Session *session = 0, QObject *parent = 0);
void packageServerReq();
......
......@@ -65,7 +65,7 @@ void TaskLogin::onLogin()
session()->addData(PosProps.Name, name);
session()->addData(PosProps.Amount, getServerJsonValue(PosProps.Amount).toInt());
session()->addData(PosProps.Birthday, birthday);
session()->addData(PosProps.Mobile, getServerJsonValue(PosProps.Mobile).toString());
session()->addData(PosProps.Phone, getServerJsonValue(PosProps.Phone).toString());
session()->addData(PosProps.Fm_open_id, account);
session()->addData(PosProps.Score, getServerJsonValue(PosProps.Score).toInt());
......
......@@ -51,7 +51,7 @@ void TaskRefundPay::packagePOSRsp()
TaskRefundOrder::TaskRefundOrder(QJsonObject &jsonObj, QObject *parent)
:FMTaskNoWnd(jsonObj, FM_Order_Refund, 0, parent)
:FMTaskNoWnd(jsonObj, FM_Refund_Order, 0, parent)
{
}
......
......@@ -2,9 +2,10 @@
#include "fmviporder.h"
#include "tasklogin.h"
TaskPay::TaskPay(QJsonObject &jsonObj, QObject *parent)
:FMTask(jsonObj, FM_Pay, 0, parent)
TaskPay::TaskPay(QJsonObject &jsonObj, Session *session, QObject *parent)
:FMTask(jsonObj, FM_Pay, session, parent)
{
}
}
......
......@@ -6,8 +6,7 @@ class TaskPay : public FMTask
{
Q_OBJECT
public:
explicit TaskPay(QJsonObject &jsonObj, QObject* parent=0);
explicit TaskPay(QJsonObject &jsonObj, Session *session = 0, QObject *parent = 0);
QByteArray doTask();
void setWindow();
void packageServerReq();
......
......@@ -8,7 +8,7 @@ FMCouponWidget::FMCouponWidget(Coupon conpon, QWidget *parent) :
{
ui->setupUi(this);
ui->code_lab->setText(conpon.code);
ui->amount_lab->setText(QString::number(conpon.disAmount, 'f', 2));
ui->amount_lab->setText(QString::number(conpon.disAmount/100, 'f', 2));
ui->desc_lab->setText(conpon.desc);
}
......
......@@ -8,7 +8,8 @@ FMMsgWnd::FMMsgWnd(QDialog *parent) :
{
ui->setupUi(this);
setAttribute(Qt::WA_TranslucentBackground);
this->setWindowFlags(windowFlags() | Qt::FramelessWindowHint);
setAttribute(Qt::WA_QuitOnClose, false);
this->setWindowFlags(windowFlags() | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
}
FMMsgWnd::~FMMsgWnd()
......@@ -20,19 +21,19 @@ void FMMsgWnd::show(InfoType type, const QString &info)
{
QString iconUrl;
switch (type) {
case InfoType::T_Normal:
case T_Normal:
iconUrl = "";
break;
case InfoType::T_Success:
case T_Success:
iconUrl = ":/tip_ok.png";
break;
case InfoType::T_Failure:
case T_Failure:
iconUrl = ":/tip_error.png";
break;
case InfoType::T_Warning:
case T_Warning:
iconUrl = ":/tip_warning.png";
break;
case InfoType::T_LoginSuccess:
case T_LoginSuccess:
ui->label_msg->setText(QString::fromLocal8Bit("会员认证成功"));
iconUrl = ":/tip_ok.png";
break;
......@@ -53,26 +54,34 @@ void FMMsgWnd::show(InfoType type, const QString &info)
void FMMsgWnd::FailureWnd(const QString &info, QDialog *parent)
{
FMMsgWnd window(parent);
if(parent != nullptr) {
window.setGeometry(parent->geometry());
}
window.show(FMMsgWnd::T_Failure, info);
}
void FMMsgWnd::WarningWnd(const QString &info, QDialog *parent)
{
FMMsgWnd window(parent);
if(parent != nullptr) {
window.setGeometry(parent->geometry());
}
window.show(FMMsgWnd::T_Warning, info);
}
void FMMsgWnd::SuccessWnd(const QString &info, QDialog *parent)
{
FMMsgWnd window(parent);
if(parent != nullptr) {
window.setGeometry(parent->geometry());
}
window.show(FMMsgWnd::T_Success, info);
}
void FMMsgWnd::LoginSuccess(const QString &account, const QString &name, const QString &birthday, QDialog *parent)
{
FMMsgWnd window(parent);
if(parent != nullptr) {
window.setGeometry(parent->geometry());
}
QString info = QString::fromLocal8Bit("账号:%1\n姓名:%2\n生日:%3").arg(account).arg(name).arg(birthday);
window.show(FMMsgWnd::T_LoginSuccess, info);
}
......
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