#include "windows.h"
#include "flowControl.h"
#include "QsLog.h"
#include "DTools/dataManger.h"
#include "preDefine.h"
#include "DTools/configManger.h"
#include "Model/cashierObject.h"
#include <QJsonValue>
#include <QTimer>
#include <QDir>
#include <QApplication>
#include <QDateTime>
#include <QThread>
#include <QtConcurrent>
#include "configManger.h"
#include <QMultiMap>
#include <QMap>
#include <QFile>
#include <DTools/simProcOrderDB.h>
#include <DTools/PrintSumBillPosDB.h>
#include <DTools/getCaboxAReAuth.h>
#include <DTools/printCupStickPosDB.h>
#include <DTools/printMsgQueueDB.h>
#include <DTools/PrintOrderPromotionDB.h>
#include <DTools/checkPoskeyExistPosDB.h>
#include <DTools/SaveNoticeMsgDB.h>
#include <DTools/PosMetaDataDB.h>
#include <QHostInfo>
#include "SocketCommunicate.h"

FlowControl &FlowControl::GetInstance()
{
   static FlowControl fc;
   return fc;
}

FlowControl::~FlowControl()
{
    QLOG_INFO() << "FlowControl::~FlowControl()........";
    m_clearTimer->deleteLater();
    m_heartTimer->deleteLater();
    m_queryStoreStatusTimer->deleteLater();
    m_pullTimer->deleteLater();
    m_analysisTimer->deleteLater();
    m_reportOMSReocrdOrderTimer->deleteLater();
    m_presistInputPosSuccessReocrdTimer->deleteLater();
    m_loginTimer->deleteLater();
    m_loopRefreshTimer->deleteLater();
    m_queryAllNoticeTimer->deleteLater();
    m_storageOrderTimer->deleteLater();
    m_delayGetRefundDetailTimer->deleteLater();
    m_remindCasherBlinkFloatTimer->deleteLater();
    m_blockInputPosWarnningTimer->deleteLater();

    loaclHttpServer->deleteLater();
}


FlowControl::FlowControl()
{
    m_bLoginResult =false;
    m_loginErrorCount = 0;
    m_sendHeartErrorCount = 0;
    m_queryStoreStatusErrorCount = 0;
    m_bCreateSelfCheckOrderError = false;
    m_openTcpChannel = true;  // 全国门店长连接已经全部开启;
    m_bFirstRecvInfo = true;
    m_bFloatFromLockSt = false;
    m_initSimProcOrderDBRet = false;
    m_initPrintSumBillPosDBRet = false;
    m_initPrintCupStickPosDBRet = false;
    m_initPrintMsgQueueDBRet = false;
    m_initPrintOrderPromotionDBRet = false;
    m_initCheckPoskeyExistPosDBRet = false;
    m_initSaveNoticeMsgDBRet = false;
    m_initPosMetaDataDBRet = false;

    //初始化门店营业状态;
    m_eleStoreStatus = UNKNOWNSTORE;
    m_mopStoreStatus = UNKNOWNSTORE;
    m_modStoreStatus = UNKNOWNSTORE;
    m_mtModStoreStatus = UNKNOWNSTORE;
    m_curbsideStoreStatus = UNKNOWNSTORE;
    m_existNoAckNotice = 0;
    //初始化上次心跳状态是否异常(false:代表心跳正常 | true:代表心跳异常);
    m_bLastHeartIsError = false;
    m_backupPosFlag = false;  // 初始化备机POS标志为 false;

    m_loginSocket = NULL;
    m_pullOrderSocket = NULL;
    m_reportOMSRecordOrderSocket = NULL;
    m_procOrderSocket = NULL;
    m_pullDishesSocket = NULL;
    m_pullOrderListSocket = NULL;
    m_queryStoreStatusSocket = NULL;
    m_orderCount = 0;
    m_o2ofulfillmentOrderCount = 0;
    m_clickPosCount = 0;
    m_serviceCallBackUrl = "";

    m_clearTimer=new QTimer(this);
    m_heartTimer=new QTimer(this);
    m_queryStoreStatusTimer = new QTimer(this);
    m_pullTimer=new QTimer(this);
    m_analysisTimer=new QTimer(this);
    m_reportOMSReocrdOrderTimer = new QTimer(this);
    m_presistInputPosSuccessReocrdTimer = new QTimer(this);
    m_loginTimer=new QTimer(this);
    m_loopRefreshTimer=new QTimer(this);
    m_queryAllNoticeTimer = new QTimer(this);
    m_storageOrderTimer = new QTimer(this);
    m_delayGetRefundDetailTimer = new QTimer(this);
    m_remindCasherBlinkFloatTimer = new QTimer(this);
    m_blockInputPosWarnningTimer = new QTimer(this);

    qRegisterMetaType<AlertForm::Type>("AlertForm::Type");

    connect(m_loginTimer,&QTimer::timeout,this,&FlowControl::_ClickToLogin);
    connect(m_loopRefreshTimer,&QTimer::timeout,this,&FlowControl::_LoopRefresh);
    connect(m_queryAllNoticeTimer,&QTimer::timeout,this,&FlowControl::_QueryAllNoticeMsg);
    connect(m_blockInputPosWarnningTimer,&QTimer::timeout,this,&FlowControl::_BlockInputPosWarnning);
    connect(m_storageOrderTimer,&QTimer::timeout,this,&FlowControl::_StoragePosOrderData);
    connect(m_delayGetRefundDetailTimer,&QTimer::timeout,this,&FlowControl::_ScanDelayGetRefundDetailList);
    connect(m_remindCasherBlinkFloatTimer,&QTimer::timeout,this,&FlowControl::_RemindCasherBlinkFloatForm);
    connect(m_pullTimer,&QTimer::timeout,this,&FlowControl::_PullOrderData);
    connect(m_analysisTimer, &QTimer::timeout, this, &FlowControl::_AnalysisOrderDetailData);
    connect(m_reportOMSReocrdOrderTimer,&QTimer::timeout,this,&FlowControl::_ReportOMSRecordOrderInfo);
    connect(m_presistInputPosSuccessReocrdTimer,&QTimer::timeout,this,&FlowControl::_PresistOrderInputPosSuccessRecord);
    connect(m_clearTimer,&QTimer::timeout,this,&FlowControl::_CrondClearExpireOrder);
    connect(m_heartTimer,&QTimer::timeout,this,&FlowControl::_SendHeart);
    connect(m_queryStoreStatusTimer,&QTimer::timeout,this,&FlowControl::_QueryAllChannelStoreStatus);
    connect(this,&FlowControl::doConfirmOrder,this,&FlowControl::_ConfirmOrder,Qt::BlockingQueuedConnection);
    connect(this,&FlowControl::doRefundOrder,this,&FlowControl::_RefundOrder,Qt::BlockingQueuedConnection);
    connect(this, &FlowControl::doLogin, this, &FlowControl::onGetNewStoreInfo,Qt::BlockingQueuedConnection);

    // 新增本地开发调试开关, 方便自测;
    bool  app_release_mode = true;  // false --> debug; true --> Release;

    if  ( app_release_mode ) {

        // 打开Sql server express 数据库并登陆外卖插件 //
        SimProcOrderDB::getInstance();
        m_initSimProcOrderDBRet = SimProcOrderDB::getInstance().initSimProcOrderDB();

        // 打开SqlServer POS打印汇总信息本地数据库 //
        PrintSumBillPosDB::getInstance();
        m_initPrintSumBillPosDBRet = PrintSumBillPosDB::getInstance().initPrintSumBillPosDB();

        // 打开SqlServer POS打印杯贴商品数据本地数据库 //
        PrintCupStickPosDB::getInstance();
        m_initPrintCupStickPosDBRet = PrintCupStickPosDB::getInstance().initPrintCupStickPosDB();

        // 打开SqlServer POS打印消息队列本地数据库 //
        PrintMsgQueueDB::getInstance();
        m_initPrintMsgQueueDBRet = PrintMsgQueueDB::getInstance().initPrintMsgQueueDB();

        // 打开SqlServer POS打印订单优惠明细数据本地数据库 //
        PrintOrderPromotionDB::getInstance();
        m_initPrintOrderPromotionDBRet = PrintOrderPromotionDB::getInstance().initPrintOrderPromotionDB();

        // 打开SqlServer 用订单的全部去重Poskey校验 在POS本地数据库的有效性 //
        CheckPoskeyExistPosDB::getInstance();
        m_initCheckPoskeyExistPosDBRet = CheckPoskeyExistPosDB::getInstance().initCheckPoskeyExistPosDB();

        // 打开SqlServer 存储上游推送的 通告消息 本地数据库 //
        SaveNoticeMsgDB::getInstance();
        m_initSaveNoticeMsgDBRet = SaveNoticeMsgDB::getInstance().initSaveNoticeMsgDB();

        // 打开SqlServer 查看 POS 收银系统的元数据: 工作站号, 收银员id, 收银员名称 等等//
        PosMetaDataDB::getInstance();
        m_initPosMetaDataDBRet = PosMetaDataDB::getInstance().initPosMetaDataDB();

        // DB 单例需要发起 告警弹窗需求;
        connect(&PrintSumBillPosDB::getInstance(), &PrintSumBillPosDB::triggerFlowContrlAlert, this, &FlowControl::onTriggerFlowContrlAlert);
        connect(&PrintCupStickPosDB::getInstance(), &PrintCupStickPosDB::triggerFlowContrlAlert, this, &FlowControl::onTriggerFlowContrlAlert);
    }

    QLOG_INFO()<<QString("[<<<<---FlowControl::FlowControl() m_initSimProcOrderDBRet: %1, m_initPrintSumBillPosDBRet: %2,"
                                        "m_initPrintCupStickPosDBRet:%3, m_initPrintMsgQueueDBRet:%4, m_initPrintOrderPromotionDBRet:%5, m_initCheckPoskeyExistPosDBRet:%6, "
                                        "m_initSaveNoticeMsgDBRet:%7, m_initPosMetaDataDBRet:%8 --->>>>]")
                 .arg( m_initSimProcOrderDBRet?1:0).arg( m_initPrintSumBillPosDBRet?1:0)
                 .arg(m_initPrintCupStickPosDBRet?1:0).arg(m_initPrintMsgQueueDBRet?1:0).arg(m_initPrintOrderPromotionDBRet?1:0)
                 .arg(m_initCheckPoskeyExistPosDBRet?1:0).arg(m_initSaveNoticeMsgDBRet?1:0).arg(m_initPosMetaDataDBRet?1:0);

    // FlowControl() 初始化时，接受信号的槽对象还没有实例化，所以在此时发信号没有用;

    /*** 启动Http服务:用来响应: ① Simphony_Script获取订单数据请求; ② 响应上游fulfillment Service推单+推送通告+门店开关店状态【回调发生在新的线程内】***/
    loaclHttpServer = new LoaclHttpServer();
    loaclHttpServer->run();

   _ClickOMSAssignArea();
   m_loginTimer->start(10*1000);
   m_loopRefreshTimer->start(5*1000); // 5s 定期循环刷新: 1、补偿开机启动插件就运行连接数据库失败后重连操作;

}


void FlowControl::_GetIpAddress()
{
    std::string macAddress = "";
    std::string ipAddress = "";
    int getMacRet = MacTool::GetMacByAdaptersAddresses( macAddress , ipAddress);
    if ( !getMacRet) {
        QLOG_ERROR() << "FlowControl::_GetIpAddress  MacTool->GetMacByAdaptersAddresses Falied";
    }
    m_posMacAddress = macAddress.c_str();
    m_ipAddress = ipAddress.c_str();

    QHostInfo info = QHostInfo::fromName(QHostInfo::localHostName());
    m_posHostName = info.hostName();
    QLOG_INFO()<<QString("[<<<<---FlowControl::_GetIpAddress HostName:%1--->>>>]").arg(m_posHostName);
    // CNSHBK01S00000(国家+城市+BK01+S+5位店号)其中的BK01代表PC
    if ( m_posHostName.indexOf("BK01",Qt::CaseInsensitive) > 2 ) {
        m_backupPosFlag = true;
    }

    m_ipPortAddress = ipAddress.c_str() + QString(":") + QString::number(ConfigManger::GetInstance().GetHttpServerPort());
    QLOG_INFO()<<QString("[<<<<---FlowControl::_GetIpAddress Request Real IpAddress: %1, hostName: %2, macAddress: %3, ipPortAddress: %4 --->>>>]")
                 .arg(m_ipAddress).arg(m_posHostName).arg(m_posMacAddress).arg(m_ipPortAddress);
}


void FlowControl::_AddOrderPull(const QString& orderId, const QString& channel, const QString& callBackUrl, const bool& skipPrint, const QJsonObject& pushOptions,
                                const int& pageNumber, const int& pageSize)
{
    bool btryLock = m_PullOrderDataMutex.tryLock(VALUE_TRYLOCKNETTIMEOUT);
    if ( btryLock )  {
        /***组装从FM外卖service端的拉单请求参数***/
        PullOrderInfo* orderPull = new PullOrderInfo();
        orderPull->orderId=orderId;
        orderPull->channel=channel;
        orderPull->pageNumber=pageNumber;
        orderPull->pageSize=pageSize;
        orderPull->callBackUrl=callBackUrl;
        orderPull->skipPrint=skipPrint;
        orderPull->pushOptions=pushOptions;
        orderPull->pullErrorCount = 0;
        QLOG_INFO()<<QString("[<<<<---FlowControl::_AddOrderPull orderId: %1, callBackUrl: %2, skipPrint: %3 --->>>>]").arg(orderId).arg(callBackUrl).arg( skipPrint ? 1 : 0 )<< pushOptions;
        m_orderPullList.append(orderPull);
        m_PullOrderDataMutex.unlock();
    } else {
        QLOG_ERROR()<<QString("[<<<<---FlowControl::_AddOrderPull orderId:%1 tryLock Faild--->>>>]").arg(orderId);
    }
}


bool FlowControl::_TryAddOrderPull(const QString& orderId, const QString& channel, const QString& callBackUrl, const bool& skipPrint, const QJsonObject& pushOptions,
                                   const int& pageNumber, const int& pageSize)
{
    bool btryLock = m_PullOrderDataMutex.tryLock(VALUE_TRYLOCKNETTIMEOUT);
    if (btryLock) {
        QLOG_INFO()<<QString::fromLocal8Bit("[<<<<---FlowControl::_TryAddOrderPull orderId=%1 skipPrint=%2 pushOptions= --->>>>]").arg(orderId).arg(skipPrint?1:0) << pushOptions;
        //调用此函数:_TryAddOrderPull() 的函数:_ResponseOMS11Request()没有能百分之百锁定住:插件正触发Simphony在录销售单时，插件立刻接受到OMS推送过来的退货单;
        if(!m_simValidOrdersList.isEmpty()) {
            //缩小锁住订单的条件范围: 服务端推单给插件程序且插件程序拒绝本次订单状态发生变化的请求
            if(orderId == m_simValidOrdersList.first() && m_bFloatFromLockSt) {
                QLOG_ERROR()<<QString::fromLocal8Bit("[<<<<---FlowControl::_TryAddOrderPull orderId:%1 当前订单正在录POS系统，请耐心等待--->>>>]").arg(orderId);
                m_PullOrderDataMutex.unlock();
                return false;
            }
        }
        /***组装从FM外卖service端的拉单请求参数***/
        //遍历 如果指定订单已经在待拉取订单列表中,则不需要在继续添加到列表中;
       PullOrderInfo* tempOrderPull = NULL;
       if(!m_orderPullList.isEmpty()){
            QList<PullOrderInfo*>::iterator i;
            for (i = m_orderPullList.begin(); i != m_orderPullList.end(); ++i) {
                tempOrderPull = (*i);   //*i 使用*运算符获取遍历容器中所指的元素;
                if (orderId == tempOrderPull->orderId) {
                    //待拉取的订单详细列表已经存在,无需在添加;
                    m_PullOrderDataMutex.unlock();
                    return true;
                } else {
                    tempOrderPull = NULL;
                }
            }
        }
        PullOrderInfo* orderPull = new PullOrderInfo();
        orderPull->orderId=orderId;
        orderPull->channel=channel;
        orderPull->callBackUrl = callBackUrl;
        orderPull->pageNumber=pageNumber;
        orderPull->pageSize=pageSize;
        orderPull->pullErrorCount = 0;
        orderPull->skipPrint = skipPrint;
        orderPull->pushOptions = pushOptions;

        m_orderPullList.append(orderPull);
        m_PullOrderDataMutex.unlock();
    } else {
        QLOG_ERROR()<<QString::fromLocal8Bit("[<<<<---FlowControl::_TryAddOrderPull orderId:%1 Try Lock Error--->>>>]").arg(orderId);
    }
    return btryLock;
}


bool FlowControl::_TryAddOrderQueueAnalysis(const QString& orderId, const QJsonObject& orderDetailJson, const QString& callBackUrl, const QJsonObject& pushOptions)
{
    bool btryLock = m_analysisOrderDataMutex.tryLock(VALUE_TRYLOCKNETTIMEOUT);
    if (btryLock) {
        QLOG_INFO()<<QString("[<<<<---FlowControl::_TryAddOrderQueueAnalysis orderId=%1 pushOptions= --->>>>]").arg(orderId) << pushOptions;
        //遍历如果指定订单已经在待解析列表中,则需要替换最新数据到列表中;
       AnalysisOrderInfo* tempOrderAnalysis = NULL;
       if ( !m_orderAnalysisList.isEmpty() ) {
            QList<AnalysisOrderInfo*>::iterator i;
            for ( i = m_orderAnalysisList.begin(); i != m_orderAnalysisList.end(); ++i ) {
                tempOrderAnalysis = (*i);   //*i 使用*运算符获取遍历容器中所指的元素;
                if ( orderId == tempOrderAnalysis->orderId ) {
                    tempOrderAnalysis->callBackUrl = callBackUrl;
                    tempOrderAnalysis->orderDetailJson = orderDetailJson;
                    tempOrderAnalysis->pushOptions = pushOptions;
                    m_analysisOrderDataMutex.unlock();
                    return true;
                } else {
                    tempOrderAnalysis = NULL;
                }
            }
        }

        AnalysisOrderInfo* orderAnalysis = new AnalysisOrderInfo();
        orderAnalysis->orderId=orderId;
        orderAnalysis->callBackUrl = callBackUrl;
        orderAnalysis->orderDetailJson = orderDetailJson;
        orderAnalysis->pushOptions = pushOptions;

        m_orderAnalysisList.append(orderAnalysis);
        m_analysisOrderDataMutex.unlock();
    } else {
        QLOG_ERROR()<<QString::fromLocal8Bit("[<<<<---FlowControl::_TryAddOrderQueueAnalysis orderId:%1 Try Lock Error--->>>>]").arg(orderId);
    }
    return btryLock;
}


void FlowControl::_ClickOMSAssignArea()
{
    m_clickPosCount++;
    if ( m_clickPosCount >=3 ) {
        if ( m_clickPosCount >= 5  ) {
            QLOG_INFO()<<QString("[<<<<---m_clickPosCount >= 3  &&  >=5, m_clickPosCount:%1 , Reset Click Count And Click POS Screen--->>>>]").arg(m_clickPosCount);
            m_clickPosCount = 0;
        } else {
            QLOG_INFO()<<QString("[<<<<---m_clickPosCount >= 3  &&  <5, m_clickPosCount:%1 , Skip Real Click POS Screen--->>>>]").arg(m_clickPosCount);
            return;
        }
    }

    // 由于星巴克POS存在 三种屏幕[①大屏：1366*768 ②小屏：1024*768  ③Mini Pad]
    // 因此采用获取系统屏幕底部坐标减去一个相对距离来实现正确的点击事件(2020-12-10 初步设定：x-16，y-88)；
    /*
    // 解耦POS, 不在使用屏幕右下角按钮点击，触发登录条件;
    int xOffset = ConfigManger::GetInstance().GetOMSBtnWidthOffset();
    int yOffset = ConfigManger::GetInstance().GetOMSBtnHeightOffset();
    QLOG_INFO()<<QString::fromLocal8Bit("(yOffset%1:,yOffset:%2)").arg(xOffset).arg(yOffset);
    int nWidth = GetSystemMetrics(SM_CXSCREEN) - xOffset;
    int nHeight = GetSystemMetrics(SM_CYSCREEN) - yOffset;
    SetCursorPos(nWidth,nHeight);
    mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0);
    mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);
    QLOG_INFO()<<QString::fromLocal8Bit("[<<<<---触发按钮点击事件：Simphony获取订单请求->坐标(x%1:,y:%2):--->>>>]").arg(nWidth).arg(nHeight);
    */
}


void FlowControl::RefreshPosMetaData() {

    PosMateDataObject tmpPosMateObj;
    bool queryPosMetaRet = PosMetaDataDB::getInstance().queryPosMetaDataDB(&tmpPosMateObj);

    if ( !queryPosMetaRet ) {
        QLOG_INFO()<<QString("[<<<<---RefreshPosMetaData: queryPosMetaRet Is Failed, Use Default Value --->>>>>]");
        m_cashierId = DEFAULT_CASHIER_ID;
        m_cashierName = DEFAULT_CASHIER_NAME;
        m_posWorkstationNum = DEFAULT_WORKSTATION_NUM;
    } else {
        m_cashierId = tmpPosMateObj.empNo;
        m_cashierName = tmpPosMateObj.empName;
        m_posWorkstationNum = tmpPosMateObj.workstationNumber;
    }

    // 针对非ONE POS (backup), 需要手动置空收银员账号;
    if ( !m_backupPosFlag ) {
        m_cashierId = DEFAULT_CASHIER_ID_EMPTY;
        m_cashierName = DEFAULT_CASHIER_NAME_EMPTY;
    }

    QLOG_INFO()<<QString("[<<<<---RefreshPosMetaData: m_storeId=%1, m_subStoreId=%2, m_posWorkstationNum=%3, cashierId=%4, cashierName=%5 --->>>>>]")
                 .arg(m_storeId).arg(m_subStoreId).arg(m_posWorkstationNum).arg(m_cashierId).arg(m_cashierName);

    emit setCashierInfo(m_cashierName);  // POS上收银员切换账号后,插件上右下角的收银员信息也及时更新;
}


void FlowControl::_ClickToLogin()
{
    QLOG_INFO()<<QString::fromLocal8Bit("[<<<<---_ClickToLogin: m_bLoginResult:%1 --->>>>>]").arg(m_bLoginResult);
    if(!m_bLoginResult)
    {
        // 先获取 posHostName; 识别是否 backup-pc机;
        _GetIpAddress();
        // V2.2023.6.26 版本开始启用插件自动登录的功能; [ 收银员账号 需设置为 "" ,不能体现收银员账号信息 ]
        // 2023-05-24 后期出现Simphony系统 服务端证书授权服务的网络异常，门店无法正常登录，插件登录又依赖 店员针对 Simphony系统的首次登录;
        _AutoLoginSkipCashier();
    } else {
        m_loginTimer->stop();  // m_loginTimer->start(1000*60);
        // 即使插件上登录成功,也需要定时刷新POS收银员账号信息;
        // RefreshPosMetaData();
    }
}

// 5s 定期循环刷新;
void FlowControl::_LoopRefresh()
{
    // QLOG_INFO()<<QString("[<<<<---_LoopRefresh.......... --->>>>>]");

    // Check Db Connect Whether Successed!!!;
    if ( m_initSimProcOrderDBRet && m_initPrintSumBillPosDBRet && m_initPrintCupStickPosDBRet
         && m_initPrintMsgQueueDBRet && m_initPrintOrderPromotionDBRet && m_initCheckPoskeyExistPosDBRet &&
         m_initSaveNoticeMsgDBRet && m_initPosMetaDataDBRet ) {
        // Do Nothing ....;
    } else {
        if ( !m_initSimProcOrderDBRet ) {
            QLOG_ERROR()<<QString("[<<<<---FlowControl::_LoopRefresh() m_initSimProcOrderDBRet Is Failed, Retry Connect--->>>>]");
            m_initSimProcOrderDBRet = SimProcOrderDB::getInstance().initSimProcOrderDB();
            QLOG_INFO()<<QString("[<<<<---FlowControl::_LoopRefresh() m_initSimProcOrderDBRet Retry Connect Ret:= %1 --->>>>]").arg( m_initSimProcOrderDBRet ? 1 : 0 );
        }
        if ( !m_initPrintSumBillPosDBRet ) {
            QLOG_ERROR()<<QString("[<<<<---FlowControl::_LoopRefresh() m_initPrintSumBillPosDBRet Is Failed, Retry Connect--->>>>]");
            m_initPrintSumBillPosDBRet = PrintSumBillPosDB::getInstance().initPrintSumBillPosDB();
            QLOG_INFO()<<QString("[<<<<---FlowControl::_LoopRefresh() m_initPrintSumBillPosDBRet Retry Connect Ret:= %1 --->>>>]").arg( m_initPrintSumBillPosDBRet ? 1 : 0 );
        }
        if ( !m_initPrintCupStickPosDBRet ) {
            QLOG_ERROR()<<QString("[<<<<---FlowControl::_LoopRefresh() m_initPrintCupStickPosDBRet Is Failed, Retry Connect--->>>>]");
            m_initPrintCupStickPosDBRet = PrintCupStickPosDB::getInstance().initPrintCupStickPosDB();
            QLOG_INFO()<<QString("[<<<<---FlowControl::_LoopRefresh() m_initPrintCupStickPosDBRet Retry Connect Ret:= %1 --->>>>]").arg( m_initPrintCupStickPosDBRet ? 1 : 0 );
        }
        if ( !m_initPrintMsgQueueDBRet ) {
            QLOG_ERROR()<<QString("[<<<<---FlowControl::_LoopRefresh() m_initPrintMsgQueueDBRet Is Failed, Retry Connect--->>>>]");
            m_initPrintMsgQueueDBRet = PrintMsgQueueDB::getInstance().initPrintMsgQueueDB();
            QLOG_INFO()<<QString("[<<<<---FlowControl::_LoopRefresh() initPrintMsgQueueDB Retry Connect Ret:= %1 --->>>>]").arg( m_initPrintMsgQueueDBRet ? 1 : 0 );
        }
        if ( !m_initPrintOrderPromotionDBRet ) {
            QLOG_ERROR()<<QString("[<<<<---FlowControl::_LoopRefresh() m_initPrintOrderPromotionDBRet Is Failed, Retry Connect--->>>>]");
            m_initPrintOrderPromotionDBRet = PrintOrderPromotionDB::getInstance().initPrintOrderPromotionDB();
            QLOG_INFO()<<QString("[<<<<---FlowControl::_LoopRefresh() initPrintOrderPromotionDB Retry Connect Ret:= %1 --->>>>]").arg( m_initPrintOrderPromotionDBRet ? 1 : 0 );
        }
        if ( !m_initCheckPoskeyExistPosDBRet ) {
            QLOG_ERROR()<<QString("[<<<<---FlowControl::_LoopRefresh() m_initCheckPoskeyExistPosDBRet Is Failed, Retry Connect--->>>>]");
            m_initCheckPoskeyExistPosDBRet = CheckPoskeyExistPosDB::getInstance().initCheckPoskeyExistPosDB();
            QLOG_INFO()<<QString("[<<<<---FlowControl::_LoopRefresh() initCheckPoskeyExistPosDB Retry Connect Ret:= %1 --->>>>]").arg( m_initCheckPoskeyExistPosDBRet ? 1 : 0 );
        }
        if ( !m_initSaveNoticeMsgDBRet ) {
            QLOG_ERROR()<<QString("[<<<<---FlowControl::_LoopRefresh() m_initSaveNoticeMsgDBRet Is Failed, Retry Connect--->>>>]");
            m_initSaveNoticeMsgDBRet = SaveNoticeMsgDB::getInstance().initSaveNoticeMsgDB();
            QLOG_INFO()<<QString("[<<<<---FlowControl::_LoopRefresh() initSaveNoticeMsgDB Retry Connect Ret:= %1 --->>>>]").arg( m_initSaveNoticeMsgDBRet ? 1 : 0 );
        }
        if ( !m_initPosMetaDataDBRet ) {
            QLOG_ERROR()<<QString("[<<<<---FlowControl::_LoopRefresh() m_initPosMetaDataDBRet Is Failed, Retry Connect--->>>>]");
            m_initPosMetaDataDBRet = PosMetaDataDB::getInstance().initPosMetaDataDB();
            QLOG_INFO()<<QString("[<<<<---FlowControl::_LoopRefresh() initPosMetaDataDB Retry Connect Ret:= %1 --->>>>]").arg( m_initPosMetaDataDBRet ? 1 : 0 );
        }
    }

}


void FlowControl::_QueryAllNoticeMsg()
{
    QLOG_INFO()<<QString::fromLocal8Bit("[<<<<---10s after Login Success _QueryAllNoticeMsg --->>>>>]");

    // 获取本地数据库 门店通告消息 进行展示;
    bool retQueryAllNoticeMsg = SaveNoticeMsgDB::getInstance().queryAllNoticeMsgRecord(m_noticeObjList);
    QLOG_INFO() << QString("[<<<<---FlowControl::_QueryAllNoticeMsg()  retQueryAllNoticeMsg: %1 ,m_noticeObjList.size() = %2 --->>>>]").arg( retQueryAllNoticeMsg ? 1 : 0 ).arg( m_noticeObjList.size() );
    foreach ( NoticeObject* tempNoticeObj, m_noticeObjList ) {
        QLOG_INFO() << QString("[<<<<---FlowControl::FlowControl(), emit changeNoticeStatus  idIndex: %1 , title: %2 , Ack:%3--->>>>]")
                       .arg(tempNoticeObj->id).arg(tempNoticeObj->title).arg(tempNoticeObj->ackStatus);
        emit changeNoticeStatus( tempNoticeObj );
    }

    // 刷新 门店通告 状态;
    m_existNoAckNotice = SaveNoticeMsgDB::getInstance().existNoAckNotice() ? 1 : 0;
    QLOG_INFO() << QString("[<<<<---FlowControl::_QueryAllNoticeMsg()  m_existNoAckNotice: %1 , Then Emit doUpdateStoreStatus()--->>>>]").arg( m_existNoAckNotice );
    emit doUpdateStoreStatus( m_eleStoreStatus, m_modStoreStatus, m_mopStoreStatus, m_mtModStoreStatus, m_curbsideStoreStatus, m_existNoAckNotice);

    if ( retQueryAllNoticeMsg ) {
        m_queryAllNoticeTimer->stop();
    }

}


void FlowControl::_SmartTriggerClickPosBtn(const bool bTimerTrigger)
{
    QLOG_INFO()<<QString("[<<<<---FlowControl:_SmartTriggerClickPosBtn: m_bFloatFromLockSt: --->>>>>]")<<m_bFloatFromLockSt<<QString::fromLocal8Bit(" bTimerTrigger:")<< bTimerTrigger;
    //判断当前插件是否锁定状态:如果是锁定状态:不做任何处理；  如果是未锁定状态:1：重置锁定标志；2：隐藏主窗体显示悬浮框；3：锁住悬浮框；4模拟点击POS机右下角button；
    if (bTimerTrigger) {
        _ClickOMSAssignArea();
    }else if (!m_bFloatFromLockSt) {
        //转移到 _ResponseSimReqFristOrderData() 实际触发录单请求时 才隐藏和锁定悬浮框;
        _ClickOMSAssignArea();
    }
}


void FlowControl::_BlockInputPosWarnning() {
    int blockInputSize = m_simValidOrdersList.size();
    QString orderId = m_simValidOrdersList.first();
    QLOG_INFO()<<QString("[<<<<---_BlockInputPosWarnning:  m_simValidOrdersList  size:  %1 And FirstOne: %2 --->>>>>]").arg( blockInputSize ).arg( orderId );

    QString orderChannel = m_FmOrdersMap.value(orderId) ? m_FmOrdersMap.value(orderId)->channel : "";
    QString orderRequestType = "3";
    QString storeDatetimeOrderId = m_storeId + "_" + QDateTime::currentDateTime().toString("MMddhhmmss");

    if ( m_FmOrdersMap.value(orderId) ) {
        m_FmOrdersMap.value(orderId)->orderStatus != 6 ? orderRequestType = "3" : orderRequestType = "6";
    }

    QString errorStorageOrderMsg = QString("BlockInputPosWarnning: StoreId: %1 Cashier: %2 BlockOrderId: %3 BlockSize: %4")
            .arg(m_storeId).arg(m_cashierName).arg(orderId).arg(blockInputSize);

     _AddOrUpdateReportOmsList(storeDatetimeOrderId,  orderChannel, orderRequestType, "2", "", errorStorageOrderMsg, QString("1109") );

}

void FlowControl::_StoragePosOrderData() {

    if ( !m_storagePosOrdersList.isEmpty() || !m_simValidOrdersList.isEmpty() ) {
        QLOG_INFO()<<QString("[<<<<---_StoragePosOrderData: m_storagePosOrdersList  Size:%1 And FirstOne: %2 , m_simValidOrdersList  size:  %3  And FirstOne: %4 --->>>>>]")
                     .arg( m_storagePosOrdersList.size() ).arg( m_storagePosOrdersList.isEmpty()? " " : m_storagePosOrdersList.first() )
                     .arg( m_simValidOrdersList.size() ).arg( m_simValidOrdersList.empty()? " " : m_simValidOrdersList.first() );
    }

    if ( m_storagePosOrdersList.isEmpty() ) {
        m_storageOrderTimer->start(10*1000);
    } else {
        m_storageOrderTimer->start(3*1000);
        bool bRetStorageOrderMutex = false;
        QString orderId =  m_storagePosOrdersList.first();
        OrderObject* order_p = m_FmOrdersMap.value(orderId);

        if ( !order_p ) {
            QLOG_INFO() << QString("[<<<<---_StoragePosOrderData: orderId: %1 OrderObject* Is Null --->>>>]").arg(orderId);
            m_storagePosOrdersList.removeOne(orderId);   // 订单对象空指针,无需考虑加锁,直接移除此订单号;
            return;
        } else {

            // 减少订单出现多次检查与汇报OMS 订单落库状态, 提前筛选订单是否需要 检查落库情况, 提高效率;【 退货单已经提前筛查  _OrderAnalysis()  】
            bool retGetDbOrderAllFlag = SimProcOrderDB::getInstance().getDbOrderAllFlag(order_p->id,order_p->dataBaseIsOrderExistInt,order_p->dataBaseIsPushInt,
            order_p->dataBaseIsCancleInt,order_p->dataBaseIsORSPushInt,order_p->dataBaseIsORSCancleInt,order_p->dataBasePosOrderCheckNo);
            Q_UNUSED(retGetDbOrderAllFlag);

            if ( order_p->orderStatus != OrderObject::Refunded  && order_p->dataBaseIsPushInt) {
                QLOG_INFO() << QString("[<<<<---_StoragePosOrderData: orderId: %1  Had Save 4 Core Table DB And Set Sale Flag Is True  Successed --->>>>]").arg(orderId);
                m_storagePosOrdersList.removeOne(orderId);
                return;
            }

            // 自定义生产小票号规则: OMS订单号后5位 + 销售单:03; 退货单: 06;  【requestType:  6 标识退货单;  3 标识销售单】
            QString  posCheckNo = orderId.right(5) + (OrderObject::Refunded == order_p->orderStatus ? QString("06") : QString("03") );
            QString  requestType = order_p->orderStatus==6?QString("6"):QString("3");

            bRetStorageOrderMutex =m_storageOrderMutex.tryLock(VALUE_TRYLOCKMEMTIMEOUT);
            int syncDbSuccessNum = 0;
            QString errorStorageOrderMsg = QString("OrderId: %1 Storage Pos Local DB Success").arg(orderId);
            bool syncOrderProductTbRet = true;
            bool syncOrderPromotionTbRet = true;
            bool syncOrderSumBillTbRet = true;
            bool syncOrderPrtMsgTbRet = true;
            bool checkProductValidRet = true;

            if(!bRetStorageOrderMutex) {
                QLOG_INFO() << QString("[<<<<---_StoragePosOrderData: orderId: %1 m_storageOrderMutex.tryLock Failed --->>>>]").arg(order_p->id);
                return;
            }

            //保存订单的商品数据; 无论是否需要入机,商品数据都必须提前存储本地DB,如果需要入机,入机后更新真实的入机小票号;
            /***** 更新 POS本地数据库的商品数据是否成功；begin:*********/
            if ( PrintCupStickPosDB::getInstance().isOrderProductExist(order_p) ) {
                syncDbSuccessNum++;
                // 销售单/退货单: 商品表 需存储2份数据(退货金额需要存储为负数);
                QLOG_INFO() << QString("[<<<<---_StoragePosOrderData: orderId: %1 Product Data Had Exist --->>>>]").arg(order_p->id);
            } else {
                if ( PrintCupStickPosDB::getInstance().insertOrderProduct(order_p, posCheckNo, checkProductValidRet) ) {
                    syncDbSuccessNum++;
                    QLOG_INFO() << QString("[<<<<---_StoragePosOrderData: orderId: %1  Insert Product Data Success--->>>>]").arg(order_p->id);
                } else {
                    syncOrderProductTbRet = false;
                    QLOG_INFO() << QString("[<<<<---_StoragePosOrderData: orderId: %1  Insert Product Data Failed --->>>>]").arg(order_p->id);
                }
            }
            /***** 更新 POS本地数据库的商品数据是否成功；end:********/

            // 检查商品数据无效订单, 需要将 ①移除待存储队列 ②向OMS汇报订单入库情况并持久化(在检查方法中汇报) ③订单迁移到异常单Tab页;
            if ( !checkProductValidRet ) {
                QLOG_ERROR() << QString("[<<<<---_StoragePosOrderData: orderId: %1   checkProductValidRet Is False  --->>>>]").arg(order_p->id);
                // ①移除待存储队列
                m_storagePosOrdersList.removeOne(order_p->id);
                m_storageOrderMutex.unlock();
                // ② 存储订单商品入库异常, 同步更新 入机状态表数据, 便于退货单过来时 参考销售单入机情况;
                // ③订单迁移到 异常单 Tab 页
                int oldStatus = order_p->orderStatus;
                if(6 == order_p->orderStatus || OrderObject::SimExceptRefund == order_p->orderStatus){
                    order_p->orderStatus = OrderObject::SimExceptRefund;
                } else {
                    order_p->orderStatus = OrderObject::SimExceptSale;
                }

                QLOG_INFO() << QString("[<<<<---_StoragePosOrderData  Change orderId: %1 OldStatus: %2: curStatus: %3]--->>>>]").arg(order_p->id).arg(oldStatus).arg(order_p->orderStatus);
                if(oldStatus != order_p->orderStatus) {
                    emit changeOrderStatus(order_p, oldStatus);
                }

                return ;
            }

            //保存订单的优惠数据; 无论是否需要入机,优惠数据都必须提前存储本地DB,如果需要入机,入机后更新真实的入机小票号;
            /***** 更新 POS本地数据库的优惠数据 是否成功；begin:*********/
            if ( PrintOrderPromotionDB::getInstance().isOrderPromotionExist(order_p) ) {
                syncDbSuccessNum++;
                // 销售单/退货单: 促销优惠表 需存储2份数据(退货金额需要存储为负数);
                QLOG_INFO() << QString("[<<<<---_StoragePosOrderData: orderId: %1 Promotion Data Had Exist --->>>>]").arg(order_p->id);
            } else {
                if ( syncOrderProductTbRet ) {
                    if ( PrintOrderPromotionDB::getInstance().insertOrderPromotion(order_p, posCheckNo) ) {
                        syncDbSuccessNum++;
                        QLOG_INFO() << QString("[<<<<---_StoragePosOrderData: orderId: %1  Insert Promotion Data Success--->>>>]").arg(order_p->id);
                    } else {
                        syncOrderPromotionTbRet = false;
                        QLOG_INFO() << QString("[<<<<---_StoragePosOrderData: orderId: %1  Insert Promotion Data Failed --->>>>]").arg(order_p->id);
                    }
                } else {
                    syncOrderPromotionTbRet = false;
                    QLOG_INFO() << QString("[<<<<---_StoragePosOrderData: orderId: %1  Insert Product Failed, So No Need Insert Promotion --->>>>]").arg(order_p->id);
                }
            }
            /***** 更新 POS本地数据库的优惠数据 是否成功；end:********/


            /***** 更新 POS本地数据库的汇总单数据 是否成功；begin:*********/
            // 2.0解耦POS->不入机流程分支: 需要在此处排队时进行数据存储;
            if ( PrintSumBillPosDB::getInstance().isOrderSumBillExist(order_p) ) {
                syncDbSuccessNum++;
                QLOG_INFO() << QString("[<<<<---_StoragePosOrderData: orderId: %1 SumBill Data Had Exist --->>>>]").arg(order_p->id);
                // 销售单/退货单:  汇总表 需存储2份数据(退货记录中chk_num值 与 销售记录中chk_num值 不等);
                // 汇总表中数据需同步更新订单状态, 此操作在解析订单数据函数(  _OrderAnalysis )中已更新DB中订单的状态;
                // 预约单->提前到店类似的变更不会走入机/存储的排队模式,所以需要在 解析订单数据函数( _OrderAnalysis )中就要更新DB中订单状态;
                //【预约单取消: 需要打印预约取消提醒单, 必须更新订单状态】;
            } else {
                // 0:未入机提前插入数据时默认小票号为0; 开单时间默认为空:insertOrderSumBill 函数内会以当前时间存储;
                if ( PrintSumBillPosDB::getInstance().insertOrderSumBill(order_p, posCheckNo, "") ) {
                    syncDbSuccessNum++;
                    QLOG_INFO() << QString("[<<<<---_StoragePosOrderData: orderId: %1  Insert SumBill Data Success--->>>>]").arg(order_p->id);
                } else {
                    syncOrderSumBillTbRet = false;
                    QLOG_INFO() << QString("[<<<<---_StoragePosOrderData: orderId: %1  Insert SumBill Data Failed --->>>>]").arg(order_p->id);
                }
            }
            /***** 更新 POS本地数据库的汇总单数据 是否成功；end:********/


            /***** 更新 POS本地数据库的打印消息数据 是否成功；begin:*********/
            // 需要保证前面三张表订单数据都成功插入成功后，才可以考虑插入打印数据 否则 对于打印小票会出现数据欠缺异常;
            if ( 3 == syncDbSuccessNum ) {
                if ( PrintMsgQueueDB::getInstance().isOrderPrtMsgExist(order_p) ) {
                    syncDbSuccessNum++;
                    // 销售单/退货单: 打印表需存储2份数据(退货记录中chk_num值 与 销售记录中chk_num值 不等);
                    //【订单接单后立即被取消, 也无法取消销售单的打印了】;
                    QLOG_INFO() << QString("[<<<<---_StoragePosOrderData: orderId: %1 PrintMsgQueue Data Had Exist --->>>>]").arg(order_p->id);
                } else {
                    if ( order_p->skipPrint ) {  // 补单场景: 跳过打印;
                        syncDbSuccessNum++;
                        QLOG_INFO() << QString("[<<<<---_StoragePosOrderData: orderId: %1 No Need Insert PrintMsgQueue Data, Order SkipPrint: %2--->>>>]").arg(order_p->id).arg(order_p->skipPrint ?1:0);
                    } else { // 非补单场景, 需要提前存储订单记录到打印队列表中;
                        // 0:未入机提前插入数据时默认小票号为0;
                        if ( PrintMsgQueueDB::getInstance().insertOrderPrtMsg(order_p, posCheckNo) ) {
                            syncDbSuccessNum++;
                            QLOG_INFO() << QString("[<<<<---_StoragePosOrderData: orderId: %1  Insert PrintMsgQueue Data Success--->>>>]").arg(order_p->id);
                        } else {
                            syncOrderPrtMsgTbRet = false;
                            QLOG_INFO() << QString("[<<<<---_StoragePosOrderData: orderId: %1  Insert PrintMsgQueue Data Failed --->>>>]").arg(order_p->id);
                        }
                    }

                }
            } else {
                syncOrderPrtMsgTbRet = false;
                QLOG_INFO() << QString("[<<<<---_StoragePosOrderData: orderId: %1  Insert Local Table Count < 3, So No Need Insert PrintMsgQueue Data --->>>>]").arg(order_p->id);
            }
            /***** 更新 POS本地数据库的打印消息数据 是否成功；end:********/

            // 订单落库成功后: 需要在此处进行数据校验 是否都存储成功 / 并汇报存储情况; ①汇报OMS落库成功;
            if ( 4 == syncDbSuccessNum ) {
                QLOG_INFO() << QString("[<<<<---_StoragePosOrderData: orderId: %1  Insert 4 Tables Data Success, Prepare Report Oms--->>>>]").arg(order_p->id);
                errorStorageOrderMsg = QString("Decouple Pos: OrderId: %1 Storage Pos Local DB Success").arg(orderId);

                _AddInputPosSuccessPresistList(order_p->id, order_p->channel, requestType, "3", posCheckNo, errorStorageOrderMsg, QString("") );
                // 落库成功, 准备将订单数据落库成功的报文消息汇报给 OMS:
                // 销售单/退货单: 会根据订单状态 是否 = 6 进行转换后进行汇报;  进入此队列 m_storagePosOrdersList 的次数决定汇报的次数;
                _AddOrUpdateReportOmsList(order_p->id,  order_p->channel, requestType, "3", posCheckNo, errorStorageOrderMsg, QString("") );

                // 订单:销售+退货 数据存储成功后，需要更新 订单表 销售 退货的成功标识, 减少添加到 存储队列中的频次;
                if ( OrderObject::Refunded == order_p->orderStatus ) {
                    SimProcOrderDB::getInstance().updateRefundOrderStatusAndChkNum(orderId, 1, posCheckNo);
                } else {
                    SimProcOrderDB::getInstance().updatePushOrderStatusAndChkNum(orderId, 1, posCheckNo);
                }
                // 解耦不入机订单, 落库成功后更新显示 详情界面上的虚拟小票号;
                order_p->dataBasePosOrderCheckNo = posCheckNo;

            } else {
                QLOG_ERROR() << QString("[<<<<---_StoragePosOrderData: orderId: %1  Insert 4 Tables Data Failed, Prepare Report Oms--->>>>]").arg(order_p->id);
                // 解耦POS标识作为最后标识尺度; 避免后期 解耦和 先打印后存储模式的 同时存在;
                // 由于在落库前就会进行 订单商品有效性进行检查: 落库失败:准备将订单数据落库失败的报文消息汇报给 OMS;
                // <1>检查商品有效: 则是表字段过长导致插入失败,必须向OMS汇报存储情况;
                errorStorageOrderMsg = QString("Decouple Pos: OrderId: %1 Storage Pos Local DB Error : %2  %3  %4  %5 ").arg(orderId)
                        .arg( syncOrderProductTbRet?"":"OrderProductTb ").arg( syncOrderPromotionTbRet?"":"OrderPromotionTb ")
                        .arg( syncOrderSumBillTbRet?"":"OrderSumBillTb ").arg( syncOrderPrtMsgTbRet?"":"OrderPrtMsgTb ");

                _AddOrUpdateReportOmsList(order_p->id,  order_p->channel, requestType, "4", posCheckNo, errorStorageOrderMsg, QString("1009") );
            }

            m_storagePosOrdersList.removeOne(order_p->id);
            m_storageOrderMutex.unlock();

            // 检查商品数据无效订单, 已经在插库前进行审核筛查;
            // 检查订单 4 Core 数据是否正常插入成功; 插入失败需要界面 显示到 异常单 Tab 页;
            if ( syncDbSuccessNum < 4 ) {
                int oldStatus = order_p->orderStatus;
                if(6 == order_p->orderStatus || OrderObject::SimExceptRefund == order_p->orderStatus){
                    order_p->orderStatus = OrderObject::SimExceptRefund;
                } else {
                    order_p->orderStatus = OrderObject::SimExceptSale;
                }
                QLOG_INFO() << QString("[<<<<---_StoragePosOrderData  Change orderId: %1 OldStatus: %2: curStatus: %3]--->>>>]").arg(order_p->id).arg(oldStatus).arg(order_p->orderStatus);
                if(oldStatus != order_p->orderStatus) {
                    emit changeOrderStatus(order_p, oldStatus);
                }
            }
            // End Refresh Ui
        }

    }
}


void  FlowControl::_ReprintOrderTickets(OrderObject* order_p) {

    if ( order_p == NULL) {
        QLOG_ERROR()<<QString("[<<<<---FlowControl::_ReprintOrderTickets  orderObjectPoint Is NULL --->>>>>]");
    } else {
        QLOG_INFO()<<QString("[<<<<---FlowControl::_ReprintOrderTickets  orderId= %1--->>>>>]").arg( order_p->id );
        QString orderId = order_p->id;
        // 自定义生产小票号规则: OMS订单号后5位 + 销售单:03; 退货单: 06;  【requestType:  6 标识退货单;  3 标识销售单】
        QString  posCheckNo = orderId.right(5) + (OrderObject::Refunded == order_p->orderStatus ? QString("06") : QString("03") );
        QString  requestType = order_p->orderStatus==6?QString("6"):QString("3");

        int syncDbSuccessNum = 0;
        QString errorStorageOrderMsg = QString("Reprint OrderId: %1 Update Pos Local DB Success").arg(orderId);
        bool syncOrderProductTbRet = true;
        bool syncOrderPromotionTbRet = true;
        bool syncOrderSumBillTbRet = true;
        bool syncOrderPrtMsgTbRet = true;
        bool checkProductValidRet = true;

        /***** 更新 POS本地数据库的商品数据是否成功；begin:*********/
        if ( PrintCupStickPosDB::getInstance().isOrderProductExist(order_p) ) {
            syncDbSuccessNum++;
            // 销售单/退货单: 商品表 需存储2份数据(退货金额需要存储为负数);
        } else {
            if ( PrintCupStickPosDB::getInstance().insertOrderProduct(order_p, posCheckNo, checkProductValidRet) ) {
                syncDbSuccessNum++;
                QLOG_INFO() << QString("[<<<<---_ReprintOrderTickets: orderId: %1  Insert Product Data Success--->>>>]").arg(order_p->id);
            } else {
                syncOrderProductTbRet = false;
                QLOG_INFO() << QString("[<<<<---_ReprintOrderTickets: orderId: %1  Insert Product Data Failed --->>>>]").arg(order_p->id);
            }
        }
        /***** 更新 POS本地数据库的商品数据是否成功；end:********/

        // 检查商品数据无效订单, 需要将 ①向OMS汇报订单入库情况(在检查类中汇报) ② 订单迁移到 异常单 Tab 页;
        if ( !checkProductValidRet ) {
            QLOG_ERROR() << QString("[<<<<---_ReprintOrderTickets: orderId: %1   checkProductValidRet Is False  --->>>>]").arg(order_p->id);
            // ①存储订单商品入库异常, 同步更新 入机状态表数据, 便于退货单过来时 参考销售单入机情况;
            errorStorageOrderMsg = QString("_ReprintOrderTickets: Decouple Pos OrderId: %1 Storage Product  Input Pos DB Failed").arg(orderId);
            // 解耦2.0订单 落库成功后也需要持久化;
            _AddInputPosSuccessPresistList(order_p->id, order_p->channel, requestType, "4", posCheckNo, errorStorageOrderMsg, "1005");
            // ②订单迁移到 异常单 Tab 页
            int oldStatus = order_p->orderStatus;
            if(6 == order_p->orderStatus || OrderObject::SimExceptRefund == order_p->orderStatus){
                order_p->orderStatus = OrderObject::SimExceptRefund;
            } else {
                order_p->orderStatus = OrderObject::SimExceptSale;
            }

            if(oldStatus != order_p->orderStatus) {
                emit changeOrderStatus(order_p, oldStatus);
            }
            return ;
        }

        // 保存订单的优惠数据; 无论是否需要入机,优惠数据都必须提前存储本地DB;
        /***** 更新 POS本地数据库的优惠数据是否成功；begin:*********/
        if ( PrintOrderPromotionDB::getInstance().isOrderPromotionExist(order_p) ) {
            syncDbSuccessNum++;
            // 销售单/退货单: 促销优惠表 需存储2份数据(退货金额需要存储为负数);
        } else {
            if ( syncOrderProductTbRet ) {
                if ( PrintOrderPromotionDB::getInstance().insertOrderPromotion(order_p, posCheckNo) ) {
                    syncDbSuccessNum++;
                    QLOG_INFO() << QString("[<<<<---_ReprintOrderTickets: orderId: %1 Insert Promotion Data Success--->>>>]").arg(order_p->id);
                } else {
                    syncOrderPromotionTbRet = false;
                    QLOG_INFO() << QString("[<<<<---_ReprintOrderTickets: orderId: %1 Insert Promotion Data Failed --->>>>]").arg(order_p->id);
                }
            } else {
                syncOrderPromotionTbRet = false;
                QLOG_INFO() << QString("[<<<<---_ReprintOrderTickets: orderId: %1  Insert Product Failed, So No Need Insert Promotion --->>>>]").arg(order_p->id);
            }
        }
        /***** 更新 POS本地数据库的优惠数据 是否成功；end:********/


        /***** 更新 POS本地数据库的汇总单数据 是否成功；begin:*********/
        if ( PrintSumBillPosDB::getInstance().isOrderSumBillExist(order_p) ) {
            syncDbSuccessNum++;
            // 销售单/退货单:  汇总表 需存储2份数据(退货记录中chk_num值 与 销售记录中chk_num值 不等);
            // 汇总表中数据需同步更新订单状态, 此操作在解析订单数据函数(  _OrderAnalysis )中已更新DB中订单的状态;
            // 预约单->提前到店类似的变更不会走入机/存储的排队模式,所以需要在 解析订单数据函数( _OrderAnalysis )中就要更新DB中订单状态;
            //【预约单取消: 需要打印预约取消提醒单, 必须更新订单状态】;
        } else {
            // 开单时间默认为空:insertOrderSumBill 函数内会以当前时间存储;
            if ( PrintSumBillPosDB::getInstance().insertOrderSumBill(order_p, posCheckNo, "") ) {
                syncDbSuccessNum++;
                QLOG_INFO() << QString("[<<<<---_ReprintOrderTickets: orderId: %1 Insert SumBill Data Success--->>>>]").arg(order_p->id);
            } else {
                syncOrderSumBillTbRet = false;
                QLOG_INFO() << QString("[<<<<---_ReprintOrderTickets: orderId: %1 Insert SumBill Data Failed --->>>>]").arg(order_p->id);
            }
        }
        /***** 更新 POS本地数据库的汇总单数据 是否成功；end:********/

        /***** 更新 POS本地数据库的打印消息数据 是否成功；begin:*********/
        // 需要保证前面三张表订单数据都成功插入成功后，才可以考虑插入打印数据 否则 对于打印小票会出现数据欠缺异常;
        if ( 3 == syncDbSuccessNum ) {
            if ( PrintMsgQueueDB::getInstance().isOrderPrtMsgExist(order_p) ) {
                // 针对补打场景: 如果订单打印记录存在则需重置订单各种打印小票的 打印状态;
                bool retReprint = PrintMsgQueueDB::getInstance().resetPrintMsgStatus(order_p, order_p->printOpt );
                if ( retReprint ) {
                    syncDbSuccessNum++;
                }
                // 销售单/退货单: 打印表需存储2份数据(退货记录中chk_num值 与 销售记录中chk_num值 不等);
            } else {
                if ( order_p->skipPrint ) {  // 补单场景: 跳过打印;
                    syncDbSuccessNum++;
                    QLOG_INFO() << QString("[<<<<---_ReprintOrderTickets: orderId: %1 No Need Insert PrintMsgQueue Data, Order SkipPrint: %2--->>>>]").arg(order_p->id).arg(order_p->skipPrint ?1:0);
                } else { // 非补单场景, 需要提前存储订单记录到打印队列表中;
                    if ( PrintMsgQueueDB::getInstance().insertOrderPrtMsg(order_p, posCheckNo) ) {
                        syncDbSuccessNum++;
                        QLOG_INFO() << QString("[<<<<---_ReprintOrderTickets: orderId: %1 Insert PrintMsgQueue Data Success--->>>>]").arg(order_p->id);
                    } else {
                        syncOrderPrtMsgTbRet = false;
                        QLOG_INFO() << QString("[<<<<---_ReprintOrderTickets: orderId: %1 Insert PrintMsgQueue Data Failed --->>>>]").arg(order_p->id);
                    }
                }
            }
        } else {
            syncOrderPrtMsgTbRet = false;
            QLOG_INFO() << QString("[<<<<---_ReprintOrderTickets: orderId: %1  Insert Local Table Count < 3, So No Need Insert PrintMsgQueue Data --->>>>]").arg(order_p->id);
        }

        order_p->pluginOptions = QJsonObject();
        order_p->printOpt = QJsonObject(); // 补打无论是否成功,必须清空补打选项设置; 否则订单状态后续变化将会出现重复打印;
        /***** 更新 POS本地数据库的打印消息数据是否成功；end:********/

        // 订单落库成功后: 需要在此处进行数据校验 是否都存储成功 / 并汇报存储情况; ①汇报OMS落库成功;
        if ( 4 == syncDbSuccessNum ) {
            QLOG_INFO() << QString("[<<<<---_ReprintOrderTickets: orderId: %1 Insert 4 Tables Data Success, Prepare Report Oms--->>>>]").arg(order_p->id);
            errorStorageOrderMsg = QString(" Reprint Order Tickets Success, OrderId: %1").arg(orderId);
            _AddInputPosSuccessPresistList(order_p->id, order_p->channel, requestType, "3", posCheckNo, errorStorageOrderMsg, QString("") );
            // 落库成功, 准备将订单数据落库成功的报文消息汇报给 OMS:
            // 销售单/退货单: 会根据订单状态 是否 = 6 进行转换后进行汇报;  进入此队列 m_storagePosOrdersList 的次数决定汇报的次数;
            _AddOrUpdateReportOmsList(order_p->id,  order_p->channel, requestType, "3", posCheckNo, errorStorageOrderMsg, QString("") );
            // 订单:销售+退货 数据存储成功后，需要更新 订单表 销售 退货的成功标识, 减少添加到 存储队列中的频次;
            if ( OrderObject::Refunded == order_p->orderStatus ) {
                SimProcOrderDB::getInstance().updateRefundOrderStatusAndChkNum(orderId, 1, posCheckNo);
            } else {
                SimProcOrderDB::getInstance().updatePushOrderStatusAndChkNum(orderId, 1, posCheckNo);
            }
            // 解耦不入机订单, 落库成功后更新显示 详情界面上的虚拟小票号;
            order_p->dataBasePosOrderCheckNo = posCheckNo;

        } else {
            QLOG_ERROR() << QString("[<<<<---_ReprintOrderTickets: orderId: %1  Insert 4 Tables Data Failed, Prepare Report Oms--->>>>]").arg(order_p->id);
            // 由于在落库前就会进行 订单商品有效性进行检查: 落库失败:准备将订单数据落库失败的报文消息汇报给 OMS;
            // <1>检查商品有效: 则是表字段过长导致插入失败,必须向OMS汇报存储情况;
            errorStorageOrderMsg = QString("Reprint Order Tickets Failed, OrderId: %1 Storage/Reset DB Error:%2,%3,%4,%5").arg(orderId)
                    .arg( syncOrderProductTbRet?"":"OrderProductTb ").arg( syncOrderPromotionTbRet?"":"OrderPromotionTb ")
                    .arg( syncOrderSumBillTbRet?"":"OrderSumBillTb ").arg( syncOrderPrtMsgTbRet?"":"OrderPrtMsgTb ");

            _AddOrUpdateReportOmsList(order_p->id,  order_p->channel, requestType, "4", posCheckNo, errorStorageOrderMsg, QString("1009") );
        }

    }
}


void FlowControl::_ScanDelayGetRefundDetailList() {

    if ( m_delayGetRefundDetailList.isEmpty() ) {
        m_delayGetRefundDetailTimer->start(25*1000);
    } else {
        QLOG_INFO()<< QString("[<<<<---_ScanDelayGetRefundDetailList:  m_delayGetRefundDetailList  size:  %1 And FirstOne: %2 --->>>>>]")
                     .arg( m_delayGetRefundDetailList.size() ).arg( m_delayGetRefundDetailList.isEmpty()? " " : m_delayGetRefundDetailList.first()->orderId );
        QLOG_INFO()<< QString("[<<<<---_ScanDelayGetRefundDetailList:  m_storagePosOrdersList  size:  %1 And FirstOne: %2 --->>>>>]")
                     .arg( m_storagePosOrdersList.size() ).arg( m_storagePosOrdersList.isEmpty()? " " : m_storagePosOrdersList.first() );
        QLOG_INFO()<< QString("[<<<<---_ScanDelayGetRefundDetailList:  m_simValidOrdersList  size:  %1  And FirstOne: %2 --->>>>>]")
                     .arg( m_simValidOrdersList.size() ).arg( m_simValidOrdersList.empty()? " " : m_simValidOrdersList.first() );

        m_delayGetRefundDetailTimer->start(15*1000);

        DelayPullOrderInfo*  delayPullOrder_p= nullptr;
        QList<DelayPullOrderInfo*> tmpDelayRefundList;
        QString tmpSimValidListFirstOrderId =  m_simValidOrdersList.isEmpty() ? "" : m_simValidOrdersList.first();
        QString tmpStorageListFirstOrderId =  m_storagePosOrdersList.isEmpty() ? "" : m_storagePosOrdersList.first();

        // 为了节约时间, 提高效率: 减少加锁/解锁频率, 优先快速判断筛选条件: SimValidList & StorageList & m_orderPullList 都是空;则无需加锁筛选;
        if ( !tmpSimValidListFirstOrderId.length()  && !tmpStorageListFirstOrderId.length() && m_orderPullList.empty() ) {

            while( !m_delayGetRefundDetailList.empty() ) {
                delayPullOrder_p = m_delayGetRefundDetailList.takeFirst();
                if ( !delayPullOrder_p ) {
                    QLOG_ERROR()<< QString("[<<<<---_ScanDelayGetRefundDetailList: m_delayGetRefundDetailList's Fisrt Item delayPullOrder_p Is empty(3 list All Empty)--->>>>>]");
                    continue;
                }
                if ( _TryAddOrderPull( delayPullOrder_p->orderId, delayPullOrder_p->channel, delayPullOrder_p->callBackUrl, delayPullOrder_p->skipPrint, delayPullOrder_p->pushOptions ) ) {
                    delete delayPullOrder_p;
                    delayPullOrder_p = nullptr;
                } else {
                    QLOG_ERROR()<< QString("[<<<<---_ScanDelayGetRefundDetailList: _TryAddOrderPull Return Failed(3 list All Empty), orderId:%1, Continue Append Delay List--->>>>>]").arg(delayPullOrder_p->orderId);
                    tmpDelayRefundList.append(delayPullOrder_p);
                }
            }
            // 将临时延迟队列重新添加到 正式延迟队列中;
            m_delayGetRefundDetailList = tmpDelayRefundList;
            QLOG_INFO()<< QString("[<<<<---_ScanDelayGetRefundDetailList: m_delayGetRefundDetailList Scan End (3 list All Empty), Size:%1 , FirstOrderId:%2--->>>>>]")
                          .arg( m_delayGetRefundDetailList.size() ).arg( m_delayGetRefundDetailList.empty() ? "" : m_delayGetRefundDetailList.first()->orderId );

            return;
        }

        // 复杂情况遍历;
        bool tryLock  = m_delayGetRefundDetailMutex.tryLock(VALUE_TRYLOCKMEMTIMEOUT);
        if ( !tryLock ) {
            QLOG_ERROR()<< QString("[<<<<---_ScanDelayGetRefundDetailList: m_delayGetRefundDetailMutex Try Lock Failed --->>>>>]");
        } else {

            while( !m_delayGetRefundDetailList.empty() ) {

                delayPullOrder_p = m_delayGetRefundDetailList.takeFirst();

                if ( !delayPullOrder_p ) {
                    QLOG_ERROR()<< QString("[<<<<---_ScanDelayGetRefundDetailList: m_delayGetRefundDetailList's item  delayPullOrder_p Is empty--->>>>>]");
                    continue;
                }

                // Case1: 筛选处理  m_simValidOrdersList 中第一个订单，如果匹配到，则将其添加到临时延迟退单队列中;
                if ( tmpSimValidListFirstOrderId.length() && delayPullOrder_p->orderId == tmpSimValidListFirstOrderId) {
                    tmpDelayRefundList.append(delayPullOrder_p);
                    QLOG_INFO()<< QString("[<<<<---_ScanDelayGetRefundDetailList:m_simValidOrdersList  FirstOrderId:%1, RefundOrderId:%2 Append Delay Get Detail List--->>>>>]")
                                  .arg( tmpSimValidListFirstOrderId ).arg( delayPullOrder_p->orderId );
                    continue;
                }

                // Case2: 筛选处理  m_storagePosOrdersList 中第一个订单，如果匹配到，则将其添加到临时延迟退单队列中;
                if ( tmpStorageListFirstOrderId.length() && delayPullOrder_p->orderId == tmpStorageListFirstOrderId) {
                    tmpDelayRefundList.append(delayPullOrder_p);
                    QLOG_INFO()<< QString("[<<<<---_ScanDelayGetRefundDetailList:m_storagePosOrdersList  FirstOrderId:%1, RefundOrderId:%2 Append Delay Get Detail List--->>>>>]")
                                  .arg( tmpStorageListFirstOrderId ).arg( delayPullOrder_p->orderId );
                    continue;
                }

                // Case3: 筛选处理 遍历待获取订单详情列表, 如果匹配到待获取订单号一致，则;
                if ( !m_orderPullList.empty() ) {
                    // 待拉取列表不空时，仅判断 待拉取列表中的第一个订单是否和 延迟退单队列 中匹配，若果匹配到 则继续保留在延迟队列中;
                    PullOrderInfo* tmpOrderPull = m_orderPullList.first();
                    if ( !tmpOrderPull ) {
                        QLOG_ERROR()<< QString("[<<<<---_ScanDelayGetRefundDetailList:m_orderPullList First Item Is Null, Remove It From m_orderPullList--->>>>>]");
                        tmpDelayRefundList.append(delayPullOrder_p);
                        m_orderPullList.removeFirst();
                        continue;
                    }

                    if (tmpOrderPull->orderId == delayPullOrder_p->orderId) {
                        // 已经有正在获取订单详情数据的请求还未执行完成, 则需要添加到延迟队列中: 避免在 m_orderPullList 中第一个订单状态是销售单，将可能出现 Bug;
                        tmpDelayRefundList.append(delayPullOrder_p);
                        QLOG_INFO()<< QString("[<<<<---_ScanDelayGetRefundDetailList: m_orderPullList.size()=%d  , m_orderPullList.first()== RefundOrderId:%1  Append Delay Get Detail List--->>>>>]")
                                      .arg( m_orderPullList.size() ).arg( delayPullOrder_p->orderId );
                        continue;
                    }
                }

                // Case4: 筛选出来 无需延迟获取退单详情的订单 需要添加到 正常的获取订单详情的队列中;
                if ( _TryAddOrderPull( delayPullOrder_p->orderId, delayPullOrder_p->channel, delayPullOrder_p->callBackUrl, delayPullOrder_p->skipPrint, delayPullOrder_p->pushOptions ) ) {
                    delete delayPullOrder_p;
                    delayPullOrder_p = nullptr;
                } else {
                    QLOG_ERROR()<< QString("[<<<<---_ScanDelayGetRefundDetailList: _TryAddOrderPull Return Failed, orderId:%1, Continue Append Delay List--->>>>>]").arg(delayPullOrder_p->orderId);
                    tmpDelayRefundList.append(delayPullOrder_p);
                }

            }

            // 将延迟队列从新添加到 延迟队列中;
            m_delayGetRefundDetailList = tmpDelayRefundList;
            QLOG_INFO()<< QString("[<<<<---_ScanDelayGetRefundDetailList: m_delayGetRefundDetailList Scan End, Size:%1 , FirstOrderId:%2--->>>>>]")
                          .arg( m_delayGetRefundDetailList.size() ).arg( m_delayGetRefundDetailList.empty() ? "" : m_delayGetRefundDetailList.first()->orderId );
            m_delayGetRefundDetailMutex.unlock();
        }

    }

}

void FlowControl::_RemindCasherBlinkFloatForm()
{
    if(!m_simValidOrdersList.isEmpty())
    {
        m_remindCasherBlinkFloatTimer->start(1000*8);
        emit startRemind(REMIND_SIM_ORDERLIST_NOEMPTY);
        QLOG_INFO()<<QString::fromLocal8Bit("[<<<<---_RemindCasherBlinkFloatForm: m_simValidOrdersList.size()==%1--->>>>>]").arg( m_simValidOrdersList.size() );
    } else {
        m_remindCasherBlinkFloatTimer->start(1000*20);
    }
}



void FlowControl::_OrderAnalysis(const QJsonObject& jsonObject)
{
    OrderObject *orderObject = NULL;
    bool  bRetStorageOrderMutex = false;
    orderObject = m_FmOrdersMap.value(jsonObject[JSON_ID].toString());
    /***<1>:FM插件维护的有效订单容器中不存在此订单：整合数据并插入到此订单容器中 ***/
    if(orderObject == NULL)
    {
        orderObject = new OrderObject(this);
        //初始化数据;
        orderObject->orderIndex = 0;
        orderObject->disPlateformFee = 0;
        orderObject->orderDiscount = 0;
        orderObject->appointmentDayFlag = 0;
        orderObject->isPackage =0;
        orderObject->packageFee = 0;
        orderObject->packDiscount = 0;
        orderObject->deliveryPrice = 0;
        orderObject->deliveryDiscount = 0;
        orderObject->tenderDeliveryDiscountB = 0;
        orderObject->forwardPosStatus =0;
        orderObject->negativePosStatus =0;
        orderObject->businessType = "0";
        orderObject->inAdvanceTakemeal = 0;
        orderObject->globalServiceType = 0;
        orderObject->globalOrderType = 0;
        orderObject->storeType = 0;
        orderObject->decouplePosVersion = 0;
        orderObject->deliveryAtProd = false;
        orderObject->packageFeeAtProduct = false;
        orderObject->extendType = 0;
        orderObject->deliveryProvider = 0;
        orderObject->deliveryType = 0;
        orderObject->isGiftitForward = 0 ;
        orderObject->callBackUrl = "";
        orderObject->skipPrint = false;
        orderObject->privacyPhone = "";
        orderObject->backupPosFlag = m_backupPosFlag;
        orderObject->totalPriceForPos = 0;

        orderObject->FromJson(jsonObject);

        // 更新订单详情数据 赋值到 OrderObject 对象中;
        orderObject->pushOrderType=0;
        orderObject->orsPushOrderType = 0;
        orderObject->isPush = false;
        orderObject->isCancle = false;
        orderObject->isORSPush = false;
        orderObject->isORSCancle = false;
        orderObject->orderSaleRefundStatus = 0;
        //初始化订单在数据库中标志性数据:用于一次性读出；减少对数据库的加锁访问+数据库连接数;防止压测插件奔溃;
        orderObject->dataBaseIsOrderExistInt = 0;
        orderObject->dataBaseIsPushInt = 0;
        orderObject->dataBaseIsCancleInt = 0;
        orderObject->dataBaseIsORSPushInt = 0;
        orderObject->dataBaseIsORSCancleInt = 0;
        orderObject->dataBasePosOrderCheckNo = "";

        // 89 == orderType 标识订单是 ELE-权益卡单,需存储(为了给OMS上游提供入机回调) 但是无需打印 且 需要界面展示;
        if ( 89 == orderObject->orderType ) {
            QLOG_INFO() << QString::fromLocal8Bit("[<<<<---FmTakeout _OrderAnalysis: orderObject->id:%1  orderType==89 权益卡单, 需跳过打印 OrderDesc: %2   OrderStatus: %3 "
                                   " MakeStatus: %4 ]--->>>>]").arg(orderObject->id).arg( orderObject->getOrderStatusDec() ).arg(orderObject->orderStatus) .arg(orderObject->makeStatus);
            orderObject->skipPrint = true;
        }

        //插件程序内存中没有此订单时需要从数据库中获取该订单标志数据;同时在接受到退单情况时，也需要从数据库中重新获取(防止内存中标志数据未更新[入机后未更新]);
        bool retGetDbOrderAllFlag = SimProcOrderDB::getInstance().getDbOrderAllFlag(orderObject->id,orderObject->dataBaseIsOrderExistInt,orderObject->dataBaseIsPushInt,
        orderObject->dataBaseIsCancleInt,orderObject->dataBaseIsORSPushInt,orderObject->dataBaseIsORSCancleInt,orderObject->dataBasePosOrderCheckNo);
        if(!retGetDbOrderAllFlag ){
            QLOG_ERROR() << QString("[<<<<---FmTakeout _OrderAnalysis:First Update orderObject->id:%1 SimProcOrderDB::getInstance().getDbOrderAllFlag Failed--->>>>]").arg(orderObject->id);
            return;
        }
        QLOG_INFO() << QString("[<<<<---FmTakeout _OrderAnalysis: First Update orderObject->id:%1 ,dataBaseIsOrderExistInt:%2 ,dataBaseIsPushInt:%3 ,dataBaseIsCancleInt:%4 ,"
                               "dataBaseIsORSPushInt:%5 ,dataBaseIsORSCancleInt:%6 ,dataBasePosOrderCheckNo:%7--->>>>]")
                       .arg(orderObject->id).arg(orderObject->dataBaseIsOrderExistInt).arg(orderObject->dataBaseIsPushInt).arg(orderObject->dataBaseIsCancleInt)
                       .arg(orderObject->dataBaseIsORSPushInt).arg(orderObject->dataBaseIsORSCancleInt).arg(orderObject->dataBasePosOrderCheckNo);

        m_FmOrdersMap.insert(orderObject->id, orderObject);

        QLOG_INFO() << QString("[<<<<---FmTakeout Valid Orders Map:Insert New Order[ OrderId: %1   OrderDesc: %2   OrderStatus: %3 "
                               " MakeStatus: %4  oldArriverAhead: %5 NewArriverAhead: %6 expectDate: %7 reserveMakeTime: %8 remindTicketTime: %9 "
                               " privacyPhone: %10  blockPrintCupTicketTask: %11   blockPrintRemindTicketTask: %12 ]--->>>>]")
                       .arg(orderObject->id).arg( orderObject->getOrderStatusDec() ).arg(orderObject->orderStatus)
                       .arg(orderObject->makeStatus).arg(0).arg(orderObject->inAdvanceTakemeal)
                       .arg(orderObject->expectDate).arg(orderObject->reserveMakeTime).arg(orderObject->remindTicketTime)
                       .arg(orderObject->privacyPhone).arg(orderObject->blockPrintCupTicketTask).arg(orderObject->blockPrintRemindTicketTask);

        if(!orderObject->dataBaseIsOrderExistInt)
        {
            QDateTime qdaTi = QDateTime::currentDateTimeUtc();
            QString createTime  =  qdaTi.addSecs(60*60*8).toString("yyyy-MM-dd hh:mm:ss");
            bool tempBResult = SimProcOrderDB::getInstance().insertSimProcOrder(orderObject->id,createTime);
            //判断插入数据库是否出现失败;
            if(!tempBResult) {
                //新增业务逻辑,针对汇报异常的订单需要;添加到 向OMS汇报入机情况的队列中;
                QString requestType = (6 == orderObject->orderStatus)?QString("6"):QString("3");
                QString msgDesc  = QString("POS Local DataBase Connect Error Or Table No Exist Error,Please Check DataBase Setting In Time");
                QString errorCode = "1009";
                if (orderObject->decouplePosVersion < 20 ) {
                    _AddOrUpdateReportOmsList(orderObject->id,  orderObject->channel, requestType, QString("2"), QString("0000"), msgDesc, QString("") );
                } else {
                    _AddOrUpdateReportOmsList(orderObject->id,  orderObject->channel, requestType, QString("4"), QString("0000"), msgDesc, errorCode );
                }
                //修改订单状态，避免后面对数据库出现不稳定的POS机仍然进行录单操作;
                if(6 == orderObject->orderStatus || OrderObject::SimExceptRefund == orderObject->orderStatus){
                    orderObject->orderStatus = OrderObject::SimExceptRefund;
                } else {
                    orderObject->orderStatus = OrderObject::SimExceptSale;
                }
            }

            if ( ( OrderObject::NewOrder == orderObject->orderStatus || OrderObject::Confirmed == orderObject->orderStatus ) ) {
                emit startRemind(REMIND_CONFIRMED_ORDER);
            }

        // 订单在数据库中已经存在, 则需要同步更新 汇总单表中数据;
        } else {
            int syncOrderRet = PrintSumBillPosDB::getInstance().syncOrderDataToDB(orderObject);
            QLOG_INFO() << QString("[<<<<---PrintSumBillPosDB.getInstance().syncOrderDataToDB orderId:%1 syncOrderRet:%2--->>>>]").arg(orderObject->id).arg(syncOrderRet);
        }

        emit changeOrderStatus(orderObject);
    }
    /***<2>:FM插件维护的有效订单容器中存在此订单:更新订单容器中此订单的订单状态***/
    else {
        int oldStatus = orderObject->orderStatus;
        int oldArriveAhead = orderObject->inAdvanceTakemeal;
        orderObject->FromJson(jsonObject);
        QLOG_INFO() << QString("[<<<<---FmTakeout Valid Order Map:Update  orderId: %1  OldStatus: %2: curStatus: %3]--->>>>]").arg(orderObject->id).arg(oldStatus).arg(orderObject->orderStatus);
        if(oldStatus != orderObject->orderStatus) {
            emit changeOrderStatus(orderObject, oldStatus);
        }

        // 89 == orderType 标识订单是 ELE-权益卡单,需存储(为了给OMS上游提供入机回调) 但是无需打印 且 需要界面展示;
        if ( 89 == orderObject->orderType ) {
            QLOG_INFO() << QString::fromLocal8Bit("[<<<<---FmTakeout _OrderAnalysis: orderObject->id:%1  orderType==89 权益卡单, 需跳过打印--->>>>]").arg(orderObject->id);
            orderObject->skipPrint = true;
        }

        // 3: 刷新订单 预约时间 & 制作时间 & 街送小票时间;
        if ( 3 == orderObject->inAdvanceTakemeal || oldArriveAhead != orderObject->inAdvanceTakemeal ) {
            int updateOrderRet = PrintSumBillPosDB::getInstance().updateOrderDataToDB(orderObject, QString("UpdateTimeAction"));
            QLOG_INFO() << QString("[<<<<---PrintSumBillPosDB.getInstance().updateOrderDataToDB orderId:%1 updateOrderRet:%2--->>>>]").arg(orderObject->id).arg(updateOrderRet);
        }

        // updateOrderDataToDB -> updateOrderTimeInfo()-> trigger show alert; [已经触发提示了;故此处注释此处代码]
        // 4: 特殊字段值存在则刷新(此类订单量小);
        // 4.1: 更新手机隐私号 或 更新Curbside业务渠道 Blcok打印 街送小票 和 杯贴 的标识;
        if ( orderObject->privacyPhone.length() || 8 == orderObject->platformSource ) {
            int updateOrderPhoneAndBlockPrintFlagRet = PrintSumBillPosDB::getInstance().updateOrderDataToDB(orderObject, QString("UpdatePhoneAndBlockPrintFlagAction"));
            QLOG_INFO() << QString("[<<<<---PrintSumBillPosDB.getInstance().updateOrderDataToDB orderId:%1 updateOrderPhoneAndBlockPrintFlagRet:%2--->>>>]")
                           .arg(orderObject->id).arg(updateOrderPhoneAndBlockPrintFlagRet);
        }  
    }

    //----------------------- 程序中不管内存订单数据是首次初始化不存在, 还是已存在, 下方业务逻辑都会执行 ---------------------------//
    // 上游触发重打订单【支持补打方式】; bizops触发补打订单(超过7天订单商品等数据需重新存储)
    if ( !orderObject->pluginOptions.empty() && !orderObject->printOpt.empty() ) {
        QLOG_INFO() << QString("[<<<<---_ReprintOrderTickets Begin orderId:%1, printOpt= --->>>>]").arg(orderObject->id) << orderObject->printOpt;
       _ReprintOrderTickets(orderObject);
    }

    // 存储订单 销售退货状态的内存标识;
    orderObject->orderSaleRefundStatus = orderObject->orderStatus == 6 ? 6 : 3 ;
    orderObject->updateTime=QDateTime::currentDateTime().toTime_t();
    if(OrderObject::RequestRefund==orderObject->orderStatus) {
        emit startRemind(REMIND_REQREFUND_ORDER);
    }

    if(orderObject->dataBaseIsPushInt) {
        orderObject->isPush = true;
    }
    // 初始化 退单数据：防止退单标志数据被异常改动；
    if(orderObject->dataBaseIsCancleInt) {
        orderObject->isCancle = true;
    }
    // 初始化 预约实物销售入机标志: 防止预约实物入机标志数据被异常改动；
    if(orderObject->dataBaseIsORSPushInt) {
        orderObject->isORSPush = true;
    }
    // 初始化 预约实物退货入机标志: 防止预约实物入机标志数据被异常改动；
    if(orderObject->dataBaseIsORSCancleInt) {
        orderObject->isORSCancle = true;
    }

    QString posOrderCheckNo = m_orderIdToPosCheckNoMap.value(orderObject->id);

    if(posOrderCheckNo.isEmpty()) {
        posOrderCheckNo = orderObject->dataBasePosOrderCheckNo;
    }
    orderObject->posCheckNo=posOrderCheckNo;

    switch (orderObject->orderStatus) {
    case OrderObject::NewOrder:
        // 存在两种Case: 正常销售单没有入机成功 && 非预约日期(录配送费判断)/默认值是初始化0; ||  预约实物销售单没有入机成功 && 预约实物送达日期
        QLOG_INFO() << QString("[<<<<---FmTakeout _OrderAnalysis:orderId：%1 NewOrder=2, Do Nothing --->>>>]").arg(orderObject->id);
        break;
    case OrderObject::Confirmed:
        // 针对已经确认的订单：POS可能录过，也可能没有; 因此就需要 orderObject->isPush 来判断POS是否录过：true：录过；false：没录过；
        // 业务逻辑使用下方的 Finished Case;
    case OrderObject::Sendout:
        // 业务逻辑使用下方的 Finished Case;
    case OrderObject::Finished:
        // 存在两种Case: 正常销售单没有入机成功;
        if( orderObject->forwardPosStatus!=1 )
        {
            // ①forwardPosStatus == 3 需要跳过解耦2.0订单的本地持久化操作【POS机重新安装】;
            if ( 3 == orderObject->forwardPosStatus) {
                QLOG_INFO() << QString("[<<<<--- _OrderAnalysis:: orderId: %1 Had Storaged Order To LocalHost Successed, Not Need Storage Again  --->>>>]").arg(orderObject->id);
                return;
            }

            orderObject->pushOrderType = 1;
            orderObject->pushOrderTimes = 0;

            if ( !m_storagePosOrdersList.contains(orderObject->id) ) {
                bRetStorageOrderMutex =m_storageOrderMutex.tryLock(VALUE_TRYLOCKMEMTIMEOUT);
                if ( !bRetStorageOrderMutex ) {
                    QLOG_INFO() << QString("[<<<<---_OrderAnalysis:orderId：%1 m_storageOrderMutex.tryLock Failed --->>>>]").arg(orderObject->id);
                    return;
                }
                // 销售单: 添加到存储队列;
                m_storagePosOrdersList.append(orderObject->id);
                m_storageOrderMutex.unlock();                
            }
            QLOG_INFO() << QString("[<<<<---_OrderAnalysis::SaleOrder m_storagePosOrdersList.first: %1 m_storagePosOrdersList.count: %2 --->>>>]")
                           .arg( m_storagePosOrdersList.isEmpty()?"":m_storagePosOrdersList.first() ).arg( m_storagePosOrdersList.count() );
        }
        break;
    case OrderObject::RequestRefund:
        break;
    case OrderObject::AgreeRefund:
        break;
    case OrderObject::Refunded:
        _analysisRefundOrderTask( orderObject );
        break;

    default:
        break;
    }
}


void FlowControl::_analysisRefundOrderTask(OrderObject* orderObject) {
    if ( !orderObject ) {
        QLOG_ERROR() << QString("[<<<<--- _analysisRefundOrderTask:: orderObject Pointer Is NULL --->>>>]");
        return;
    }

    bool bRetStorageOrderMutex  = false;

    //内存逻辑BUG：重新获取数据库中订单数据标记来判断;
    //插件程序内存中没有此订单时需要从数据库中获取该订单标志数据;同时在接受到退单情况时，也需要从数据库中重新获取(防止内存中标志数据未更新[入机后未更新]);
    bool retRefundedGetDbOrderAllFlag = SimProcOrderDB::getInstance().getDbOrderAllFlag(orderObject->id,orderObject->dataBaseIsOrderExistInt,orderObject->dataBaseIsPushInt,
    orderObject->dataBaseIsCancleInt,orderObject->dataBaseIsORSPushInt,orderObject->dataBaseIsORSCancleInt,orderObject->dataBasePosOrderCheckNo);
    if(!retRefundedGetDbOrderAllFlag ){
        QLOG_ERROR() << QString("[<<<<---_analysisRefundOrderTask: Refund Order SimProcOrderDB::getInstance().getDbOrderAllFlag Failed--->>>>]");
        return;
    }
    QLOG_INFO() << QString("[<<<<---_analysisRefundOrderTask: Refund Order orderObject->id:%1 ,dataBaseIsOrderExistInt:%2 ,dataBaseIsPushInt:%3 ,dataBaseIsCancleInt:%4 ,"
                           "dataBaseIsORSPushInt:%5 ,dataBaseIsORSCancleInt:%6 ,dataBasePosOrderCheckNo:%7,negativePosStatus:%8--->>>>]")
                   .arg(orderObject->id).arg(orderObject->dataBaseIsOrderExistInt).arg(orderObject->dataBaseIsPushInt).arg(orderObject->dataBaseIsCancleInt)
                   .arg(orderObject->dataBaseIsORSPushInt).arg(orderObject->dataBaseIsORSCancleInt).arg(orderObject->dataBasePosOrderCheckNo).arg(orderObject->negativePosStatus);
    //存在两种Case:正常退货单没有入机成功 +  正常退货单已经入机落库成功
    //为避免换系统盘导致订单重复入机,顾需要额外使用 OMS提供的订单是否入机状态进行过滤;
    if( !orderObject->dataBaseIsCancleInt && orderObject->negativePosStatus!=1 )
    {
        //校验此订单是否已经 销售单录入POS 成功, 内存中处理存在BUG:现在改用 直接读数据库中的标志；
        //存在两种Case: 正常销售单没有入机成功  +  正常销售单入机落库成功;
        if(!orderObject->dataBaseIsPushInt) {
            orderObject->pushOrderType = 0; //标记通常订单-冲正销售单待入机状态；
            orderObject->pushOrderTimes = 0;

            // ① negativePosStatus == 3 情况订单, 需要跳过解耦2.0订单的本地持久化操作【POS机重新安装】;
            if ( 3 == orderObject->negativePosStatus ) {
                QLOG_INFO() << QString("[<<<<--- _analysisRefundOrderTask:: orderId: %1 Had Storaged Order To LocalHost Successed, Not Need Storage Again  --->>>>]").arg(orderObject->id);
                return;
            }

            // 特殊场景: 针对销售单没有正常存储, 此时订单被退单取消, 插件也需要将订单取消正常汇报给上游系统 O2O-FULFULLMENT / OMS;
            // 上述场景产生一种缺陷: 销售单由于商品Poskey过期, 导致没有存储成功, 此时退货单过来后, 直接返回存库成功, 导致财务侧出现单边账;
            QString  posCheckNo = orderObject->id.right(5) + QString("06");
            QJsonObject orderInputPosSuccessRecord;
            SimProcOrderDB::getInstance().queryPresistInputPosSuccessRecord(orderObject->id, orderInputPosSuccessRecord );

            // 销售单/退货单: 会根据订单状态 是否 = 6 进行转换后进行汇报;  进入此队列 m_storagePosOrdersList 的次数决定汇报的次数;
            if (orderInputPosSuccessRecord.contains("failCode") && orderInputPosSuccessRecord["failCode"].isString() ) {
                QString recordStatus = orderInputPosSuccessRecord["status"].toString();
                QString recordRemark = orderInputPosSuccessRecord["remark"].toString();
                QString recordFailedCode = orderInputPosSuccessRecord["failCode"].toString();
                _AddOrUpdateReportOmsList(orderObject->id,  orderObject->channel, "6",recordStatus , posCheckNo, recordRemark, recordFailedCode);
            } else {
                QString errorStorageOrderMsg = QString("Decouple Pos: OrderId: %1 Storage Pos Local DB Success (No Sale Order Record)").arg(orderObject->id);
                _AddOrUpdateReportOmsList(orderObject->id,  orderObject->channel, "6", "3", posCheckNo, errorStorageOrderMsg, QString("") );
                SimProcOrderDB::getInstance().updateRefundOrderStatusAndChkNum(orderObject->id,1,posCheckNo); // 需要-更新同步-本地数据库标识退单成功;
            }

            bRetStorageOrderMutex = m_storageOrderMutex.tryLock(VALUE_TRYLOCKMEMTIMEOUT);
            if ( !bRetStorageOrderMutex ) {
                QLOG_INFO() << QString("[<<<<---_analysisRefundOrderTask:: orderId: %1 m_storageOrderMutex.tryLock Failed --->>>>]").arg(orderObject->id);
                return;
            }
            m_storagePosOrdersList.removeOne(orderObject->id);
            m_storageOrderMutex.unlock();

        }  //case:校验此订单是否已经push到POS：订单已经push到POS
        else {
            // 为了兼容解耦Pos版本的过度: 不入机类型的订单也会存储订单号后5位+销售退货标识 【详情界面显示时排除销售退货标识】
            if(!orderObject->dataBasePosOrderCheckNo.isEmpty()) {
                orderObject->isCancle =true;    // 和orderObject->pushOrderType 来联合标记传出数据；
                orderObject->isORSCancle =true; // 和orderObject->orsPushOrderType 来联合标记传出数据；
                orderObject->pushOrderType = 0; //标记通常订单-准备退单动作；
                orderObject->pushOrderTimes = 0;
                orderObject->orsPushOrderType = 0; //标记预约实物-准备退单动作；
                orderObject->orsPushOrderTimes = 0;

                if ( !m_storagePosOrdersList.contains(orderObject->id) ) {
                    bRetStorageOrderMutex = m_storageOrderMutex.tryLock(VALUE_TRYLOCKMEMTIMEOUT);
                    if ( !bRetStorageOrderMutex ) {
                        QLOG_INFO() << QString("[<<<<---_analysisRefundOrderTask::orderId：%1 m_storageOrderMutex.tryLock Failed --->>>>]").arg(orderObject->id);
                        return;
                    }
                    // 退货单: 添加到存储队列;
                    m_storagePosOrdersList.append(orderObject->id);
                    m_storageOrderMutex.unlock();
                }
                QLOG_INFO() << QString("[<<<<---_analysisRefundOrderTask:: m_storagePosOrdersList.first: %1 m_storagePosOrdersList.count: %2 --->>>>]")
                               .arg( m_storagePosOrdersList.isEmpty()?"":m_storagePosOrdersList.first() ).arg( m_storagePosOrdersList.count() );
            }
            //else{未处理}
        }
    }

}


void FlowControl::onGetNewStoreInfo()
{
    m_loginSocket = new BillSocket(this);
    m_pullOrderSocket = new BillSocket(this);
    m_reportOMSRecordOrderSocket = new BillSocket(this);
    m_procOrderSocket = new BillSocket(this);
    m_pullDishesSocket = new BillSocket(this);
    m_pullOrderListSocket = new BillSocket(this);
    m_queryStoreStatusSocket = new BillSocket(this);

    // 所有数据库表初始化都成功; [不包含: m_initGetAuthPosDBRet ; m_initPosMetaDataDBRet ]
    if ( m_initSimProcOrderDBRet & m_initPrintSumBillPosDBRet & m_initPrintCupStickPosDBRet & m_initPrintMsgQueueDBRet & m_initPrintOrderPromotionDBRet
         & m_initCheckPoskeyExistPosDBRet & m_initSaveNoticeMsgDBRet ) {

        emit showAlert(AlertForm::LOADING, QString::fromLocal8Bit("正在获取门店信息......"));
    } else {
        emit showAlert(AlertForm::LOADING, QString::fromLocal8Bit("POS本地数据库共享访问权限没有开通......"));
        return;
    }

    ConfigManger::GetInstance().GetStoreConfigPassword(m_password);
    _Login();
    m_bFirstRecvInfo =false;
    return ;
}


void FlowControl::_GetFcMajorInfo(bool &loginResult, bool &openTcpChannel, QString &storeId, QString &posIp, QString &posHostName, QString &posWorkStationNum, bool &backupPos) {
    loginResult = m_bLoginResult;
    openTcpChannel = m_openTcpChannel;
    storeId = m_storeId;
    posIp = m_ipAddress;
    posHostName = m_posHostName;
    posWorkStationNum = m_posWorkstationNum;
    backupPos = m_backupPosFlag;
}


QString FlowControl::_GetCashierId()
{
    return m_cashierId;
}


QString FlowControl::_GetCashierName()
{
    return m_cashierName;
}


bool FlowControl::_SimValidOrdersListIsEmpty(){
    return m_simValidOrdersList.empty();
}


bool FlowControl::_Login()
{
    QString error;
    QString url;
    bool result;
    QJsonObject sendJson;
    QJsonObject recvJson;

    //获取POS机的 [IP地址] + [IP+PORT地址] -> 更新到成员变量:m_ipAddress, m_ipPortAddress;
    //必须在登录请求的时候才能去实时获取POS的IP地址;否则可能会出现 127.0.0.1的情况出现; 插件未登录前就接受请求会出现 m_backupPosFlag 未及时更新;
    _GetIpAddress();
    m_subStoreId =  ConfigManger::GetInstance().GetSubStoreId();
    // 跳过 校验配置 子门店 与 母门店的前三位是否一致；增加安全保护机制 (同时实现参数可控 校验功能 );
    if ( ConfigManger::GetInstance().GetSubStoreSkipVerify() ) {
        m_storeId = m_subStoreId.length() ? m_subStoreId : m_storeId;
    } else {
        m_storeId  = (m_subStoreId.length() && m_subStoreId.left(3) == m_storeId.left(3) ) ? m_subStoreId : m_storeId;
    }

    m_existNoAckNotice = SaveNoticeMsgDB::getInstance().existNoAckNotice() ? 1 : 0;
    m_puginVersionComments = ConfigManger::GetInstance().GetOrderServerUrl();

    sendJson = DataManger::GetInstance().GetLoginData(ConfigManger::GetInstance().GetPartnerId(),m_storeId, m_password, m_posId, m_cashierId,
                                                      m_ipPortAddress, m_puginVersionComments);
    // 登录新增Pos相关属性字段;
    sendJson.insert(JSON_POS_IP_ADDR, m_ipAddress);
    sendJson.insert(JSON_POS_WORKS_NUM, m_posWorkstationNum);
    sendJson.insert(JSON_POS_HOST_NAME, m_posHostName);
    sendJson.insert(JSON_POS_MAC_ADDRESS, m_posMacAddress);
    sendJson.insert(JSON_POS_BACKUP_PC, m_backupPosFlag);
    sendJson.insert(JSON_LOGIN_WITH_CONTAINS_ORDER_DETAIL, true);

    emit showAlert(AlertForm::LOADING, QString::fromLocal8Bit("正在登录......"));

    if ( ConfigManger::GetInstance().GetLoginSslConfig() ) {
        m_loginSocket->SetSslConfig();
    }

    // 如果前3次使用初始地址登录失败 3 次, 则切换使用 备用地址 再尝试3次, 合计超过6次，则切回初始地址继续登录;
    if ( m_serviceCallBackUrl.length() && m_loginErrorCount > 2 && m_loginErrorCount < 6 ) {
        url = m_serviceCallBackUrl + "/pos/" + ConfigManger::GetInstance().GetInterfaceName(INI_INTERFACE_ILOGIN);
        sendJson.remove(JSON_PLUGINVERSIONCOMMENTS);
        sendJson.insert(JSON_PLUGINVERSIONCOMMENTS, m_serviceCallBackUrl);
    } else {
        url = ConfigManger::GetInstance().GetLoginServerUrl() + ConfigManger::GetInstance().GetInterfaceName(INI_INTERFACE_ILOGIN);
    }

    m_loginSocket->SetUrl(QUrl( url ));

    QLOG_INFO() << QString("[<<<<---_Login Qurl: %1 --->>>>][requestData: ]").arg(url) << sendJson;
    result = m_loginSocket->PostRequest(sendJson, recvJson, error);
    QLOG_INFO() << QString("[<<<<---Login Finshed--->>>>][result:%1][msg:%2][recvData:").arg(result).arg(error)<<recvJson;
    if(!result) {
        emit showAlert(AlertForm::MSGERROR, QString::fromLocal8Bit("登录失败![网络错误]"));
        m_loginErrorCount++;
    } else {
        if(JSON_STATUSCODE_OK != recvJson[JSON_LOGINCODE].toInt()) {
            result = false;
            emit showAlert(AlertForm::MSGERROR, QString::fromLocal8Bit("登录失败![%1]").arg(recvJson[JSON_MESSAGE].toString()));
            m_loginErrorCount++;
        } else {
            m_storeName = recvJson[JSON_STORENAME].toString();
            DataManger::GetInstance().SetToken(recvJson[JSON_DATA].toObject()[JSON_TOKEN].toString());
            DataManger::GetInstance().SetStoreId(m_storeId);
            DataManger::GetInstance().SetPosIpAddress(m_ipPortAddress);
            DataManger::GetInstance().SetPartnerId(ConfigManger::GetInstance().GetPartnerId());
            emit hideAlert();
            emit setStoreInfo(m_storeId);
            emit setCashierInfo(m_cashierName);
            emit setTerminalIp(m_ipAddress);

            //***********************登陆时获取门店的营业状态 begin ************************//
            m_eleStoreStatus = recvJson[JSON_ELESTORESTS].toInt();
            m_modStoreStatus = recvJson[JSON_MODSTORESTS].toInt();
            m_mopStoreStatus = recvJson[JSON_MOPSTORESTS].toInt();
            m_mtModStoreStatus = recvJson[JSON_MTMODSTORESTS].toInt();
            m_curbsideStoreStatus = recvJson[JSON_CURBSIDE_STORESTS].toInt();
            QLOG_INFO()<<QString("[<<<<---FlowControl::_Login eleStoreStatus: %1, modStoreStatus: %2, mopStoreStatus: %3,"
                                 " mtModStoreStatus: %4, curbsideStoreStatus:%5, existNoAckNotice:%6 --->>>>]")
                         .arg(m_eleStoreStatus).arg(m_modStoreStatus).arg(m_mopStoreStatus).arg(m_mtModStoreStatus).arg(m_curbsideStoreStatus).arg(m_existNoAckNotice);

            emit doUpdateStoreStatus( m_eleStoreStatus, m_modStoreStatus, m_mopStoreStatus, m_mtModStoreStatus, m_curbsideStoreStatus, m_existNoAckNotice);
            //***********************登陆时获取门店的营业状态 end ************************//
            m_bLoginResult= true;
            m_clearTimer->start(1000*60*60*3); // 测试时5分钟执行1次清理任务:生产环境3小时清理一次；
            m_heartTimer->start(1000*60*5);
            m_queryStoreStatusTimer->start(1000*60*2);
            m_pullTimer->start(1000*5);
            m_analysisTimer->start(1000*5);
            m_reportOMSReocrdOrderTimer->start(1000*10);
            m_presistInputPosSuccessReocrdTimer->start(1000*8);
            m_clickPosCount = 0;
            m_loginErrorCount = 0;
            m_storageOrderTimer->start(10*1000);
            m_delayGetRefundDetailTimer->start(15*1000);
            m_remindCasherBlinkFloatTimer->start(5*1000);

            //在登陆时再次检查数据库连接是否都正常;
            if( !m_initSimProcOrderDBRet || !m_initPrintSumBillPosDBRet || !m_initPrintCupStickPosDBRet
                    || !m_initPrintMsgQueueDBRet || !m_initPrintOrderPromotionDBRet || !m_initCheckPoskeyExistPosDBRet || !m_initSaveNoticeMsgDBRet)
            {
                result = false;
                QLOG_INFO()<<QString("[<<<<---FlowControl::_Login() m_initSimProcOrderDBRet: %1, m_initPrintSumBillPosDBRet: %2,"
                                                    "m_initPrintCupStickPosDBRet:%3, m_initPrintMsgQueueDBRet:%4, m_initPrintOrderPromotionDBRet:%5, m_initCheckPoskeyExistPosDBRet:%6,"
                                                    "m_initSaveNoticeMsgDBRet:%7, m_initPosMetaDataDBRet:%8 --->>>>]")
                             .arg( m_initSimProcOrderDBRet?1:0).arg( m_initPrintSumBillPosDBRet?1:0)
                             .arg(m_initPrintCupStickPosDBRet?1:0).arg(m_initPrintMsgQueueDBRet?1:0).arg(m_initPrintOrderPromotionDBRet?1:0)
                             .arg(m_initCheckPoskeyExistPosDBRet?1:0).arg(m_initSaveNoticeMsgDBRet?1:0).arg(m_initPosMetaDataDBRet?1:0);

                emit showAlert(AlertForm::MSGERROR, QString::fromLocal8Bit("尝试打开POS本地数据库(MMXB** 或 DataS**)失败"));
            } else {
                // 获取原生链路的全量订单列表数据;
                _AddOrderPull( QString(), QString() );

                // 获取 o2ofulfillment 链路的全量订单列表数据;
                if ( ConfigManger::GetInstance().GetLoginServerUrl().contains(".stg") ) {
                    _AddOrderPull( QString(), QString(), GET_O2OFULFILLMENT_STG_CBL );
                } else if ( ConfigManger::GetInstance().GetLoginServerUrl().contains(".dev") ) {
                    _AddOrderPull( QString(), QString(), GET_O2OFULFILLMENT_DEV_CBL );
                } else if ( ConfigManger::GetInstance().GetLoginServerUrl().contains(".uat") ) {
                    _AddOrderPull( QString(), QString(), GET_O2OFULFILLMENT_UAT_CBL );
                } else {
                    _AddOrderPull( QString(), QString(), GET_O2OFULFILLMENT_PRO_CBL );
                }

            }
        }
    }

    if(!result) {
        QLOG_INFO() << QString("[<<<<---Login Retry--->>>>] %1 msec after login...").arg(VALUE_RELOGINTIME);
        QTimer::singleShot(VALUE_RELOGINTIME, this, &FlowControl::_Login);
    }

    QLOG_INFO() << QString("[<<<<---Login--->>>>][m_bLoginResult: %1, result: %2 ]").arg(m_bLoginResult?1:0).arg(result?1:0);

    if ( m_bLoginResult ) {
        QLOG_INFO() << QString("[<<<<---Login Success, Emit Signal To SocketCommunicate Begin Connect Tcp Socket --->>>>]");
        emit doLoginSuccess(true, m_openTcpChannel, m_storeId, m_ipAddress, m_posHostName, m_posWorkstationNum);
    }
    // 启动定时器: 15s 后, 插件读取本地全部门店通告记录; 防止在此处执行,程序奔溃无法 正常运行;
    m_queryAllNoticeTimer->start(1000 * 15);
    return result;
}


void FlowControl::_PullOrderData()
{
    if(m_orderPullList.isEmpty())
        return;

    emit hideAlert();
    QLOG_INFO()<<QString("[<<<<----_PullOrderData ListSize=%1, FirstOne: %2 ---->>>>>]").arg( m_orderPullList.size() ).arg( m_orderPullList.size()?m_orderPullList.first()->orderId:"" );

    bool btryLock = m_PullOrderDataMutex.tryLock(VALUE_TRYLOCKNETTIMEOUT);
    if (!btryLock) {
        QLOG_ERROR()<<"[<<<<----_PullOrderData Try Lock Failed ---->>>>>]";
        return;
    }

    PullOrderInfo* info = m_orderPullList.takeFirst();
    if ( info->pullErrorCount > 2 ) {
        QLOG_INFO()<<QString( "[<<<<----_PullOrderData orderId:%1,Channel:%2,PullErrorCount:%3, CallBackUrl:%4, Pull Faild More Than 3 Times, Abandon This Item ---->>>>>]" )
                     .arg(info->orderId).arg(info->channel).arg(info->pullErrorCount).arg(info->callBackUrl);

        m_orderPullList.removeOne(info);

        // 获取 o2ofulfillment 订单列表数据失败3次,之后丢弃 此拉单列表请求 item, 不切换域名重试获取;
        if ( info->orderId.isEmpty() && info->callBackUrl.contains("o2ofulfillment") ) {
            QLOG_ERROR() << QString("[<<<<---_PullOrderData <o2ofulfillment> Error, And Don't Display Error--->>>>]");
            delete info;
            m_PullOrderDataMutex.unlock();
            return;
        }

        // 特殊处理: 获取订单列表接口, 默认接口地址拉取失败，则尝试一次从备用OMS 回调地址在此进行拉取;
        if ( info->orderId.isEmpty() && m_serviceCallBackUrl.length() && info->callBackUrl != m_serviceCallBackUrl ) {
            info->callBackUrl = m_serviceCallBackUrl;
            info->pullErrorCount = 0; // Pull Error Must Rest Zero, Or No Chance Goto Pull All Order;
            m_orderPullList.append(info);
        } else {
            delete info;
        }

        m_PullOrderDataMutex.unlock();
        return;
    }

    if(info->orderId.isEmpty()) {
        if ( _PullOrderList( info->pageSize, info->pageNumber, info->callBackUrl ) ) {
            QLOG_INFO()<<"[<<<<----_PullOrderData  _PullOrderList successful---->>>>>]";
            m_orderPullList.removeOne(info);
            delete info;
        } else {
            QLOG_INFO()<<"[<<<<----_PullOrderData _PullOrderList failed---->>>>>]";
            m_orderPullList.removeOne(info);
            info->pullErrorCount++;
            m_orderPullList.append(info);
        }
    } else {
        if ( _PullOrderDetail( info->orderId, info->channel, info->callBackUrl, info->skipPrint, info->pushOptions ) ) {
             QLOG_INFO()<<"[<<<<----_PullOrderData  _PullOrderDetail successful---->>>>>]";
             m_orderPullList.removeOne(info);
             delete info;
        } else {
             QLOG_INFO()<<"[<<<<----_PullOrderData  _PullOrderDetail fail---->>>>>]";
             m_orderPullList.removeOne(info);
             info->pullErrorCount++;
             m_orderPullList.append(info);
        }
    }

    m_PullOrderDataMutex.unlock();
    return ;
}


bool FlowControl::_PullOrderDetail(const QString& orderId, const QString& channel, const QString &callBackUrl, const bool& skipPrint, const QJsonObject& pushOptins,
                                   const bool &skipErrorDisplay)
{
    if(m_pullOrderSocket==NULL)
        m_pullOrderSocket =new BillSocket(this);
    QString error;
    QString url;
    bool result;
    QJsonObject recvJson;

    if(ConfigManger::GetInstance().GetOrderSslConfig()) {
        m_pullOrderSocket->SetSslConfig();
    }

    if ( callBackUrl.length() ) {
        url = callBackUrl + "/order/" + ConfigManger::GetInstance().GetInterfaceName(INI_INTERFACE_PULLORDER);
    } else {
        url = ConfigManger::GetInstance().GetOrderServerUrl() + ConfigManger::GetInstance().GetInterfaceName(INI_INTERFACE_PULLORDER);
    }

    // 拉取订单详情接口:订单编号
    url.append(orderId);
    // 拉取订单详情接口: 新增 渠道 参数
    url.append(QString("&")+JSON_CHANNEL+QString("=")+channel);
    url.append(QString("&")+JSON_POSIPADDRESS+QString("=")+m_ipPortAddress);
    url.append(QString("&")+JSON_STORE_ID+QString("=")+m_storeId);
    QLOG_INFO() << QString("[<<<<---Pull Order Detail--->>>>][requestUrl:]")<<url;
    QUrl  tmpUrl = QUrl(url);
    m_pullOrderSocket->SetUrl( tmpUrl );
    result = m_pullOrderSocket->GetRequest(recvJson, error);
    QLOG_INFO() << QString("[<<<<---Pull Order Detail Finsh--->>>>][result:%1][msg:%2]").arg(result).arg(error)<<recvJson;

    if ( !result ) {
        if ( !skipErrorDisplay ) {
            emit setNetStatus(QString::fromLocal8Bit("<font color='#ff0000'>网络不稳定,正在重试</font>"));
        }

    } else {
        emit setNetStatus(QString::fromLocal8Bit("正常"));
        if(JSON_STATUSCODE_OK != recvJson[JSON_ERRCODE].toInt())
        {
            error = recvJson[JSON_ERRMSG].toString();
            QLOG_ERROR() << QString("[<<<<---Pull Order Detail Error--->>>>][msg->%1]").arg(error);
            if ( !skipErrorDisplay ) {
                emit showAlert(AlertForm::MSGERROR, QString::fromLocal8Bit("获取订单失败![%1]").arg(error));
            }
            result=false;
        } else {
            QJsonObject order = recvJson[JSON_DATA].toObject();
            // 服务端返回 code=100 , 但订单体中无订单详情数据;
            if ( !order.contains( JSON_ID ) ) {
                QLOG_ERROR()<<QString("[<<<<---Pull Order Detail Failed, OrderId= %1, Channel= %2  Code= 100, But 'data'  Is Empty --->>>>]").arg( orderId ).arg( channel );
                error = QString(" OrderId=%1, Code=100, But 'data' Is Empty ");
                result = false;
                if ( !skipErrorDisplay ) {
                    emit showAlert(AlertForm::MSGERROR, QString::fromLocal8Bit("获取订单失败![%1]").arg( error ) );
                }
                // 此种情况: 肯定服务端服务异常, 即使 result = false,下次拉单, 依旧还会失败, 顾再次放弃此订单详情的继续拉取;
            } else {
                if ( !order.contains( JSON_CALL_BACK_URL ) ) {
                    order.insert( JSON_CALL_BACK_URL, callBackUrl );
                }
                if ( !order.contains( JSON_SKIP_PRINT ) ) {
                    order.insert( JSON_SKIP_PRINT, skipPrint );
                }
                if ( !order.contains( JSON_PUSH_PLUGIN_OPTIONS ) ) {
                    order.insert( JSON_PUSH_PLUGIN_OPTIONS, pushOptins );
                }
                _OrderAnalysis(order);
            }
        }
    }
    /*解析json数据失败则20秒后重新拉单*/
    if ( !result ) {
        m_pullTimer->start(1000*20);
        // 如果某次拉订单列表出现失败；此函数的外层函数 _PullOrderData：会将本次拉单对象存起来，等待下次拉取;
    } else {
        m_pullTimer->start(1000*6);
    }

    QLOG_INFO() << QString("[<<<<---Pull Order Detail Final Result: %1 --->>>>]").arg( result ? 1 : 0);
    return result;
}


bool FlowControl::_PullOrderList( const int &pageSize, const int &pageNo, const QString &callBackUrl )
{
    if(m_pullOrderListSocket==NULL) {
        m_pullOrderListSocket =new BillSocket(this);
    }
    QString error;
    QString url;
    bool result;
    QJsonObject sendJson;
    QJsonObject recvJson;
    int ordertotalSum;
    sendJson = DataManger::GetInstance().GetPullOrderListData(pageNo,pageSize);
    sendJson.insert(JSON_POS_BACKUP_PC, m_backupPosFlag);

    QLOG_INFO() << QString("[<<<<---FlowControl::_PullOrderList: Pull Order List--->>>>]");
    if(ConfigManger::GetInstance().GetOrderSslConfig()) {
        m_pullOrderListSocket->SetSslConfig();
        QLOG_INFO()<<"FlowControl::_PullOrderList load ssl";
    }

    if ( callBackUrl.length() ) {
        url = callBackUrl + "/order/" + ConfigManger::GetInstance().GetInterfaceName(INI_INTERFACE_PULLORDERLIST);
    } else {
        url = ConfigManger::GetInstance().GetOrderServerUrl() + ConfigManger::GetInstance().GetInterfaceName(INI_INTERFACE_PULLORDERLIST);
    }

    m_pullOrderListSocket->SetUrl(QUrl( url ));
    QLOG_INFO()<< url << " requestData: " <<sendJson;

    result = m_pullOrderListSocket->PostRequest(sendJson, recvJson, error);
    QLOG_INFO() << QString("[<<<<---FlowControl::_PullOrderList:Pull Order List Finish.--->>>>][result:%1][msg:%2]").arg(result).arg(error)<<recvJson;

    if(!result) {

        if ( callBackUrl.length() && callBackUrl.contains("o2ofulfillment") ) {
            QLOG_ERROR() << QString("[<<<<---FlowControl::_PullOrderList:Pull Order List <o2ofulfillment> Error, And Don't Display Error--->>>>]");
        } else {
            emit setNetStatus(QString::fromLocal8Bit("<font color='#ff0000'>网络不稳定，正在重试</font>"));
        }

    } else {

        emit setNetStatus(QString::fromLocal8Bit("正常"));
        if ( JSON_STATUSCODE_OK != recvJson[JSON_ERRCODE].toInt() ) {
            QString error = recvJson[JSON_ERRMSG].toString();
            QLOG_ERROR() << QString("[<<<<---FlowControl::_PullOrderList:Pull Order List Error--->>>>][msg->%1]").arg(error);

            if ( callBackUrl.length() && callBackUrl.contains("o2ofulfillment") ) {
                QLOG_ERROR() << QString("[<<<<---FlowControl::_PullOrderList:Pull Order List <o2ofulfillment> Error, And Don't Display Error--->>>>]");
                m_o2ofulfillmentOrderCount = 0;
            } else {
                emit showAlert(AlertForm::MSGERROR, QString::fromLocal8Bit("获取订单失败![%1]").arg(error));
                m_orderCount = 0;
            }
            result=false;

        } else {

            QJsonArray orders = recvJson[JSON_DATA].toObject()[JSON_ORDERS].toArray();
            foreach ( QJsonValue order, orders ) {
                QJsonObject  orderObject = order.toObject();
                // 订单 JsonObject -> OrderObject 前数据安全检查;
                if ( orderObject.contains(JSON_ID) ) {
                    _OrderAnalysis( orderObject );
                }
            }
            ordertotalSum = recvJson[JSON_DATA].toObject()[JSON_COUNT].toInt();

            // 1、o2ofulfillment 地址获取订单列表分页操作;
            // 2、原生拉取订单列表分页操作;
            bool  bLocalPullOrderCountNotFull = false;
            if ( callBackUrl.length() && callBackUrl.contains("o2ofulfillment") ) {
                m_o2ofulfillmentOrderCount += orders.size();
                bLocalPullOrderCountNotFull  =  m_o2ofulfillmentOrderCount < ordertotalSum;
            } else {
                m_orderCount += orders.size();
                bLocalPullOrderCountNotFull  =  m_orderCount < ordertotalSum;
            }

            if ( bLocalPullOrderCountNotFull && orders.size() > 0 )  {
                //避免出现存在多页数据，导致出现死锁: 先调用定时器的timeout 触发槽函数:_PullOrderData,
                //_PullOrderData:内部会有加锁并且会调用分页获取订单函数_AddOrderPull(QString(),QString(),pageNo+1,pageSize): 内部也有加锁，所以导致死锁;
                //_AddOrderPull(QString(),QString(),pageNo+1,pageSize);
                /***组装从FM外卖service端的拉单请求参数***/
                PullOrderInfo* orderPull = new PullOrderInfo();
                orderPull->orderId=QString();
                orderPull->channel=QString();
                orderPull->pageNumber=pageNo+1;
                orderPull->pageSize=pageSize;
                orderPull->pullErrorCount = 0;
                orderPull->callBackUrl = callBackUrl;
                QLOG_INFO()<<QString::fromLocal8Bit("[<<<<---FlowControl::_PullOrderList: Next Page Order List :pageNo:%1 pageSize:%2--->>>>]").arg(pageNo+1).arg(pageSize);
                m_orderPullList.append(orderPull);
                //避免出现存在多页数据，导致出现死锁;
            } else {
                //分页拉取订单列表最后一页成功后,需要重置本地拉单计数缓存, 防止影响下一次获取订单列表判断;
                if ( callBackUrl.length() && callBackUrl.contains("o2ofulfillment") ) {
                    m_o2ofulfillmentOrderCount = 0;
                    QLOG_INFO()<<QString("[<<<<---FlowControl::_PullOrderList  < o2ofulfillment > Had Finished: The Last Request PageNo:%1, Last Get Orders =%2 --->>>>]").arg( pageNo ).arg( orders.size() );
                } else {
                    m_orderCount = 0;
                    QLOG_INFO()<<QString("[<<<<---FlowControl::_PullOrderList  Had Finished: The Last Request PageNo:%1, Last Get Orders =%2 --->>>>]").arg( pageNo ).arg( orders.size() );
                }
            }

        }
    }
    // 如果出现拉取订单列表失败，触发下一次拉门店有效订单的时间间隔变更为20(如果一开始就获取订单列表成功:时间间隔为5s)
    if(!result) {
        m_pullTimer->start(1000*20);
        // 如果某次拉订单列表出现失败；此函数的外层函数 _PullOrderData: 还会将本次拉单列表存起来等待下次拉取;
    }
    QLOG_INFO()<<"[<<<<---Pull Order List Result--->>>>]"<< result;
    return result;
}


void FlowControl::_AnalysisOrderDetailData()
{
    if ( m_orderAnalysisList.isEmpty() ) {
        m_analysisTimer->start(1000*5);
        return;
    }

    QLOG_INFO()<<QString("[<<<<----_AnalysisOrderDetailData ListSize=%1, FirstOne: %2 ---->>>>>]").arg( m_orderAnalysisList.size() ).arg( m_orderAnalysisList.size()?m_orderAnalysisList.first()->orderId:"" );

    bool btryLock = m_analysisOrderDataMutex.tryLock(VALUE_TRYLOCKNETTIMEOUT);
    if (!btryLock) {
        QLOG_ERROR()<<"[<<<<----_AnalysisOrderDetailData Try Lock Failed ---->>>>>]";
        m_analysisTimer->start(1000*8);
        return;
    }

    AnalysisOrderInfo* info = m_orderAnalysisList.takeFirst();
    m_analysisOrderDataMutex.unlock();

    if ( info ) {
        QLOG_INFO()<<QString( "[<<<<----_AnalysisOrderDetailData orderId:%1, CallBackUrl:%2, pushOptions:  ---->>>>>]" ).arg(info->orderId).arg(info->callBackUrl) << info->pushOptions;
        // 目前场景: 假设 _OrderAnalysis() 函数处理异常, 存在丢失订单详情数据的可能 [之前的模式也存在同样情况];
        if ( !info->orderDetailJson.contains( JSON_CALL_BACK_URL ) ) {
            info->orderDetailJson.insert( JSON_CALL_BACK_URL, info->callBackUrl );
        }
        if ( !info->orderDetailJson.contains( JSON_PUSH_PLUGIN_OPTIONS ) ) {
            info->orderDetailJson.insert( JSON_PUSH_PLUGIN_OPTIONS, info->pushOptions );
        }

        _OrderAnalysis(info->orderDetailJson);
        delete info;
    } else {
        QLOG_ERROR()<<"[<<<<----_AnalysisOrderDetailData:: AnalysisOrderInfo Pointer Is Null ---->>>>>]";
    }

    m_analysisTimer->start(1000*2);
    return;
}


bool FlowControl::_SendHeart()
{
    QString error;
    QString url;
    bool result;
    QJsonObject sendJson;
    QJsonObject recvJson;
    m_existNoAckNotice = SaveNoticeMsgDB::getInstance().existNoAckNotice() ? 1 : 0;
    m_puginVersionComments = ConfigManger::GetInstance().GetOrderServerUrl();

    sendJson = DataManger::GetInstance().GetHeartData(m_password,m_posId,m_ipPortAddress,m_puginVersionComments,m_bLastHeartIsError);
    sendJson.insert(JSON_POS_IP_ADDR, m_ipAddress);
    sendJson.insert(JSON_POS_WORKS_NUM, m_posWorkstationNum);
    sendJson.insert(JSON_POS_HOST_NAME, m_posHostName);
    sendJson.insert(JSON_POS_MAC_ADDRESS, m_posMacAddress);
    sendJson.insert(JSON_POS_BACKUP_PC, m_backupPosFlag);
    sendJson.insert(JSON_LOGIN_WITH_CONTAINS_ORDER_DETAIL, true);

    // 如果前3次使用初始地址心跳失败 3 次, 则切换使用 备用地址 再尝试3次, 合计超过6次，则切回初始地址继续心跳;
    if ( m_serviceCallBackUrl.length() && m_sendHeartErrorCount > 2 && m_sendHeartErrorCount < 6 ) {
        url = m_serviceCallBackUrl + "/pos/" + ConfigManger::GetInstance().GetInterfaceName(INI_INTERFACE_HEART);
        sendJson.remove(JSON_PLUGINVERSIONCOMMENTS);
        sendJson.insert(JSON_PLUGINVERSIONCOMMENTS, m_serviceCallBackUrl);
    } else {
        url = ConfigManger::GetInstance().GetLoginServerUrl() + ConfigManger::GetInstance().GetInterfaceName(INI_INTERFACE_HEART);
    }

    m_loginSocket->SetUrl(QUrl( url ) );

    QLOG_INFO() << QString("[<<<<---Send Heart--->>>>][Url: %1, RequestData: ]").arg(url) << sendJson;
    result = m_loginSocket->PostRequest(sendJson, recvJson, error);
    QLOG_INFO() << QString("[<<<<---Send Heart Finish--->>>>][result:%1][msg:%2][recvData:]").arg(result).arg(error)<<recvJson;

    if ( !result ) {
        m_bLastHeartIsError = true;
        m_sendHeartErrorCount++;
        emit setNetStatus(QString::fromLocal8Bit("<font color='#ff0000'>网络不稳定，正在重试</font>"));
        if ( m_queryStoreStatusErrorCount ) {  //当查询全渠道营业状态接口 不支持 或 请求失败时,才使用心跳接口数据更新;
            emit doUpdateStoreStatus(0, 0, 0, 0, 0, m_existNoAckNotice);  //NetWork Is Error , Refresh Store Default Status;
        }
    } else {

        if ( JSON_STATUSCODE_OK != recvJson[JSON_LOGINCODE].toInt())
        {
            result = false;
            m_bLastHeartIsError = true;
            m_sendHeartErrorCount++;
            emit setNetStatus(QString::fromLocal8Bit("<font color='#ff0000'>网络不稳定，正在重试</font>"));
            if ( m_queryStoreStatusErrorCount ) {  //当查询全渠道营业状态接口 不支持 或 请求失败时,才使用心跳接口数据更新;
                emit doUpdateStoreStatus(0, 0, 0, 0, 0, m_existNoAckNotice);  //Interface Return Error , Refresh Store Default Status;
            }
        } else {
           result = true;
           emit setNetStatus(QString::fromLocal8Bit("<font color='#f5f5f5'>正常</font>"));
           //只有上一次心跳是异常：才根据心跳来展示门店营业状态 [数据延迟比较严重:同时也需要通过OMS推门店状态给插件]
           //OMS服务端 门店开关店不主动推送,主要依赖心跳请求更新数据;

           if ( m_queryStoreStatusErrorCount ) {  //当查询全渠道营业状态接口 不支持 或 请求失败时,才使用心跳接口数据更新;
               if ( recvJson.contains(JSON_ELESTORESTS) ) {
                   m_eleStoreStatus = recvJson[JSON_ELESTORESTS].toInt();
               }
               if ( recvJson.contains(JSON_MODSTORESTS) ) {
                   m_modStoreStatus = recvJson[JSON_MODSTORESTS].toInt();
               }
               if ( recvJson.contains(JSON_MOPSTORESTS) ) {
                   m_mopStoreStatus = recvJson[JSON_MOPSTORESTS].toInt();
               }
               if ( recvJson.contains(JSON_MTMODSTORESTS) ) {
                   m_mtModStoreStatus = recvJson[JSON_MTMODSTORESTS].toInt();
               }
               if ( recvJson.contains(JSON_CURBSIDE_STORESTS) ) {
                   m_curbsideStoreStatus = recvJson[JSON_CURBSIDE_STORESTS].toInt();
               }
               QLOG_INFO()<<QString("[<<<<---FlowControl::_SendHeart eleStoreStatus: %1, modStoreStatus: %2 , mopStoreStatus: %3 , mtModStoreStatus: %4, "
                                    " m_curbsideStoreStatus: %5, existNoAckNotice:%6 --->>>>]")
                            .arg(m_eleStoreStatus).arg(m_modStoreStatus).arg(m_mopStoreStatus).arg(m_mtModStoreStatus).arg(m_curbsideStoreStatus).arg(m_existNoAckNotice);
               emit doUpdateStoreStatus( m_eleStoreStatus, m_modStoreStatus, m_mopStoreStatus, m_mtModStoreStatus, m_curbsideStoreStatus, m_existNoAckNotice );
           }
           //还原并标记上一次心跳为正常状态;
           m_bLastHeartIsError = false;
       }
    }
    return result;
}


bool FlowControl::_QueryAllChannelStoreStatus()
{
    QLOG_INFO() << QString("[<<<<---_QueryAllChannelStoreStatus m_sendQueryStoreStatusErrorCount=%1  Begin--->>>>]").arg(m_queryStoreStatusErrorCount);
    // 查询门店营业状态 请求失败次数, 决定延迟定时查询频率; 【目前后端服务发版时间在插件发版之后】
    if ( m_queryStoreStatusErrorCount > 4 ) {
        m_queryStoreStatusTimer->start(1000*60*30);
    } else if ( m_queryStoreStatusErrorCount > 2 ) {
        m_queryStoreStatusTimer->start(1000*60*10);
    } else {
        m_queryStoreStatusTimer->start(1000*60*2);
    }

    QString error;
    QString url;
    bool result;
    QJsonObject sendJson;
    QJsonObject recvJson;
    m_existNoAckNotice = SaveNoticeMsgDB::getInstance().existNoAckNotice() ? 1 : 0;
    m_puginVersionComments = ConfigManger::GetInstance().GetOrderServerUrl();

    sendJson.insert(JSON_IPADDRESS, m_ipPortAddress);
    sendJson.insert(JSON_ORGCODE, m_storeId);
    sendJson.insert(JSON_PASSWORD, m_password);
    sendJson.insert(JSON_MACHINECODE, m_posId);
    sendJson.insert(JSON_PLUGINVERSION, APP_VERSION);
    sendJson.insert(JSON_SYNCSTORESTATUS, 1);
    sendJson.insert(JSON_POS_IP_ADDR, m_ipAddress);
    sendJson.insert(JSON_POS_WORKS_NUM, m_posWorkstationNum);
    sendJson.insert(JSON_POS_HOST_NAME, m_posHostName);
    sendJson.insert(JSON_POS_MAC_ADDRESS, m_posMacAddress);
    sendJson.insert(JSON_POS_BACKUP_PC, m_backupPosFlag);

    /*
    // 此接口只有 oms 系统提供 【o2o-fulfillment 服务没有提供, 故无需使用 m_serviceCallBackUrl 进行调用】
    // 如果前3次使用初始地址心跳失败 3 次, 则切换使用 备用地址 再尝试3次, 合计超过6次，则切回初始地址继续心跳;
    if ( m_serviceCallBackUrl.length() && m_sendHeartErrorCount > 2 && m_sendHeartErrorCount < 6 ) {
        url = m_serviceCallBackUrl + "/pos/" + ConfigManger::GetInstance().GetInterfaceName(INI_INTERFACE_HEART);
        //sendJson.remove(JSON_PLUGINVERSIONCOMMENTS);
        //sendJson.insert(JSON_PLUGINVERSIONCOMMENTS, m_serviceCallBackUrl);
    } else {
        url = ConfigManger::GetInstance().GetLoginServerUrl() + ConfigManger::GetInstance().GetInterfaceName(INI_INTERFACE_HEART);
    }
    */
    url = ConfigManger::GetInstance().GetLoginServerUrl() + "getChannelStoreStatus";
    m_queryStoreStatusSocket->SetSslConfig();
    m_queryStoreStatusSocket->SetUrl(QUrl( url ) );

    QLOG_INFO() << QString("[<<<<---_QueryAllChannelStoreStatus--->>>>][Url: %1, RequestData: ]").arg(url) << sendJson;
    result = m_queryStoreStatusSocket->PostRequest(sendJson, recvJson, error);
    QLOG_INFO() << QString("[<<<<---_QueryAllChannelStoreStatus Finish--->>>>][result:%1][msg:%2][recvData:]").arg(result).arg(error)<<recvJson;

    if ( !result ) {
        m_queryStoreStatusErrorCount++;
        // emit setNetStatus(QString::fromLocal8Bit("<font color='#ff0000'>网络不稳定，正在重试</font>"));
    } else {

       if(JSON_STATUSCODE_OK != recvJson[JSON_LOGINCODE].toInt())
       {
            result = false;
            m_queryStoreStatusErrorCount++;
            emit setNetStatus(QString::fromLocal8Bit("<font color='#ff0000'>网络不稳定，正在重试</font>"));
            emit doUpdateStoreStatus(0, 0, 0, 0, 0, m_existNoAckNotice);  //Interface Return Error , Refresh Store Default Status;
       } else {
           // 请求成功后，才能重置查询失败错误数;
           m_queryStoreStatusErrorCount = 0;
           result = true;

           if ( recvJson.contains(JSON_ELESTORESTS) ) {
               m_eleStoreStatus = recvJson[JSON_ELESTORESTS].toInt();
           }
           if ( recvJson.contains(JSON_MODSTORESTS) ) {
               m_modStoreStatus = recvJson[JSON_MODSTORESTS].toInt();
           }
           if ( recvJson.contains(JSON_MOPSTORESTS) ) {
               m_mopStoreStatus = recvJson[JSON_MOPSTORESTS].toInt();
           }
           if ( recvJson.contains(JSON_MTMODSTORESTS) ) {
               m_mtModStoreStatus = recvJson[JSON_MTMODSTORESTS].toInt();
           }
           if ( recvJson.contains(JSON_CURBSIDE_STORESTS) ) {
               m_curbsideStoreStatus = recvJson[JSON_CURBSIDE_STORESTS].toInt();
           }

           emit doUpdateStoreStatus( m_eleStoreStatus, m_modStoreStatus, m_mopStoreStatus, m_mtModStoreStatus, m_curbsideStoreStatus, m_existNoAckNotice );
       }
    }
    return result;
}


bool FlowControl::_ConfirmOrder(const QString &orderId)
{
    Q_UNUSED(orderId);
    bool result = false;
    return result;
}


bool FlowControl::_SendOrder(const QString& orderId)
{
    Q_UNUSED(orderId);
    bool result = false;
    return result;
}

bool FlowControl::_CompleteOrder(const QString& orderId)
{
    Q_UNUSED(orderId);
    bool result = false;
    return result;
}


bool FlowControl::_RefundOrder(const QString &orderId,int reasonCode,const QString& reason,const QString& dishesListString)
{

    QLOG_INFO() << QString("[<<<<---FlowControl::_RefundOrder--->>>>][orderId:%1 reasonCode:%2 reason:%3 dishesListString:]").arg(orderId).arg(reasonCode).arg(reason).arg(dishesListString);
    QString error;
    QString url;
    QString callBackUrl = "";
    bool result = false;
    QJsonObject sendJson;
    QJsonObject recvJson;
    sendJson = DataManger::GetInstance().GetRefundOrderData(reasonCode,reason,orderId,m_FmOrdersMap.value(orderId)->channel, dishesListString, m_cashierId, m_cashierName);
    emit showAlert(AlertForm::LOADING, QString::fromLocal8Bit("正在通信......"));
    QLOG_INFO() << QString("[<<<<---Refund Order Begin--->>>>][requestData:%1]")<<sendJson;
    // 如果退款原因：商品已售完，使用下面接口; // 如果退款原因：其他，都同意使用一个接口；
    if ( m_FmOrdersMap.value(orderId) ) {
        callBackUrl = m_FmOrdersMap.value(orderId)->callBackUrl;
    }

    if ( callBackUrl.length() ) {
        url = callBackUrl + "/order/" + ConfigManger::GetInstance().GetInterfaceName(INI_INTERFACE_CANCLE);
    } else {
        url = ConfigManger::GetInstance().GetOrderServerUrl() + ConfigManger::GetInstance().GetInterfaceName(INI_INTERFACE_CANCLE);
    }

    m_procOrderSocket->SetUrl(QUrl( url ) );
    QLOG_INFO() << QString("[<<<<<-----_RefundOrder: orderId:%1  Request URL: ----->>>>>]").arg(orderId)<< m_procOrderSocket->GetUrl();

    if(ConfigManger::GetInstance().GetOrderSslConfig()) {
        m_procOrderSocket->SetSslConfig();
    }

    result = m_procOrderSocket->PostRequest(sendJson, recvJson, error);
    QLOG_INFO() << QString("[<<<<---Refund Order Finish--->>>>][result:%1][msg:%2][recvData:]").arg(result).arg(error)<<recvJson;

    if ( !result ) {
        emit showAlert(AlertForm::MSGERROR, QString::fromLocal8Bit("退单失败![网络错误]"));
    } else {
        if ( JSON_STATUSCODE_OK != recvJson[JSON_ERRCODE].toInt() )
        {
            result = false;
            emit showAlert(AlertForm::MSGERROR, QString::fromLocal8Bit("退单失败![%1]").arg(recvJson[JSON_MESSAGE].toString()));
        } else {
            QJsonObject data = recvJson[JSON_DATA].toObject();
            int status = data[JSON_RECEIVINGSTATUS].toInt();
            if ( 1==status ) {
                emit showAlert(AlertForm::SUCCESS, QString::fromLocal8Bit("退单成功,稍后入机"));
                //获取POS退单成功,OMS服务端返回的RefundFmId ( 此字段只有星巴克APP SVC卡支付的case,才会使用到 )
                QString refundFmIdTemp = data[JSON_REFUNDFMID].toString();
                int orderStatus = data[JSON_ORDERSTATUS].toInt();
                int tempGlobalOrderType = data[JSON_GLOBALORDERTYPE].toInt();
                int tempGlobalServiceType = data[JSON_GLOBALSERVICETYPE].toInt();
                int tempRefundMethod = 0;
                if ( data.contains(JSON_GLOBALREFUNDMETHOD) )
                    tempRefundMethod = data[JSON_GLOBALREFUNDMETHOD].toInt();   // 1: srkit-全退  2: srkit-部分退

                OrderObject* orderObject = m_FmOrdersMap.value(orderId);
                int oldOrderStatus = orderObject->orderStatus;
                orderObject->orderStatus = orderStatus;
                orderObject->refundFmId = refundFmIdTemp;
                orderObject->globalOrderType = tempGlobalOrderType;
                orderObject->globalServiceType = tempGlobalServiceType;
                // 避免订单正在尝试录入之前的销售单;
                orderObject->pushOrderType = 0;
                orderObject->pushOrderTimes = 0;
                orderObject->orsPushOrderType = 0;
                orderObject->orsPushOrderTimes = 0;

                emit changeOrderStatus(orderObject, oldOrderStatus);

                // 部分退场景, 不能提前进入入机队列, 需等待上游更新订单数据;  同步退插件存在小概率崩溃可能, 顾需异步入机; // refundMethod: [2: srkit-部分退];
                // 不立刻入机等待拉取订单详情后再如入机(插件上退单后，OMS 不推送 fulfillment 服务更新订单数据 );
                QLOG_INFO() << QString("[<<<<---_RefundOrder: orderId: %1, orderStatus: %2, refundFmId: %3, refundMethod: %4,  globalServiceType: %5, globalOrderType: %6, isCancle:%7--->>>>]")
                               .arg( orderObject->id ).arg(orderObject->orderStatus).arg(refundFmIdTemp).arg( tempRefundMethod ).arg(tempGlobalServiceType).arg(tempGlobalOrderType).arg(orderObject->isCancle);
                if (  0 != tempRefundMethod && 1 != tempRefundMethod ) {
                    // 添加到待拉取订单详情列表;
                    PullOrderInfo* orderPull = new PullOrderInfo();
                    if ( orderPull ) {
                        orderPull->orderId=orderObject->id;
                        orderPull->channel = orderObject->channel;
                        orderPull->pageNumber=0;
                        orderPull->pageSize=0;
                        orderPull->pullErrorCount = 0;
                        orderPull->callBackUrl = orderObject->callBackUrl;
                        orderPull->skipPrint = orderObject->skipPrint;
                        // orderPull->pushOptions = orderObject->pushOptions;
                        m_orderPullList.append( orderPull );
                    }
                    QLOG_INFO() << QString("[<<<<---_RefundOrder::  m_orderPullList.size: %1 , m_orderPullList.last: %2, m_simValidOrdersList.size: %3 , m_simValidOrdersList.first: %4 --->>>>]")
                                   .arg( m_orderPullList.size() ).arg( m_orderPullList.last() ? m_orderPullList.last()->orderId : "" )
                                   .arg( m_simValidOrdersList.size() ).arg( m_simValidOrdersList.size() ? m_simValidOrdersList.first() : "" );
                } else {
                    // 存储订单 销售退货状态的内存标识;
                    orderObject->orderSaleRefundStatus = orderObject->orderStatus == 6 ? 6 : 3 ;
                    _analysisRefundOrderTask( orderObject );
                }
                result = true;

            } else {
                result = false;
                emit showAlert(AlertForm::MSGERROR, QString::fromLocal8Bit("退单失败![%1]").arg(recvJson[JSON_ERRMSG].toString()));
            }
        }
    }
    return result;

}


void FlowControl::_ReportOMSRecordOrderInfo()
{
    if ( m_orderRecordRepOMSList.isEmpty() )
        return ;

    // 遍历查询时, 不加锁提高性能，原本应该使用读锁，在遍历时: 对遍历的对象进行判空处理，无需担心会导致程序崩溃;
    bool btryLock = false;
    RepOMSRecordOrderInfo* RepOMSRecOrderIn = NULL;
    bool  findFlag = false;
    QList<RepOMSRecordOrderInfo*>::iterator i;
    for (i = m_orderRecordRepOMSList.begin(); i != m_orderRecordRepOMSList.end(); ++i) {
        if (*i) {
            RepOMSRecOrderIn = (*i);   //*i 使用*运算符获取遍历容器中所指的元素;
            if ( 1== RepOMSRecOrderIn->status.toInt() || ( 2 == RepOMSRecOrderIn->status.toInt() && 0 == RepOMSRecOrderIn->reqResult)
                 || 3 == RepOMSRecOrderIn->status.toInt() || ( 4 == RepOMSRecOrderIn->status.toInt() && 0 == RepOMSRecOrderIn->reqResult)  ) {
                findFlag = true;
                break;
            } else {
                findFlag = false;
            }
        } else {
            QLOG_INFO()<<QString("[<<<<----_ReportOMSRecordOrderInfo   *i Is Null, ListCount:%1 ---->>>>>]").arg( m_orderRecordRepOMSList.count() );
        }

    }

    // 为了避免下面执行POST请求超时期间, 同时其他订单入机汇报状态添加到此队列中时尝试加锁失败,导致汇报结果丢消息
    if ( !findFlag  ||  !RepOMSRecOrderIn ) {
        //上面的汇报OMS订单入机状态的汇报列表 遍历循环后：如果出现  RepOMSRecOrderIn == NULL;不能从List容器的头部移除已汇报成功结果
        //【注意: 筛除 ①订单已经成功入机订单  ②入机失败且汇报OMS成功的订单】;
        return ;
    }

    QLOG_INFO()<<QString("[<<<<----_ReportOMSRecordOrderInfo  m_orderRecordRepOMSList size:%1, findFlag:%2 ---->>>>>]").arg( m_orderRecordRepOMSList.size() ).arg(findFlag?1:0);

    //准备https请求,准备向OMS汇报订单的入机情况;
    if(m_reportOMSRecordOrderSocket==NULL)
        m_reportOMSRecordOrderSocket =new BillSocket(this);

    QString error;
    QString url;
    QString callBackUrl;
    bool result;
    QJsonObject sendJson;
    QJsonObject recvJson;
    m_reportOMSRecordOrderSocket->SetSslConfig();
    //组装POST请求数据;
    sendJson.insert("orderNo", RepOMSRecOrderIn->orderNo);
    sendJson.insert("channel", RepOMSRecOrderIn->channel);
    sendJson.insert("type", RepOMSRecOrderIn->type);
    sendJson.insert("status", RepOMSRecOrderIn->status);
    sendJson.insert("opUser", RepOMSRecOrderIn->opUser);
    sendJson.insert("recordDate",  RepOMSRecOrderIn->recordDate);
    sendJson.insert("storeId",  RepOMSRecOrderIn->storeId);
    sendJson.insert("remark",  RepOMSRecOrderIn->remark);
    sendJson.insert("checkNo",  RepOMSRecOrderIn->checkNo);
    sendJson.insert("failCode",  RepOMSRecOrderIn->failCode);
    sendJson.insert(JSON_IP_ADDRESS, m_ipAddress);
    sendJson.insert(JSON_POS_WORKS_NUM, m_posWorkstationNum);
    sendJson.insert(JSON_POS_HOST_NAME, m_posHostName);
    sendJson.insert(JSON_POS_MAC_ADDRESS, m_posMacAddress);
    sendJson.insert(JSON_POS_PLUGIN_VERSION,  RepOMSRecOrderIn->pluginVersion);
    sendJson.insert(JSON_TCP_DEVICE_TYPE , "posPlugin");
    sendJson.insert(JSON_POS_BACKUP_PC, m_backupPosFlag);
    sendJson.insert(JSON_LOGIN_WITH_CONTAINS_ORDER_DETAIL, true);

    QLOG_INFO() << QString("[<<<<---_ReportOMSRecordOrderInfo:Begin--->>>>][requestData:%1]")<<sendJson;
    // 查找到 orderObject point 后，查找到 callBackUrl ;
    if ( m_FmOrdersMap.value( RepOMSRecOrderIn->orderNo ) ) {
        callBackUrl =  m_FmOrdersMap.value( RepOMSRecOrderIn->orderNo )->callBackUrl;
    }

    if ( callBackUrl.length() ) {
        url = callBackUrl + "/pos/" + ConfigManger::GetInstance().GetInterfaceName(INI_INTERFACE_REPORTOMSRECORDORDER);
    } else {
        url = ConfigManger::GetInstance().GetLoginServerUrl() + ConfigManger::GetInstance().GetInterfaceName(INI_INTERFACE_REPORTOMSRECORDORDER);
    }

    m_reportOMSRecordOrderSocket->SetUrl( QUrl( url ) );
    QLOG_INFO()<<QString("[<<<<---Report OMS Record Order Entry POS Info--->>>>][requestUrl:]") << url;

    result = m_reportOMSRecordOrderSocket->PostRequest(sendJson, recvJson, error);
    QLOG_INFO() << QString("[<<<<---Report OMS Record Order Entry POS Info Finish--->>>>][result:%1][msg:%2][orderId:%3]")
                   .arg(result).arg(error).arg( RepOMSRecOrderIn->orderNo )<<recvJson;

    if(!result) {
        emit setNetStatus(QString::fromLocal8Bit("<font color='#ff0000'>网络不稳定,正在重试</font>"));
    } else {
        // 再次加锁 操作汇报列表中指针对象;
        btryLock = m_RepOMSRecordOrderMutex.tryLock(VALUE_TRYLOCKNETTIMEOUT);
        if ( !btryLock ) {     //加锁失败后，直接return;
            QLOG_INFO()<<"[<<<<----_ReportOMSRecordOrderInfo After Execute Post Request  tryLock Failed, Can't Do Nothing ---->>>>>]";
            return ;
        }

        emit setNetStatus(QString::fromLocal8Bit("正常"));
        if(JSON_STATUSCODE_OK != recvJson[JSON_ERRCODE].toInt()) {
            QString error = recvJson[JSON_ERRMSG].toString();
            QLOG_ERROR()<< QString("[<<<<---Report OMS Record Order Entry POS Info Error--->>>>][msg->%1]").arg(error);
            RepOMSRecOrderIn->requestRetryErrorCount++;
            if ( RepOMSRecOrderIn->requestRetryErrorCount > 5 ) {
                QLOG_INFO()<< QString("[<<<<---Report OMS Order Entry POS Failed, And Retry Count > 5, OrderId:%1--->>>>][msg->%2]").arg(RepOMSRecOrderIn->orderNo).arg(RepOMSRecOrderIn->remark);
                m_orderRecordRepOMSList.removeOne( RepOMSRecOrderIn );
                delete  RepOMSRecOrderIn;
                RepOMSRecOrderIn = NULL;
            } else {
                m_orderRecordRepOMSList.removeOne( RepOMSRecOrderIn );
                m_orderRecordRepOMSList.append( RepOMSRecOrderIn );
            }

        } else {
            //解析汇报存储POS数据库状态成功;
            if ( 1 == RepOMSRecOrderIn->status.toInt() || 3 == RepOMSRecOrderIn->status.toInt() ) {
                //只有订单成功入机的订单，才能将此订单从 List容器中移除;否则必须保留在此容器中 避免重复多次向OMS汇报;
                QLOG_INFO()<< QString("[<<<<---Report OMS Order Entry POS/Storage Pos DB Successful, Remove OrderId:%1--->>>>][msg->%2]").arg(RepOMSRecOrderIn->orderNo).arg(RepOMSRecOrderIn->remark);
                m_orderRecordRepOMSList.removeOne( RepOMSRecOrderIn );
                delete  RepOMSRecOrderIn;
                RepOMSRecOrderIn = NULL;
            } else {
                //订单入机失败的订单，不能从 List容器中移除;否则 同笔订单的入机异常情况，会出现多次 或一直向oms回报的情况;
                RepOMSRecOrderIn->reqResult=1;
                RepOMSRecOrderIn->requestRetryErrorCount = 0;
                QLOG_INFO()<< QString("[<<<<---Report OMS Order Entry POS Successful,Reserve OrderId:%1--->>>>][msg->%2]").arg(RepOMSRecOrderIn->orderNo).arg(RepOMSRecOrderIn->remark);
            }
        }

        m_RepOMSRecordOrderMutex.unlock();
    }

}


void FlowControl::_PresistOrderInputPosSuccessRecord() {
    if ( m_presistInputPosSuccessRecdList.isEmpty() )
        return ;

    // m_presistInputPosSuccessRecdList 操作简单，两个入口，一个出口，无需加锁;
    OrderObject::PresistInputPosSuccessRecord* preInputPosSuccRecd = m_presistInputPosSuccessRecdList.first();
    if ( !preInputPosSuccRecd ) {
        // 指针 null，需要移除队列;
        m_presistInputPosSuccessRecdList.removeFirst();
        QLOG_ERROR()<<QString("[<<<<----_PresistOrderInputPosSuccessRecord  List First Pointer Is Null, Left ListSize=%1 After Remove---->>>>>]")
                      .arg( m_presistInputPosSuccessRecdList.size() );
    } else {
        // 持久化本地数据库后，移除队列首个对象;
        bool result = SimProcOrderDB::getInstance().presistOrderInputPosSuccessRecord( preInputPosSuccRecd->orderNo, preInputPosSuccRecd );
        // 同步后 -> 无论成功还是失败 都移除持久化队列 和 释放内存空间;
        QString orderId = preInputPosSuccRecd->orderNo;
        m_presistInputPosSuccessRecdList.removeFirst();
        delete preInputPosSuccRecd;
        preInputPosSuccRecd = NULL;
        QLOG_INFO()<<QString("[<<<<----_PresistOrderInputPosSuccessRecord  OrderId: %1 Left ListSize = %2, PresistRet = %3 ---->>>>>]")
                     .arg(orderId).arg( m_presistInputPosSuccessRecdList.size() ).arg( result?1:0 );
    }

}


void FlowControl::_AddOrUpdateReportOmsList(const QString &orderId,  const QString &channel,  const QString &repType, const QString &status, const QString &chkNum,
                                            const QString &error, const QString &errorCode) {

    bool repReportLockRet = m_RepOMSRecordOrderMutex.tryLock(VALUE_TRYLOCKNETTIMEOUT);
    if (repReportLockRet) {

        RepOMSRecordOrderInfo* repOMSRecordOrder = NULL;

        if (!m_orderRecordRepOMSList.isEmpty()) {
            QList<RepOMSRecordOrderInfo*>::iterator i;
            for (i = m_orderRecordRepOMSList.begin(); i != m_orderRecordRepOMSList.end(); ++i) {
                repOMSRecordOrder = (*i);   //*i 使用*运算符获取遍历容器中所指的元素;
                if (orderId == repOMSRecordOrder->orderNo) {
                    break;
                } else {
                    repOMSRecordOrder = NULL;
                }
            }
        }

        if (!repOMSRecordOrder){
            repOMSRecordOrder = new RepOMSRecordOrderInfo();
            repOMSRecordOrder->reqResult = 0;
            repOMSRecordOrder->requestRetryErrorCount = 0;
        } else {
            if ( error == repOMSRecordOrder->remark && repType == repOMSRecordOrder->type && 1== repOMSRecordOrder->reqResult ) {
                m_orderRecordRepOMSList.removeOne(repOMSRecordOrder);
            } else {
                m_orderRecordRepOMSList.removeOne(repOMSRecordOrder);
                repOMSRecordOrder->reqResult=0;
            }
        }

        repOMSRecordOrder->orderNo = orderId;
        repOMSRecordOrder->channel = channel;
        repOMSRecordOrder->type = repType;
        repOMSRecordOrder->status = status;
        repOMSRecordOrder->opUser = m_cashierName;
        repOMSRecordOrder->recordDate = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
        repOMSRecordOrder->storeId = m_storeId;
        repOMSRecordOrder->remark = error;
        repOMSRecordOrder->failCode = errorCode;
        repOMSRecordOrder->checkNo =  chkNum;
        repOMSRecordOrder->pluginVersion =  APP_VERSION;
        QLOG_INFO()<<QString::fromLocal8Bit("[<<<<---FlowControl::_AddOrUpdateReportOmsList:m_orderRecordRepOMSList.append() orderId:%1 error:%2--->>>>]").arg(orderId).arg(error);
        m_orderRecordRepOMSList.append(repOMSRecordOrder);
        m_RepOMSRecordOrderMutex.unlock();
        // 后期可能对汇报入机存储情况要求更加严格, 就需要对内存待汇报记录进行 持久化记录: 只持久化成功的记录;
    } else {
        QLOG_INFO()<<QString::fromLocal8Bit("[<<<<---FlowControl::_AddOrUpdateReportOmsList: tryLock failed  orderId:%1 error:%2 --->>>>]").arg(orderId).arg(error);
    }

}


void FlowControl::_AddInputPosSuccessPresistList( const QString &orderId, const QString &channel, const QString &reqType, const QString &status, const QString &chkNum,
                                                  const QString &errorMsg, const QString& errorCode ) {

    OrderObject::PresistInputPosSuccessRecord* inputPosSuccessRecd = new OrderObject::PresistInputPosSuccessRecord();
    if ( !inputPosSuccessRecd ) {
        QLOG_ERROR()<< QString("[<<<<---_AddInputPosSuccessPresistList: New PresistInputPosSuccessRecord Memory Failed orderId:%1, Presist*List.size(): %2 --->>>>]")
                       .arg( orderId ).arg( m_presistInputPosSuccessRecdList.size() );
    } else {
        inputPosSuccessRecd->orderNo = orderId;
        inputPosSuccessRecd->channel = channel;
        inputPosSuccessRecd->type = reqType;
        inputPosSuccessRecd->status = status;
        inputPosSuccessRecd->opUser = m_cashierName;
        inputPosSuccessRecd->recordDate = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
        inputPosSuccessRecd->storeId = m_storeId;
        inputPosSuccessRecd->remark = errorMsg;
        inputPosSuccessRecd->failCode = errorCode;
        inputPosSuccessRecd->checkNo =  chkNum;
        inputPosSuccessRecd->posPluginVersion =  APP_VERSION;
        inputPosSuccessRecd->ipAddress = m_ipAddress;
        inputPosSuccessRecd->decouplePosNo = m_posWorkstationNum;
        inputPosSuccessRecd->posHostName = m_posHostName;
        inputPosSuccessRecd->posMacAddress = m_posMacAddress;
        inputPosSuccessRecd->deviceType = "posPlugin";
        m_presistInputPosSuccessRecdList.append(inputPosSuccessRecd);
        QLOG_INFO()<< QString("[<<<<---_AddInputPosSuccessPresistList:  m_presistInputPosSuccessRecdList Append orderId:%1 Successed, Presist*List.size(): %2 --->>>>]")
                      .arg( orderId ).arg( m_presistInputPosSuccessRecdList.size() );
    }

}


QString FlowControl::_GetJsonStr(const QJsonObject &json)
{
    return QString(QJsonDocument(json).toJson(QJsonDocument::Compact)).replace("\"","");
}

QJsonObject FlowControl::_PackHttpReplyJson(const int status, const QString &msg, const QJsonObject &data,const int& iscontinue, const QString &orderId)
{
    QJsonObject rObj;
    rObj.insert("statusCode", status);
    rObj.insert("msg", msg);
    rObj.insert("iscontinue",iscontinue);
    rObj.insert("data", data);
    rObj.insert("orderId", orderId);
    return rObj;
}

void FlowControl::onPullDishes()
{
}

void FlowControl::onUpdDishes(QString channelCode, QMap<QString, int> dishes)
{
    Q_UNUSED(channelCode);
    Q_UNUSED(dishes);
}

void FlowControl::onUpdDishesForRef(QString channelCode, QMap<QString, int> dishes)
{
}

void FlowControl::onSetStoreOperatingStatus(const QString &channelCode, const QString &channelName, int business_status)
{
    //TODO
    Q_UNUSED(channelName);
    return ;
    QString error;
    bool result;
    QJsonObject sendJson;
    QJsonObject recvJson;

    sendJson = DataManger::GetInstance().GetOperatingStatusData(channelCode, business_status);
    emit showAlert(AlertForm::LOADING, QString::fromLocal8Bit("正在设置门店营业状态......"));
    QLOG_INFO() << QString("[<<<<---SetStoreOperatingStatus:Begin--->>>>][requestData:%1]")<<sendJson;
    m_pullDishesSocket->SetUrl(QUrl(ConfigManger::GetInstance().GetStoreServerUrl()+
                               ConfigManger::GetInstance().GetInterfaceName(INI_INTERFACE_UPDATESTATE)));
    qDebug()<<QUrl(ConfigManger::GetInstance().GetStoreServerUrl()+
                   ConfigManger::GetInstance().GetInterfaceName(INI_INTERFACE_UPDATESTATE));
    result = m_pullDishesSocket->PostRequest(sendJson, recvJson, error);
    QLOG_INFO() << QString("[<<<<---SetStoreOperatingStatus:Finish--->>>>][result:%1][msg:%2][recvData:%3]")
                   .arg(result).arg(error)<<recvJson;
    if(!result)
    {
        emit showAlert(AlertForm::MSGERROR, QString::fromLocal8Bit("设置门店营业状态失败![网络错误]"));
    }else
    {
        if(JSON_STATUSCODE_OK != recvJson[JSON_STATUSCODE].toInt())
        {
            emit showAlert(AlertForm::MSGERROR, QString::fromLocal8Bit("设置门店营业状态失败![%1]").arg(recvJson[JSON_MESSAGE].toString()));
        }else
        {
            emit hideAlert();
            emit setStoreOperatingStatusFinsh(channelCode);
        }
    }
}


void FlowControl::onSendSelfCheck()
{
    if(!m_bLoginResult)
    {
        emit showAlert(AlertForm::MSGERROR, QString::fromLocal8Bit("门店未登录"));
        return;
    }
    QString error;
    QString url;
    bool result;
    QJsonObject sendJson;
    QJsonObject recvJson;
    sendJson = DataManger::GetInstance().GetSelfCheckReqData();

    if(ConfigManger::GetInstance().GetOrderSslConfig())
    {
        m_procOrderSocket->SetSslConfig();
        QLOG_INFO()<<"load ssl";
    } else {
        QLOG_INFO()<<"load not ssl";
    }

    if ( m_serviceCallBackUrl.length() && m_bCreateSelfCheckOrderError ) {
        url = m_serviceCallBackUrl + "/order/"+ "pos/create/checkOrder";
    } else {
        url = ConfigManger::GetInstance().GetOrderServerUrl()+ "pos/create/checkOrder";
    }

    QLOG_INFO() << QString("[<<<<---FlowControl::onSendSelfCheck Begin--->>>>][ requestUrl:%1 ,  requestData:] ").arg(url) << sendJson;
    m_procOrderSocket->SetUrl(QUrl(url));
    result = m_procOrderSocket->PostRequest(sendJson, recvJson, error);
    QLOG_INFO() << QString("[<<<<---Get onSendSelfCheck:Finish--->>>>][result:%1][msg:%2]  [recvData:] ").arg(result).arg(error)<<recvJson;

    if(!result) {
        emit showAlert(AlertForm::MSGERROR, QString::fromLocal8Bit("发送自测请求失败![网络错误]"));
        m_bCreateSelfCheckOrderError ? m_bCreateSelfCheckOrderError = false : m_bCreateSelfCheckOrderError = true; // 一次失败一次切换主备地址;
    } else {
        if(JSON_STATUSCODE_OK != recvJson[JSON_ERRCODE].toInt()) {
            result = false;
            m_bCreateSelfCheckOrderError ? m_bCreateSelfCheckOrderError = false : m_bCreateSelfCheckOrderError = true; // 一次失败一次切换主备地址;
            emit showAlert(AlertForm::MSGERROR, QString::fromLocal8Bit("发送自测请求失败![%1]").arg(recvJson[JSON_MESSAGE].toString()));
        } else {
            emit showAlert(AlertForm::SUCCESS, QString::fromLocal8Bit("发送自测请求成功"));
            m_bCreateSelfCheckOrderError = false;
           // Test Modify Time
           //emit showAlert(AlertForm::WARNNING, QString::fromLocal8Bit("用户修改 MOP 预约时间;订单尾号:  12345;"
           //                                                             "    订单号:  9876543210012345678;    新预约时间:  18:00;    原预约时间:  17:30"));
        }
    }
}



void FlowControl::onDailyReport()
{
    if(!m_bLoginResult)
    {
        emit showAlert(AlertForm::MSGERROR, QString::fromLocal8Bit("门店未登录"));
        return;
    }
    QString error;
    bool result;
    QJsonObject sendJson;
    QJsonObject recvJson;
    QString m_business=QDateTime::currentDateTime().toString("yyyyMMdd");

    sendJson = DataManger::GetInstance().GetDayReportData(m_business);

    emit showAlert(AlertForm::LOADING, QString::fromLocal8Bit("正在通信......"));

    QLOG_INFO() << QString("[<<<<---Get DailyReport:Begin--->>>>][requestData:%1]")<<sendJson;
    result = m_procOrderSocket->PostRequest(sendJson, recvJson, error);
    QLOG_INFO() << QString("[<<<<---Get DailyReport:Finish--->>>>][result:%1][msg:%2][recvData:%3]")
                   .arg(result).arg(error)<<recvJson;
    if(!result)
    {
        emit showAlert(AlertForm::MSGERROR, QString::fromLocal8Bit("获取入账日结失败![网络错误]"));
    }else
    {
        if(JSON_STATUSCODE_OK != recvJson[JSON_STATUSCODE].toInt())
        {
            result = false;
            emit showAlert(AlertForm::MSGERROR, QString::fromLocal8Bit("获取入账日结失败![%1]").arg(recvJson[JSON_MESSAGE].toString()));
        }else
        {
            recvJson.insert(JSON_STORENAME,m_storeName);
            recvJson.insert(JSON_POSNO,m_posId);
            recvJson.insert(JSON_STOREID,m_storeId);
            recvJson.insert(JSON_USERID,m_cashierId);
            recvJson.insert(JSON_USERNAME,m_cashierName);
            recvJson.insert(JSON_BUSINESSDATE,m_business);
            emit hideAlert();
            emit showDailyReportData(recvJson);
        }
    }
}

void FlowControl::onTriggerFlowContrlAlert(AlertForm::Type alterType, const QString& msg) {
    QLOG_INFO() << QString("[<<<<-FlowControl::onTriggerFlowContrlAlert alterType:%1 ,alterMsg:%2 -->>>>]")
                   .arg(alterType).arg(msg);

    emit FlowControl::GetInstance().showAlert(alterType, msg);
}


void FlowControl::_CrondClearExpireOrder()
{
    //QDateTime currentDateTime= QDateTime::currentDateTime();  //--按秒数来验证ok--
    QDate currentDate= QDate::currentDate();
    //QLOG_INFO()<<QString::fromLocal8Bit("[<<<<---_CrondClearExpireOrder: 清理内存中订单数据的清理日期：%1 --->>>>]").arg(currentDateTime.toString("yyyy-MM-dd hh:mm:ss")); //--按秒数来验证OK--
    QLOG_INFO()<<QString::fromLocal8Bit("[<<<<---_CrondClearExpireOrder: 清理内存中订单数据的清理日期：%1 --->>>>]").arg(currentDate.toString("yyyy-MM-dd"));
    OrderObject *order=NULL;
    foreach (order, m_FmOrdersMap.values()) {

        QDate createDate = QDate::fromString( (order->createTime).mid(0,10),"yyyy-MM-dd");
        // 如果是预约单 则需以预约日期为准，实现过期订单清理条件;
        if ( 7 == order->orderType || 11 == order->orderType ) {
            createDate = QDate::fromString( (order->expectDate).mid(0,10),"yyyy-MM-dd");
        }

        //QLOG_INFO()<<QString("[<<<<---_CrondClearExpireOrder-> order->createTime Or expectDate : %1--->>>>]").arg(order->createTime); //--按秒数来验证ok--
        QLOG_INFO()<<QString("[<<<<---_CrondClearExpireOrder-> order  createDate Or expectDate: %1--->>>>]").arg(createDate.toString("yyyy-MM-dd"));
        //qint64 seconds = createDateTime.secsTo(currentDateTime);  //--按秒数来验证ok--
        qint64 days = createDate.daysTo(currentDate);
        //QLOG_INFO()<<QString::fromLocal8Bit("[<<<<---_CrondClearExpireOrder: ClearExpireOrder: 相差多少秒:%1--->>>>]").arg(seconds); //--按秒数来验证ok--
        QLOG_INFO()<<QString::fromLocal8Bit("[<<<<---_CrondClearExpireOrder: ClearExpireOrder: 相差多少天:%1--->>>>]").arg(days);
        if(days>=1)
        {
            QLOG_INFO()<<QString("[<<<<---_CrondClearExpireOrder: ClearExpireOrder: Emit Signal:Clear Order  orderID:%1--->>>>]").arg(order->id);
            emit clearorder(order->id,order->orderStatus);
            m_FmOrdersMap.value(order->id)->deleteLater();
            m_FmOrdersMap.remove(order->id);
            // 任何情况情况下都不能清理 Simphony获取的有效队列【除非已经被simphony处理过的数据】;目前已经在POS 触发的Action1:_ResponseSimReqFristOrderData 中做数据清理了
        }
    }

    // 清理汇报入机结果的列表;
    if ( !m_orderRecordRepOMSList.isEmpty() ) {
        bool btryLock = m_RepOMSRecordOrderMutex.tryLock(VALUE_TRYLOCKMEMTIMEOUT);
        if ( !btryLock ) {     //加锁失败后，直接return;
            QLOG_INFO()<<"[<<<<----FlowControl::_CrondClearExpireOrder m_RepOMSRecordOrderMutex tryLock Failed ---->>>>>]";
        } else {
            RepOMSRecordOrderInfo* RepOMSRecOrderIn = NULL;
            foreach ( RepOMSRecOrderIn, m_orderRecordRepOMSList ) {
                if ( RepOMSRecOrderIn ) {
                    QDate recordDate = QDate::fromString( (RepOMSRecOrderIn->recordDate ).mid(0,10),"yyyy-MM-dd");
                    qint64 recordDays = recordDate.daysTo(currentDate);
                    QLOG_INFO()<<QString::fromLocal8Bit("[<<<<---_CrondClearExpireOrder: ClearExpireRecordOrderInfo: 相差多少天:%1--->>>>]").arg(recordDays);
                    if ( recordDays >= 1 ) {
                        m_orderRecordRepOMSList.removeOne( RepOMSRecOrderIn );
                        delete RepOMSRecOrderIn;
                        RepOMSRecOrderIn = NULL;
                    }
                } else {
                    m_orderRecordRepOMSList.removeOne( RepOMSRecOrderIn );
                }
            }

            m_RepOMSRecordOrderMutex.unlock();
        }
    }

    // 清理门店通告消息列表; 和 门店通告消息界面展示
//    if ( !m_noticeObjList.isEmpty() ) {
//        bool btryLock = m_RepOMSRecordOrderMutex.tryLock(VALUE_TRYLOCKNETTIMEOUT);
//        if ( !btryLock ) {     //加锁失败后，直接return;
//            QLOG_INFO()<<"[<<<<----FlowControl::_ReportOMSRecordOrderInfo tryLock Failed ---->>>>>]";
//        } else {
//            RepOMSRecordOrderInfo* RepOMSRecOrderIn = NULL;
//            foreach ( RepOMSRecOrderIn, m_orderRecordRepOMSList ) {
//                if ( RepOMSRecOrderIn ) {
//                    QDate recordDate = QDate::fromString( (RepOMSRecOrderIn->recordDate ).mid(0,10),"yyyy-MM-dd");
//                    qint64 recordDays = recordDate.daysTo(currentDate);
//                    QLOG_INFO()<<QString::fromLocal8Bit("[<<<<---_CrondClearExpireOrder: ClearExpireRecordOrderInfo: 相差多少天:%1--->>>>]").arg(recordDays);
//                    if ( recordDays >= 1 ) {
//                        m_orderRecordRepOMSList.removeOne( RepOMSRecOrderIn );
//                        delete RepOMSRecOrderIn;
//                        RepOMSRecOrderIn = NULL;
//                    }
//                } else {
//                    m_orderRecordRepOMSList.removeOne( RepOMSRecOrderIn );
//                }
//            }
//            m_RepOMSRecordOrderMutex.unlock();
//        }
//    }

    SimProcOrderDB::getInstance().deleteOrderRecord(QDate::currentDate().addDays(-45).toString("yyyyMMdd"));
    PrintSumBillPosDB::getInstance().deleteSumBillRecord( QDate::currentDate().addDays(-7).toString("yyyy-MM-dd") );
    PrintCupStickPosDB::getInstance().deleteProductRecord(QDate::currentDate().addDays(-7).toString("yyyy-MM-dd"));
    PrintOrderPromotionDB::getInstance().deletePromotionRecord(QDate::currentDate().addDays(-7).toString("yyyy-MM-dd"));
    PrintMsgQueueDB::getInstance().deletePrintMsgRecord(QDate::currentDate().addDays(-3).toString("yyyy-MM-dd"));
    SaveNoticeMsgDB::getInstance().deleteNoticeMsgRecord(QDate::currentDate().addDays(-7).toString("yyyy-MM-dd"));

}


bool FlowControl::_ResponseHttpRequest(const QJsonObject &content,QJsonObject &data, QString& error)
{
    bool result = true;
    /****校验Http请求参数有效性: 校验参数->actionId不存在****/
    if(!content.contains("actionId")) {
        error =QString::fromLocal8Bit("解析Http请求参数:参数中没有actionId");
        result = false;
    }/****校验Http请求参数有效性: 校验参数->actionId存在****/
    else {
        int actionId;
        if(content["actionId"].isString()){
            actionId=content["actionId"].toString().toInt();
        } else {
            actionId=content["actionId"].toInt();
        }
        QLOG_INFO()<<QString::fromLocal8Bit("[<<<<---Response Http请求[action:%1] --->>>>]").arg(actionId);
        /****校验请求参数actionId的具体数值:****/
        switch (actionId) {
        case 1://simphony拉取订单
            result=_ResponseSimphony01Request(content,data,error);
            break;
        case 2://simphony确认接单
            result=true;
            break;
        case 3://simphony取消接单
            result=true;
            break;
        case 4://simphony汇报小票号信息回复
            result=_ResponseSimphony04Request(content,data,error);
            break;
        case 5://simphony更新订单数据到POS本地数据库以便POS打印小票及汇总单信息 回复
            result=_ResponseSimphony05Request(content,data,error);
            break;
        case 6://simphony汇报SIM录单异常 回复
            result=_ResponseSimphony06Request(content,data,error);
            break;
        case 11://FM OMS推送订单
            result=_ResponseOMS11Request(content,data,error);
            break;
        case 12://推送门店营业状态
            result=_ResponseOMS12Request(content,data,error);
            break;
        case 13: //推送 宣导提醒消息
            result=_ResponseOMS13Request(content,data,error);
            break;
        case 14: //推送 订单入机查询状态;
            result=_ResponseOMS14Request(content,data,error);
            break;
        case 21://盒马生鲜 推送订单
            result=_ResponseHM21Request(content,data,error);
            break;
        default:
            error =QString::fromLocal8Bit("解析Http请求actionId值不在规定的接口文档内");
            result = false;
            break;
        }
    }
    return result;
}


bool FlowControl::_ResponseSimphony01Request(const QJsonObject &content, QJsonObject &data, QString &error)
{
    QLOG_INFO()<<__FUNCTION__;
    bool result=true;

    // 优先判断此POS机是否是备机
    if ( m_backupPosFlag ) {
        error = QString("Pos Is Backup PC, No Need Simulator Input Simphony, HostName: %1 simValidOrdersList.size: %2").arg( m_posHostName ).arg( m_simValidOrdersList.size() );
        m_simValidOrdersList.isEmpty() ? 1 : m_simValidOrdersList.removeFirst();
        QLOG_INFO()<< error;
        return result;
    }

    if(!m_bLoginResult&&content.contains("storeId")) {
        result=_ResponseSimReqTryLogin(content,error);
    }

    if( result ){
        result=_ResponseSimReqFristOrderData(content, data,error,content["orderId"].toString());
    } else {
        result = false;
        if ( error.isEmpty() ) {
            error=QString::fromLocal8Bit("Response Simphony_Script Request 01: Login Store Failed");
        }
    }
    return result;
}


bool FlowControl::_ResponseSimphony04Request(const QJsonObject &content, QJsonObject &data, QString &error)
{
    QLOG_INFO()<<__FUNCTION__;
    Q_UNUSED(content);
    Q_UNUSED(data);
    Q_UNUSED(error);
    /*
    bool result=true;
    m_clickPosCount = 0;
    if(m_bLoginResult&&content.contains("orderId")){
        QString orderId=content["orderId"].toString();
        QString posCheckNo=content["posSaleId"].toString();

        if(posCheckNo.isEmpty()) {
            posCheckNo=m_orderIdToPosCheckNoMap.value(orderId);
        }
        if(!posCheckNo.isEmpty()&&!orderId.isEmpty()) {
            if(!m_orderIdToPosCheckNoMap.contains(orderId)) {
                QLOG_INFO()<<QString::fromLocal8Bit("[<<<<---Simphony_Script请求[ACTION:04:汇报小票号] 订单:%1 , 汇报小票号:%2:--->>>>]").arg(orderId,posCheckNo);
                m_orderIdToPosCheckNoMap.insert(orderId,posCheckNo);
            }

            OrderObject* order_p =  m_FmOrdersMap.value(orderId);
            if (!order_p) {
                QLOG_ERROR()<<QString::fromLocal8Bit("[<<<<---%1订单并不存在m_FmOrdersMap[键值对]中;m_FmOrdersMap.size()=%2--->>>>]").arg(orderId).arg(m_FmOrdersMap.size());
                error=QString::fromLocal8Bit("Request Action04: %1 Delivery Order Don't Exist In m_FmOrdersMap[key-map] m_FmOrdersMap.size()=%2").arg(orderId).arg(m_FmOrdersMap.size());
                emit doUnLockFloatFrom();
                if(m_bFloatFromLockSt){
                    m_bFloatFromLockSt = false; //更新悬浮框的锁定状态 =false;
                }
                return false;
            }

            if(m_simValidOrdersList.contains(orderId)) {
                // 汇报POS小票号是否成功;
                // 更新 POS本地数据库的销售/退货 标识表中的真实小票号: 用于界面显示(不入机订单需要变更显示逻辑);
                bool bRetReportCheckNo = false;
                bool checkProductValidRet = false; // 无效订单就不会进行入机,故无需担心此类情况;

                if ( order_p->pushOrderType==1 ) {
                    // SimProcOrderDB::getInstance().updatePushOrderStatus(orderId,1);  //淘汰了;
                    bRetReportCheckNo = SimProcOrderDB::getInstance().updatePushOrderStatusAndChkNum( orderId, 1, posCheckNo );
                    order_p->isPush= true;
                    order_p->forwardPosStatus = 1;
                } else if ( 0 == order_p->pushOrderType ) {
                    // SimProcOrderDB::getInstance().updateRefundOrderStatus(orderId,1);  //淘汰了;
                    bRetReportCheckNo = SimProcOrderDB::getInstance().updateRefundOrderStatusAndChkNum( orderId, 1, posCheckNo );
                    order_p->isCancle = true;
                    order_p->negativePosStatus = 1;
                }

                // 更新 POS本地数据库的商品表 真实小票号: 解耦后,仍然有能正确打印订单数据的关联关系  begin: -----
                bool retSyncOrderProduct = true;  //默认是同步POS商品数据成功; 目前只有 businessType: 20:WSG-杯贴祝福;  30: 拼团;
                if ( PrintCupStickPosDB::getInstance().isOrderProductExist(order_p) ) {
                    if (m_hurryPrintSum)  {
                        QLOG_INFO()<<QString("[<<<<---_ResponseSimphony04Request::orderId:%1 Is HurryPrintSum, No Need Update PrintCupStickPosDB CheckNo, Because Recive Order Had Storage, Can't Change CheckNo--->>>>]").arg(orderId);
                    } else {
                        if (!PrintCupStickPosDB::getInstance().updateOrderProductCheckNum(order_p, posCheckNo) )
                            retSyncOrderProduct = false;
                    }
                } else {
                    if (m_hurryPrintSum)  {
                        QLOG_INFO()<<QString("[<<<<---_ResponseSimphony04Request::orderId:%1 Is HurryPrintSum, No Need Insert PrintCupStickPosDB, Because Recive Order Had Storage, Can't Change CheckNo--->>>>]").arg(orderId);
                    } else {  
                        if (!PrintCupStickPosDB::getInstance().insertOrderProduct(order_p, posCheckNo, checkProductValidRet) )
                            retSyncOrderProduct = false;
                    }
                }
                // 更新 POS本地数据库的商品表 真实小票号；end: -------

                // 更新 POS本地数据库的促销优惠表-真实小票号: 解耦后,仍然有能正确打印订单数据的关联关系:；begin: -------
                bool retSyncOrderPromotion = true;  //默认是同步POS促销优惠成功; 目前只有 businessType: 20:WSG-杯贴祝福;  30: 拼团;
                if ( PrintOrderPromotionDB::getInstance().isOrderPromotionExist(order_p) ) {
                    if (m_hurryPrintSum)  {
                        QLOG_INFO()<<QString("[<<<<---_ResponseSimphony04Request::orderId:%1 Is HurryPrintSum, No Need Update PrintOrderPromotionDB CheckNo, Because Recive Order Had Storage, Can't Change CheckNo--->>>>]").arg(orderId);
                    } else {
                        if (!PrintOrderPromotionDB::getInstance().updateOrderPromotionCheckNum(order_p, posCheckNo) )
                            retSyncOrderPromotion = false;
                    }
                } else {
                    if (m_hurryPrintSum)  {
                        QLOG_INFO()<<QString("[<<<<---_ResponseSimphony04Request::orderId:%1 Is HurryPrintSum, No Need Insert PrintOrderPromotionDB, Because Recive Order Had Storage, Can't Change CheckNo--->>>>]").arg(orderId);
                    } else {
                        if (!PrintOrderPromotionDB::getInstance().insertOrderPromotion(order_p, posCheckNo) )
                            retSyncOrderPromotion = false;
                    }

                }
                // 更新 POS本地数据库的促销优惠数据是否成功；end:-------

                bool insertPrtMsgRet = false;
                if ( bRetReportCheckNo && retSyncOrderProduct && retSyncOrderPromotion) {
                    // 汇报小票号成功后，需要向打印消息队列中插入一条记录;
                    // 同时也需要更新汇总小票表中的 reserve1 字段值 ( 将在函数 insertOrderPrtMsg(*,*,*) 内部处理 );
                    // 向打印队列表中添加 入机成功订单记录 已经在入机前，本地数据存储阶段就已经存储完成，目前入机后将无需插入与更新;
                    if ( PrintMsgQueueDB::getInstance().isOrderPrtMsgExist(order_p) ) {
                        insertPrtMsgRet = true;
                    } else {
                        if ( order_p->skipPrint ) {  // 补单场景: 跳过打印;
                            insertPrtMsgRet = true;
                            QLOG_INFO()<< QString("[<<<<---_ResponseSimphony04Request: orderId: %1 Is SkipPrint, No Need Insert PrintMsgQueueDB, SkipPrint: %2--->>>>]").arg(order_p->id).arg(order_p->skipPrint ?1:0);
                        } else if ( m_hurryPrintSum )  {
                            QLOG_INFO()<<QString("[<<<<---_ResponseSimphony04Request: orderId:%1 Is HurryPrintSum, No Need Insert PrintMsgQueueDB, Because Recive Order Had Storage, Can't Change CheckNo--->>>>]").arg(orderId);
                            insertPrtMsgRet = true;
                        } else {
                            insertPrtMsgRet = PrintMsgQueueDB::getInstance().insertOrderPrtMsg(order_p, posCheckNo);
                        }
                    } 
                    QLOG_INFO()<<QString("[<<<<---PrintMsgQueueDB::insertOrderPrtMsg orderId:%1  chk_num:%2  ret:%3--->>>>]").arg(orderId).arg(posCheckNo).arg(insertPrtMsgRet?1:0);
                }

                //入机成功更新插件上POS小票号显示;
                order_p->dataBasePosOrderCheckNo = posCheckNo;
                // 解析 汇报POS小票号是否成功:bRetReportCheckNo:true->成功 -------
                QJsonObject rObj, cObj;
                rObj.insert("fm_cmd", "");
                rObj.insert("fm_ver", "1.0");
                cObj.insert("pay_id", "002");
                cObj.insert("pay_str", QString::fromLocal8Bit("非码外卖"));
                cObj.insert("paid_trans_id",orderId);
                if(bRetReportCheckNo && retSyncOrderProduct && retSyncOrderPromotion && insertPrtMsgRet ){  //已经汇报完小票号，因此必须从 m_simValidOrdersList 列表中移除;
                    cObj.insert("reqResult",1); // 汇报POS小票号结果：[1:成功；0:失败]
                    rObj.insert("pay_id", cObj);
                    data = rObj;
                    m_OrderEntryMutex.lock();
                    m_simValidOrdersList.removeOne(orderId);
                    m_OrderEntryMutex.unlock();
                }
                // 解析 汇报POS小票号是否成功:bRetReportCheckNo:true->成功 -------
                else{
                    result=false;
                    error=QString::fromLocal8Bit("Report POS Check Num Failed");
                    // 即使汇报小票号失败，同样也必须将此订单从 m_simValidOrdersList 列表中移除:【汇报小票号的前提条件就是:POS已经结单完成】；
                    cObj.insert("reqResult",0); // 汇报POS小票号结果：[1:成功；0:失败]
                    rObj.insert("pay_id", cObj);
                    data = rObj;
                    m_OrderEntryMutex.lock();
                    m_simValidOrdersList.removeOne(orderId);
                    m_OrderEntryMutex.unlock();
                }

                //新增业务逻辑,针对汇报小票号成功的订单需要;添加到 向OMS汇报入机情况的队列中;            
                QString requestType  = (6 == order_p->orderStatus)?QString::fromLocal8Bit("6"):QString::fromLocal8Bit("3");
                QString msgDesc = QString::fromLocal8Bit("入机成功");
                QLOG_INFO()<<QString::fromLocal8Bit("[<<<<---FlowControl::_ResponseSimphony04Request:m_orderRecordRepOMSList.append() orderId:%1 orderStatus:%2 checkNo:%3--->>>>]")
                             .arg(orderId).arg(requestType).arg(posCheckNo);
                _AddOrUpdateReportOmsList(orderId, order_p->channel,requestType, QString("1"), posCheckNo, msgDesc, QString(""));
                _AddInputPosSuccessPresistList(orderId, order_p->channel, requestType, QString("1"), posCheckNo, msgDesc );
            }

        } else {
            result=false;
            error=QString::fromLocal8Bit("Request Action04: Delivery OrderId Or Check Num Can't Empty");
        }
    } else {
        result=false;
        error=QString::fromLocal8Bit("Request Action04: Request Pragram Error");
    }
    emit doUnLockFloatFrom(); //-------解锁悬浮框-------//
    if(m_bFloatFromLockSt){
        m_bFloatFromLockSt = false; //更新悬浮框的锁定状态 =false;
    }
    // 存在Action4说明POS有反应, 故停止 Block告警定时器;
    if ( m_blockInputPosWarnningTimer->isActive() ) {
        m_blockInputPosWarnningTimer->stop();
    }
    //为了避免压测插件时,高频的加锁悬浮框 与 高频点击POS机;所以将 及时点击POS机右下角按钮放到上次录单成功后再触发下一次录单事件；
    _ClickOMSAssignArea();
    return result;
    */
    return true;
}


bool FlowControl::_ResponseSimphony05Request(const QJsonObject &content, QJsonObject &data, QString &error)
{
    QLOG_INFO()<<__FUNCTION__;
    Q_UNUSED(content);
    Q_UNUSED(data);
    Q_UNUSED(error);
     /*
    bool result=true;
    m_clickPosCount = 0;
    if(m_bLoginResult&&content.contains("orderId")){
        QString orderId=content["orderId"].toString();
        QString posCheckNo=content["posSaleId"].toString();
        QString posCheckTime=content["posCheckTime"].toString();

        if(posCheckNo.isEmpty())
        {
            error=QString::fromLocal8Bit("Request Action05: %1 Delivery Order: Check Num Can't Empty").arg(orderId);
            return false;
        }
        if(!posCheckNo.isEmpty()&&!orderId.isEmpty())
        {
            OrderObject* order_p =  m_FmOrdersMap.value(orderId);
            if (!order_p){
                QLOG_ERROR()<<QString::fromLocal8Bit("[<<<<---%1订单并不存在m_FmOrdersMap[键值对]中;m_FmOrdersMap.size()=%2--->>>>]").arg(orderId).arg(m_FmOrdersMap.size());
                error=QString::fromLocal8Bit("Request Action05: %1 Delivery Order Don't Exist In m_FmOrdersMap[key-map] m_FmOrdersMap.size()=%2").arg(orderId).arg(m_FmOrdersMap.size());
                return false;
            }
            //更新小票号;
            if(!m_orderIdToPosCheckNoMap.contains(orderId))
            {
                QLOG_INFO()<<QString::fromLocal8Bit("[<<<<---Simphony_Script请求[ACTION:05: 更新POS本地数据库打印信息] %1订单已经成功推送给simphony:--->>>>]").arg(orderId);
                m_orderIdToPosCheckNoMap.insert(orderId,posCheckNo);
            } else {
                if(OrderObject::Refunded==order_p->orderStatus){
                    if(posCheckNo != m_orderIdToPosCheckNoMap.value(order_p->id)){
                        m_orderIdToPosCheckNoMap.remove(order_p->id);
                        m_orderIdToPosCheckNoMap.insert(orderId,posCheckNo);
                    }
                }
            }

            if(m_simValidOrdersList.contains(orderId))
            {
                //--------  更新 POS本地数据库的打印信息是否成功；begin: --------//
                int retSyncOrderSum = 0;  //默认是同步POS本地数据失败;
                //-------- 解耦前后汇总表中都会保存2条记录 --------//
                if (PrintSumBillPosDB::getInstance().isOrderSumBillExist(order_p) ) {
                    if ( m_hurryPrintSum ) {
                        // 着急打印的情况，接受到订单时就已经插入了,且无需更新小票号;
                        QLOG_INFO()<<QString("[<<<<---_ResponseSimphony05Request::orderId:%1 Is HurryPrintSum, No Need Update SumInfo, Because Recive Order Had Storage, Can't Change CheckNo--->>>>]").arg(orderId);
                        retSyncOrderSum = 1;
                    } else {
                        if ( PrintSumBillPosDB::getInstance().updateSumBillCknoAndCktime(order_p,posCheckNo,posCheckTime) ) {
                            retSyncOrderSum = 1;
                        }
                    }

                } //--------  POS本地数据库不存在 orderId &&posCheckNo --------//
                else{
                    QLOG_ERROR()<<QString::fromLocal8Bit("[<<<<---Simphony[ACTION:05:] OrderId:%1 Not Exist In tb_msr_customer_info --->>>>]").arg(orderId);
                    if ( PrintSumBillPosDB::getInstance().insertOrderSumBill(order_p, posCheckNo, posCheckTime) ){
                      retSyncOrderSum = 1;
                    }
                }
                //-------- 更新 POS本地数据库的打印信息是否成功；end: --------/

                //-------- 解析 同步更新POS本地数据库是否成功:retSyncOrderPrintInfo:1->成功 --------/
                if(retSyncOrderSum){
                    // 还没汇报完小票号，因此还不能从 m_simValidOrdersList 列表中移除;
                    QJsonObject rObj, cObj;
                    rObj.insert("fm_cmd", "");
                    rObj.insert("fm_ver", "1.0");
                    cObj.insert("pay_id", "002");
                    cObj.insert("pay_str", QString::fromLocal8Bit("FmTakeout"));
                    cObj.insert("reqResult",retSyncOrderSum); //同步POS本地数据库汇总表：[1:同步成功；0:同步失败]
                    cObj.insert("paid_trans_id",orderId);
                    rObj.insert("pay_id", cObj);
                    data = rObj;
                }  //-------- 解析 同步更新POS本地数据库是否成功:retSyncOrderSum:0->失败--------//
                else{
                    result=false;
                    error=QString::fromLocal8Bit("Request Action05:Sync POS Local DataBase-Summary Failed");
                }
            } else {
                m_OrderEntryMutex.lock();
                m_simValidOrdersList.append(orderId);
                m_OrderEntryMutex.unlock();
            }
        } else {
            result=false;
            error=QString::fromLocal8Bit("Request Action05: Delivery OrderId And Check Num Can't Empty");
        }
    } else {
        result=false;
        error=QString::fromLocal8Bit("Request Action05: Pragram Error");
    }

    // 存在Action5说明POS有反应, 故停止 Block告警定时器;
    if ( m_blockInputPosWarnningTimer->isActive() ) {
        m_blockInputPosWarnningTimer->stop();
    }

    return result;
    */
    return true;
}


bool FlowControl::_ResponseSimphony06Request(const QJsonObject &content, QJsonObject &data, QString &error)
{
    QLOG_INFO()<<__FUNCTION__;
    Q_UNUSED(content);
    Q_UNUSED(data);
    Q_UNUSED(error);
    /*
    bool result=true;
    m_clickPosCount = 0;
    if(m_bLoginResult&&content.contains("orderId")){
        QString orderId=content["orderId"].toString();
        QString simExceptCode=content["simExceptCode"].toString();
        QString simExceptMsg=content["simExceptMsg"].toString();

        if(!simExceptCode.isEmpty()&&!orderId.isEmpty()) {
            //---------------------- 新增一种优化case: 门店店员正在操作POS,从而阻塞插件程序录外卖订单,此时必须解锁悬浮框，从而减少Simphony队列中first出现OMS退单的请求; begin ----------------------//
            //此时的订单号时固定给的620620 [action:6,simExceptCode=20]
            if( 20 == simExceptCode.toInt() ){
                error=QString::fromLocal8Bit("Request Action06: Partner is serving Offline Customer ");
                QLOG_INFO()<<QString::fromLocal8Bit("[<<<<---_ResponseSimphony06Request::%1--->>>>>]").arg(error);
                emit doUnLockFloatFrom();
                if(m_bFloatFromLockSt){
                    m_bFloatFromLockSt = false; //更新悬浮框的锁定状态 =false;
                }
                //为了避免压测插件时,高频的加锁悬浮框 与 高频点击POS机; _ClickOMSAssignArea();
                //由于上面出现了异常;不能也不需要及时点击POS机按钮触发下一次的录单事件
                QJsonObject rObj, cObj;
                rObj.insert("fm_cmd", "");
                rObj.insert("fm_ver", "1.0");
                cObj.insert("pay_id", "002");
                cObj.insert("pay_str", QString::fromLocal8Bit("FmTakeout"));
                cObj.insert("reqResult",1); //响应SIM汇报异常结果：[1:处理异常成功；0:处理异常失败]
                cObj.insert("paid_trans_id",orderId);
                rObj.insert("pay_id", cObj);
                data = rObj;

                //新增业务逻辑,针对汇报异常的订单需要;添加到 向OMS汇报入机情况的队列中;
                if(!m_simValidOrdersList.empty()){
                    QString tmpOrderId = m_simValidOrdersList.first();
                    QString requestType = "0";
                    QString tmpChannel = "";
                    OrderObject* order_temp =  m_FmOrdersMap.value(tmpOrderId);
                    if (!order_temp){
                        QLOG_INFO()<<QString::fromLocal8Bit("[<<<<---%1订单并不存在m_FmOrdersMap[键值对]中;m_FmOrdersMap.size()=%2--->>>>]").arg(orderId).arg(m_FmOrdersMap.size());
                    }else{
                        requestType = order_temp->orderStatus==6?QString::fromLocal8Bit("6"):QString::fromLocal8Bit("3");
                        tmpChannel = order_temp->channel;
                    }
                    QLOG_INFO()<<QString::fromLocal8Bit("[<<<<---FlowControl::_ResponseSimphony06Request:m_orderRecordRepOMSList.append() orderId:%1 simExceptMsg:%2--->>>>]").arg(orderId).arg(simExceptMsg);
                    _AddOrUpdateReportOmsList(tmpOrderId,  tmpChannel, requestType, QString("2"), QString(""), simExceptMsg, QString("") );
                }
                return true;
            }
            //---------------------- 新增一种优化case: 门店店员正在操作POS,从而阻塞插件程序录外卖订单,此时必须解锁悬浮框，从而减少Simphony队列中first出现OMS退单的请求; end  ----------------------//

            // 存在Action6说明POS有反应 && 且 不是POS存在CheckNum的情况, 故停止 Block告警定时器;
            if ( m_blockInputPosWarnningTimer->isActive() ) {
                m_blockInputPosWarnningTimer->stop();
            }

            //---------------------- 根据订单编号找到 非码订单Map容器中订单的详细信息; begin ----------------------//
            OrderObject* order_p =  m_FmOrdersMap.value(orderId);
            if (!order_p) {
                QLOG_ERROR()<<QString::fromLocal8Bit("[<<<<---%1订单并不存在m_FmOrdersMap[键值对]中;m_FmOrdersMap.size()=%2--->>>>]").arg(orderId).arg(m_FmOrdersMap.size());
                error=QString::fromLocal8Bit("Request Action06: %1 Delivery Order Don't Exist In m_FmOrdersMap[key-map]; m_FmOrdersMap.size()=%2").arg(orderId).arg(m_FmOrdersMap.size());
                emit doUnLockFloatFrom();//---------------------- 解锁悬浮框 ----------------------//
                if(m_bFloatFromLockSt){
                    m_bFloatFromLockSt = false; //更新悬浮框的锁定状态 =false;
                }
                return false;
            }
            //---------------------- 根据订单编号找到 非码订单Map容器中订单的详细信息; end ----------------------//

            // 判断SIM是否存在错误码: 0:会在汇报完小票号发送此错误码的请求给插件以便做一些特别事件: 解锁悬浮框；1:SIM录单出异常:转移订单tab至异常单、请求sim的有效订单列表、解锁悬浮框:
            int retProcSimExceptCode =0;
            // 特殊处理录单异常的详细case:
            if(simExceptCode.toInt()) {
                QLOG_INFO()<<QString::fromLocal8Bit("[<<<<---_ResponseSimphony06Request:: OrderId:%1,simExceptCode:%2 录单异常--->>>>>]").arg(orderId).arg(simExceptCode.toInt());
                //异常错误码10的case:: 常见的正常业务场景下的异常 这些异常不应该阻塞订单的多次尝试录入，如果没有尝试多次录入的机会将会出现POS机少录订单不出小票的case:更多的详细请参考Simphony脚本中错误码为10情况，
                if(10 == simExceptCode.toInt()){
                    error=QString::fromLocal8Bit("Request Action06 :simExceptCode==10: Catch Sim Refund Auth Exception And Report Success");
                    retProcSimExceptCode = 1;
                    result=true;
                }
                //异常错误码非10的case::
                //simExceptCode ==5: POS录单过程中 同步本地数据库小票信息出现异常时触发多次录单的异常必须捕捉,此时必须解锁悬浮框;[action:6,simExceptCode=5]
                //simExceptCode ==1: POS录单过程中 POS机中没有相应的SKU 的异常必须捕捉,此时必须解锁悬浮框;[action:6,simExceptCode=1]
                else {
                    if(m_simValidOrdersList.contains(orderId)) {
                                        m_OrderEntryMutex.lock();
                                        m_simValidOrdersList.removeOne(orderId);
                                        m_OrderEntryMutex.unlock();
                                        int oldStatus = order_p->orderStatus;
                                        if(6 == oldStatus || OrderObject::SimExceptRefund == order_p->orderStatus){
                                            order_p->orderStatus = OrderObject::SimExceptRefund;
                                        }else{
                                            order_p->orderStatus = OrderObject::SimExceptSale;
                                        }
                                        emit changeOrderStatus(order_p,oldStatus);
                                        error=QString::fromLocal8Bit("Request Action06: Catch Sim Recorded Order Exception And Report Success");
                                        retProcSimExceptCode = 1;
                                        result=true;
                                    }
                }
            } else { //录单正常//
                QLOG_INFO()<<QString::fromLocal8Bit("[<<<<---_ResponseSimphony06Request:: OrderId:%1 录单成功--->>>>>]").arg(orderId);
                error=QString::fromLocal8Bit("Request Action06: Catch Sim Recorded Order Exception And Report Success");
                retProcSimExceptCode = 1;
                result=true;
            }
            //---------------------- 组装响应SIM录单异常响应 ----------------------//
            QJsonObject rObj, cObj;
            rObj.insert("fm_cmd", "");
            rObj.insert("fm_ver", "1.0");
            cObj.insert("pay_id", "002");
            cObj.insert("pay_str", QString::fromLocal8Bit("FmTakeout"));
            cObj.insert("reqResult",retProcSimExceptCode); //响应SIM汇报异常结果：[1:处理异常成功；0:处理异常失败]
            cObj.insert("paid_trans_id",orderId);
            rObj.insert("pay_id", cObj);
            data = rObj;
            //---------------------- 新增业务逻辑,针对汇报异常的订单需要;添加到 向OMS汇报入机情况的队列中;  Begin ----------------------
            QString requestType = order_p->orderStatus==6?QString::fromLocal8Bit("6"):QString::fromLocal8Bit("3");
            QLOG_INFO()<<QString::fromLocal8Bit("[<<<<---FlowControl::_ResponseSimphony06Request:m_orderRecordRepOMSList.append() orderId:%1 simExceptMsg:%2--->>>>]").arg(orderId).arg(simExceptMsg);
            _AddOrUpdateReportOmsList(orderId,  order_p->channel, requestType, QString("2"), QString(""), simExceptMsg, QString("") );
            //---------------------- 新增业务逻辑,针对汇报异常的订单需要;添加到 向OMS汇报入机情况的队列中;  end ----------------------
        } else {
            result=false;
            error=QString::fromLocal8Bit("Request Action06: Delivery OrderId And Sim Exception ErrorCode Can't Empty");
        }
    } else {
        result=false;
        error=QString::fromLocal8Bit("Request Action06: Request Pragram Error");
    }
    //-------------------------解锁悬浮框-------------------------
    emit doUnLockFloatFrom();
    if(m_bFloatFromLockSt){
        m_bFloatFromLockSt = false; //更新悬浮框的锁定状态 =false;
    }
    //为了避免压测插件时,高频的加锁悬浮框 与 高频点击POS机; _ClickOMSAssignArea();
    //由于上面出现了异常;不能也不需要及时点击POS机按钮触发下一次的录单事件;
    return result;
    */
    return true;
}


bool FlowControl::_ResponseOMS11Request(const QJsonObject &content, QJsonObject &data, QString &error)
{
    Q_UNUSED(data);
    QLOG_INFO()<<__FUNCTION__;
    bool result = true;
    QString omsPushOrderId;
    m_clickPosCount = 0;

    if ( !m_bLoginResult ) {
        error = QString::fromLocal8Bit("FMOMS未登录");
        if ( content[JSON_CALL_BACK_URL].toString().length() ) {
            m_serviceCallBackUrl = content[JSON_CALL_BACK_URL].toString();  // https://delposserviceapi.starbucks.net/backstage  : 域名/backstage
        }
        return false;
    } else {
        if ( content[JSON_ORDER_ID].toString().isEmpty() ) {
            error =QString::fromLocal8Bit("订单号不能为空");
            return false;
        } else {
            omsPushOrderId = content[JSON_ORDER_ID].toString();
            QString omsPushOrderChannel = content[JSON_CHANNEL].toString();
            QString omsCallBackUrl= content[JSON_CALL_BACK_URL].toString();  // https://delposserviceapi.starbucks.net/backstage  : 域名/backstage
            bool omsSkipPrint = false;
            content[JSON_SKIP_PRINT].toBool() ? omsSkipPrint = true : 0;  // skipPrint
            int omsPushOrderStatus = content[JSON_STATUS].toInt();

            QJsonObject omsPushOptions;
            if ( content.contains(JSON_PUSH_OPTIONS) ) {
                omsPushOptions  = content[JSON_PUSH_OPTIONS].toObject();  // KEY -> options
            }

            if ( omsCallBackUrl.length() ) {
                m_serviceCallBackUrl = omsCallBackUrl;
            }

            // New Mode: Upstream Push Order Contain Order Detail Data;
            QJsonObject omsPushOrderDetail;
            if ( content.contains(JSON_PUSH_ORDER_DETAIL) ) {
                omsPushOrderDetail = content[JSON_PUSH_ORDER_DETAIL].toObject();

                if ( omsPushOrderDetail.contains(JSON_ID) ) {
                    // 如果O2O-fullfillment Push Order Contain Order Detail Data, Call _TryAddOrderQueueAnalysis(...), Then Direct Return;
                    QLOG_INFO() << QString("[<<<<---_ResponseOMS11Request: OrderId: %1 Use New Mode->Push&Contains Order Detail Data --->>>>]").arg(omsPushOrderId);
                    error = QString("Recv OrderId: %1 Data Success").arg(omsPushOrderId);
                    QLOG_INFO() << QString("[<<<<---_ResponseOMS11Request: Order Detail Data --->>>>]") << omsPushOrderDetail;
                    return _TryAddOrderQueueAnalysis(omsPushOrderId, omsPushOrderDetail, omsCallBackUrl, omsPushOptions);
                } else {
                    QLOG_ERROR() << QString("[<<<<---_ResponseOMS11Request: OrderId: %1 Contains Key:[orderDetail], But Not Contain More Data--->>>>]").arg(omsPushOrderId);
                    QLOG_ERROR() << QString("[<<<<---_ResponseOMS11Request: OrderId: %1 Will Continue Old Mode->Push&Pull, Get Order Detail--->>>>]").arg(omsPushOrderId);
                }
            }

            if ( 6 == omsPushOrderStatus ) {
                // 避免小概率事件：①重复录单  ②单边账;
                bool bRetDelayGetRefundDetailMutex =m_delayGetRefundDetailMutex.tryLock(VALUE_TRYLOCKMEMTIMEOUT);
                if( !bRetDelayGetRefundDetailMutex ) {
                    QLOG_ERROR() << QString("[<<<<---_ResponseOMS11Request:orderId: %1  m_delayGetRefundDetailMutex.tryLock  Failed --->>>>]").arg(omsPushOrderId);
                    error =QString::fromLocal8Bit("当前订单是退单，准备将其添加到 延迟获取退单详情队列时，加锁失败，请重新推送");
                    return false;
                }

                /***组装延迟拉单请求对象参数***/
                DelayPullOrderInfo* delayOrderPull_p = new DelayPullOrderInfo();
                if ( !delayOrderPull_p ) {
                    QLOG_ERROR() << QString("[<<<<---_ResponseOMS11Request:orderId: %1  New  DelayPullOrderInfo Failed --->>>>]").arg(omsPushOrderId);
                    error =QString::fromLocal8Bit("当前订单是退单，准备将其添加到 延迟获取退单详情队列时，New DelayPullOrderInfo 失败，请重新推送");
                    return false;
                }
                delayOrderPull_p->orderId=omsPushOrderId;
                delayOrderPull_p->channel=omsPushOrderChannel;
                delayOrderPull_p->callBackUrl = omsCallBackUrl;
                delayOrderPull_p->skipPrint = omsSkipPrint;
                delayOrderPull_p->pushOptions = omsPushOptions;
                m_delayGetRefundDetailList.append(delayOrderPull_p);
                QLOG_INFO()<<QString("[<<<<---_ResponseOMS11Request: orderId: %1 Append Success,  m_delayGetRefundDetailList size: %2  And FirstOne: %3 --->>>>>]")
                             .arg( omsPushOrderId ).arg( m_delayGetRefundDetailList.size() ).arg( m_delayGetRefundDetailList.isEmpty()? " " : m_delayGetRefundDetailList.first()->orderId );
                m_delayGetRefundDetailMutex.unlock();

            } else {
                // 接受到非码oms推过来的订单，进行向队列中进行添加；
                result =  _TryAddOrderPull( omsPushOrderId, omsPushOrderChannel, omsCallBackUrl, omsSkipPrint, omsPushOptions );
            }

        }

        if ( result ) {
            error = QString("Recv OrderId: %1 Data Success").arg(omsPushOrderId);
        } else {
            error = QString("Recv OrderId: %1 Data Failed").arg(omsPushOrderId);
        }
    }

    return result;
}


bool FlowControl::_ResponseOMS12Request(const QJsonObject &content, QJsonObject &data, QString &error)
{
    QLOG_INFO()<<__FUNCTION__;
    Q_UNUSED(data);
    //判断当前POS插件是否登录成功: 如果没有登录成功，尝试在次登录;
    bool result = true;
    if(!m_bLoginResult&&content.contains("storeId")) {
        result=_ResponseSimReqTryLogin(content,error);
    }
    //如果登录成功 or 插件正在尝试登录中:则return true 并返回相应的错误信息;
    if(result){
        if(!content["storeId"].toString().compare(m_storeId)) {
            QLOG_INFO()<<"FlowControl::_ResponseOMS12Request:"<<content;
            m_eleStoreStatus = content[JSON_ELESTORESTS].toInt();
            m_modStoreStatus = content[JSON_MODSTORESTS].toInt();
            m_mopStoreStatus = content[JSON_MOPSTORESTS].toInt();
            m_mtModStoreStatus = content[JSON_MTMODSTORESTS].toInt();
            m_curbsideStoreStatus = content[JSON_CURBSIDE_STORESTS].toInt();
            m_existNoAckNotice = SaveNoticeMsgDB::getInstance().existNoAckNotice() ? 1 : 0;
            QLOG_INFO()<<QString("[<<<<---FlowControl::_ResponseOMS12Request eleStoreStatus: %1, modStoreStatus: %2 , mopStoreStatus: %3 ,"
                                 " mtModStoreStatus: %4, curbsideStoreStatus:%5, existNoAckNotice:%6 --->>>>]").
                         arg(m_eleStoreStatus).arg(m_modStoreStatus).arg(m_mopStoreStatus).arg(m_mtModStoreStatus).arg(m_curbsideStoreStatus).arg(m_existNoAckNotice);

            emit doUpdateStoreStatus(m_eleStoreStatus, m_modStoreStatus, m_mopStoreStatus, m_mtModStoreStatus, m_curbsideStoreStatus, m_existNoAckNotice);

            error=QString("success");
            result = true;
        } else {
            error=QString::fromLocal8Bit("门店信息不匹配");
            result = false;
        }
    }
    return result;
}


bool FlowControl::_ResponseOMS13Request(const QJsonObject &content, QJsonObject &data, QString &error)
{
    QLOG_INFO()<<__FUNCTION__;
    Q_UNUSED(data);
    //判断当前POS插件是否登录成功: 如果没有登录成功，尝试在次登录;
    QLOG_INFO()<<"FlowControl::_ResponseOMS13Request:"<<content;

    bool result = true;
    if ( !m_bLoginResult && content.contains("storeId") ) {
        result = _ResponseSimReqTryLogin(content,error);
    }

    //无论插件是否登录成功: 插件接受到消息 则 return true 同时返回有意义的错误信息;
    NoticeObject* noticeObjPtr = new NoticeObject();
    if ( !noticeObjPtr ) {
        result = false;
        QLOG_ERROR()<<"FlowControl::_ResponseOMS13Request, New Memory Space Failed , Abandon This Notice Msg";
        error=QString::fromLocal8Bit("插件接受消息成功, 但插件分配内存失败, 需重试");
    } else {
        result = true;

        noticeObjPtr->title = content[JSON_NOTICE_TITLE].toString();
        noticeObjPtr->content = content[JSON_NOTICE_CONTENT].toString();
        noticeObjPtr->title = QString::fromUtf8( noticeObjPtr->title.toUtf8() );
        noticeObjPtr->content = QString::fromUtf8( noticeObjPtr->content.toUtf8() );
        noticeObjPtr->ackStatus = 0;
        QDateTime qdaTi = QDateTime::currentDateTimeUtc();
        noticeObjPtr->createDatetime  =  qdaTi.addSecs(60*60*8).toString("yyyy-MM-dd hh:mm:ss");

        // ①同步 Notice 到本地数据库,进行数据持久化; ②展示门店通告提醒;
        int  insertIdIndex = 0;
        SaveNoticeMsgDB::getInstance().insertNoticeMsg( noticeObjPtr, insertIdIndex );
        noticeObjPtr->id = insertIdIndex;
        m_noticeObjList.insert(0,noticeObjPtr);
        QLOG_INFO()<<QString("FlowControl::_ResponseOMS13Request, NoticeObjList Append Success, title: %1, noticeListSize: %2, firstTitle: %3")
                     .arg( noticeObjPtr->title ).arg( m_noticeObjList.size() ).arg( m_noticeObjList.first()->title );
        // 更新主框架 Notice List 和 悬浮框未读提示;
        emit changeNoticeStatus( noticeObjPtr );

        // m_existNoAckNotice =1 新通告消息,必须显示带确认通知;
        emit doUpdateStoreStatus(m_eleStoreStatus, m_modStoreStatus, m_mopStoreStatus, m_mtModStoreStatus, m_curbsideStoreStatus, 1);

        if ( !content["storeId"].toString().compare(m_storeId) ) {
            error=QString::fromLocal8Bit("插件接受消息成功, 插件目前登陆状态");
        } else {
            error=QString::fromLocal8Bit("插件接受消息成功, 但插件未登陆成功 或 门店号不匹配");
        }
        // 待完善, Plugin收到 门店通告消息 后,要想能够在oms侧进行统计，需要通过Plugin 向上游系统进汇报;
    }

    return result;
}


bool FlowControl::_ResponseOMS14Request(const QJsonObject& content, QJsonObject& data, QString& error)
{
    //无需检查插件是否登录成功, 直接从数据库读取数据;
    QLOG_INFO()<<"FlowControl::_ResponseOMS14Request:"<<content;
    bool result = false;

    if ( content[JSON_ORDER_ID].toString().isEmpty() ) {
        error =QString::fromLocal8Bit("订单号不能为空");
    } else {
        QString omsPushOrderId = content[JSON_ORDER_ID].toString();
        QJsonObject orderInputPosSuccessRecord;
        // 查询订单入机记录;
        result = SimProcOrderDB::getInstance().queryPresistInputPosSuccessRecord( omsPushOrderId, orderInputPosSuccessRecord )  ;
        if ( !result ) {
            QLOG_ERROR() << QString("[<<<<---_ResponseOMS14Request: orderId: %1 QueryOrderInputPosSuccessRecord Failed --->>>>]").arg( omsPushOrderId );
            error = QString("OrderId: %1, Query Pos DataBase Failed, Or Not Find Input Pos Successed Record ...").arg( omsPushOrderId );
        } else {
            // Http Response Had Printer Result, Not Need Output Agagin;
            QLOG_INFO() << QString("[<<<<---_ResponseOMS14Request: orderId: %1 QueryOrderInputPosSuccessRecord Success --->>>>]").arg( omsPushOrderId );
            error = QString("OrderId: %1, Query Pos DataBase Input Pos Record Successed...").arg( omsPushOrderId );
            data = orderInputPosSuccessRecord;
        }
    }

    if ( result ) {
        error = QString("success");
    } else {
        error = QString("failed");
    }
    return result;
}



bool FlowControl::_ResponseHM21Request(const QJsonObject &content, QJsonObject &data, QString &error)
{
    QLOG_INFO()<<__FUNCTION__;
    //判断当前POS插件是否登录成功: 如果没有登录成功，尝试在次登录;
    Q_UNUSED(data);
    bool result=true;
    m_clickPosCount = 0;
    if(!m_bLoginResult&&content.contains("storeId")) {
        result=_ResponseSimReqTryLogin(content,error);
    }
    //如果登录成功 or 插件正在尝试登录中:则return true 并返回相应的错误信息;
    if(result){
        //<1>:更新 OrderObject 中的数据;
        //增加筛选条件,判断当前POS系统录单的订单是否还没录单完成:如果该订单录单没有完成,不返回100,务必让服务的等待;
        if(content[JSON_ORDER_ID].toString().isEmpty()) {
            error =QString::fromLocal8Bit("订单号不能为空");
            return false;
        } else {
            if(!m_simValidOrdersList.isEmpty()){
                QString simValidOrderListFirstOne = m_simValidOrdersList.first();
                //缩小锁住订单的条件范围: 服务端推单给插件程序且插件程序拒绝本次订单状态发生变化的请求
                if(content[JSON_ORDER_ID].toString() == simValidOrderListFirstOne && m_bFloatFromLockSt){
                    error =QString::fromLocal8Bit("当前订单正在录POS系统，请耐心等待");
                    return false;
                }
            }
        }

        QJsonObject hmOrderJson =  content["orderDetail"].toObject();
        QLOG_INFO()<<"FlowControl::_ResponseHM21Request:"<<hmOrderJson;
        if(!hmOrderJson.isEmpty()){
            result = true;
            error=QString::fromLocal8Bit("_ResponseHM21Request Action:21:accept HM Order Success");
             _OrderAnalysis(hmOrderJson);
        }else{
            result = false;
            error=QString::fromLocal8Bit("_ResponseHM21Request Action:21:accept HM Order empty");
        }
        //<2>:向simphony整合订单数据:准备向POS录单【_OrderAnalysis(hmOrderJson);函数会触发simphony录单动作(退单的情况也会存入队列中)】
    } else {
        result = false;
        if(error.isEmpty()) {
            error=QString::fromLocal8Bit("Response Simphony_Script Request 01: Login Store Failed");
        }
    }
    return result;
}


bool FlowControl::_ResponseSimReqTryLogin(const QJsonObject &content,QString &error)
{
    QLOG_INFO()<<__FUNCTION__;
    // 插件点击 POS右下角触发的 登录请求;
    m_storeId=content["storeId"].toString();   //未登陆成功前 storeId;
    m_subStoreId =  ConfigManger::GetInstance().GetSubStoreId();
    // 跳过 校验配置 子门店 与 母门店的前三位是否一致；增加安全保护机制 (同时实现参数可控 校验功能 );
    if ( ConfigManger::GetInstance().GetSubStoreSkipVerify() ) {
        m_storeId = m_subStoreId.length()?m_subStoreId:m_storeId;
    } else {
        m_storeId  = (m_subStoreId.length() && m_subStoreId.left(3) == m_storeId.left(3) )?m_subStoreId:m_storeId;
    }
    QLOG_INFO()<<QString::fromLocal8Bit("[<<<<---_ResponseSimReqTryLogin: m_storeId=%1 ,  m_subStoreId=%2 --->>>>>]").arg(m_storeId).arg(m_subStoreId);

    if ( m_backupPosFlag ) {
        m_posId= BACKUP_POS_UNIQUE_ID;
    } else {
        m_posId= MASTER_POS_UNIQUE_ID;
    }
    m_posWorkstationNum=content["businessDay"].toString();   // 折中方案,使用营业时间透传 POS WorkStation Num;
    m_cashierId=content["operatorId"].toString();
    m_cashierName=content["operatorName"].toString();
    emit setCashierInfo(m_cashierName); //POS上收银员切换账号后,插件上右下角的收银员信息也及时更新;
    // 登录
    if(m_bFirstRecvInfo) {
        error = QString::fromLocal8Bit("FMOMS Plug-in Program Try Login On");
        emit doLogin();
    }
    return true;
}


bool FlowControl::_ResponseSimReqFristOrderData(const QJsonObject &content, QJsonObject &data, QString &error, const QString &orderId)
{
    QLOG_INFO()<<__FUNCTION__<<error<<orderId;
    // m_deviceNo=content["posId"].toString();  //将来用来扩展新字段值
    if ( m_backupPosFlag ) {
        m_posId= BACKUP_POS_UNIQUE_ID;
    } else {
        m_posId= MASTER_POS_UNIQUE_ID;
    }
    m_posWorkstationNum=content["businessDay"].toString();  // 折中方案,使用营业时间透传 POS WorkStation Num;
    m_cashierId=content["operatorId"].toString();
    m_cashierName=content["operatorName"].toString();
    emit setCashierInfo(m_cashierName); //POS上收银员切换账号后,插件上右下角的收银员信息也及时更新;

    QLOG_INFO()<<QString::fromLocal8Bit("[<<<<---Simphony_Script请求[ACTION:01: 获取订单数据] 开始获取 OrderId:%1 给simphony:--->>>>>]").arg(orderId);
    bool result=true;
    if(!m_bLoginResult) {
        error = QString::fromLocal8Bit("FMOMS Plug-in Program Not Login On");
        return false;
    }

    if(m_simValidOrdersList.isEmpty()) {
        error = QString::fromLocal8Bit("No New Delivery Order Need To Pull.");
        return  true;
    } else {
        error.clear();
        QString orderId=m_simValidOrdersList.first();
        QLOG_INFO()<<QString::fromLocal8Bit("[<<<<---Simphony_Script请求[ACTION:01:]FMOMS已登录，且有订单待拉取:orderId:%1--->>>>>]").arg(orderId);

        OrderObject* orderObject = m_FmOrdersMap.value(orderId);
        if(!orderObject){
            error = QString::fromLocal8Bit("Delivery Order had been clear by _CrondClearExpireOrder.");
            m_OrderEntryMutex.lock();
            m_simValidOrdersList.removeFirst();
            m_OrderEntryMutex.unlock();
            return  false;
        }

        if (orderObject->decouplePosVersion >= 20 ) {
            error = QString::fromLocal8Bit("Delivery Order Decouple Pos Version: %1 , No Need Record Pos").arg(orderObject->decouplePosVersion);
            m_OrderEntryMutex.lock();
            m_simValidOrdersList.removeFirst();
            m_OrderEntryMutex.unlock();
            return  false;
        }

        if(MAXPUTTIMES==orderObject->pushOrderTimes) {
            orderObject->pushOrderTimes = 0;
        } else {
            orderObject->pushOrderTimes=orderObject->pushOrderTimes+1;
        }
        if(MAXPUTTIMES==orderObject->orsPushOrderTimes) {
            orderObject->orsPushOrderTimes = 0;
        } else {
            orderObject->orsPushOrderTimes=orderObject->orsPushOrderTimes+1;
        }
        //防止POS出现多次录单：退货单(销售单应该不会)；
        bool retGetDbOrderAllFlag = SimProcOrderDB::getInstance().getDbOrderAllFlag(orderObject->id,orderObject->dataBaseIsOrderExistInt,orderObject->dataBaseIsPushInt,
        orderObject->dataBaseIsCancleInt,orderObject->dataBaseIsORSPushInt,orderObject->dataBaseIsORSCancleInt,orderObject->dataBasePosOrderCheckNo);

        if(!retGetDbOrderAllFlag ){
            QLOG_ERROR() << QString("[<<<<---FmTakeout _ResponseSimReqFristOrderData:orderObject->id:%1 SimProcOrderDB::getInstance().getDbOrderAllFlag Failed --->>>>]").arg(orderObject->id);
        }

        QLOG_INFO() << QString("[<<<<---FmTakeout _ResponseSimReqFristOrderData: orderObject->id:%1 ,dataBaseIsOrderExistInt:%2 ,dataBaseIsPushInt:%3 ,dataBaseIsCancleInt:%4 ,"
                               "dataBaseIsORSPushInt:%5 ,dataBaseIsORSCancleInt:%6 ,dataBasePosOrderCheckNo:%7--->>>>]")
        .arg(orderObject->id).arg(orderObject->dataBaseIsOrderExistInt).arg(orderObject->dataBaseIsPushInt).arg(orderObject->dataBaseIsCancleInt)
        .arg(orderObject->dataBaseIsORSPushInt).arg(orderObject->dataBaseIsORSCancleInt).arg(orderObject->dataBasePosOrderCheckNo);

        bool  bIsPushOrder = orderObject->dataBaseIsPushInt;
        bool  bIsRefundOrder = orderObject->dataBaseIsCancleInt;
        bool  bIsORSPushOrder = orderObject->dataBaseIsORSPushInt;
        bool  bIsORSCancleOrder = orderObject->dataBaseIsORSCancleInt;

        //避免：销售单,退货单 两个方向都已经入机完成订单重复入机【&& !orderObject->appointmentDayFlag || && orderObject->appointmentDayFlag】;
        // if(bIsPushOrder && bIsRefundOrder && !orderObject->appointmentDayFlag  || bIsORSPushOrder && bIsORSCancleOrder && orderObject->appointmentDayFlag )
        if( bIsPushOrder && bIsRefundOrder || bIsORSPushOrder && bIsORSCancleOrder || !retGetDbOrderAllFlag ) {
            QLOG_INFO()<<QString::fromLocal8Bit("[<<<<---Simphony_Script请求[ACTION:01:] bIsPushOrder: ;bIsRefundOrder: ;--->>>>>]")<<bIsPushOrder<<bIsRefundOrder;
            //error = QString::fromLocal8Bit("该订单已经被POS系统录入完成");
            error = QString::fromLocal8Bit("This Delivery Order Have Been Recorded In POS System Successfully");
            m_OrderEntryMutex.lock();
            m_simValidOrdersList.removeOne(orderObject->id);
            m_OrderEntryMutex.unlock();
            return true;
        }

        // 正向单不是最后一次录入必须结合订单入机类型，而退货是最后一次入机，故无需 额外条件组合判断;
        if( (orderObject->pushOrderType==1 || orderObject->orsPushOrderType==1) && (1==orderObject->forwardPosStatus) || (1==orderObject->negativePosStatus) ) {
            QLOG_INFO()<<QString::fromLocal8Bit("[<<<<---Simphony_Script请求[ACTION:01:] forwardPosStatus:  negativePosStatus: ;--->>>>>]")
                      <<orderObject->forwardPosStatus<<orderObject->negativePosStatus;
            error = QString::fromLocal8Bit("This Delivery Order Have Been Recorded In POS System Successfully");
            m_OrderEntryMutex.lock();
            m_simValidOrdersList.removeOne(orderObject->id);
            m_OrderEntryMutex.unlock();
            return true;
        }

        //检查Order Data Valid; 防止录入销售单时 接受到OMS推送取消订单请求且插件未锁屏时，列表录单请求被移除;
        if( m_simValidOrdersList.isEmpty() ) {
            error = QString::fromLocal8Bit("This Delivery Order:%1 Is Invalid, No Need Record  POS System").arg(orderObject->id);
            return true;
        }

        //检查: 录入销售单时未成功待排队,此时插件退单 并且订单数据已被退单数据更新，需要踢出待入机队列;
        if( 6 == orderObject->orderStatus && 0 == bIsPushOrder  ) {
            m_OrderEntryMutex.lock();
            m_simValidOrdersList.removeOne(orderObject->id);
            m_OrderEntryMutex.unlock();
            error = QString::fromLocal8Bit("This Delivery Order Had Refund: %1 Is Invalid, No Need Record  POS System").arg(orderObject->id);
            return true;
        }

        //录单时才触发隐藏 主窗口 + 锁定悬浮框;
        if(!m_bFloatFromLockSt){
            m_bFloatFromLockSt = true; //更新悬浮框的锁定状态=true;
        }
        emit doHideMainShowFloatFrom();
        // emit doLockFloatForm();

        QJsonObject rObj, cObj;
        if(orderObject->pushOrderType==1 || orderObject->orsPushOrderType==1) {
            rObj.insert("fm_cmd", "put_order");
        } else {
            rObj.insert("fm_cmd", "refund_order");
        }
        rObj.insert("fm_ver", "1.0");
        cObj.insert("pay_id", "002");
        cObj.insert("pay_str", QString::fromLocal8Bit("FmTakeout"));
        int tempServiceType = 0,  tempOrderPayType = 0,  tempSbkAppPayType=0;
        QString tempSbkAppPayValue="0";
        // 转换成星巴克规定的订单类型;
        //星巴克的订单类型：1:新订单; 2:预订单; 3:客诉单; 4:MOP自测订单; 5:预约订单; 7:当日预约单；8拼单(使用父级订单类型)
        // 客诉单 支付方式 由现金 变更为  OrderPayType=1;在Simphony扩展程序将其转换成 84:MOD + 非码订单:orderId 入机;
        if(3 == orderObject->getOrderType()) {
            tempOrderPayType = 1;
        }
        // MOP自测订单 在下方处理;星巴克-预约订单:在下方处理;
        // OMS提供的数据://订单渠道: 星巴克-MOD,百度外卖,饿了么APP,美团外卖,星巴克-MOP;
        // MOD渠道对应的业务逻辑 ;
        else if ( "MOD" == orderObject->channel ) {
            // platformSource:平台来源:1 app;  2 ele;  3 ors;  4 WeChat ;   5 口碑;
            tempOrderPayType = 84;
            //星巴克App端支付方式: 1:支付宝; 2:微信; 3:银联; 4:SVC卡; 5/7:MOP使用券或星星抵扣 0元支付; 8:IStore订单; 9:银联支付(=3);
            if(4 == orderObject->payWay){
                tempSbkAppPayType = 14 ;
                //svc卡支付时传交易流水号协定:
                if(OrderObject::Refunded == orderObject->orderStatus ||OrderObject::SimExceptRefund == orderObject->orderStatus){
                    tempSbkAppPayValue = orderObject->refundFmId.isEmpty()?QString("0"):orderObject->refundFmId;
                }else{
                    tempSbkAppPayValue = orderObject->payfmId;
                }
            }else if(1 == orderObject->payWay){
                tempSbkAppPayType = 78;
                tempSbkAppPayValue = (orderObject->thirdPartyBatch).length()?orderObject->thirdPartyBatch :QString("0");
            }else if(2 == orderObject->payWay){
                tempSbkAppPayType = 77;
                tempSbkAppPayValue = (orderObject->thirdPartyBatch).length()?orderObject->thirdPartyBatch :QString("0");
            //防止后期 MOD 使用 券 + 星星折扣 +（券&星星折扣）用户不用实际支付任何金额，需要采用0元支付方式结单;
            //插件传给Simphony扩展程序时支付方式=1;在Simphony扩展程序将其转换成 84:MOD + 非码订单:orderId 入机;
            }else if(5 == orderObject->payWay || 7 == orderObject->payWay){
                tempOrderPayType = 1;
            }else{
                tempSbkAppPayType = -1;
                tempSbkAppPayValue = "-1";
            }

        } else if ( "WSG-MOD" == orderObject->channel || "WSG-MOP" == orderObject->channel ) {
            // platformSource:平台来源:1 app;  2 ele;  3 ors;  4 WeChat;   5 口碑;
            tempOrderPayType = 84;
            tempSbkAppPayType = -1;
            tempSbkAppPayValue = "-1";

       }// MOP渠道对应的业务逻辑;
        else if ( "MOP" == orderObject->channel || "EC-MOP" == orderObject->channel || "EC_WECHAT_MOP" == orderObject->channel ) {

            tempOrderPayType = 84;
            //星巴克App端支付方式: 1:支付宝; 2:微信; 3:银联; 4:SVC卡; 5/7:MOP使用券或星星抵扣 0元支付; 8:IStore订单; 9:银联支付(=3);
            if ( 4 == orderObject->payWay ) {
                tempSbkAppPayType = 14 ;
                //svc卡支付时传交易流水号协定:
                if(OrderObject::Refunded == orderObject->orderStatus ||OrderObject::SimExceptRefund == orderObject->orderStatus){
                    tempSbkAppPayValue = orderObject->refundFmId.isEmpty()?QString("0"):orderObject->refundFmId;
                }else{
                    tempSbkAppPayValue = orderObject->payfmId;
                }
            }else if(1 == orderObject->payWay){
                tempSbkAppPayType = 78;
                tempSbkAppPayValue = (orderObject->thirdPartyBatch).length()?orderObject->thirdPartyBatch :QString("0");
            }else if(2 == orderObject->payWay){
                tempSbkAppPayType = 77;
                tempSbkAppPayValue = (orderObject->thirdPartyBatch).length()?orderObject->thirdPartyBatch :QString("0");
            //针对使用 券 + 星星折扣 +（券&星星折扣）用户不用实际支付任何金额，需要采用0元支付方式结单;
            //插件传给Simphony扩展程序时支付方式=1;在Simphony扩展程序将其转换成 84:MOD + 非码订单:orderId 入机;
            }else if(5 == orderObject->payWay || 7 == orderObject->payWay){
                tempOrderPayType = 1;
            }else{
                tempSbkAppPayType = -1;
                tempSbkAppPayValue = "-1";
            }

            //MOP最后判断 是否是 MOP自测订单;
            if(4== orderObject->getOrderType()) {
                tempOrderPayType = 1;
            }

        } else if ( "MT-MOD" == orderObject->channel ) {
            tempOrderPayType = 84;
            // tempSbkAppPayValue = orderObject->id;
            tempSbkAppPayType = 92;
            tempSbkAppPayValue = orderObject->thirdPartyOrderId;
        } else if ( "MT-MOP" == orderObject->channel ) {
            tempOrderPayType = 84;
            tempSbkAppPayType = 92;  // 待变更为 MT-MOP 支付 Tender;
            tempSbkAppPayValue = orderObject->thirdPartyOrderId;
        } else if ("ELE" == orderObject->channel) {
            tempOrderPayType = 83;
            tempSbkAppPayValue = orderObject->id;
        //星巴克-预约订单: 预约实物入机: 销售单订单类型:21; 退货单订单类型: 22;
        //为了配合服务端调整:兼容 预约退货 不区分 预约配送费 与 预约实物；必须重点注意退货时支付方式赋值;
        }else if("ORS" == orderObject->channel && orderObject->appointmentDayFlag ){
            // 端支付方式: 15纸质卷 16电子卷;需要循环商品列表中的券支付方式;
            // 星巴克-预约订单: 配送费入机: 销售单订单类型:23; 退货单订单类型: 24;
        }else if("ORS" == orderObject->channel && !orderObject->appointmentDayFlag ){
        }else{
            tempOrderPayType = 83;
            tempSbkAppPayValue = orderObject->id;
        }
        //如果是退单,更新订单的来源类型; 需要考虑 订单二次入机方式;
        //存在两种Case:正常退货单 && 【非预约日期(录配送费判断)/默认值是初始化0】; || 预约实物退货单 【&&预约实物送达日期 不支持此case】 || 预约退单:只能退配送费;
        // 预约如果出现退单，也只能退配送费和打包费[不存在退预约实物(券)]
        if (orderObject->pushOrderType==0) {
        }

        // 优先使用OMS传递的 globalServiceType 与 globalOrderType 值为准;
        if ( orderObject->globalServiceType ) {
                tempServiceType = orderObject->globalServiceType;
        }

        //需要重点注意订单对象的数据初始化问题;
        cObj.insert("orderOriginType", tempServiceType);
        cObj.insert("orderPayType", tempOrderPayType);
        cObj.insert("sbkAppPayType", tempSbkAppPayType);
        cObj.insert("sbkAppPayValue", tempSbkAppPayValue);
        cObj.insert("orderTransFlowNo", (orderObject->thirdPartyBatch).length()?orderObject->thirdPartyBatch:QString("0") ); //第三方交易流水号

        // 2020-10-14 筛选出能与Simphony 通信 可占用的字段; begin------->
        cObj.insert("packFree", 0);
        cObj.insert("packDiscount",0);
        cObj.insert("deliveryFree", 0);
        cObj.insert("deliveryDiscount", 0);
        cObj.insert("waybillId", (orderObject->waybillId).length()?orderObject->waybillId:QString("0") );
        // 2020-10-14 筛选出能与Simphony 通信的字段;   end------->

        //只有这个字段（dis_shop_fee）传给Simphony(代表平台优惠给POS系统),对应的字段是dis_shop_fee :平台优惠总额 只能通过 dis_shop_fee 字段传递给 POS;
        // 目前已经通过本地数据库表字段存储传递, 无需这样传递;
        //cObj.insert("dis_shop_fee", abs(orderObject->disPlateformFee)); // 商家承担优惠金额（实际传递的是: 平台优惠金额 orderObject->disPlateformFee）;
        // 目前设定 CommonFlag 为通用标志：对应Dll: discountFee  Simphony: globalCommonFlag 数字: 个位:标识***   十位标识*** ；百位标识***；千位标识***；万位***;
        int commonFlag = 0;
        //commonFlag = commonFlag + 31281;
        cObj.insert("dis_shop_fee", commonFlag);

        // 整单折扣在Simphony扩展程序中没有实际意义,目前使用此字段透传 插件的版本号信息;
        QString pluginVersion = APP_VERSION ;
        pluginVersion = pluginVersion.mid(4);
        cObj.insert("orderDiscount", pluginVersion.remove(QChar('.'),Qt::CaseInsensitive).toInt() );
        cObj.insert("order_status",orderObject->orderStatus);//订单的状态
        cObj.insert("products_fee", orderObject->productPrice);    // 商品金额
        //只有星巴克App 才挂MSR的虚拟卡号;目前饿了么也要挂MSR的虚拟卡号;卡号是空 则 MSR_NO='-1' 卡号不入机;
        QString temp_MSR_NO;
        temp_MSR_NO = (orderObject->msr_no.length()==0)?orderObject->customerId:orderObject->msr_no;
        temp_MSR_NO = (temp_MSR_NO.length()==0)?QString::fromLocal8Bit("-1"):temp_MSR_NO;
        cObj.insert("msr_card_no", temp_MSR_NO); // MSR卡号

        if("ELE" == orderObject->channel || "MT-MOD" == orderObject->channel || "MT-MOP" == orderObject->channel ){
            cObj.insert("thirdPartyOrderId",orderObject->thirdPartyOrderId);
        } else {
            cObj.insert("thirdPartyOrderId","0");
        }
        cObj.insert("paid_trans_id",orderObject->id);
        /************************************************************************************/
        cObj.insert("hasCashbox",1);
        cObj.insert("hasRefundAuth",1);
        /************************************************************************************/
        rObj.insert("pay_id", cObj);
        QJsonArray products;
        QJsonArray coupons;
        QJsonArray payments;
        QJsonArray orderCoupons;
        /**********************************************************************************/
        // 循环订单的最外层商品列表；
        /**********************************************************************************/
        for(int i=0; i < orderObject->proList.count(); i++) {
            dishesObject* dish=orderObject->proList.at(i);
            //初步设定20个促销优惠折扣类型(其value值对应 为 折扣已添加数量): 万能优惠 + 星星优惠 + 券-B账户优惠 + SVC-B账户优惠
            int promotTypeTotal = 20;
            int promotTypeArray[20] = {0};

            // 安全检查:Sku,Qty ...:不合法直接跳过录单【①主商品属性：code中含有Default字符串（不区分大小写）+ ②code中以非数字开头 + ③商品数量是0】 直接跳过录单;
            QString tempCodeLeftHead = dish->code.left(1);
            if (dish->code.contains("Default",Qt::CaseInsensitive) || (tempCodeLeftHead<QString('0') || tempCodeLeftHead>QString('9'))
                    || !dish->qty || dish->code.length()<3 || dish->code.length()>9 ) {
                //①code中以非数字开头直接退出本次录单
                //②code中长度小于3位 直接退出本次录单; [ '34' , '16' ]
                //③code中长度大于9位 直接退出本次录单; [ '1234567890' ]
                //④code 异常, 向oms 汇报异常;
                error = QString::fromLocal8Bit("This Order Has PosKey Is Combo Error Or Default*  Or  qty Is Zore  Or  Sku Length < 3 Or  Sku Length > 9");
                m_OrderEntryMutex.lock();
                m_simValidOrdersList.removeOne(orderObject->id);
                m_OrderEntryMutex.unlock();
                m_bFloatFromLockSt = false; //解锁悬浮框的锁定标志;
                emit doUnLockFloatFrom();   //解锁悬浮框锁定
                // 存储订单入机前异常信息并汇报OMS;
                QString requestType = orderObject->orderStatus==6?QString::fromLocal8Bit("6"):QString::fromLocal8Bit("3");
                _AddOrUpdateReportOmsList(orderObject->id,  orderObject->channel,requestType, QString("2"), QString(""), error, QString("1010"));
                return true;
            }
            /**********************************************************************************/
            // 针对同一商品，多份数量需要将其，拆分成单份;[如果不拆分，将导致多份商品中配料价格出现 漏钱:POS中的账将会出现少金额]
            // 新增 一种case: 餐具费项目需要合并, 进行不拆分 处理: qtyNoSplit
            /**********************************************************************************/
            if (dish->qtyNoSplit ) {       // ------> 不拆分主商品数量 --Begin ---->>>
                //声明临时栈对象: 多个主商品;
                QJsonObject noSplitMainProObj;
                QJsonArray noSplitSubProductArry;
                QJsonObject noSplitSubObj;
                noSplitMainProObj.insert("consume_num", dish->qty);
                noSplitMainProObj.insert("pid", dish->chgPrcFlgCode);   // 传递含改价标识重新组装的sku;
                noSplitMainProObj.insert("original_price", dish->price);
                /**********************************************************************************/
                // 处理原始的配料信息;
                /**********************************************************************************/
                if(!dish->sub_products.isEmpty()) {
                    for(int j=0; j < dish->sub_products.count(); j++) {
                        dishesObject* subDish=dish->sub_products.at(j);
                        //安全检查:Sku,Qty ...:不合法直接跳过录单
                        if(!subDish->code.isEmpty() && !subDish->code.contains("Default",Qt::CaseInsensitive) && subDish->qty ) {
                            //①code中以非数字开头直接退出本次录单;
                            //②code中长度小于3位 直接退出本次录单; [ '34' , '16' ]
                            //③code中长度大于9位 直接退出本次录单; [ '1234567890' ]
                            //④code 异常, 向oms 汇报异常;
                            QString  tempSubCodeLeftHead  = subDish->code.left(1);
                            if ( tempSubCodeLeftHead<QString('0') || tempSubCodeLeftHead>QString('9')  ||  subDish->code.length()<3 ||  subDish->code.length()>9 ) {
                                error = QString::fromLocal8Bit("This Order SubProduct PosKey Is String And No Contains Default Or Sku Length < 3 Or Sku Length > 9 ");
                                m_OrderEntryMutex.lock();
                                m_simValidOrdersList.removeOne(orderObject->id);
                                m_OrderEntryMutex.unlock();

                                m_bFloatFromLockSt = false; //解锁悬浮框的锁定标志;
                                emit doUnLockFloatFrom();   //解锁悬浮框锁定

                                // 存储订单入机前异常信息并汇报OMS;
                                QString requestType = orderObject->orderStatus==6?QString::fromLocal8Bit("6"):QString::fromLocal8Bit("3");
                                _AddOrUpdateReportOmsList(orderObject->id,  orderObject->channel,requestType, QString("2"), QString(""), error, QString("1011") );
                                return true;
                            }
                            noSplitSubObj.insert("consume_num", subDish->qty);
                            noSplitSubObj.insert("pid", subDish->code);      // 传递含改价标识重新组装的sku; 目前客制化不存在改价可能,故不替换：subDish->chgPrcFlgCode
                            noSplitSubObj.insert("original_price", subDish->price);
                            noSplitSubProductArry.push_back(noSplitSubObj);
                        }
                    }
                }
                /**********************************************************************************/
                // 处理商品的属性(热 -> 特别热)的额外配料信息;
                /**********************************************************************************/
                if(dish->options.length()){
                    noSplitSubObj.insert("consume_num", 1);
                    noSplitSubObj.insert("pid", dish->options);
                    noSplitSubObj.insert("original_price", 0);
                    noSplitSubProductArry.push_back(noSplitSubObj);
                }
                /**********************************************************************************/
                // 不拆分商品合并：优惠折扣数量默认为 1 但是整单体现是 * 主商品数量;
                // 商品促销优惠数组存在: dish->itemsDiscount 则不会再取接口返回的 星星优惠 与 万能优惠;
                if ( !dish->itemsDiscount.isEmpty() ) {
                    for(int m=0; m < dish->itemsDiscount.count(); m++) {
                        PromotionItemObject* promotionObj= dish->itemsDiscount.at(m);
                        if (promotionObj->promotionQty && promotionObj->discountFee && promotionObj->promotionSku.length() ) {
                            noSplitSubObj.insert("consume_num", 1);
                            noSplitSubObj.insert("pid", promotionObj->promotionSku);
                            noSplitSubObj.insert("original_price",  promotionObj->promotionQty * promotionObj->discountFee);
                            noSplitSubProductArry.push_back(noSplitSubObj);
                        }
                    }
                }
                /**********************************************************************************/
                // 汇总插入子商品[sub_products];
                if(noSplitSubProductArry.size()){
                    noSplitMainProObj.insert("sub_products",noSplitSubProductArry);
                } // end 整合子商品结束；
                //products.insert(i, tObj); //防止default*的主商品码出现,上面代码出现continue;导致 i出现跳数，插入时出现崩溃;
                products.push_back(noSplitMainProObj);
                // ------> 不拆分主商品数量 --End   ---->>>

            } else {    // ------> 拆分主商品数量 --Begin ---->>>
                for (int temp_qty = 0; temp_qty < dish->qty; temp_qty++) {
                    //声明临时栈对象: 单个主商品 + 子商品列表 + 子商品;
                    QJsonObject tObj;
                    QJsonArray subProduct;
                    QJsonObject sObj;
                    tObj.insert("consume_num", 1);
                    tObj.insert("pid", dish->chgPrcFlgCode);   // 传递含改价标识重新组装的sku;
                    tObj.insert("original_price", dish->price);
                    /**********************************************************************************/
                    // 处理原始的配料信息;
                    if(!dish->sub_products.isEmpty()) {
                        for(int j=0; j < dish->sub_products.count(); j++) {
                            dishesObject* subDish=dish->sub_products.at(j);
                            //安全检查:Sku,Qty ...:不合法直接跳过录单
                            if(!subDish->code.isEmpty() && !subDish->code.contains("Default",Qt::CaseInsensitive) && subDish->qty ) {
                                //①code中以非数字开头直接退出本次录单;
                                //②code中长度小于3位 直接退出本次录单; [ '34' , '16' ]
                                //③code中长度大于9位 直接退出本次录单; [ '1234567890' ]
                                //④code 异常, 向oms 汇报异常;
                                QString  tempSubCodeLeftHead  = subDish->code.left(1);
                                if ( tempSubCodeLeftHead<QString('0') || tempSubCodeLeftHead>QString('9')  ||  subDish->code.length()<3 ||  subDish->code.length()>9 ) {
                                    error = QString::fromLocal8Bit("This Order SubProduct PosKey Is String And No Contains Default Or Sku Length < 3 Or Sku Length > 9 ");
                                    m_OrderEntryMutex.lock();
                                    m_simValidOrdersList.removeOne(orderObject->id);
                                    m_OrderEntryMutex.unlock();

                                    m_bFloatFromLockSt = false; //解锁悬浮框的锁定标志;
                                    emit doUnLockFloatFrom();   //解锁悬浮框锁定

                                    // 存储订单入机前异常信息并汇报OMS;
                                    QString requestType = orderObject->orderStatus==6?QString::fromLocal8Bit("6"):QString::fromLocal8Bit("3");
                                    _AddOrUpdateReportOmsList(orderObject->id,  orderObject->channel,requestType, QString("2"), QString(""), error, QString("1011") );

                                    return true;
                                }
                                sObj.insert("consume_num", subDish->qty);
                                sObj.insert("pid", subDish->code);     // 传递含改价标识重新组装的sku; 目前客制化不存在改价可能,故不替换：subDish->chgPrcFlgCode
                                sObj.insert("original_price", subDish->price);
                                subProduct.push_back(sObj);
                            }
                        }
                    }
                    /**********************************************************************************/
                    // 处理商品的属性(热 -> 特别热)的额外配料信息;
                    if(dish->options.length()){
                        sObj.insert("consume_num", 1);
                        sObj.insert("pid", dish->options);
                        sObj.insert("original_price", 0);
                        subProduct.push_back(sObj);
                    }
                    /**********************************************************************************/
                    // 处理商品的优惠金额信息;针对单个商品多数量情况：需要将这部分优惠折扣金额放在前面 拆分数量的商品上
                    // [多少个折扣券，放在前几个商品上，一个上面下对应一个折扣项];
                    // 商品促销优惠数组存在: dish->itemsDiscount 则不会再取接口返回的 星星优惠 与 万能优惠;
                    if ( !dish->itemsDiscount.isEmpty() ) {
                        for(int m=0; m < dish->itemsDiscount.count(); m++) {
                            PromotionItemObject* promotionObj= dish->itemsDiscount.at(m);
                            if (promotionObj->promotionQty && promotionObj->discountFee && promotionObj->promotionSku.length() ) {
                                // 合理平铺折扣数量: 万能优惠 + 星星优惠  + 券B账户优惠 + SVC卡-B账户优惠;
                                for ( int  p = 1; p < promotTypeTotal ; p++) {
                                    if ( p == promotionObj->type && promotTypeArray[p] < promotionObj->promotionQty ) {
                                        sObj.insert("consume_num", 1);
                                        sObj.insert("pid", promotionObj->promotionSku);
                                        sObj.insert("original_price",  promotionObj->discountFee);
                                        subProduct.push_back(sObj);
                                        promotTypeArray[p]++;
                                        break;
                                    }
                                }
                            }
                        }
                    }
                    /**********************************************************************************/
                    // 汇总插入子商品[sub_products];
                    if(subProduct.size()){
                        tObj.insert("sub_products",subProduct);
                    } // end 整合子商品结束；
                    //products.insert(i, tObj); //防止default*的主商品码出现,上面代码出现continue;导致 i出现跳数，插入时出现崩溃;
                    products.push_back(tObj);
                }  // ------> 拆分主商品数量 --End ---->>>

            }

        }

        //**********************************整合WSG券信息-begin*****************************************//
        // 循环订单的WSG券 列表 [进入循环条件: 存在券列表;];
        // 美好咖啡不能在录入额外券 Tender 【单品券 + 配送费券】否则会有额外报错;
        /**********************************************************************************/
        for(int i=0; i < orderObject->coupList.count() && ( "WSG-MOD" == orderObject->channel || "WSG-MOP" == orderObject->channel ) ; i++) {
            CouponsObject* coupon=orderObject->coupList.at(i);
            QJsonObject tCoupObj;
            /**********************************************************/
            // 先整合非门店售券的所有三方券列表数据;
            /**********************************************************/
            //为了后续追踪,录入一个MOD(84)0元支付方式;
            if(0==i){
                QJsonObject tStarbusAppFmIdObj;;
                tStarbusAppFmIdObj.insert("couponSeq",QString::number(0) ) ;         //券的序号
                tStarbusAppFmIdObj.insert("couponCode",orderObject->id.right(24));   //存放非码订单号（防止存不下，自动截取后24位）： couponCode目前最长19位长度;DLL设置24长度;
                tStarbusAppFmIdObj.insert("couponType",QString("0"));
                tStarbusAppFmIdObj.insert("payMethodId",QString("84")); //订单支付方式:MOD(84) 0元支付方式 ;
                tStarbusAppFmIdObj.insert("consumeFactAmount",0);
                coupons.push_back(tStarbusAppFmIdObj);
            }

            //先跳过门店售券,现金支付:最后在补录一个现金支付方式;
            //针对美好咖啡订单 也必须跳过券tender信息;
            if(!coupon->storeChannel && 1 != orderObject->isGiftitForward ) {
                tCoupObj.insert("couponSeq",QString::number(i+1) ) ;             //券的序号
                tCoupObj.insert("couponCode",coupon->code);   //准确的券号码；例: 7019380051100056143 目前最长 19位长度;
                tCoupObj.insert("couponType",coupon->couponType);
                tCoupObj.insert("payMethodId",coupon->payMethodId); //券支付方式: 15纸质卷 16电子卷 ;
                tCoupObj.insert("consumeFactAmount",coupon->consumeFactAmount); //券实际支付金额 (单位:分);
                coupons.push_back(tCoupObj);
            }
            /**********************************************************/
            // 整合所有券核销的商品+券折扣 列表数据;
            /**********************************************************/
            for (int tempSkuSeq = 0; tempSkuSeq < coupon->skus.size(); tempSkuSeq++) {
                QString tempSkuCode = coupon->skus[tempSkuSeq]->code;
                int  tempSkuQty   = coupon->skus[tempSkuSeq]->qty;
                //安全检查:Sku,Qty ...:不合法直接跳过录单
                if(tempSkuCode.isEmpty() || tempSkuCode.contains("Default",Qt::CaseInsensitive)  || tempSkuCode.left(1) < QString('0') || tempSkuCode.left(1) > QString('9')
                        || tempSkuCode.length()<3 ||  tempSkuCode.length()>9 || 0== tempSkuQty  ) {
                    //①code中 空, 含default字符串, 以及 非数字开头直接退出本次录单;
                    //②code中长度小于3位 直接退出本次录单; [ '34' , '16' ]
                    //③code中长度大于9位 直接退出本次录单; [ '1234567890' ]
                    //④code 异常, 向oms 汇报异常;
                    error = QString::fromLocal8Bit("This Order Coupon Product PosKey Is String And No Contains Default Or Sku Length < 3 Or Sku Length > 9 ");
                    m_OrderEntryMutex.lock();
                    m_simValidOrdersList.removeOne(orderObject->id);
                    m_OrderEntryMutex.unlock();
                    m_bFloatFromLockSt = false; //解锁悬浮框的锁定标志;
                    emit doUnLockFloatFrom();   //解锁悬浮框锁定
                    // 存储订单入机前异常信息并汇报OMS;
                    QString requestType = orderObject->orderStatus==6?QString::fromLocal8Bit("6"):QString::fromLocal8Bit("3");
                    _AddOrUpdateReportOmsList(orderObject->id,  orderObject->channel,requestType, QString("2"), QString(""), error, QString("1010") );
                    return true;
                }

                //声明临时栈对象: 单个券关联商品;
                QJsonObject tCoupProductObj;
                tCoupProductObj.insert("couponSeq", QString::number(i+1) );
                tCoupProductObj.insert("consume_num", coupon->skus[tempSkuSeq]->qty );
                // tCoupProductObj.insert("pid", coupon->skus[tempSkuSeq]->code);  // 支持 WSG券改价模式入机;
                tCoupProductObj.insert("pid", coupon->skus[tempSkuSeq]->chgPrcFlgCode);
                //需要考虑 门店券 蛋糕的Combo头开始会限定后续蛋糕子项的价格后面的价格是否会都是0;
                if (coupon->skus[tempSkuSeq]->isCoupon) {
                    tCoupProductObj.insert("original_price", coupon->skus[tempSkuSeq]->price );

                }else{
                    tCoupProductObj.insert("original_price",0);
                }
                products.push_back(tCoupProductObj);
                //如果单品是券menuItem: 需要将券折扣挂在此券单品名下;
                if ( coupon->skus[tempSkuSeq]->isCoupon ) {
                    if ( !coupon->itemsDiscount.isEmpty() ) {
                        for(int m=0; m < coupon->itemsDiscount.count(); m++) {
                            PromotionItemObject* promotionObj= coupon->itemsDiscount.at(m);
                            if (promotionObj->promotionQty && promotionObj->discountFee && promotionObj->promotionSku.length() ) {
                                QJsonObject tCoupProductDiscObj;
                                tCoupProductDiscObj.insert("consume_num", promotionObj->promotionQty);
                                tCoupProductDiscObj.insert("pid", promotionObj->promotionSku);
                                tCoupProductDiscObj.insert("original_price",  promotionObj->discountFee);
                                products.push_back(tCoupProductDiscObj);
                            }
                        }
                    }
                }

            }

        }
        //开头已经新增一条【MOD:84 0元支付方式】
        //**********************************整合WSG券信息-end*****************************************//

        //**********************************整合多支付方式信息【银联】-begin*****************************************//
        // 循环订单的 多支付方式列表【银联】 [进入循环条件: 存在多支付方式列表];
        /**********************************************************************************/
        for(int i=0; i < orderObject->paymentList.count() ; i++) {
            PaymentObject* payment=orderObject->paymentList.at(i);
            QJsonObject tPaymentObj;
            //如果是ELEME的istore 订单，需要额外录入一个标志IStore订单: 8==orderObject->payWay
            //如果是App银联支付的多笔支付方式;也必须额外录入一条84的支付方式;
            if(0==i){
                /**** orderObject->payWay: 8 ->IStore渠道订单(87:istore 0元支付方式); 3/9 ->App银联支付标志(84:MOD 0元支付方式) ****/
                /**** orderObject->payWay: 11 -> 招行一招付[ 84-0MOD; 61-积分抵扣; *-一招付;  *招行满减Tender ] ****/
                QJsonObject tStarbAppOrderPayFlagObj;
                tStarbAppOrderPayFlagObj.insert("couponSeq",QString::number(0) ) ; //支付方式的序号
                tStarbAppOrderPayFlagObj.insert("couponType",QString("0"));
                //存放非码订单号（防止存不下，自动截取后24位）： couponCode目前最长19位长度;DLL设置24长度;
                tStarbAppOrderPayFlagObj.insert("couponCode",orderObject->id.right(24));
                tStarbAppOrderPayFlagObj.insert("payMethodId",QString("84"));
                tStarbAppOrderPayFlagObj.insert("consumeFactAmount",0);
                payments.push_back(tStarbAppOrderPayFlagObj);
            }
            tPaymentObj.insert("couponSeq",QString::number(i+1) ) ;  //券的序号
            // 准确的券号码；例: 7019380051100056143 目前最长 19位长度;  //退货订单: 需要录入 refundFmId;
            // App银联支付: 最多存在两条相同 Upp FmId 的交易支付记录;
            // 但是IStore渠道的多笔SVC不同交易Upp FmId 将仍会是bug 【后台退单(OK); + 插件上退单(bug);】;
            if( 9 == orderObject->payWay || 3 == orderObject->payWay || 11 == orderObject->payWay ) {
                if(OrderObject::Refunded == orderObject->orderStatus ||OrderObject::SimExceptRefund == orderObject->orderStatus){
                    tPaymentObj.insert("couponCode",orderObject->refundFmId.isEmpty()?QString("0"):orderObject->refundFmId);
                } else {
                    tPaymentObj.insert("couponCode",payment->paymentFmId);
                }
            } else {
                //准确的券号码；例: 7019380051100056143 目前最长 19位长度;
                tPaymentObj.insert("couponCode",payment->paymentFmId);
            }
            tPaymentObj.insert("couponType",QString("0"));
            tPaymentObj.insert("payMethodId",payment->payMethodId); //券支付方式: 15纸质卷 16电子卷 ;
            tPaymentObj.insert("consumeFactAmount",payment->paymentMoney); //券实际支付金额 (单位:分);
            payments.push_back(tPaymentObj);
        }
        //**********************************整合多支付方式信息【银联】-end*****************************************//

        //**********************************整合 订单组合券 信息-begin*****************************************//
        // 循环订单组合券列表 [进入循环条件: 存在订单组合券列表];
        // 三种可能场景:  ① 银联支付列表空 && WSG券支付列表空 ② 银联支付列表空 && WSG券支付列表非空 ③银联支付列表非空 && WSG券支付列表空
        /**********************************************************************************/
        for(int i=0; i < orderObject->orderCoupList.count(); i++) {
            CouponsObject* orderCoupon=orderObject->orderCoupList.at(i);
            QJsonObject tOrderCoupObj;
            // 银联支付列表空 && WSG券支付列表空;
            if (0==i && payments.isEmpty() && coupons.isEmpty() ) {
                QJsonObject tOmsOrderIdObj;;
                tOmsOrderIdObj.insert("couponSeq",QString::number(0) ) ;         //券的序号
                tOmsOrderIdObj.insert("couponCode",orderObject->id.right(24));   //存放非码订单号(防止存不下,自动截取后24位) couponCode目前最长19位长度;DLL设置24长度;
                tOmsOrderIdObj.insert("couponType",QString("0"));
                tOmsOrderIdObj.insert("payMethodId",QString("84"));   //订单支付方式:MOD(84) 0元支付方式 ;
                tOmsOrderIdObj.insert("consumeFactAmount",0);
                orderCoupons.push_back(tOmsOrderIdObj);
            }

            if (!orderCoupon->storeChannel) {
                tOrderCoupObj.insert("couponSeq",QString::number( orderCoupons.size() ) ) ;   //券的序号
                tOrderCoupObj.insert("couponCode",orderCoupon->code);   //准确的券号码；例: 7019380051100056143 目前最长 19位长度;DLL设置24长度;
                tOrderCoupObj.insert("couponType",orderCoupon->couponType);
                tOrderCoupObj.insert("payMethodId",orderCoupon->payMethodId); //券支付方式: 15纸质卷 16电子卷 ;
                tOrderCoupObj.insert("consumeFactAmount",orderCoupon->consumeFactAmount); //券实际支付金额 (单位:分);
                orderCoupons.push_back(tOrderCoupObj);
            }
            // 添加组合支付后 其他方式的支付方式: 微信 / 支付宝 / SVC / 等等【不含 ELE】
            if ( (orderObject->orderCoupList.count() -1) == i ) {
                if ( !orderObject->paymentList.isEmpty() ||  !orderObject->coupList.isEmpty()  ) {
                    QLOG_INFO()<<QString::fromLocal8Bit("--- paymentList.size()=%1, coupList.size()=%2 至少一个支付List非空, 无需整合常规支付方式---")
                                 .arg( orderObject->paymentList.size() ).arg( orderObject->coupList.size() );
                } else {
                    // 添加常规支付方式和交易流水: 微信 / 支付宝 / SVC / 等等【不含 ELE】
                    if ( tempSbkAppPayValue.length() > 4 ) {
                        tOrderCoupObj.insert("couponSeq",QString::number(orderCoupons.size() ) ) ;  //券的序号
                        // svc:长度20; 支付宝:长度28; 微信:长度28; DLL设置24长度,只能使用Simphony程序中接受完整的 tempSbkAppPayValue;
                        tOrderCoupObj.insert("couponCode",tempSbkAppPayValue.mid(6) );
                        tOrderCoupObj.insert("couponType",QString("-1"));
                        tOrderCoupObj.insert("payMethodId",tempSbkAppPayType); //混合支付尾部支付: 78:支付宝; 77:微信; *:银联; 14:SVC卡;
                        tOrderCoupObj.insert("consumeFactAmount", -1 ); //券实际支付金额 (单位:分);
                        orderCoupons.push_back(tOrderCoupObj);
                    }
                }
            }

        }
        //整合WSG券 + 整合银联支付 已经新增一条【MOD:84 0元支付方式】
        //**********************************整合 订单组合券 信息-end*****************************************//


        //向商品列表中 添加 是否打包的SKU;
        if(orderObject->isPackage && orderObject->packageSku.length()) {
            QJsonObject tPackageObj;
            tPackageObj.insert("consume_num", 1);
            tPackageObj.insert("pid", orderObject->packageSku);
            tPackageObj.insert("original_price", 0);
            products.push_back(tPackageObj);
        }
        /* 需要将 到店做 SKU 分配的每个主商品的配料的最尾部:此部分逻辑放到 服务端处理;向商品列表中 添加 是否到店做SKU;*/

        //**********************************整合包装费-begin*****************************************//
        // 向商品列表尾部 添加 包装费项 + 包装费折扣项;
        // 包装费 >0  + MOP 也不能入机【特别说明:WSG-MOD 配送费及配送费折扣信息存储 coupons中;故在此处排除】
        //【包装费不能是已经添加到商品列表: !orderObject->packageFeeAtProduct】
        if ( orderObject->packageFee > 0 && !orderObject->packageFeeAtProduct && ( "MOD"==orderObject->channel || "ELE" == orderObject->channel || "MT-MOD" == orderObject->channel )  ) {
            QJsonObject tPackageFeeObj;
            tPackageFeeObj.insert("consume_num", orderObject->packageFee/100);
            tPackageFeeObj.insert("pid", "6000201"); //包装费SKU;
            tPackageFeeObj.insert("original_price", 100);
            products.push_back(tPackageFeeObj);
            //星巴克APP/预约系统的支付方式是84; ELE的支付方式是83; [MOP不应该存在打包费且不存在包装费折扣]
            if( orderObject->packDiscount>0 ){
                QJsonObject tPackDiscountObj;
                tPackDiscountObj.insert("consume_num", 1);
                if ( "ELE" == orderObject->channel ) {
                    tPackDiscountObj.insert("pid","10400"); //ELEME万能折扣码;
                } else if ( "MT-MOD" == orderObject->channel ) {
                    tPackDiscountObj.insert("pid","10400"); // MT万能折扣码;  by 待更新 wuyang 2021-08
                } else {
                    tPackDiscountObj.insert("pid","285"); //星巴克APP万能折扣码;
                }
                tPackDiscountObj.insert("original_price", orderObject->packDiscount);
                products.push_back(tPackDiscountObj);
            }
        //打包费是0元时( MOP 包装费不能入机):需录入打包费[非-MOP(销售退货),非-MOP测试];  【包装费不能是已经添加到商品列表: !orderObject->packageFeeAtProduct】
        } else if ( 0 == orderObject->packageFee && !orderObject->packageFeeAtProduct && ( "MOD"==orderObject->channel || "ELE" == orderObject->channel  || "MT-MOD" == orderObject->channel ) ) {
            QJsonObject tPackageFeeObj;
            tPackageFeeObj.insert("consume_num", 1);
            tPackageFeeObj.insert("pid","6000201"); //包装费SKU;
            tPackageFeeObj.insert("original_price", 0);
            products.push_back(tPackageFeeObj);
        }
        //**********************************整合包装费-end*****************************************//

        //**********************************整合配送费-begin*****************************************//
        //向商品列表尾部 添加 配送费项 + 配送费折扣项; 【特别说明:WSG-MOD 配送费及配送费折扣信息存储 coupons中;故在此处排除】
        //上游oms 开关已完全打开: 配送费已添加到商品列表中; 顾无需此处配送费整合逻辑;
        //*********************************整合配送费-end******************************************//

        //****************************整合订单商品列表末尾追加一个MenuItem:9107815 无其他-begin******************//
        //此操作是防止一种异常情况发生: 退货 + 最后一个商品尾部存在一个折扣 + 且后面无客制化且无卡号 + 直接挂支付方式;
        //避免在退货的dsc事件中 挂 支付方式信息;
        if(1){
            QJsonObject tDefaultWuQiTaObj;
            tDefaultWuQiTaObj.insert("consume_num", 1);
            tDefaultWuQiTaObj.insert("pid","9107815"); //无其他-SKU;
            tDefaultWuQiTaObj.insert("original_price", 0);
            products.push_back(tDefaultWuQiTaObj);
        }
        //****************************整合订单商品列表末尾追加一个MenuItem: 无其他-end******************//
        //组装完成JSON 对象的商品数据；
        rObj.insert("products", products);
        //如果存在预约券信息，则不可能存在<多条支付方式>可能[App的银联支付+istore的多张SVC卡消费记录],两者相斥，但公用一个Dll[coupons]数据传输通道;
        QJsonValue tmpOrderCoup;
        if( coupons.count() ) {
            while ( orderCoupons.size() ){
                tmpOrderCoup = orderCoupons.first();
                coupons.push_back(tmpOrderCoup);
                orderCoupons.removeFirst();
            }
            rObj.insert("coupons", coupons);
        } else {
            while ( orderCoupons.size() ){
                tmpOrderCoup = orderCoupons.first();
                payments.push_back(tmpOrderCoup);
                orderCoupons.removeFirst();
            }
            rObj.insert("coupons", payments);
        }
        data= rObj;
    }
    return result;
}


void FlowControl::_AutoLoginSkipCashier() {

    QLOG_INFO()<<__FUNCTION__;
    // m_storeId = GetCaboxAReAuth::getInstance().getDbStoreId(); //未登陆成功前 DB storeId;
    m_storeId = PosMetaDataDB::getInstance().getDbStoreId();
    m_subStoreId =  ConfigManger::GetInstance().GetSubStoreId();
    if ( m_backupPosFlag ) {
        m_posId= BACKUP_POS_UNIQUE_ID;
    } else {
        m_posId= MASTER_POS_UNIQUE_ID;
    }

    // m_posWorkstationNum = GetCaboxAReAuth::getInstance().getDbWorkStationNum();   //POS DB WorkStation Num; [不准确: 存在空值]
    RefreshPosMetaData();

    if ( m_storeId.length() ) {
        // emit doLogin(); signal Can't Send Success;  Same Pthread, No Need Use Signal & Slot;
        onGetNewStoreInfo();  // New Timer And Login Upstream Service;
    } else {
        //人性化提示:门店号没有正常从POS DB 中获取到;
        emit showAlert(AlertForm::MSGERROR, QString::fromLocal8Bit("从POS数据库中获取门店号失败"));
        QLOG_ERROR()<<QString::fromLocal8Bit("[<<<<---_AutoLoginSkipCashier: Get m_storeId Is Empty From DataBase Error--->>>>>]");
    }

    return;
}


QString FlowControl::_Penny2Dollar(int penny)
{
    double dollar = (double)penny/100;
    return QString::number(dollar,'f',1);
}


void FlowControl::onGetBusinessStatus()
{
}


void FlowControl::onGetOMSAllOrders()
{
    QLOG_INFO()<<__FUNCTION__;
    if(!m_bLoginResult) {
        emit showAlert(AlertForm::MSGERROR, QString::fromLocal8Bit("门店还未登录"));
        return ;
    }
    // 类登陆后的获取全部订单动作;
    QLOG_INFO() << QString(" FlowControl::onGetOMSAllOrders only _AddOrderPull begin.");

    // 获取原生链路的全量订单列表数据;
    _AddOrderPull( QString(), QString() );

    // 获取 o2ofulfillment 链路的全量订单列表数据;
    if ( ConfigManger::GetInstance().GetLoginServerUrl().contains(".stg") ) {
        _AddOrderPull( QString(), QString(), GET_O2OFULFILLMENT_STG_CBL );
    } else if ( ConfigManger::GetInstance().GetLoginServerUrl().contains(".dev") ) {
        _AddOrderPull( QString(), QString(), GET_O2OFULFILLMENT_DEV_CBL );
    } else if ( ConfigManger::GetInstance().GetLoginServerUrl().contains(".uat") ) {
        _AddOrderPull( QString(), QString(), GET_O2OFULFILLMENT_UAT_CBL );
    } else {
        _AddOrderPull( QString(), QString(), GET_O2OFULFILLMENT_PRO_CBL );
    }

     emit showAlert(AlertForm::SYNCDATA, QString::fromLocal8Bit("正在获取平台全部订单,稍后刷新......"));
    QLOG_INFO() << QString(" FlowControl::onGetOMSAllOrders only _AddOrderPull end.");
}



void FlowControl::onProcessOrder(const QString &operation, const QString &orderId)
{
    if(!operation.compare(OPERATION_GETDELIVERS))
    {
        _ConfirmOrder(orderId);
    }else if(!operation.compare(OPERATION_CONFRIM))
    {
        _ConfirmOrder(orderId);
    }
    else if(!operation.compare(OPERATION_SENDOUT))
    {
        _SendOrder(orderId);
    }else if(!operation.compare(OPERATION_COMPLETE))
    {
        _CompleteOrder(orderId);
    }else if(!operation.compare(OPERATION_REFUSEREFUND))
    {

    }else if(!operation.compare(OPERATION_REFUNDORDER))
    {
        _RefundOrder(orderId,5,QString::fromLocal8Bit("同意退款"),QString());
    }
}

void FlowControl::onAckNoticeMsg(const QString& noticeTitle, const int insertIdIndex) {
    bool retUpdateAckStatus = SaveNoticeMsgDB::getInstance().updateNoticeAckStatus( noticeTitle, insertIdIndex );
    QLOG_INFO()<<QString("FlowControl::onAckNoticeMsg  noticeTitle: %1 ,  retUpdateAckStatus : %2 , insertIdIndex:%3 Then Refresh FloatForm & MainForm ")
                 .arg( noticeTitle ).arg( retUpdateAckStatus ? 1 : 0 ).arg( insertIdIndex );

    // 更新 主框体中 notice list 中 Item Ack 状态;
    if ( retUpdateAckStatus ) {
        foreach (NoticeObject* tempNoticeObj, m_noticeObjList) {
            if ( tempNoticeObj->id == insertIdIndex ) {
                tempNoticeObj->ackStatus = 1;
                emit changeNoticeStatus( tempNoticeObj );
            }
        }
    }
    // 更新悬浮框 通告未读告警提示;
    m_existNoAckNotice = SaveNoticeMsgDB::getInstance().existNoAckNotice() ? 1 : 0;
    emit doUpdateStoreStatus(m_eleStoreStatus, m_modStoreStatus, m_mopStoreStatus, m_mtModStoreStatus, m_curbsideStoreStatus, m_existNoAckNotice);
}


bool FlowControl::onRecvSocketPushedMsg(QByteArray &msgData, int & actionId) {
    bool recvRet = false;

    if ( 11 == actionId ) {
        QJsonDocument document = QJsonDocument::fromJson(msgData);
        if ( document.isNull() ) {
            QLOG_ERROR()<<QString("onRecvSocketPushedMsg  QJsonDocument::fromJson(*) Is Null , ActionId : %1").arg(actionId);
        } else {
            QJsonObject orderDataObject = document.object();
            QJsonObject unusedData;
            QString error;
            recvRet = _ResponseOMS11Request(orderDataObject, unusedData, error);
            QLOG_INFO()<<QString("onRecvSocketPushedMsg  recvRet: %1, error: %2").arg(recvRet?1:0).arg(error);
        }

    } else if ( 21 == actionId ) {
        QLOG_INFO() << "onRecvSocketPushedMsg::  ActionID: 21 , Wait Process";
    } else {
        QLOG_ERROR() << "onRecvSocketPushedMsg::  OMS Push Plugin Action Out Of Range";
    }

    return recvRet;
}


void FlowControl::onGetOrderDetails(const QString& orderId)
{
    emit hideAlert();
    if ( !orderId.isEmpty() ) {
        QMap<QString, OrderObject*>::iterator orderIterator;
        orderIterator = m_FmOrdersMap.find(orderId);
        if ( orderIterator == m_FmOrdersMap.end() ){
            QLOG_ERROR() << QString("[<<<<---FlowControl::onGetOrderDetails: OrderId:%1 No Find In m_FmOrdersMap, Can't Get UI Detail--->>>>]").arg(orderId);
        } else {
            emit showOrderDetails(m_FmOrdersMap.value(orderId));
        }
    } else {
        QLOG_INFO() << QString("[<<<<---FlowControl::onGetOrderDetails: OrderId:%1 Is Empty --->>>>]").arg(orderId);
        return;
    }

}


void FlowControl::onGetEcMopOrderDetails(const QString& orderId, const QString& channel)
{
    // 入参非法校验;
    QString tempOrderId = orderId.trimmed();   // 返回一个字符串,移除从一开始到结尾的空白。也去掉头尾的空白【simplified】

    if ( tempOrderId.isEmpty() || channel.isEmpty() || tempOrderId.length() < 17 ||  tempOrderId.length() > 25 ) {
        QLOG_INFO() << QString("[<<<<---FlowControl::onGetEcMopOrderDetails: OrderId:%1 /  channel:%2  Is Empty / Error  --->>>>]").arg( tempOrderId ).arg( channel );
        emit showAlert(AlertForm::MSGERROR,  QString::fromLocal8Bit("扫描订单号异常") );
        return;
    } else {
        QString callBackUrl = "";
        // 入参有效;
        // 判断插件是否登录成功了，没有登录成功，弹框提示;
        if ( !m_bLoginResult  ) {
            emit showAlert(AlertForm::MSGERROR,  QString::fromLocal8Bit("插件程序还未成功登录") );
            return;
        }
        // 组装请求报文 [ 含门店编号:便于 OMS 校验此订单是否属于本门店 ] , 获取订单详情数据 ;[ 失败则弹框提示]

        if ( m_FmOrdersMap.value( tempOrderId ) ) {
            callBackUrl = m_FmOrdersMap.value( tempOrderId )->callBackUrl;
        }

        // 初步上线, 兼容现有环境, EC-MOP 如果拉取失败, 需要 跳过错误展示
        bool pullOrderDetailRet = _PullOrderDetail( tempOrderId, channel, callBackUrl, false, QJsonObject(), true );

        if ( !pullOrderDetailRet ) {

            if ( ConfigManger::GetInstance().GetOrderServerUrl().contains(".stg") ) {
                callBackUrl = GET_O2OFULFILLMENT_STG_CBL ;
            } else if ( ConfigManger::GetInstance().GetOrderServerUrl().contains(".dev") ) {
                callBackUrl = GET_O2OFULFILLMENT_DEV_CBL ;
            } else if ( ConfigManger::GetInstance().GetOrderServerUrl().contains(".uat") ) {
                callBackUrl = GET_O2OFULFILLMENT_UAT_CBL ;
            } else {
                callBackUrl = GET_O2OFULFILLMENT_PRO_CBL ;
            }

            pullOrderDetailRet =  _PullOrderDetail( tempOrderId, channel , callBackUrl );
        }

        if ( pullOrderDetailRet ) {
            // 展示跳转订单详情页面; // 同一线程, 理论无需 Sleep
            Sleep(1000*3);
            emit showOrderDetails( m_FmOrdersMap.value( tempOrderId ) );
        }
    }

}


void FlowControl::onSerachOrder(const QString &text)
{
    QLOG_INFO() << QString::fromLocal8Bit("[<<<<---FlowControl::onSerachOrder:输入的数字串:%1 --->>>>]").arg(text);
    QMap<QString,QString> orderMap;
    if(!text.isEmpty()) {
        QMap<QString, OrderObject*>::iterator order;
        for(order = m_FmOrdersMap.begin(); order!=m_FmOrdersMap.end(); order++) {
            QString orderId = order.key();
            QString phoneId = order.value()->consigneePhone;
            QString thirdPartyOrderId = order.value()->thirdPartyOrderId;
            while (!orderId.at(0).isDigit()) {
              orderId = orderId.mid(1);
            }
            if(orderId.startsWith(text)) {
                orderMap.insert(QString::fromLocal8Bit("订单号:")+orderId,QString::fromLocal8Bit("三方订单号:")+thirdPartyOrderId);
            }
            //移除手机号检索
            /*
            if(phoneId.startsWith(text)) {
                orderMap.insert(QString::fromLocal8Bit("订单号:")+orderId,QString::fromLocal8Bit("手机号:")+phoneId);
            }
            */
            //新增第三方订单号检索;
            if(thirdPartyOrderId.startsWith(text)) {
                orderMap.insert(QString::fromLocal8Bit("订单号:")+orderId,QString::fromLocal8Bit("三方订单号:")+thirdPartyOrderId);
            }
        }
    }
    emit showSearchOrderResult(orderMap);
}


void FlowControl::onProcessRejectOrder(const QString &orderId, const int &reasonCode,const QString &reason)
{
    Q_UNUSED(orderId);
    Q_UNUSED(reasonCode);
    Q_UNUSED(reason);
}


void FlowControl::onProcessRepealOrder(const QString &orderId, const int &reasonCode,const QString &reason,const QString& dishesListString)
{
    QLOG_INFO() << QString("[<<<<---FlowControl::onProcessRepealOrder: --->>>>]");
    _RefundOrder(orderId,reasonCode,reason,dishesListString);
}


void FlowControl::onProcessRetryPrintOrder(const QString& orderId, const int& printTicketTypeCode, const QString& printTicketTypeStr)
{
    QLOG_INFO() << QString("[<<<<---FlowControl::onProcessRetryPrintOrder: OrderId: %1 TicketTypeCode: %2 TicketTypeStr: %3--->>>>]")
                   .arg(orderId).arg(printTicketTypeCode).arg(printTicketTypeStr);
    //先判断非码订单容器不为空;
    if ( !m_FmOrdersMap.isEmpty() ) {
        OrderObject* tempOrder = NULL;
        if ( m_FmOrdersMap.value( orderId ) ) {
            tempOrder = m_FmOrdersMap.value( orderId );
        }
        PrintMsgQueueDB::getInstance().resetPrintMsgStatus(tempOrder, printTicketTypeCode);
    } else {
        QLOG_INFO() << QString("[<<<<---FlowControl::onProcessRetryPrintOrder: m_FmOrdersMap Is Empty --->>>>]");
    }

}


void FlowControl::onProcessRetryInputOrder(const QString &orderId)
{
    QLOG_INFO() << QString("[<<<<---FlowControl::onProcessReTryInputOrder: OrderId: %1 --->>>>]").arg(orderId);
    //先判断非码订单容器不为空;
    if ( !m_FmOrdersMap.isEmpty() ) {
        QMap<QString, OrderObject*>::iterator TempOrder;
        //遍历订单容器列表,找到指定订单;
        for( TempOrder = m_FmOrdersMap.begin(); TempOrder != m_FmOrdersMap.end(); TempOrder++ ) {
            if( TempOrder.key() == orderId) {

                OrderObject* TempOrderObject = TempOrder.value();
                bool btryLock = m_PullOrderDataMutex.tryLock(VALUE_TRYLOCKNETTIMEOUT);
                if (!btryLock) {
                    QLOG_ERROR()<<"[<<<<----FlowControl::onProcessReTryInputOrder Try Lock Failed ---->>>>>]";
                    return;
                }
                /***组装从FM外卖service端的拉单请求参数***/
                PullOrderInfo* orderPull = new PullOrderInfo();
                orderPull->orderId=orderId;
                orderPull->channel=TempOrderObject->channel;
                orderPull->pageNumber=1;
                orderPull->pageSize=30;
                orderPull->pullErrorCount = 0;
                orderPull->callBackUrl = TempOrderObject->callBackUrl;
                orderPull->skipPrint = TempOrderObject->skipPrint;
                orderPull->pushOptions = TempOrderObject->pluginOptions;
                m_orderPullList.append(orderPull);
                m_PullOrderDataMutex.unlock();
            }
        }
    } else {
        QLOG_INFO() << QString("[<<<<---FlowControl::onProcessReTryInputOrder: m_FmOrdersMap Is Empty --->>>>]");
    }
}
