Commit 11ce624b by NitefullWind

1. 新增“设置门店信息”接口。 2. 实现新登录接口。

parent 16f5697b
......@@ -13,6 +13,8 @@ greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++11
DEFINES += FM_DEBUG
SOURCES += \
fmp_vip.cpp \
fmp_vip_p.cpp \
......
......@@ -72,12 +72,21 @@ bool DBOP::CreateTable(const QString &tableName)
"[payTransId] VARCHAR(50),"
"[orderId] INTEGER"
");";
QString tableStoreInfoSql = "CREATE TABLE [StoreInfo]("
"[id] INTEGER PRIMARY KEY autoincrement, "
"[store_id] VARCHAR(50), "
"[pos_id] VARCHAR(50), "
"[operator_id] VARCHAR(50), "
"[business_date] VARCHAR(50)"
");";
QString sql;
if(tableName.compare("Order") == 0) {
if(tableName.compare(TABLE_ORDER) == 0) {
sql = tableOrderSql;
} else if(tableName.compare("Pay") == 0) {
} else if(tableName.compare(TABLE_PAY) == 0) {
sql = tablePaySql;
} else if(tableName.compare(TABLE_STOREINFO) == 0) {
sql = tableStoreInfoSql;
}
bool isOk = _db->creat(sql);
qDebug() << "Create table: " << tableName << (isOk ? " Success." : " Failed.");
......@@ -212,3 +221,26 @@ QSharedPointer<FMItem::Pay> DBOP::GetPayByDBId(unsigned int DBID)
GetPayByDBId(DBID, pay.data());
return pay;
}
void DBOP::GetLastItem(Item *item)
{
Q_ASSERT(item != nullptr);
QSqlQuery query;
QString condition = "1=1 ORDER BY id DESC LIMIT 1";
bool isOk = Instance()->_db->find(item->ShortClassName(), query, QStringList(), condition);
if(isOk && query.next()) {
item->SetPropertiesBySqlRecord(query.record());
} else {
FMP_WARN() << "Dont't find last item in table: " << item->ShortClassName();
}
}
//template<typename T>
//QSharedPointer<T> DBOP::GetLastItem()
//{
// QSharedPointer<T> itemPointer(new T());
// GetLastItem(itemPointer.data());
// return itemPointer;
//}
......@@ -5,13 +5,15 @@
#include <QVector>
#include "global.h"
#define TABLE_PAY "Pay"
#define TABLE_ORDER "Order"
#define TABLE_PAY "Pay"
#define TABLE_ORDER "Order"
#define TABLE_STOREINFO "StoreInfo"
namespace FMItem {
class Item;
class Order;
class Pay;
class StoreInfo;
}
class FMPDataBase;
......@@ -34,6 +36,11 @@ public:
static QList<QSharedPointer<FMItem::Pay> > GetPaysByOrderId(int orderId);
static void GetPayByDBId(unsigned int DBID, FMItem::Pay *pay);
static QSharedPointer<FMItem::Pay> GetPayByDBId(unsigned int DBID);
static void GetLastItem(FMItem::Item *item);
// template<typename T>
// static QSharedPointer<T> GetLastItem();
private:
DBOP();
FMPDataBase *_db;
......
......@@ -47,7 +47,9 @@ SOURCES += \
$$PWD/items/item.cpp \
$$PWD/windows/fmviprefund.cpp \
$$PWD/task/taskrefund.cpp \
$$PWD/database/fmp_database.cpp
$$PWD/database/fmp_database.cpp \
$$PWD/task/tasksetstoreinfo.cpp \
$$PWD/items/storeinfo.cpp
HEADERS +=\
$$PWD/backup/fmbackup.h \
......@@ -85,7 +87,9 @@ HEADERS +=\
$$PWD/items/item.h \
$$PWD/windows/fmviprefund.h \
$$PWD/task/taskrefund.h \
$$PWD/database/fmp_database.h
$$PWD/database/fmp_database.h \
$$PWD/task/tasksetstoreinfo.h \
$$PWD/items/storeinfo.h
unix {
target.path = /usr/lib
......
......@@ -13,6 +13,7 @@
#include "taskothers.h"
#include "taskfinal.h"
#include "taskrefund.h"
#include "tasksetstoreinfo.h"
#include <ctkPluginContext.h>
#undef StartService
#include <fmp_epay_i.h>
......@@ -45,6 +46,11 @@ void FMVipDispatcher::doTask(const QByteArray &reqData, QByteArray &rspData)
FM_TYPE type = (FM_TYPE)jsonObj["fm_cmd"].toInt();
switch (type) {
case FM_Set_Store_Info: {
TaskSetStoreInfo taskSetStoreInfo(jsonObj);
rspData = taskSetStoreInfo.doTask();
break;
}
case FM_Login: {
TaskLogin taskLogin(jsonObj, &session);
rspData = taskLogin.doTask();
......
......@@ -20,6 +20,7 @@
// 请求类型的枚举值
enum FM_TYPE {
FM_Set_Store_Info = 1000,
FM_Login = 1001,
FM_Pay = 1003,
FM_Refund = 1004,
......@@ -138,6 +139,9 @@ struct PP{
CashAmount = "cashAmount";
Print = "print";
ThirdAmount = "thirdAmount";
MandatoryField = "MandatoryField";
OptionalField = "OptionalField";
}
QString AppId ;
......@@ -219,6 +223,9 @@ struct PP{
QString CashAmount ;
QString Print ;
QString ThirdAmount ;
QString MandatoryField;
QString OptionalField;
};
const static PP PosProps;
......
#include "storeinfo.h"
namespace FMItem {
StoreInfo::StoreInfo(QObject *parent)
: Item(parent)
, _storeId("")
, _posId("")
, _businessDate("")
, _operatorId("")
{
}
QString StoreInfo::storeId() const
{
return _storeId;
}
void StoreInfo::setStoreId(const QString &storeId)
{
_storeId = storeId;
}
QString StoreInfo::posId() const
{
return _posId;
}
void StoreInfo::setPosId(const QString &posId)
{
_posId = posId;
}
QString StoreInfo::businessDate() const
{
return _businessDate;
}
void StoreInfo::setBusinessDate(const QString &businessDate)
{
_businessDate = businessDate;
}
QString StoreInfo::operatorId() const
{
return _operatorId;
}
void StoreInfo::setOperatorId(const QString &operatorId)
{
_operatorId = operatorId;
}
}
#ifndef STOREINFO_H
#define STOREINFO_H
#include "item.h"
namespace FMItem {
class StoreInfo : public Item
{
Q_OBJECT
Q_PROPERTY(QString store_id READ storeId WRITE setStoreId)
Q_PROPERTY(QString pos_id READ posId WRITE setPosId)
Q_PROPERTY(QString business_date READ businessDate WRITE setBusinessDate)
Q_PROPERTY(QString operator_id READ operatorId WRITE setOperatorId)
public:
explicit StoreInfo(QObject *parent = 0);
QString storeId() const;
void setStoreId(const QString &storeId);
QString posId() const;
void setPosId(const QString &posId);
QString businessDate() const;
void setBusinessDate(const QString &businessDate);
QString operatorId() const;
void setOperatorId(const QString &operatorId);
private:
QString _storeId;
QString _posId;
QString _businessDate;
QString _operatorId;
};
}
#endif // STOREINFO_H
......@@ -5,15 +5,7 @@
#include <QJsonDocument>
#include <QJsonParseError>
#include <QCryptographicHash>
#include "fmp_vip_settings.h"
#define RunFunction(function) do { \
function##(); \
if(error() != FM_API_SUCCESS) { \
FMP_WARN() << QString("Task error %1: %2").arg(error()).arg(errorString()); \
return QString(ErrorMsgJson).arg(error()).arg(errorString()).toLatin1(); \
} \
} while(0);
#include <QFile>
FMTask::FMTask(QJsonObject &jsonObj, FM_TYPE fmType, Session *session, QObject *parent) :
QObject(parent),
......@@ -45,6 +37,13 @@ FMTask::~FMTask()
QByteArray FMTask::doTask()
{
FMP_DEBUG() << __FUNCTION__;
#ifdef FM_DEBUG
if(!checkReqJson()) {
return errorStringJson().toUtf8();
}
#endif
RunFunction(packagePOSReq);
RunFunction(copyPros);
RunFunction(setWindow);
RunFunction(showWindow);
......@@ -227,3 +226,79 @@ QString FMTask::sign() const
QByteArray md5Bt = QCryptographicHash::hash(bt, QCryptographicHash::Md5);
return md5Bt.toHex();
}
bool FMTask::checkReqJson()
{
bool isOk = false;
QFile jsonFile("FMCMDKeys.json");
if(!jsonFile.open(QFile::ReadOnly)) {
setError(FM_API_BADJSON, QString::fromLocal8Bit("读取FMCMDKeys.json失败(%1)").arg(jsonFile.errorString()));
} else {
QByteArray jsonArray = jsonFile.readAll();
QJsonParseError error;
QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonArray, &error);
if(error.error != QJsonParseError::NoError) {
setError(FM_API_BADJSON, QString::fromLocal8Bit("解析FMCMDKeys文件内容失败(%1)").arg(error.errorString()));
} else {
QJsonObject jsonObj = jsonDoc.object();
_checkJsonObj = jsonObj[QString::number(FM_Type())].toObject();
isOk = true;
}
}
jsonFile.close();
if(isOk) {
QJsonObject mandatoryFieldObj = _checkJsonObj[PosProps.MandatoryField].toObject();
QJsonObject optionalFieldObj = _checkJsonObj[PosProps.OptionalField].toObject();
QStringList checkKeys = mandatoryFieldObj.keys() + optionalFieldObj.keys();
foreach (const QString &checkKey, checkKeys) {
if(!posReqJsonObj.contains(checkKey) && mandatoryFieldObj.contains(checkKey)) {
isOk = false;
setError(FM_API_BADJSON, QString::fromLocal8Bit("请求不合法,需要[%1]字段。").arg(checkKey));
break;
}
QVariant expectValue;
if(mandatoryFieldObj.contains(checkKey)) {
expectValue = mandatoryFieldObj[checkKey].toVariant();
} else {
expectValue = optionalFieldObj[checkKey].toVariant();
}
QVariant actualValue = posReqJsonObj[checkKey].toVariant();
QVariant::Type expectType = expectValue.type();
QVariant::Type actualType = actualValue.type();
if(expectType == QVariant::Double) {
//! NOTE 判断期待是否是int类型
double tempExpect = expectValue.toDouble();
if(tempExpect == (int)tempExpect) {
expectType = QVariant::Int;
}
}
//! NOTE 当期待是int类型时,判断实际值是否是int类型
if(expectType==QVariant::Int && actualType == QVariant::Double) {
double tempActual = actualValue.toDouble();
if(tempActual == (int)tempActual) {
actualType = QVariant::Int;
}
}
if(mandatoryFieldObj.contains(checkKey) && actualType == QVariant::String && posReqJsonObj[checkKey].toString().isEmpty()) {
isOk = false;
setError(FM_API_BADJSON, QString::fromLocal8Bit("请求不合法,字段[%1]值不能为空。").arg(checkKey));
break;
}
if(expectType != actualType) {
isOk = false;
setError(FM_API_BADJSON, QString::fromLocal8Bit("请求不合法,字段[%1]应该为 %2 类型。")
.arg(checkKey)
.arg(QVariant::typeToName(expectType)));
break;
}
}
}
return isOk;
}
......@@ -7,6 +7,15 @@
#include <QJsonObject>
#include <QJsonArray>
#include <QDebug>
#include "fmp_vip_settings.h"
#define RunFunction(function) do { \
function##(); \
if(error() != FM_API_SUCCESS) { \
FMP_WARN() << QString("Task error %1: %2").arg(error()).arg(errorString()); \
return errorStringJson().toUtf8(); \
} \
} while(0);
class FMTask : public QObject
{
......@@ -27,9 +36,12 @@ public:
QJsonValue getServerJsonValue(const QString prop);
QJsonValue getPosJsonValue(const QString prop);
bool checkReqJson();
protected:
// 从配置文件中拷贝数据信息
void copyPros();
virtual void packagePOSReq(){}
virtual void setWindow(){}
virtual void showWindow();
virtual void packageServerReq() = 0;
......@@ -50,6 +62,8 @@ protected:
FMTask *preTask;
QJsonObject _checkJsonObj;
private:
QString sign() const;
......@@ -75,6 +89,9 @@ public:
return fm_error.at(_error);
}
}
QString errorStringJson() {
return QString(ErrorMsgJson).arg(error()).arg(errorString());
}
private:
FMError _error;
QString _errorMsg;
......
......@@ -10,13 +10,19 @@ FMTaskNoWnd::FMTaskNoWnd(QJsonObject &jsonObj, FM_TYPE fmType, Session *session,
QByteArray FMTaskNoWnd::doTask()
{
copyPros();
#ifdef FM_DEBUG
if(!checkReqJson()) {
return errorStringJson().toUtf8();
}
#endif
RunFunction(packagePOSReq);
RunFunction(copyPros);
bool isOk = sendToServer();
if(!isOk) {
FMP_WARN() << QString("Task error %1: %2").arg(error()).arg(errorString());
return QString(ErrorMsgJson).arg(error()).arg(errorString()).toLatin1();
return errorStringJson().toUtf8();
}
packagePOSRsp();
RunFunction(packagePOSRsp);
QJsonDocument json(posRspJsonObj);
return json.toJson(QJsonDocument::Compact);
......
......@@ -3,12 +3,22 @@
#include "fmp_vip_settings.h"
#include "fmnetwork.h"
#include <QJsonDocument>
#include "items/storeinfo.h"
#include "dbop.h"
TaskLogin::TaskLogin(QJsonObject &jsonObj, Session *session, QObject *parent)
:FMTask(jsonObj, FM_Login, session, parent)
{
}
void TaskLogin::packagePOSReq()
{
auto storeInfo = new FMItem::StoreInfo();
DBOP::GetLastItem(storeInfo);
posReqJsonObj = storeInfo->toJson(QStringList(), posReqJsonObj);
}
void TaskLogin::setWindow()
{
_window = new FMVipLogin;
......
......@@ -10,9 +10,10 @@ public:
explicit TaskLogin(QJsonObject &jsonObj, Session* session = 0, QObject* parent=0);
private:
void packagePOSReq() override;
void setWindow() override;
void packageServerReq();
void packagePOSRsp();
void packageServerReq() override;
void packagePOSRsp() override;
public slots:
void onLogin();
......
#include "tasksetstoreinfo.h"
#include "items/storeinfo.h"
#include "dbop.h"
#include <QJsonDocument>
TaskSetStoreInfo::TaskSetStoreInfo(QJsonObject &jsonObj, QObject *parent)
: FMTaskNoWnd(jsonObj, FM_Set_Store_Info, 0, parent)
, _isSuccessSave(false)
{
}
QByteArray TaskSetStoreInfo::doTask()
{
#ifdef FM_DEBUG
if(!checkReqJson()) {
return errorStringJson().toUtf8();
}
#endif
RunFunction(packagePOSReq);
RunFunction(packageServerReq);
RunFunction(packagePOSRsp);
QJsonDocument json(posRspJsonObj);
return json.toJson(QJsonDocument::Compact);
}
void TaskSetStoreInfo::packageServerReq()
{
FMItem::StoreInfo storeInfo;
storeInfo.SetPropertiesByJson(posReqJsonObj);
_isSuccessSave = DBOP::Save(&storeInfo);
}
void TaskSetStoreInfo::packagePOSRsp()
{
int statusCode = _isSuccessSave ? FM_API_SUCCESS : FM_API_ERROR;
QString msg("");
if(!_isSuccessSave) {
msg = QString::fromLocal8Bit("保存门店信息失败");
}
posRspJsonObj[PosProps.StatusCode] = statusCode;
posRspJsonObj[PosProps.Msg] = msg;
}
#ifndef TASKSETSTOREINFO_H
#define TASKSETSTOREINFO_H
#include "fmtasknownd.h"
class TaskSetStoreInfo : public FMTaskNoWnd
{
Q_OBJECT
public:
explicit TaskSetStoreInfo(QJsonObject &jsonObj, QObject *parent = nullptr);
QByteArray doTask() override;
void packageServerReq() override;
void packagePOSRsp() override;
bool _isSuccessSave;
};
#endif // TASKSETSTOREINFO_H
......@@ -4,7 +4,7 @@ QT += testlib sql
CONFIG += C++11
DEFINES += FMTEST
DEFINES += FMTEST FM_DEBUG
CONFIG += qt console warn_on depend_includepath testcase
CONFIG -= app_bundle
......
......@@ -4,6 +4,7 @@
#include "items/order.h"
#include "items/pay.h"
#include "items/product.h"
#include "items/storeinfo.h"
#include "fmtool.h"
#include "database/dbop.h"
#include <QJsonObject>
......@@ -14,6 +15,7 @@ using FMItem::Item;
using FMItem::Order;
using FMItem::Pay;
using FMItem::Product;
using FMItem::StoreInfo;
class TestItem : public QObject
{
......@@ -48,6 +50,9 @@ private slots:
void test_GetOrderByTransId_data();
void test_GetOrderByTransId();
void test_GetTableLastItem_data();
void test_GetTableLastItem();
};
TestItem::TestItem()
......@@ -252,6 +257,38 @@ void TestItem::test_GetOrderByTransId()
QVERIFY(payList.first().data()->isEqual(in_pay));
}
void TestItem::test_GetTableLastItem_data()
{
QTest::addColumn<Item*>("save_item");
QTest::addColumn<Item*>("get_item");
Order *order = new Order(this);
Pay *pay = new Pay(this);
StoreInfo *si_save = new StoreInfo(this);
si_save->setStoreId("fm9999");
si_save->setPosId("2");
si_save->setBusinessDate("2017");
si_save->setOperatorId("001");
StoreInfo *si_get = new StoreInfo(this);
QTest::newRow("Order") << qobject_cast<Item*>(gOrder) << qobject_cast<Item*>(order);
QTest::newRow("Pay") << qobject_cast<Item*>(gPay) << qobject_cast<Item*>(pay);
QTest::newRow("StoreInfo") << qobject_cast<Item*>(si_save) << qobject_cast<Item*>(si_get);
}
void TestItem::test_GetTableLastItem()
{
QFETCH(Item *, save_item);
QFETCH(Item *, get_item);
bool isOk = DBOP::Save(save_item);
QVERIFY2(isOk, "Save item failed.");
DBOP::GetLastItem(get_item);
QVERIFY2(save_item->isEqual(get_item), "Get table last item failed.");
}
QTEST_MAIN(TestItem)
#include "tst_testitem.moc"
......@@ -47,7 +47,12 @@ void TestPlugin::test_dotask_data()
QTest::addColumn<QByteArray>("reqData");
QTest::newRow("Refund") << QByteArray("{\"fm_cmd\": 1004,\"trans_id\": \"12345\"}");
// QTest::newRow("Refund not") << QByteArray("{\"fm_cmd\": 1004,\"trans_id\": \"123456\"}");
QTest::newRow("Refund not") << QByteArray("{\"fm_cmd\": 1004,\"trans_id\": \"123456\"}");
QTest::newRow("SetStoreInfo") << QByteArray("{\"fm_cmd\": 1000,\"store_id\": \"fm9999\",\"pos_id\": \"1\",\"business_date\": \"20171016\",\"operator_id\": \"001\"}");
QTest::newRow("SetStoreInfo_need_posId") << QByteArray("{\"fm_cmd\": 1000,\"store_id\": \"fm9999\",\"pos_id\": \"\",\"business_date\": \"20171016\",\"operator_id\": \"001\"}");
QTest::newRow("SetStoreInfo_notnull_posId") << QByteArray("{\"fm_cmd\": 1000,\"store_id\": \"fm9999\",\"business_date\": \"20171016\",\"operator_id\": \"001\"}");
QTest::newRow("SetStoreInfo_error_type") << QByteArray("{\"fm_cmd\": 1000,\"store_id\": \"fm9999\",\"pos_id\": 1,\"business_date\": \"20171016\",\"operator_id\": \"001\"}");
QTest::newRow("Login") << QByteArray("{\"fm_cmd\": 1001,\"member_sign\": \"12345\"}");
}
void TestPlugin::test_dotask()
......@@ -56,6 +61,8 @@ void TestPlugin::test_dotask()
QByteArray rspData;
fmvip.doTask(reqData, rspData);
qDebug() << "RspData: " << rspData.data();
}
QTEST_MAIN(TestPlugin)
......
......@@ -5,7 +5,7 @@
#define VER_MINOR 1
#define VER_REVISION 0
#define VER_BUILD 13
#define VER_BUILD 14
//! Convert version numbers to string
#define _STR(S) #S
......
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